18 changed files with 3687 additions and 377 deletions
@ -0,0 +1,186 @@ |
|||
/* |
|||
* GCC linker script for STM32 microcontrollers (ARM Cortex-M). |
|||
* |
|||
* It exports the symbols needed for the CMSIS assembler startup script for GCC |
|||
* ARM toolchains (_sidata, _sdata, _edata, _sbss, _ebss) and sets the entry |
|||
* point to Reset_Handler. |
|||
* |
|||
* Adapt FLASH/RAM size for your particular device below. |
|||
* |
|||
* @author Bjørn Forsman |
|||
*/ |
|||
|
|||
MEMORY |
|||
{ |
|||
flash (rx) : ORIGIN = 0x08000000, LENGTH = 320K |
|||
ccmram (rw) : ORIGIN = 0x10000000, LENGTH = 64k |
|||
ram (rwx) : ORIGIN = 0x20000000, LENGTH = 2048K |
|||
} |
|||
|
|||
ENTRY(Reset_Handler) |
|||
|
|||
/* |
|||
* Reserve memory for heap and stack. The linker will issue an error if there |
|||
* is not enough memory. |
|||
* |
|||
* NOTE: The reserved heap and stack will be added to the bss column of the |
|||
* binutils size command. |
|||
*/ |
|||
_heap_size = 0x200; /* required amount of heap */ |
|||
_stack_size = 0x400; /* required amount of stack */ |
|||
|
|||
/* |
|||
* The stack starts at the end of RAM and grows downwards. Full-descending |
|||
* stack; decrement first, then store. |
|||
*/ |
|||
_estack = ORIGIN(ram) + LENGTH(ram); |
|||
|
|||
SECTIONS |
|||
{ |
|||
/* Reset and ISR vectors */ |
|||
.isr_vector : |
|||
{ |
|||
__isr_vector_start__ = .; |
|||
KEEP(*(.isr_vector)) /* without 'KEEP' the garbage collector discards this section */ |
|||
ASSERT(. != __isr_vector_start__, "The .isr_vector section is empty"); |
|||
} >flash |
|||
|
|||
|
|||
/* Text section (code and read-only data) */ |
|||
.text : |
|||
{ |
|||
. = ALIGN(4); |
|||
_stext = .; |
|||
*(.text*) /* code */ |
|||
*(.rodata*) /* read only data */ |
|||
|
|||
/* |
|||
* NOTE: .glue_7 and .glue_7t sections are not needed because Cortex-M |
|||
* only supports Thumb instructions, no ARM/Thumb interworking. |
|||
*/ |
|||
|
|||
/* Static constructors and destructors */ |
|||
KEEP(*(.init)) |
|||
KEEP(*(.fini)) |
|||
|
|||
. = ALIGN(4); |
|||
_etext = .; |
|||
} >flash |
|||
|
|||
|
|||
/* |
|||
* Stack unwinding and exception handling sections. |
|||
* |
|||
* ARM compilers emit object files with .ARM.extab and .ARM.exidx sections |
|||
* when using C++ exceptions. Also, at least GCC emits those sections when |
|||
* dividing large numbers (64-bit) in C. So we have to handle them. |
|||
* |
|||
* (ARM uses .ARM.extab and .ARM.exidx instead of the .eh_frame section |
|||
* used on x86.) |
|||
*/ |
|||
.ARM.extab : /* exception unwinding information */ |
|||
{ |
|||
*(.ARM.extab*) |
|||
} >flash |
|||
.ARM.exidx : /* index entries for section unwinding */ |
|||
{ |
|||
*(.ARM.exidx*) |
|||
} >flash |
|||
|
|||
|
|||
/* |
|||
* Newlib and Eglibc (at least) need these for C++ support. |
|||
* |
|||
* (Copied from Sourcery CodeBench Lite: arm-none-eabi-gcc -V) |
|||
*/ |
|||
.preinit_array : |
|||
{ |
|||
PROVIDE_HIDDEN(__preinit_array_start = .); |
|||
KEEP(*(.preinit_array*)) |
|||
PROVIDE_HIDDEN(__preinit_array_end = .); |
|||
} >flash |
|||
.init_array : |
|||
{ |
|||
PROVIDE_HIDDEN(__init_array_start = .); |
|||
KEEP(*(SORT(.init_array.*))) |
|||
KEEP(*(.init_array*)) |
|||
PROVIDE_HIDDEN(__init_array_end = .); |
|||
} >flash |
|||
.fini_array : |
|||
{ |
|||
PROVIDE_HIDDEN(__fini_array_start = .); |
|||
KEEP(*(SORT(.fini_array.*))) |
|||
KEEP(*(.fini_array*)) |
|||
PROVIDE_HIDDEN(__fini_array_end = .); |
|||
} >flash |
|||
|
|||
|
|||
/* |
|||
* Initialized data section. This section is programmed into FLASH (LMA |
|||
* address) and copied to RAM (VMA address) in startup code. |
|||
*/ |
|||
_sidata = .; |
|||
.data : AT(_sidata) /* LMA address is _sidata (in FLASH) */ |
|||
{ |
|||
. = ALIGN(4); |
|||
_sdata = .; /* data section VMA address (in RAM) */ |
|||
*(.data*) |
|||
. = ALIGN(4); |
|||
_edata = .; |
|||
} >ram |
|||
|
|||
/* |
|||
* CCM-RAM data section. Initialization variables can be placed here |
|||
* when the initialization code is provided by the user. Else it is used |
|||
* as an extra piece of memory for heap/stack |
|||
*/ |
|||
_eidata = (_sidata + SIZEOF(.data)); |
|||
.ccm : AT(_sidata + SIZEOF(.data)) /* We want LMA address to be in FLASH (if used for init data) */ |
|||
{ |
|||
. = ALIGN(4); |
|||
_sccm = .; /* data section VMA address (in CCMRAM) */ |
|||
*(.ccm) |
|||
. = ALIGN(4); |
|||
_eccm = .; |
|||
} >ccmram |
|||
|
|||
|
|||
/* Uninitialized data section (zeroed out by startup code) */ |
|||
.bss : |
|||
{ |
|||
. = ALIGN(4); |
|||
_sbss = .; |
|||
__bss_start__ = _sbss; |
|||
*(.bss*) |
|||
*(COMMON) |
|||
. = ALIGN(4); |
|||
_ebss = .; |
|||
__bss_end__ = _ebss; |
|||
} >ram |
|||
|
|||
|
|||
/* |
|||
* Reserve memory for heap and stack. The linker will issue an error if |
|||
* there is not enough memory. |
|||
*/ |
|||
._heap : |
|||
{ |
|||
. = ALIGN(4); |
|||
_end = .; |
|||
__end__ = _end; |
|||
. = . + _heap_size; |
|||
. = ALIGN(4); |
|||
} >ram |
|||
._stack : |
|||
{ |
|||
. = ALIGN(4); |
|||
. = . + _stack_size; |
|||
. = ALIGN(4); |
|||
} >ram |
|||
} |
|||
|
|||
/* Nice to have */ |
|||
__isr_vector_size__ = SIZEOF(.isr_vector); |
|||
__text_size__ = SIZEOF(.text); |
|||
__data_size__ = SIZEOF(.data); |
|||
__bss_size__ = SIZEOF(.bss); |
@ -0,0 +1,309 @@ |
|||
/*
|
|||
* This file is subject to the terms of the GFX License. If a copy of |
|||
* the license was not distributed with this file, you can obtain one at: |
|||
* |
|||
* http://ugfx.org/license.html
|
|||
*/ |
|||
|
|||
#ifndef _GDISP_LLD_BOARD_H |
|||
#define _GDISP_LLD_BOARD_H |
|||
|
|||
/* Avoid naming collisions with CubeHAL. */ |
|||
#undef Red |
|||
#undef Green |
|||
#undef Blue |
|||
|
|||
/* HAL drivers needed for configuration. */ |
|||
#include "stm32f4xx_hal.h" |
|||
#include "stm32f4xx_hal_rcc.h" |
|||
#include "stm32f4xx_hal_gpio.h" |
|||
#include "stm32f4xx_hal_dsi.h" |
|||
/* sdram driver provided by ST. */ |
|||
#include "stm32f469i_discovery_sdram.h" |
|||
/* OTM8009A driver provided by ST. */ |
|||
#include "otm8009a.h" |
|||
|
|||
/** Manually set the LTDC timing. */ |
|||
#ifndef GFX_LTDC_TIMING_SET |
|||
#define GFX_LTDC_TIMING_SET |
|||
#endif |
|||
|
|||
/** Most boards will be revision A. */ |
|||
#ifndef USE_STM32469I_DISCO_REVA |
|||
#define USE_STM32469I_DISCO_REVA |
|||
#endif |
|||
|
|||
/** @brief Panel parameters
|
|||
* |
|||
* This panel is a KoD KM-040TMP-02-0621 DSI LCD Display. |
|||
*/ |
|||
|
|||
static const ltdcConfig driverCfg = { |
|||
800, 480, // Width, Height (pixels)
|
|||
1, 2, // Horizontal, Vertical sync (pixels)
|
|||
15, 34, // Horizontal, Vertical back porch (pixels)
|
|||
16, 34, // Horizontal, Vertical front porch (pixels)
|
|||
0, // Sync flags
|
|||
0x000000, // Clear color (RGB888)
|
|||
|
|||
{ // Background layer config
|
|||
(LLDCOLOR_TYPE *)SDRAM_DEVICE_ADDR, // Frame buffer address
|
|||
800, 480, // Width, Height (pixels)
|
|||
800 * LTDC_PIXELBYTES, // Line pitch (bytes)
|
|||
LTDC_PIXELFORMAT, // Pixel format
|
|||
0, 0, // Start pixel position (x, y)
|
|||
800, 480, // Size of virtual layer (cx, cy)
|
|||
LTDC_COLOR_FUCHSIA, // Default color (ARGB8888)
|
|||
0x980088, // Color key (RGB888)
|
|||
LTDC_BLEND_FIX1_FIX2, // Blending factors
|
|||
0, // Palette (RGB888, can be NULL)
|
|||
0, // Palette length
|
|||
0xFF, // Constant alpha factor
|
|||
LTDC_LEF_ENABLE // Layer configuration flags
|
|||
}, |
|||
|
|||
LTDC_UNUSED_LAYER_CONFIG // Foreground layer config
|
|||
}; |
|||
|
|||
/** Display timing setting */ |
|||
#define KoD_FREQUENCY_DIVIDER 7 |
|||
|
|||
/** Global DSI handle to hold DSI parameters. */ |
|||
DSI_HandleTypeDef dsiHandle; |
|||
|
|||
static GFXINLINE void reset_lcd(GDisplay* g); |
|||
|
|||
/**
|
|||
* @brief Function to intialize the STM32F46i-DISCO board. |
|||
* |
|||
* @param g: Structure holding display parameters. |
|||
*/ |
|||
static GFXINLINE void init_board(GDisplay *g) { |
|||
|
|||
// As we are not using multiple displays we set g->board to NULL as we don't use it
|
|||
g->board = 0; |
|||
|
|||
#ifdef GFX_LTDC_TIMING_SET |
|||
// KoD LCD clock configuration
|
|||
// PLLSAI_VCO Input = HSE_VALUE/PLL_M = 1 Mhz
|
|||
// PLLSAI_VCO Output = PLLSAI_VCO Input * PLLSAIN = 384 Mhz
|
|||
// PLLLCDCLK = PLLSAI_VCO Output/PLLSAIR = 384/7 = 54.857 Mhz
|
|||
// LTDC clock frequency = PLLLCDCLK / LTDC_PLLSAI_DIVR_2 = 54.857/2 = 27.429Mhz
|
|||
#define STM32_SAISRC_NOCLOCK (0 << 23) /**< No clock. */ |
|||
#define STM32_SAISRC_PLL (1 << 23) /**< SAI_CKIN is PLL. */ |
|||
#define STM32_SAIR_DIV2 (0 << 16) /**< R divided by 2. */ |
|||
#define STM32_SAIR_DIV4 (1 << 16) /**< R divided by 4. */ |
|||
#define STM32_SAIR_DIV8 (2 << 16) /**< R divided by 8. */ |
|||
#define STM32_SAIR_DIV16 (3 << 16) /**< R divided by 16. */ |
|||
|
|||
#define STM32_PLLSAIN_VALUE 384 |
|||
#define STM32_PLLSAIQ_VALUE 4 |
|||
#define STM32_PLLSAIR_VALUE KoD_FREQUENCY_DIVIDER |
|||
#define STM32_PLLSAIR_POST STM32_SAIR_DIV2 |
|||
|
|||
RCC->PLLSAICFGR = (STM32_PLLSAIN_VALUE << 6) | (STM32_PLLSAIR_VALUE << 28) | (STM32_PLLSAIQ_VALUE << 24); |
|||
RCC->DCKCFGR = (RCC->DCKCFGR & ~RCC_DCKCFGR_PLLSAIDIVR) | STM32_PLLSAIR_POST; |
|||
RCC->CR |= RCC_CR_PLLSAION; |
|||
#endif |
|||
|
|||
__HAL_RCC_DSI_CLK_ENABLE(); |
|||
|
|||
DSI_PLLInitTypeDef dsiPllInit; |
|||
DSI_CmdCfgTypeDef dsiCmdMode; |
|||
DSI_LPCmdTypeDef dsiAPBCmd; |
|||
/* Filling the DSI intialization struct. */ |
|||
dsiHandle.Instance = DSI; // There is only one DSI interface
|
|||
dsiHandle.Init.AutomaticClockLaneControl = DSI_AUTO_CLK_LANE_CTRL_ENABLE; // Automatic clock lane control: powers down the clock lane when not in use
|
|||
/* Highest speed = 500MHz. */ |
|||
uint16_t laneByteClk_kHz = 62500; /* 500 MHz / 8 = 62.5 MHz = 62500 kHz */ |
|||
/* TXEscapeCkdiv = f(LaneByteClk)/15.62 = 4 -> 500MHz/4 = 25MHz datasheet says around 20MHz */ |
|||
dsiHandle.Init.TXEscapeCkdiv = laneByteClk_kHz/15620; // Low power clock relative to the laneByteClock
|
|||
dsiHandle.Init.NumberOfLanes = DSI_TWO_DATA_LANES; // Two data lines for the fastest transfer speed
|
|||
|
|||
/* Fill in the command mode struct. */ |
|||
dsiCmdMode.VirtualChannelID = 0; // The first virtual channel
|
|||
|
|||
/* Select the appropriate color coding. */ |
|||
#ifdef GDISP_PIXELFORMAT_RGB565 |
|||
dsiCmdMode.ColorCoding = DSI_RGB565; |
|||
#else |
|||
dsiCmdMode.ColorCoding = DSI_RGB888; |
|||
#endif |
|||
|
|||
dsiCmdMode.CommandSize = driverCfg.width; // Amount of pixels sent at once -> one line at a time
|
|||
dsiCmdMode.TearingEffectSource = DSI_TE_EXTERNAL; // Use pin PJ2
|
|||
dsiCmdMode.TearingEffectPolarity = DSI_TE_RISING_EDGE; |
|||
dsiCmdMode.HSPolarity = DSI_HSYNC_ACTIVE_HIGH; |
|||
dsiCmdMode.VSPolarity = DSI_VSYNC_ACTIVE_HIGH; |
|||
dsiCmdMode.DEPolarity = DSI_DATA_ENABLE_ACTIVE_HIGH; |
|||
dsiCmdMode.VSyncPol = DSI_VSYNC_FALLING; |
|||
dsiCmdMode.AutomaticRefresh = DSI_AR_ENABLE; // Use the automatic refresh mode
|
|||
dsiCmdMode.TEAcknowledgeRequest = DSI_TE_ACKNOWLEDGE_DISABLE; // Not needed when using TE through GPIO
|
|||
|
|||
/* GPIO configuration. */ |
|||
GPIO_InitTypeDef gpioInit; |
|||
/* PH7 LCD_RESET */ |
|||
__HAL_RCC_GPIOH_CLK_ENABLE(); |
|||
gpioInit.Pin = GPIO_PIN_7; |
|||
gpioInit.Mode = GPIO_MODE_OUTPUT_OD; |
|||
gpioInit.Pull = GPIO_NOPULL; |
|||
gpioInit.Speed = GPIO_SPEED_HIGH; |
|||
HAL_GPIO_Init(GPIOH, &gpioInit); |
|||
|
|||
/* PJ2 DSIHOST_TE */ |
|||
__HAL_RCC_GPIOJ_CLK_ENABLE(); |
|||
gpioInit.Pin = GPIO_PIN_2; |
|||
gpioInit.Mode = GPIO_MODE_AF_PP; |
|||
gpioInit.Alternate = GPIO_AF13_DSI; |
|||
HAL_GPIO_Init(GPIOJ, &gpioInit); |
|||
|
|||
/* PA3 LCD_BL_CTRL This pin is not physically connected. */ |
|||
__HAL_RCC_GPIOA_CLK_ENABLE(); |
|||
gpioInit.Pin = GPIO_PIN_3; |
|||
gpioInit.Mode = GPIO_MODE_OUTPUT_OD; |
|||
HAL_GPIO_Init(GPIOA, &gpioInit); |
|||
|
|||
/* Fvco = f(CLKin/IDF) * 2 * NDIV; fPHI = Fvco/(2*ODF) */ |
|||
#if !defined(USE_STM32469I_DISCO_REVA) |
|||
/* fPHI = CLKin*62.5; Fvco = CLKin*125 */ |
|||
dsiPllInit.PLLNDIV = 125; |
|||
dsiPllInit.PLLIDF = DSI_PLL_IN_DIV2; |
|||
#else |
|||
/* fPHI = CLKin*20; Fvco = CLKin*40 */ |
|||
dsiPllInit.PLLNDIV = 100; |
|||
dsiPllInit.PLLIDF = DSI_PLL_IN_DIV5; |
|||
#endif |
|||
dsiPllInit.PLLODF = DSI_PLL_OUT_DIV1; |
|||
|
|||
/* Initialize the DSI peripheral. */ |
|||
HAL_DSI_Init(&dsiHandle, &dsiPllInit); |
|||
|
|||
DSI_PHY_TimerTypeDef PhyTimings; |
|||
/* Configure DSI PHY HS2LP and LP2HS timings. Datasheet says 95ns max */ |
|||
PhyTimings.ClockLaneHS2LPTime = 35; |
|||
PhyTimings.ClockLaneLP2HSTime = 35; |
|||
PhyTimings.DataLaneHS2LPTime = 35; |
|||
PhyTimings.DataLaneLP2HSTime = 35; |
|||
PhyTimings.DataLaneMaxReadTime = 0; |
|||
PhyTimings.StopWaitTime = 10; |
|||
HAL_DSI_ConfigPhyTimer(&dsiHandle, &PhyTimings); |
|||
|
|||
/* Configure adapted command mode. */ |
|||
HAL_DSI_ConfigAdaptedCommandMode(&dsiHandle, &dsiCmdMode); |
|||
|
|||
/* Hardware reset LCD */ |
|||
reset_lcd(g); |
|||
|
|||
/* Initialize the SDRAM */ |
|||
BSP_SDRAM_Init(); |
|||
} |
|||
|
|||
static GFXINLINE void set_backlight(GDisplay* g, uint8_t percent) |
|||
{ |
|||
(void)g; |
|||
(void)percent; |
|||
} |
|||
|
|||
/**
|
|||
* @brief Perform a hardware reset on the LCD. |
|||
* |
|||
* @param g: Display parameter structure. |
|||
*/ |
|||
static GFXINLINE void reset_lcd(GDisplay* g) |
|||
{ |
|||
(void)g; |
|||
/* Hardware display reset. */ |
|||
HAL_GPIO_WritePin(GPIOH, GPIO_PIN_7, GPIO_PIN_RESET); |
|||
gfxSleepMilliseconds(20); |
|||
HAL_GPIO_WritePin(GPIOH, GPIO_PIN_7, GPIO_PIN_SET); |
|||
gfxSleepMilliseconds(10); |
|||
/* Turn on backlight. */ |
|||
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_3, GPIO_PIN_RESET); |
|||
} |
|||
|
|||
/**
|
|||
* @brief Extra initialization that is performed after the LTDC intialization. |
|||
* |
|||
* @param g: Display paramter structure. |
|||
*/ |
|||
static GFXINLINE void post_init_board(GDisplay* g) |
|||
{ |
|||
(void)g; |
|||
DSI_LPCmdTypeDef dsiAPBCmd; |
|||
|
|||
/* Enable the DSI host and wrapper after the LTDC initialization
|
|||
To avoid any synchronization issue, the DSI shall be started after enabling the LTDC */ |
|||
HAL_DSI_Start(&dsiHandle); |
|||
|
|||
/* The configuration commands for the LCD have to be send through the dsiAPBCmd
|
|||
* interface as the adapted command mode only supports DCS, WMS and WMC commands. */ |
|||
dsiAPBCmd.LPGenShortWriteNoP = DSI_LP_GSW0P_ENABLE; // Put everything in low power mode
|
|||
dsiAPBCmd.LPGenShortWriteOneP = DSI_LP_GSW1P_ENABLE; |
|||
dsiAPBCmd.LPGenShortWriteTwoP = DSI_LP_GSW2P_ENABLE; |
|||
dsiAPBCmd.LPGenShortReadNoP = DSI_LP_GSR0P_ENABLE; |
|||
dsiAPBCmd.LPGenShortReadOneP = DSI_LP_GSR1P_ENABLE; |
|||
dsiAPBCmd.LPGenShortReadTwoP = DSI_LP_GSR2P_ENABLE; |
|||
dsiAPBCmd.LPGenLongWrite = DSI_LP_GLW_ENABLE; |
|||
dsiAPBCmd.LPDcsShortWriteNoP = DSI_LP_DSW0P_ENABLE; |
|||
dsiAPBCmd.LPDcsShortWriteOneP = DSI_LP_DSW1P_ENABLE; |
|||
dsiAPBCmd.LPDcsShortReadNoP = DSI_LP_DSR0P_ENABLE; |
|||
dsiAPBCmd.LPDcsLongWrite = DSI_LP_DLW_ENABLE; |
|||
HAL_DSI_ConfigCommand(&dsiHandle, &dsiAPBCmd); |
|||
|
|||
/* Configure the LCD. */ |
|||
#ifdef GDISP_PIXELFORMAT_RGB565 |
|||
OTM8009A_Init(OTM8009A_FORMAT_RBG565, 1); |
|||
#else |
|||
OTM8009A_Init(OTM8009A_FORMAT_RGB888, 1); |
|||
#endif |
|||
|
|||
/* Enable the tearing effect line. */ |
|||
HAL_DSI_ShortWrite(&dsiHandle, 0, DSI_DCS_SHORT_PKT_WRITE_P1, DSI_SET_TEAR_ON, 0); // Only V-Blanking info
|
|||
|
|||
/* Disable the APB command mode again to go into adapted command mode. (going into high speed mode) */ |
|||
dsiAPBCmd.LPGenShortWriteNoP = DSI_LP_GSW0P_DISABLE; |
|||
dsiAPBCmd.LPGenShortWriteOneP = DSI_LP_GSW1P_DISABLE; |
|||
dsiAPBCmd.LPGenShortWriteTwoP = DSI_LP_GSW2P_DISABLE; |
|||
dsiAPBCmd.LPGenShortReadNoP = DSI_LP_GSR0P_DISABLE; |
|||
dsiAPBCmd.LPGenShortReadOneP = DSI_LP_GSR1P_DISABLE; |
|||
dsiAPBCmd.LPGenShortReadTwoP = DSI_LP_GSR2P_DISABLE; |
|||
dsiAPBCmd.LPGenLongWrite = DSI_LP_GLW_DISABLE; |
|||
dsiAPBCmd.LPDcsShortWriteNoP = DSI_LP_DSW0P_DISABLE; |
|||
dsiAPBCmd.LPDcsShortWriteOneP = DSI_LP_DSW1P_DISABLE; |
|||
dsiAPBCmd.LPDcsShortReadNoP = DSI_LP_DSR0P_DISABLE; |
|||
dsiAPBCmd.LPDcsLongWrite = DSI_LP_DLW_DISABLE; |
|||
HAL_DSI_ConfigCommand(&dsiHandle, &dsiAPBCmd); |
|||
|
|||
HAL_DSI_Refresh(&dsiHandle); |
|||
} |
|||
|
|||
/**
|
|||
* @brief DCS or Generic short/long write command |
|||
* @param NbrParams: Number of parameters. It indicates the write command mode: |
|||
* If inferior to 2, a long write command is performed else short. |
|||
* @param pParams: Pointer to parameter values table. |
|||
* @retval HAL status |
|||
*/ |
|||
void DSI_IO_WriteCmd(uint32_t NbrParams, uint8_t *pParams) |
|||
{ |
|||
if(NbrParams <= 1) |
|||
{ |
|||
HAL_DSI_ShortWrite(&dsiHandle, 0, DSI_DCS_SHORT_PKT_WRITE_P1, pParams[0], pParams[1]); |
|||
} |
|||
else |
|||
{ |
|||
HAL_DSI_LongWrite(&dsiHandle, 0, DSI_DCS_LONG_PKT_WRITE, NbrParams, pParams[NbrParams], pParams); |
|||
} |
|||
} |
|||
|
|||
/**
|
|||
* @brief Delay function for the OTM8009A driver. |
|||
* |
|||
* @param Delay: The requested delay in ms. |
|||
*/ |
|||
void OTM8009A_IO_Delay(uint32_t Delay) |
|||
{ |
|||
gfxSleepMilliseconds(Delay); |
|||
} |
|||
|
|||
#endif /* _GDISP_LLD_BOARD_H */ |
@ -0,0 +1,88 @@ |
|||
/*
|
|||
* This file is subject to the terms of the GFX License. If a copy of |
|||
* the license was not distributed with this file, you can obtain one at: |
|||
* |
|||
* http://ugfx.org/license.html
|
|||
*/ |
|||
|
|||
#ifndef _FT6x06_H |
|||
#define _FT6x06_H |
|||
|
|||
// Slave address
|
|||
#define FT6x06_ADDR 0x70//(0x70 >> 1)
|
|||
|
|||
// Maximum timeout
|
|||
#define FT6x06_TIMEOUT 0x3000 |
|||
|
|||
#define FT6x06_DEVICE_MODE 0x00 |
|||
#define FT6x06_GESTURE_ID 0x01 |
|||
#define FT6x06_TOUCH_POINTS 0x02 |
|||
|
|||
#define FT6x06_TOUCH1_EV_FLAG 0x03 |
|||
#define FT6x06_TOUCH1_XH 0x03 |
|||
#define FT6x06_TOUCH1_XL 0x04 |
|||
#define FT6x06_TOUCH1_YH 0x05 |
|||
#define FT6x06_TOUCH1_YL 0x06 |
|||
#define FT6x06_P1_WEIGHT 0x07 |
|||
#define FT6x06_P1_AREA 0x08 |
|||
|
|||
#define FT6x06_TOUCH2_EV_FLAG 0x09 |
|||
#define FT6x06_TOUCH2_XH 0x09 |
|||
#define FT6x06_TOUCH2_XL 0x0A |
|||
#define FT6x06_TOUCH2_YH 0x0B |
|||
#define FT6x06_TOUCH2_YL 0x0C |
|||
#define FT6x06_P2_WEIGHT 0x0D |
|||
#define FT6x06_P2_AREA 0x0E |
|||
|
|||
#define FT6x06_TOUCH3_EV_FLAG 0x0F |
|||
#define FT6x06_TOUCH3_XH 0x0F |
|||
#define FT6x06_TOUCH3_XL 0x10 |
|||
#define FT6x06_TOUCH3_YH 0x11 |
|||
#define FT6x06_TOUCH3_YL 0x12 |
|||
#define FT6x06_P3_WEIGHT 0x13 |
|||
#define FT6x06_P3_AREA 0x14 |
|||
|
|||
#define FT6x06_TOUCH4_EV_FLAG 0x15 |
|||
#define FT6x06_TOUCH4_XH 0x15 |
|||
#define FT6x06_TOUCH4_XL 0x16 |
|||
#define FT6x06_TOUCH4_YH 0x17 |
|||
#define FT6x06_TOUCH4_YL 0x18 |
|||
#define FT6x06_P4_WEIGHT 0x19 |
|||
#define FT6x06_P4_AREA 0x1A |
|||
|
|||
#define FT6x06_TOUCH5_EV_FLAG 0x1B |
|||
#define FT6x06_TOUCH5_XH 0x1B |
|||
#define FT6x06_TOUCH5_XL 0x1C |
|||
#define FT6x06_TOUCH5_YH 0x1D |
|||
#define FT6x06_TOUCH5_YL 0x1E |
|||
#define FT6x06_P5_WEIGHT 0x1F |
|||
#define FT6x06_P5_AREA 0x20 |
|||
|
|||
#define FT6x06_ID_G_THGROUP 0x80 |
|||
#define FT6x06_ID_G_THPEAK 0x81 |
|||
#define FT6x06_ID_G_THCAL 0x82 |
|||
#define FT6x06_ID_G_THWATER 0x83 |
|||
#define FT6x06_ID_G_THTEMP 0x84 |
|||
#define FT6x06_ID_G_THDIFF 0x85 |
|||
#define FT6x06_ID_G_CTRL 0x86 |
|||
#define FT6x06_ID_G_TIME_ENTER_MONITOR 0x87 |
|||
#define FT6x06_ID_G_PERIODACTIVE 0x88 |
|||
#define FT6x06_ID_G_PERIODMONITOR 0x89 |
|||
#define FT6x06_RADIAN_VALUE 0x91 |
|||
#define FT6x06_OFFSET_LEFT_RIGHT 0x92 |
|||
#define FT6x06_OFFSET_UP_DOWN 0x93 |
|||
//#define FT6x06_OFFSET_LEFT_RIGHT 0x94
|
|||
#define FT6x06_DISTANCE_U_D 0x95 |
|||
#define FT6x06_DISTANCE_ZOOM 0x96 |
|||
#define FT6x06_ID_G_AUTO_CLB_MODE 0xA0 |
|||
#define FT6x06_ID_G_LIB_VERSION_H 0xA1 |
|||
#define FT6x06_ID_G_LIB_VERSION_L 0xA2 |
|||
#define FT6x06_ID_G_CIPHER 0xA3 |
|||
#define FT6x06_ID_G_MODE 0xA4 |
|||
#define FT6x06_ID_G_PMODE 0xA5 |
|||
#define FT6x06_ID_G_FIRMID 0xA6 |
|||
#define FT6x06_ID_G_STATE 0xA7 |
|||
#define FT6x06_ID_G_ID 0xA8 |
|||
#define FT6x06_ID_G_ERR 0xA9 |
|||
|
|||
#endif /* _FT6x06_H */ |
@ -0,0 +1,110 @@ |
|||
/*
|
|||
* This file is subject to the terms of the GFX License. If a copy of |
|||
* the license was not distributed with this file, you can obtain one at: |
|||
* |
|||
* http://ugfx.org/license.html
|
|||
*/ |
|||
|
|||
#ifndef _GINPUT_LLD_MOUSE_BOARD_H |
|||
#define _GINPUT_LLD_MOUSE_BOARD_H |
|||
|
|||
#include "ft6x06.h" |
|||
#include "stm32f4xx.h" |
|||
#include "stm32f4xx_hal.h" |
|||
|
|||
// Resolution and Accuracy Settings
|
|||
#define GMOUSE_FT6x06_PEN_CALIBRATE_ERROR 40 |
|||
#define GMOUSE_FT6x06_PEN_CLICK_ERROR 16 |
|||
#define GMOUSE_FT6x06_PEN_MOVE_ERROR 14 |
|||
#define GMOUSE_FT6x06_FINGER_CALIBRATE_ERROR 50 |
|||
#define GMOUSE_FT6x06_FINGER_CLICK_ERROR 28 |
|||
#define GMOUSE_FT6x06_FINGER_MOVE_ERROR 24 |
|||
|
|||
// How much extra data to allocate at the end of the GMouse structure for the board's use
|
|||
#define GMOUSE_FT6x06_BOARD_DATA_SIZE 0 |
|||
|
|||
/* The FT6x06 I2C slave address */ |
|||
#define FT6x06_SLAVE_ADDR 0x54 |
|||
|
|||
I2C_HandleTypeDef i2cHandle; |
|||
/* Maximum speed (400kHz) */ |
|||
#define CLOCKSPEED 400000; |
|||
|
|||
static bool_t init_board(GMouse* m, unsigned instance) { |
|||
(void)m; |
|||
(void)instance; |
|||
|
|||
GPIO_InitTypeDef gpioInit; |
|||
/* I2C1_SCL PB8 */ |
|||
__HAL_RCC_GPIOB_CLK_ENABLE(); // Enable GPIOB clock
|
|||
gpioInit.Pin = GPIO_PIN_8; |
|||
gpioInit.Mode = GPIO_MODE_AF_OD; // I2C -> Open-drain
|
|||
gpioInit.Pull = GPIO_NOPULL; // Open-drain -> no pull
|
|||
gpioInit.Speed = GPIO_SPEED_FREQ_HIGH; // High speed
|
|||
gpioInit.Alternate = GPIO_AF4_I2C1; // Alternate function 4
|
|||
HAL_GPIO_Init(GPIOB, &gpioInit); |
|||
|
|||
/* I2C1_SDA PB9 */ |
|||
gpioInit.Pin = GPIO_PIN_9; |
|||
HAL_GPIO_Init(GPIOB, &gpioInit); |
|||
|
|||
/* LCD_INT PJ5 */ |
|||
__HAL_RCC_GPIOJ_CLK_ENABLE(); |
|||
gpioInit.Pin = GPIO_PIN_5; |
|||
gpioInit.Mode = GPIO_MODE_INPUT; // Input mode
|
|||
gpioInit.Pull = GPIO_PULLUP; // Pull-up
|
|||
HAL_GPIO_Init(GPIOJ, &gpioInit); |
|||
|
|||
/* I2C1 intialization */ |
|||
i2cHandle.Instance = I2C1; |
|||
i2cHandle.Init.ClockSpeed = CLOCKSPEED; |
|||
i2cHandle.Init.DutyCycle = I2C_DUTYCYCLE_2; // Normal duty cycle
|
|||
i2cHandle.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE; // No dual adressing needed
|
|||
i2cHandle.Init.OwnAddress1 = 0x00; |
|||
i2cHandle.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT; |
|||
i2cHandle.Init.OwnAddress2 = 0x00; |
|||
i2cHandle.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE; // All not needed so disabled
|
|||
i2cHandle.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE; |
|||
|
|||
__HAL_RCC_I2C1_CLK_ENABLE(); |
|||
|
|||
if(HAL_I2C_Init(&i2cHandle) == HAL_OK) |
|||
return TRUE; |
|||
|
|||
return FALSE; |
|||
} |
|||
|
|||
static GFXINLINE void aquire_bus(GMouse* m) { |
|||
(void)m; |
|||
} |
|||
|
|||
static GFXINLINE void release_bus(GMouse* m) { |
|||
(void)m; |
|||
} |
|||
|
|||
static void write_reg(GMouse* m, uint8_t reg, uint8_t val) { |
|||
(void)m; |
|||
|
|||
HAL_I2C_Mem_Write(&i2cHandle, FT6x06_SLAVE_ADDR, (uint16_t)reg, I2C_MEMADD_SIZE_8BIT, &val, 1, 1000); |
|||
} |
|||
|
|||
static uint8_t read_byte(GMouse* m, uint8_t reg) { |
|||
(void)m; |
|||
uint8_t result; |
|||
|
|||
HAL_I2C_Mem_Read(&i2cHandle, FT6x06_SLAVE_ADDR, (uint16_t)reg, I2C_MEMADD_SIZE_8BIT, &result, 1, 1000); |
|||
|
|||
return result; |
|||
} |
|||
|
|||
static uint16_t read_word(GMouse* m, uint8_t reg) { |
|||
(void)m; |
|||
uint8_t result[2]; |
|||
|
|||
HAL_I2C_Mem_Read(&i2cHandle, FT6x06_SLAVE_ADDR, (uint16_t)reg, I2C_MEMADD_SIZE_8BIT, result, 2, 1000); |
|||
|
|||
return (result[0]<<8 | result[1]); |
|||
|
|||
} |
|||
|
|||
#endif /* _GINPUT_LLD_MOUSE_BOARD_H */ |
@ -0,0 +1,189 @@ |
|||
/* |
|||
***************************************************************************** |
|||
** |
|||
|
|||
** File : LinkerScript.ld |
|||
** |
|||
** Abstract : Linker script for STM32F469NIHx Device with |
|||
** 2048KByte FLASH, 320KByte RAM |
|||
** |
|||
** Set heap size, stack size and stack location according |
|||
** to application requirements. |
|||
** |
|||
** Set memory bank area and size if external memory is used. |
|||
** |
|||
** Target : STMicroelectronics STM32 |
|||
** |
|||
** |
|||
** Distribution: The file is distributed as is, without any warranty |
|||
** of any kind. |
|||
** |
|||
** (c)Copyright Ac6. |
|||
** You may use this file as-is or modify it according to the needs of your |
|||
** project. Distribution of this file (unmodified or modified) is not |
|||
** permitted. Ac6 permit registered System Workbench for MCU users the |
|||
** rights to distribute the assembled, compiled & linked contents of this |
|||
** file as part of an application binary file, provided that it is built |
|||
** using the System Workbench for MCU toolchain. |
|||
** |
|||
***************************************************************************** |
|||
*/ |
|||
|
|||
/* Entry Point */ |
|||
ENTRY(Reset_Handler) |
|||
|
|||
/* Highest address of the user mode stack */ |
|||
_estack = 0x20050000; /* end of RAM */ |
|||
/* Generate a link error if heap and stack don't fit into RAM */ |
|||
_Min_Heap_Size = 0x200;; /* required amount of heap */ |
|||
_Min_Stack_Size = 0x400;; /* required amount of stack */ |
|||
|
|||
/* Specify the memory areas */ |
|||
MEMORY |
|||
{ |
|||
FLASH (rx) : ORIGIN = 0x8000000, LENGTH = 2048K |
|||
RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 320K |
|||
CCMRAM (rw) : ORIGIN = 0x10000000, LENGTH = 64K |
|||
} |
|||
|
|||
/* Define output sections */ |
|||
SECTIONS |
|||
{ |
|||
/* The startup code goes first into FLASH */ |
|||
.isr_vector : |
|||
{ |
|||
. = ALIGN(4); |
|||
KEEP(*(.isr_vector)) /* Startup code */ |
|||
. = ALIGN(4); |
|||
} >FLASH |
|||
|
|||
/* The program code and other data goes into FLASH */ |
|||
.text : |
|||
{ |
|||
. = ALIGN(4); |
|||
*(.text) /* .text sections (code) */ |
|||
*(.text*) /* .text* sections (code) */ |
|||
*(.glue_7) /* glue arm to thumb code */ |
|||
*(.glue_7t) /* glue thumb to arm code */ |
|||
*(.eh_frame) |
|||
|
|||
KEEP (*(.init)) |
|||
KEEP (*(.fini)) |
|||
|
|||
. = ALIGN(4); |
|||
_etext = .; /* define a global symbols at end of code */ |
|||
} >FLASH |
|||
|
|||
/* Constant data goes into FLASH */ |
|||
.rodata : |
|||
{ |
|||
. = ALIGN(4); |
|||
*(.rodata) /* .rodata sections (constants, strings, etc.) */ |
|||
*(.rodata*) /* .rodata* sections (constants, strings, etc.) */ |
|||
. = ALIGN(4); |
|||
} >FLASH |
|||
|
|||
.ARM.extab : { *(.ARM.extab* .gnu.linkonce.armextab.*) } >FLASH |
|||
.ARM : { |
|||
__exidx_start = .; |
|||
*(.ARM.exidx*) |
|||
__exidx_end = .; |
|||
} >FLASH |
|||
|
|||
.preinit_array : |
|||
{ |
|||
PROVIDE_HIDDEN (__preinit_array_start = .); |
|||
KEEP (*(.preinit_array*)) |
|||
PROVIDE_HIDDEN (__preinit_array_end = .); |
|||
} >FLASH |
|||
.init_array : |
|||
{ |
|||
PROVIDE_HIDDEN (__init_array_start = .); |
|||
KEEP (*(SORT(.init_array.*))) |
|||
KEEP (*(.init_array*)) |
|||
PROVIDE_HIDDEN (__init_array_end = .); |
|||
} >FLASH |
|||
.fini_array : |
|||
{ |
|||
PROVIDE_HIDDEN (__fini_array_start = .); |
|||
KEEP (*(SORT(.fini_array.*))) |
|||
KEEP (*(.fini_array*)) |
|||
PROVIDE_HIDDEN (__fini_array_end = .); |
|||
} >FLASH |
|||
|
|||
/* used by the startup to initialize data */ |
|||
_sidata = LOADADDR(.data); |
|||
|
|||
/* Initialized data sections goes into RAM, load LMA copy after code */ |
|||
.data : |
|||
{ |
|||
. = ALIGN(4); |
|||
_sdata = .; /* create a global symbol at data start */ |
|||
*(.data) /* .data sections */ |
|||
*(.data*) /* .data* sections */ |
|||
|
|||
. = ALIGN(4); |
|||
_edata = .; /* define a global symbol at data end */ |
|||
} >RAM AT> FLASH |
|||
|
|||
_siccmram = LOADADDR(.ccmram); |
|||
|
|||
/* CCM-RAM section |
|||
* |
|||
* IMPORTANT NOTE! |
|||
* If initialized variables will be placed in this section, |
|||
* the startup code needs to be modified to copy the init-values. |
|||
*/ |
|||
.ccmram : |
|||
{ |
|||
. = ALIGN(4); |
|||
_sccmram = .; /* create a global symbol at ccmram start */ |
|||
*(.ccmram) |
|||
*(.ccmram*) |
|||
|
|||
. = ALIGN(4); |
|||
_eccmram = .; /* create a global symbol at ccmram end */ |
|||
} >CCMRAM AT> FLASH |
|||
|
|||
|
|||
/* Uninitialized data section */ |
|||
. = ALIGN(4); |
|||
.bss : |
|||
{ |
|||
/* This is used by the startup in order to initialize the .bss secion */ |
|||
_sbss = .; /* define a global symbol at bss start */ |
|||
__bss_start__ = _sbss; |
|||
*(.bss) |
|||
*(.bss*) |
|||
*(COMMON) |
|||
|
|||
. = ALIGN(4); |
|||
_ebss = .; /* define a global symbol at bss end */ |
|||
__bss_end__ = _ebss; |
|||
} >RAM |
|||
|
|||
/* User_heap_stack section, used to check that there is enough RAM left */ |
|||
._user_heap_stack : |
|||
{ |
|||
. = ALIGN(4); |
|||
PROVIDE ( end = . ); |
|||
PROVIDE ( _end = . ); |
|||
. = . + _Min_Heap_Size; |
|||
. = . + _Min_Stack_Size; |
|||
. = ALIGN(4); |
|||
} >RAM |
|||
|
|||
|
|||
|
|||
/* Remove information from the standard libraries */ |
|||
/DISCARD/ : |
|||
{ |
|||
libc.a ( * ) |
|||
libm.a ( * ) |
|||
libgcc.a ( * ) |
|||
} |
|||
|
|||
.ARM.attributes 0 : { *(.ARM.attributes) } |
|||
} |
|||
|
|||
|
@ -0,0 +1,33 @@ |
|||
GFXINC += $(GFXLIB)/boards/base/STM32F469i-Discovery \
|
|||
$(GFXLIB)/boards/base/STM32F469i-Discovery/CubeHAL \
|
|||
$(STMHAL)/Inc |
|||
|
|||
GFXSRC += $(GFXLIB)/boards/base/STM32F469i-Discovery/stm32f469i_discovery_sdram.c |
|||
|
|||
ifeq ($(OPT_OS),raw32) |
|||
GFXDEFS += STM32F469xx |
|||
GFXSRC += $(STMHAL)/Src/stm32f4xx_hal.c \
|
|||
$(STMHAL)/Src/stm32f4xx_hal_cortex.c \
|
|||
$(STMHAL)/Src/stm32f4xx_hal_rcc.c \
|
|||
$(STMHAL)/Src/stm32f4xx_hal_rcc_ex.h \
|
|||
$(STMHAL)/Src/stm32f4xx_hal_gpio.c \
|
|||
$(STMHAL)/Src/stm32f4xx_hal_pwr.c \
|
|||
$(STMHAL)/Src/stm32f4xx_hal_pwr_ex.c \
|
|||
$(STMHAL)/Src/stm32f4xx_hal_dma.c \
|
|||
$(STMHAL)/Src/stm32f4xx_hal_i2c.c \
|
|||
$(STMHAL)/Src/stm32f4xx_hal_sdram.c \
|
|||
$(STMHAL)/Src/stm32f4xx_hal_dsi.c \
|
|||
$(STMHAL)/Src/stm32f4xx_ll_fmc.c \
|
|||
$(GFXLIB)/boards/base/STM32F469i-Discovery/otm8009a.c |
|||
GFXSRC += $(GFXLIB)/boards/base/STM32F469i-Discovery/startup_stm32f469xx.s \
|
|||
$(GFXLIB)/boards/base/STM32F469i-Discovery/stm32f469i_raw32_ugfx.c \
|
|||
$(GFXLIB)/boards/base/STM32F469i-Discovery/stm32f469i_raw32_system.c \
|
|||
$(GFXLIB)/boards/base/STM32F469i-Discovery/stm32f469i_raw32_it.c |
|||
GFXDEFS += GFX_OS_PRE_INIT_FUNCTION=Raw32OSInit GFX_OS_INIT_NO_WARNING=TRUE |
|||
GFXINC += $(CMSIS)/Device/ST/STM32F4xx/Include \
|
|||
$(CMSIS)/Include |
|||
LDSCRIPT = $(GFXLIB)/boards/base/STM32F469i-Discovery/STM32_FLASH.ld |
|||
endif |
|||
|
|||
include $(GFXLIB)/drivers/gdisp/STM32LTDC/driver.mk |
|||
include $(GFXLIB)/drivers/ginput/touch/FT6x06/driver.mk |
@ -1,292 +0,0 @@ |
|||
/*
|
|||
* This file is subject to the terms of the GFX License. If a copy of |
|||
* the license was not distributed with this file, you can obtain one at: |
|||
* |
|||
* http://ugfx.org/license.html
|
|||
*/ |
|||
|
|||
#ifndef _GDISP_LLD_BOARD_H |
|||
#define _GDISP_LLD_BOARD_H |
|||
|
|||
// Avoid naming collisions with CubeHAL
|
|||
#undef Red |
|||
#undef Green |
|||
#undef Blue |
|||
|
|||
// Don't allow the driver to init the LTDC clock. We will do it here
|
|||
#define LTDC_NO_CLOCK_INIT TRUE |
|||
|
|||
//#include "stm32f4xx_hal.h"
|
|||
//#include "stm32f4xx_hal_sdram.h"
|
|||
//#include "stm32f4xx_hal_rcc.h"
|
|||
//#include "stm32f4xx_hal_gpio.h"
|
|||
//#include "stm32f4xx_hal_ltdc.h"
|
|||
#include "stm32469i_discovery_lcd.h" |
|||
|
|||
LTDC_HandleTypeDef hltdc_eval; |
|||
static DSI_VidCfgTypeDef hdsivideo_handle; |
|||
DSI_HandleTypeDef hdsi_eval; |
|||
|
|||
#define ALLOW_2ND_LAYER FALSE // Do we really have the RAM bandwidth for this?
|
|||
|
|||
// Panel parameters
|
|||
// This panel is a KoD KM-040TMP-02-0621 DSI LCD Display.
|
|||
|
|||
static const ltdcConfig driverCfg = { |
|||
800, 480, // Width, Height (pixels)
|
|||
120, 12, // Horizontal, Vertical sync (pixels)
|
|||
120, 12, // Horizontal, Vertical back porch (pixels)
|
|||
120, 12, // Horizontal, Vertical front porch (pixels)
|
|||
0, // Sync flags
|
|||
0x000000, // Clear color (RGB888)
|
|||
|
|||
{ // Background layer config
|
|||
(LLDCOLOR_TYPE *)SDRAM_DEVICE_ADDR, // Frame buffer address
|
|||
800, 480, // Width, Height (pixels)
|
|||
800 * LTDC_PIXELBYTES, // Line pitch (bytes)
|
|||
LTDC_PIXELFORMAT, // Pixel format
|
|||
0, 0, // Start pixel position (x, y)
|
|||
800, 480, // Size of virtual layer (cx, cy)
|
|||
0x00000000, // Default color (ARGB8888)
|
|||
0x000000, // Color key (RGB888)
|
|||
LTDC_BLEND_FIX1_FIX2, // Blending factors
|
|||
0, // Palette (RGB888, can be NULL)
|
|||
0, // Palette length
|
|||
0xFF, // Constant alpha factor
|
|||
LTDC_LEF_ENABLE // Layer configuration flags
|
|||
}, |
|||
|
|||
#if ALLOW_2ND_LAYER |
|||
{ // Foreground layer config (if turned on)
|
|||
(LLDCOLOR_TYPE *)(SDRAM_DEVICE_ADDR+(800 * 480 * LTDC_PIXELBYTES)), // Frame buffer address
|
|||
800, 480, // Width, Height (pixels)
|
|||
800 * LTDC_PIXELBYTES, // Line pitch (bytes)
|
|||
LTDC_PIXELFORMAT, // Pixel format
|
|||
0, 0, // Start pixel position (x, y)
|
|||
800, 480, // Size of virtual layer (cx, cy)
|
|||
0x00000000, // Default color (ARGB8888)
|
|||
0x000000, // Color key (RGB888)
|
|||
LTDC_BLEND_MOD1_MOD2, // Blending factors
|
|||
0, // Palette (RGB888, can be NULL)
|
|||
0, // Palette length
|
|||
0xFF, // Constant alpha factor
|
|||
LTDC_LEF_ENABLE // Layer configuration flags
|
|||
} |
|||
#else |
|||
LTDC_UNUSED_LAYER_CONFIG |
|||
#endif |
|||
}; |
|||
|
|||
/* Display timing */ |
|||
#define KoD_FREQUENCY_DIVIDER 7 |
|||
|
|||
static GFXINLINE void init_board(GDisplay *g) { |
|||
(void) g; |
|||
|
|||
DSI_PLLInitTypeDef dsiPllInit; |
|||
DSI_PHY_TimerTypeDef PhyTimings; |
|||
// static RCC_PeriphCLKInitTypeDef PeriphClkInitStruct;
|
|||
uint32_t LcdClock = 30000;//27429; /*!< LcdClk = 27429 kHz */
|
|||
|
|||
/**
|
|||
* @brief Default Active LTDC Layer in which drawing is made is LTDC Layer Background |
|||
*/ |
|||
// static uint32_t ActiveLayer = LTDC_ACTIVE_LAYER_BACKGROUND;
|
|||
|
|||
/**
|
|||
* @brief Current Drawing Layer properties variable |
|||
*/ |
|||
// static LCD_DrawPropTypeDef DrawProp[LTDC_MAX_LAYER_NUMBER];
|
|||
|
|||
uint32_t laneByteClk_kHz = 0; |
|||
uint32_t VSA; /*!< Vertical start active time in units of lines */ |
|||
uint32_t VBP; /*!< Vertical Back Porch time in units of lines */ |
|||
uint32_t VFP; /*!< Vertical Front Porch time in units of lines */ |
|||
uint32_t VACT; /*!< Vertical Active time in units of lines = imageSize Y in pixels to display */ |
|||
uint32_t HSA; /*!< Horizontal start active time in units of lcdClk */ |
|||
uint32_t HBP; /*!< Horizontal Back Porch time in units of lcdClk */ |
|||
uint32_t HFP; /*!< Horizontal Front Porch time in units of lcdClk */ |
|||
uint32_t HACT; /*!< Horizontal Active time in units of lcdClk = imageSize X in pixels to display */ |
|||
|
|||
|
|||
/* Toggle Hardware Reset of the DSI LCD using
|
|||
* its XRES signal (active low) */ |
|||
BSP_LCD_Reset(); |
|||
|
|||
/* Call first MSP Initialize only in case of first initialization
|
|||
* This will set IP blocks LTDC, DSI and DMA2D |
|||
* - out of reset |
|||
* - clocked |
|||
* - NVIC IRQ related to IP blocks enabled |
|||
*/ |
|||
BSP_LCD_MspInit(); |
|||
|
|||
/*************************DSI Initialization***********************************/ |
|||
|
|||
/* Base address of DSI Host/Wrapper registers to be set before calling De-Init */ |
|||
hdsi_eval.Instance = DSI; |
|||
|
|||
HAL_DSI_DeInit(&(hdsi_eval)); |
|||
|
|||
#if !defined(USE_STM32469I_DISCO_REVA) |
|||
dsiPllInit.PLLNDIV = 125; |
|||
dsiPllInit.PLLIDF = DSI_PLL_IN_DIV2; |
|||
dsiPllInit.PLLODF = DSI_PLL_OUT_DIV1; |
|||
#else |
|||
dsiPllInit.PLLNDIV = 100; |
|||
dsiPllInit.PLLIDF = DSI_PLL_IN_DIV5; |
|||
dsiPllInit.PLLODF = DSI_PLL_OUT_DIV1; |
|||
#endif |
|||
laneByteClk_kHz = 62500; /* 500 MHz / 8 = 62.5 MHz = 62500 kHz */ |
|||
|
|||
/* Set number of Lanes */ |
|||
hdsi_eval.Init.NumberOfLanes = DSI_TWO_DATA_LANES; |
|||
|
|||
/* TXEscapeCkdiv = f(LaneByteClk)/15.62 = 4 */ |
|||
hdsi_eval.Init.TXEscapeCkdiv = laneByteClk_kHz/15620; |
|||
|
|||
HAL_DSI_Init(&(hdsi_eval), &(dsiPllInit)); |
|||
|
|||
/* Timing parameters for all Video modes
|
|||
* Set Timing parameters of LTDC depending on its chosen orientation |
|||
*/ |
|||
|
|||
/* lcd_orientation == LCD_ORIENTATION_LANDSCAPE */ |
|||
uint32_t lcd_x_size = OTM8009A_800X480_WIDTH; /* 800 */ |
|||
uint32_t lcd_y_size = OTM8009A_800X480_HEIGHT; /* 480 */ |
|||
|
|||
HACT = lcd_x_size; |
|||
VACT = lcd_y_size; |
|||
|
|||
/* The following values are same for portrait and landscape orientations */ |
|||
VSA = 12;//OTM8009A_480X800_VSYNC; /* 12 */
|
|||
VBP = 12;//OTM8009A_480X800_VBP; /* 12 */
|
|||
VFP = 12;//OTM8009A_480X800_VFP; /* 12 */
|
|||
HSA = 120;//OTM8009A_480X800_HSYNC; /* 63 */
|
|||
HBP = 120;//OTM8009A_480X800_HBP; /* 120 */
|
|||
HFP = 120;//OTM8009A_480X800_HFP; /* 120 */
|
|||
|
|||
hdsivideo_handle.VirtualChannelID = LCD_OTM8009A_ID; |
|||
hdsivideo_handle.ColorCoding = LCD_DSI_PIXEL_DATA_FMT_RBG888; |
|||
hdsivideo_handle.VSPolarity = DSI_VSYNC_ACTIVE_HIGH; |
|||
hdsivideo_handle.HSPolarity = DSI_HSYNC_ACTIVE_HIGH; |
|||
hdsivideo_handle.DEPolarity = DSI_DATA_ENABLE_ACTIVE_HIGH; |
|||
hdsivideo_handle.Mode = DSI_VID_MODE_BURST; /* Mode Video burst ie : one LgP per line */ |
|||
hdsivideo_handle.NullPacketSize = 0xFFF; |
|||
hdsivideo_handle.NumberOfChunks = 0; |
|||
hdsivideo_handle.PacketSize = HACT; /* Value depending on display orientation choice portrait/landscape */ |
|||
hdsivideo_handle.HorizontalSyncActive = (HSA * laneByteClk_kHz) / LcdClock; |
|||
hdsivideo_handle.HorizontalBackPorch = (HBP * laneByteClk_kHz) / LcdClock; |
|||
hdsivideo_handle.HorizontalLine = ((HACT + HSA + HBP + HFP) * laneByteClk_kHz) / LcdClock; /* Value depending on display orientation choice portrait/landscape */ |
|||
hdsivideo_handle.VerticalSyncActive = VSA; |
|||
hdsivideo_handle.VerticalBackPorch = VBP; |
|||
hdsivideo_handle.VerticalFrontPorch = VFP; |
|||
hdsivideo_handle.VerticalActive = VACT; /* Value depending on display orientation choice portrait/landscape */ |
|||
|
|||
/* Enable or disable sending LP command while streaming is active in video mode */ |
|||
hdsivideo_handle.LPCommandEnable = DSI_LP_COMMAND_ENABLE; /* Enable sending commands in mode LP (Low Power) */ |
|||
|
|||
/* Largest packet size possible to transmit in LP mode in VSA, VBP, VFP regions */ |
|||
/* Only useful when sending LP packets is allowed while streaming is active in video mode */ |
|||
hdsivideo_handle.LPLargestPacketSize = 16; |
|||
|
|||
/* Largest packet size possible to transmit in LP mode in HFP region during VACT period */ |
|||
/* Only useful when sending LP packets is allowed while streaming is active in video mode */ |
|||
hdsivideo_handle.LPVACTLargestPacketSize = 0; |
|||
|
|||
/* Specify for each region of the video frame, if the transmission of command in LP mode is allowed in this region */ |
|||
/* while streaming is active in video mode */ |
|||
hdsivideo_handle.LPHorizontalFrontPorchEnable = DSI_LP_HFP_ENABLE; /* Allow sending LP commands during HFP period */ |
|||
hdsivideo_handle.LPHorizontalBackPorchEnable = DSI_LP_HBP_ENABLE; /* Allow sending LP commands during HBP period */ |
|||
hdsivideo_handle.LPVerticalActiveEnable = DSI_LP_VACT_ENABLE; /* Allow sending LP commands during VACT period */ |
|||
hdsivideo_handle.LPVerticalFrontPorchEnable = DSI_LP_VFP_ENABLE; /* Allow sending LP commands during VFP period */ |
|||
hdsivideo_handle.LPVerticalBackPorchEnable = DSI_LP_VBP_ENABLE; /* Allow sending LP commands during VBP period */ |
|||
hdsivideo_handle.LPVerticalSyncActiveEnable = DSI_LP_VSYNC_ENABLE; /* Allow sending LP commands during VSync = VSA period */ |
|||
|
|||
/* Configure DSI Video mode timings with settings set above */ |
|||
HAL_DSI_ConfigVideoMode(&(hdsi_eval), &(hdsivideo_handle)); |
|||
|
|||
/* Configure DSI PHY HS2LP and LP2HS timings */ |
|||
PhyTimings.ClockLaneHS2LPTime = 35; |
|||
PhyTimings.ClockLaneLP2HSTime = 35; |
|||
PhyTimings.DataLaneHS2LPTime = 35; |
|||
PhyTimings.DataLaneLP2HSTime = 35; |
|||
PhyTimings.DataLaneMaxReadTime = 0; |
|||
PhyTimings.StopWaitTime = 10; |
|||
HAL_DSI_ConfigPhyTimer(&hdsi_eval, &PhyTimings); |
|||
|
|||
/*************************End DSI Initialization*******************************/ |
|||
|
|||
/************************LTDC Initialization***********************************/ |
|||
|
|||
// KoD LCD clock configuration
|
|||
// PLLSAI_VCO Input = HSE_VALUE/PLL_M = 1 Mhz
|
|||
// PLLSAI_VCO Output = PLLSAI_VCO Input * PLLSAIN = 384 Mhz
|
|||
// PLLLCDCLK = PLLSAI_VCO Output/PLLSAIR = 384/7 = 54.857 Mhz
|
|||
// LTDC clock frequency = PLLLCDCLK / LTDC_PLLSAI_DIVR_2 = 54.857/2 = 27.429Mhz
|
|||
#define STM32_SAISRC_NOCLOCK (0 << 23) /**< No clock. */ |
|||
#define STM32_SAISRC_PLL (1 << 23) /**< SAI_CKIN is PLL. */ |
|||
#define STM32_SAIR_DIV2 (0 << 16) /**< R divided by 2. */ |
|||
#define STM32_SAIR_DIV4 (1 << 16) /**< R divided by 4. */ |
|||
#define STM32_SAIR_DIV8 (2 << 16) /**< R divided by 8. */ |
|||
#define STM32_SAIR_DIV16 (3 << 16) /**< R divided by 16. */ |
|||
|
|||
#define STM32_PLLSAIN_VALUE 384 |
|||
#define STM32_PLLSAIQ_VALUE 4 |
|||
#define STM32_PLLSAIR_VALUE KoD_FREQUENCY_DIVIDER |
|||
#define STM32_PLLSAIR_POST STM32_SAIR_DIV2 |
|||
|
|||
RCC->PLLSAICFGR = (STM32_PLLSAIN_VALUE << 6) | (STM32_PLLSAIR_VALUE << 28) | (STM32_PLLSAIQ_VALUE << 24); |
|||
RCC->DCKCFGR = (RCC->DCKCFGR & ~RCC_DCKCFGR_PLLSAIDIVR) | STM32_PLLSAIR_POST; |
|||
RCC->CR |= RCC_CR_PLLSAION; |
|||
|
|||
// PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_LTDC;
|
|||
// PeriphClkInitStruct.PLLSAI.PLLSAIN = 384;
|
|||
// PeriphClkInitStruct.PLLSAI.PLLSAIR = 7;
|
|||
// PeriphClkInitStruct.PLLSAIDivR = RCC_PLLSAIDIVR_2;
|
|||
// HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct);
|
|||
|
|||
/* Get LTDC Configuration from DSI Configuration */ |
|||
// HAL_LTDC_StructInitFromVideoConfig(&(hltdc_eval), &(hdsivideo_handle));
|
|||
|
|||
/* Initialize the LTDC */ |
|||
// HAL_LTDC_Init(&hltdc_eval);
|
|||
|
|||
/* Enable the DSI host and wrapper : but LTDC is not started yet at this stage */ |
|||
HAL_DSI_Start(&(hdsi_eval)); |
|||
|
|||
#if !defined(DATA_IN_ExtSDRAM) |
|||
/* Initialize the SDRAM */ |
|||
BSP_SDRAM_Init(); |
|||
#endif /* DATA_IN_ExtSDRAM */ |
|||
|
|||
} |
|||
|
|||
static GFXINLINE void post_init_board(GDisplay* g) |
|||
{ |
|||
(void)g; |
|||
|
|||
if (g->controllerdisplay) |
|||
return; |
|||
|
|||
/* Initialize the font */ |
|||
BSP_LCD_SetFont(&LCD_DEFAULT_FONT); |
|||
|
|||
/************************End LTDC Initialization*******************************/ |
|||
|
|||
|
|||
/***********************OTM8009A Initialization********************************/ |
|||
|
|||
/* Initialize the OTM8009A LCD Display IC Driver (KoD LCD IC Driver)
|
|||
* depending on configuration set in 'hdsivideo_handle'. |
|||
*/ |
|||
OTM8009A_Init(OTM8009A_FORMAT_RGB888, OTM8009A_ORIENTATION_LANDSCAPE); |
|||
} |
|||
|
|||
static GFXINLINE void set_backlight(GDisplay* g, uint8_t percent) |
|||
{ |
|||
(void)g; |
|||
(void)percent; |
|||
} |
|||
|
|||
#endif /* _GDISP_LLD_BOARD_H */ |
@ -1,85 +0,0 @@ |
|||
/*
|
|||
* This file is subject to the terms of the GFX License. If a copy of |
|||
* the license was not distributed with this file, you can obtain one at: |
|||
* |
|||
* http://ugfx.org/license.html
|
|||
*/ |
|||
|
|||
#ifndef _GINPUT_LLD_MOUSE_BOARD_H |
|||
#define _GINPUT_LLD_MOUSE_BOARD_H |
|||
|
|||
#include "tm_stm32_i2c.h" |
|||
#include "stm32469i_discovery_ts.h" |
|||
#include "ft6x06.h" |
|||
|
|||
// Resolution and Accuracy Settings
|
|||
#define GMOUSE_FT6x06_PEN_CALIBRATE_ERROR 8 |
|||
#define GMOUSE_FT6x06_PEN_CLICK_ERROR 6 |
|||
#define GMOUSE_FT6x06_PEN_MOVE_ERROR 4 |
|||
#define GMOUSE_FT6x06_FINGER_CALIBRATE_ERROR 14 |
|||
#define GMOUSE_FT6x06_FINGER_CLICK_ERROR 18 |
|||
#define GMOUSE_FT6x06_FINGER_MOVE_ERROR 14 |
|||
|
|||
// How much extra data to allocate at the end of the GMouse structure for the board's use
|
|||
#define GMOUSE_FT6x06_BOARD_DATA_SIZE 0 |
|||
|
|||
// Set this to TRUE if you want self-calibration.
|
|||
// NOTE: This is not as accurate as real calibration.
|
|||
// It requires the orientation of the touch panel to match the display.
|
|||
// It requires the active area of the touch panel to exactly match the display size.
|
|||
//#define GMOUSE_FT6x06_SELF_CALIBRATE TRUE
|
|||
|
|||
#define FT6x06_SLAVE_ADDR 0x54 |
|||
|
|||
static bool_t init_board(GMouse* m, unsigned driverinstance) { |
|||
(void)m; |
|||
|
|||
TS_StateTypeDef ts_state; |
|||
|
|||
return TS_OK == BSP_TS_Init(BSP_LCD_GetXSize(), BSP_LCD_GetYSize()); |
|||
} |
|||
|
|||
#define aquire_bus(m) |
|||
#define release_bus(m); |
|||
|
|||
static void write_reg(GMouse* m, uint8_t reg, uint8_t val) { |
|||
(void)m; |
|||
|
|||
//TM_I2C_Write(I2C1, FT6x06_SLAVE_ADDR, reg, val);
|
|||
} |
|||
|
|||
static uint8_t read_byte(GMouse* m, uint8_t reg) { |
|||
(void)m; |
|||
|
|||
/*uint8_t data;
|
|||
TM_I2C_Read(I2C1, FT6x06_SLAVE_ADDR, reg, &data); |
|||
return data;*/ |
|||
TS_StateTypeDef ts_state; |
|||
if(reg == FT6x06_TOUCH_POINTS){ |
|||
if (TS_OK != BSP_TS_GetState(&ts_state)) |
|||
{ |
|||
return FALSE; |
|||
} |
|||
return ts_state.touchDetected; |
|||
} |
|||
} |
|||
|
|||
static uint16_t read_word(GMouse* m, uint8_t reg) { |
|||
(void)m; |
|||
|
|||
/*uint8_t data[2];
|
|||
TM_I2C_ReadMulti(I2C1, FT6x06_SLAVE_ADDR, reg, data, 2); |
|||
return (data[1]<<8 | data[0]);*/ |
|||
|
|||
TS_StateTypeDef ts_state; |
|||
if (TS_OK == BSP_TS_GetState(&ts_state)) |
|||
{ |
|||
if(reg == FT6x06_TOUCH1_XH){ |
|||
return (coord_t)ts_state.touchX[0]; |
|||
}else if(reg == FT6x06_TOUCH1_YH){ |
|||
return (coord_t)ts_state.touchY[0]; |
|||
} |
|||
} |
|||
} |
|||
|
|||
#endif /* _GINPUT_LLD_MOUSE_BOARD_H */ |
@ -0,0 +1,454 @@ |
|||
/**
|
|||
****************************************************************************** |
|||
* @file otm8009a.c |
|||
* @author MCD Application Team |
|||
* @version V1.0.2 |
|||
* @date 27-January-2017 |
|||
* @brief This file provides the LCD Driver for KoD KM-040TMP-02-0621 (WVGA) |
|||
* DSI LCD Display OTM8009A. |
|||
****************************************************************************** |
|||
* @attention |
|||
* |
|||
* <h2><center>© COPYRIGHT(c) 2017 STMicroelectronics</center></h2> |
|||
* |
|||
* Redistribution and use in source and binary forms, with or without modification, |
|||
* are permitted provided that the following conditions are met: |
|||
* 1. Redistributions of source code must retain the above copyright notice, |
|||
* this list of conditions and the following disclaimer. |
|||
* 2. Redistributions in binary form must reproduce the above copyright notice, |
|||
* this list of conditions and the following disclaimer in the documentation |
|||
* and/or other materials provided with the distribution. |
|||
* 3. Neither the name of STMicroelectronics nor the names of its contributors |
|||
* may be used to endorse or promote products derived from this software |
|||
* without specific prior written permission. |
|||
* |
|||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" |
|||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
|||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE |
|||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE |
|||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
|||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR |
|||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER |
|||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, |
|||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
|||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
|||
* |
|||
****************************************************************************** |
|||
*/ |
|||
|
|||
/* Includes ------------------------------------------------------------------*/ |
|||
#include "otm8009a.h" |
|||
|
|||
/** @addtogroup BSP
|
|||
* @{ |
|||
*/ |
|||
|
|||
/** @addtogroup Components
|
|||
* @{ |
|||
*/ |
|||
|
|||
/** @defgroup OTM8009A OTM8009A
|
|||
* @brief This file provides a set of functions needed to drive the |
|||
* otm8009a IC display driver. |
|||
* @{ |
|||
*/ |
|||
|
|||
/* Private types -------------------------------------------------------------*/ |
|||
/* Private variables ---------------------------------------------------------*/ |
|||
/* Private constants ---------------------------------------------------------*/ |
|||
/** @defgroup OTM8009A_Private_Constants OTM8009A Private Constants
|
|||
* @{ |
|||
*/ |
|||
|
|||
/*
|
|||
* @brief Constant tables of register settings used to transmit DSI |
|||
* command packets as power up initialization sequence of the KoD LCD (OTM8009A LCD Driver) |
|||
*/ |
|||
const uint8_t lcdRegData1[] = {0x80,0x09,0x01,0xFF}; |
|||
const uint8_t lcdRegData2[] = {0x80,0x09,0xFF}; |
|||
const uint8_t lcdRegData3[] = {0x00,0x09,0x0F,0x0E,0x07,0x10,0x0B,0x0A,0x04,0x07,0x0B,0x08,0x0F,0x10,0x0A,0x01,0xE1}; |
|||
const uint8_t lcdRegData4[] = {0x00,0x09,0x0F,0x0E,0x07,0x10,0x0B,0x0A,0x04,0x07,0x0B,0x08,0x0F,0x10,0x0A,0x01,0xE2}; |
|||
const uint8_t lcdRegData5[] = {0x79,0x79,0xD8}; |
|||
const uint8_t lcdRegData6[] = {0x00,0x01,0xB3}; |
|||
const uint8_t lcdRegData7[] = {0x85,0x01,0x00,0x84,0x01,0x00,0xCE}; |
|||
const uint8_t lcdRegData8[] = {0x18,0x04,0x03,0x39,0x00,0x00,0x00,0x18,0x03,0x03,0x3A,0x00,0x00,0x00,0xCE}; |
|||
const uint8_t lcdRegData9[] = {0x18,0x02,0x03,0x3B,0x00,0x00,0x00,0x18,0x01,0x03,0x3C,0x00,0x00,0x00,0xCE}; |
|||
const uint8_t lcdRegData10[] = {0x01,0x01,0x20,0x20,0x00,0x00,0x01,0x02,0x00,0x00,0xCF}; |
|||
const uint8_t lcdRegData11[] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xCB}; |
|||
const uint8_t lcdRegData12[] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xCB}; |
|||
const uint8_t lcdRegData13[] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xCB}; |
|||
const uint8_t lcdRegData14[] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xCB}; |
|||
const uint8_t lcdRegData15[] = {0x00,0x04,0x04,0x04,0x04,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xCB}; |
|||
const uint8_t lcdRegData16[] = {0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x04,0x04,0x04,0x04,0x00,0x00,0x00,0x00,0xCB}; |
|||
const uint8_t lcdRegData17[] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xCB}; |
|||
const uint8_t lcdRegData18[] = {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xCB}; |
|||
const uint8_t lcdRegData19[] = {0x00,0x26,0x09,0x0B,0x01,0x25,0x00,0x00,0x00,0x00,0xCC}; |
|||
const uint8_t lcdRegData20[] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x26,0x0A,0x0C,0x02,0xCC}; |
|||
const uint8_t lcdRegData21[] = {0x25,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xCC}; |
|||
const uint8_t lcdRegData22[] = {0x00,0x25,0x0C,0x0A,0x02,0x26,0x00,0x00,0x00,0x00,0xCC}; |
|||
const uint8_t lcdRegData23[] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x25,0x0B,0x09,0x01,0xCC}; |
|||
const uint8_t lcdRegData24[] = {0x26,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xCC}; |
|||
const uint8_t lcdRegData25[] = {0xFF,0xFF,0xFF,0xFF}; |
|||
/*
|
|||
* CASET value (Column Address Set) : X direction LCD GRAM boundaries |
|||
* depending on LCD orientation mode and PASET value (Page Address Set) : Y direction |
|||
* LCD GRAM boundaries depending on LCD orientation mode |
|||
* XS[15:0] = 0x000 = 0, XE[15:0] = 0x31F = 799 for landscape mode : apply to CASET |
|||
* YS[15:0] = 0x000 = 0, YE[15:0] = 0x31F = 799 for portrait mode : : apply to PASET |
|||
*/ |
|||
const uint8_t lcdRegData27[] = {0x00, 0x00, 0x03, 0x1F, OTM8009A_CMD_CASET}; |
|||
/*
|
|||
* XS[15:0] = 0x000 = 0, XE[15:0] = 0x1DF = 479 for portrait mode : apply to CASET |
|||
* YS[15:0] = 0x000 = 0, YE[15:0] = 0x1DF = 479 for landscape mode : apply to PASET |
|||
*/ |
|||
const uint8_t lcdRegData28[] = {0x00, 0x00, 0x01, 0xDF, OTM8009A_CMD_PASET}; |
|||
|
|||
|
|||
const uint8_t ShortRegData1[] = {OTM8009A_CMD_NOP, 0x00}; |
|||
const uint8_t ShortRegData2[] = {OTM8009A_CMD_NOP, 0x80}; |
|||
const uint8_t ShortRegData3[] = {0xC4, 0x30}; |
|||
const uint8_t ShortRegData4[] = {OTM8009A_CMD_NOP, 0x8A}; |
|||
const uint8_t ShortRegData5[] = {0xC4, 0x40}; |
|||
const uint8_t ShortRegData6[] = {OTM8009A_CMD_NOP, 0xB1}; |
|||
const uint8_t ShortRegData7[] = {0xC5, 0xA9}; |
|||
const uint8_t ShortRegData8[] = {OTM8009A_CMD_NOP, 0x91}; |
|||
const uint8_t ShortRegData9[] = {0xC5, 0x34}; |
|||
const uint8_t ShortRegData10[] = {OTM8009A_CMD_NOP, 0xB4}; |
|||
const uint8_t ShortRegData11[] = {0xC0, 0x50}; |
|||
const uint8_t ShortRegData12[] = {0xD9, 0x4E}; |
|||
const uint8_t ShortRegData13[] = {OTM8009A_CMD_NOP, 0x81}; |
|||
const uint8_t ShortRegData14[] = {0xC1, 0x66}; |
|||
const uint8_t ShortRegData15[] = {OTM8009A_CMD_NOP, 0xA1}; |
|||
const uint8_t ShortRegData16[] = {0xC1, 0x08}; |
|||
const uint8_t ShortRegData17[] = {OTM8009A_CMD_NOP, 0x92}; |
|||
const uint8_t ShortRegData18[] = {0xC5, 0x01}; |
|||
const uint8_t ShortRegData19[] = {OTM8009A_CMD_NOP, 0x95}; |
|||
const uint8_t ShortRegData20[] = {OTM8009A_CMD_NOP, 0x94}; |
|||
const uint8_t ShortRegData21[] = {0xC5, 0x33}; |
|||
const uint8_t ShortRegData22[] = {OTM8009A_CMD_NOP, 0xA3}; |
|||
const uint8_t ShortRegData23[] = {0xC0, 0x1B}; |
|||
const uint8_t ShortRegData24[] = {OTM8009A_CMD_NOP, 0x82}; |
|||
const uint8_t ShortRegData25[] = {0xC5, 0x83}; |
|||
const uint8_t ShortRegData26[] = {0xC4, 0x83}; |
|||
const uint8_t ShortRegData27[] = {0xC1, 0x0E}; |
|||
const uint8_t ShortRegData28[] = {OTM8009A_CMD_NOP, 0xA6}; |
|||
const uint8_t ShortRegData29[] = {OTM8009A_CMD_NOP, 0xA0}; |
|||
const uint8_t ShortRegData30[] = {OTM8009A_CMD_NOP, 0xB0}; |
|||
const uint8_t ShortRegData31[] = {OTM8009A_CMD_NOP, 0xC0}; |
|||
const uint8_t ShortRegData32[] = {OTM8009A_CMD_NOP, 0xD0}; |
|||
const uint8_t ShortRegData33[] = {OTM8009A_CMD_NOP, 0x90}; |
|||
const uint8_t ShortRegData34[] = {OTM8009A_CMD_NOP, 0xE0}; |
|||
const uint8_t ShortRegData35[] = {OTM8009A_CMD_NOP, 0xF0}; |
|||
const uint8_t ShortRegData36[] = {OTM8009A_CMD_SLPOUT, 0x00}; |
|||
const uint8_t ShortRegData37[] = {OTM8009A_CMD_COLMOD, OTM8009A_COLMOD_RGB565}; |
|||
const uint8_t ShortRegData38[] = {OTM8009A_CMD_COLMOD, OTM8009A_COLMOD_RGB888}; |
|||
const uint8_t ShortRegData39[] = {OTM8009A_CMD_MADCTR, OTM8009A_MADCTR_MODE_LANDSCAPE}; |
|||
const uint8_t ShortRegData40[] = {OTM8009A_CMD_WRDISBV, 0x7F}; |
|||
const uint8_t ShortRegData41[] = {OTM8009A_CMD_WRCTRLD, 0x2C}; |
|||
const uint8_t ShortRegData42[] = {OTM8009A_CMD_WRCABC, 0x02}; |
|||
const uint8_t ShortRegData43[] = {OTM8009A_CMD_WRCABCMB, 0xFF}; |
|||
const uint8_t ShortRegData44[] = {OTM8009A_CMD_DISPON, 0x00}; |
|||
const uint8_t ShortRegData45[] = {OTM8009A_CMD_RAMWR, 0x00}; |
|||
const uint8_t ShortRegData46[] = {0xCF, 0x00}; |
|||
const uint8_t ShortRegData47[] = {0xC5, 0x66}; |
|||
const uint8_t ShortRegData48[] = {OTM8009A_CMD_NOP, 0xB6}; |
|||
const uint8_t ShortRegData49[] = {0xF5, 0x06}; |
|||
const uint8_t ShortRegData50[] = {OTM8009A_CMD_NOP, 0xB1}; |
|||
const uint8_t ShortRegData51[] = {0xC6, 0x06}; |
|||
/**
|
|||
* @} |
|||
*/ |
|||
|
|||
/* Private macros ------------------------------------------------------------*/ |
|||
/* Private functions ---------------------------------------------------------*/ |
|||
/** @defgroup OTM8009A_Exported_Variables
|
|||
* @{ |
|||
*/ |
|||
|
|||
/**
|
|||
* @} |
|||
*/ |
|||
|
|||
/* Exported functions ---------------------------------------------------------*/ |
|||
/** @defgroup OTM8009A_Exported_Functions OTM8009A Exported Functions
|
|||
* @{ |
|||
*/ |
|||
|
|||
/**
|
|||
* @brief DSI IO write short/long command. |
|||
* @note : Can be surcharged by application code implementation of the function. |
|||
*/ |
|||
__weak void DSI_IO_WriteCmd(uint32_t NbrParams, uint8_t *pParams) |
|||
{ |
|||
/* NOTE : This function Should not be modified, when it is needed,
|
|||
the DSI_IO_WriteCmd could be implemented in the user file |
|||
*/ |
|||
} |
|||
|
|||
/**
|
|||
* @brief Initializes the LCD KoD display part by communication in DSI mode in Video Mode |
|||
* with IC Display Driver OTM8009A (see IC Driver specification for more information). |
|||
* @param hdsi_eval : pointer on DSI configuration structure |
|||
* @param hdsivideo_handle : pointer on DSI video mode configuration structure |
|||
* @retval Status |
|||
*/ |
|||
uint8_t OTM8009A_Init(uint32_t ColorCoding, uint32_t orientation) |
|||
{ |
|||
/* Enable CMD2 to access vendor specific commands */ |
|||
/* Enter in command 2 mode and set EXTC to enable address shift function (0x00) */ |
|||
DSI_IO_WriteCmd(0, (uint8_t *)ShortRegData1); |
|||
DSI_IO_WriteCmd( 3, (uint8_t *)lcdRegData1); |
|||
|
|||
/* Enter ORISE Command 2 */ |
|||
DSI_IO_WriteCmd(0, (uint8_t *)ShortRegData2); /* Shift address to 0x80 */ |
|||
DSI_IO_WriteCmd( 2, (uint8_t *)lcdRegData2); |
|||
|
|||
/////////////////////////////////////////////////////////////////////
|
|||
/* SD_PCH_CTRL - 0xC480h - 129th parameter - Default 0x00 */ |
|||
/* Set SD_PT */ |
|||
/* -> Source output level during porch and non-display area to GND */ |
|||
DSI_IO_WriteCmd(0, (uint8_t *)ShortRegData2); |
|||
DSI_IO_WriteCmd(0, (uint8_t *)ShortRegData3); |
|||
OTM8009A_IO_Delay(10); |
|||
/* Not documented */ |
|||
DSI_IO_WriteCmd(0, (uint8_t *)ShortRegData4); |
|||
DSI_IO_WriteCmd(0, (uint8_t *)ShortRegData5); |
|||
OTM8009A_IO_Delay(10); |
|||
/////////////////////////////////////////////////////////////////////
|
|||
|
|||
/* PWR_CTRL4 - 0xC4B0h - 178th parameter - Default 0xA8 */ |
|||
/* Set gvdd_en_test */ |
|||
/* -> enable GVDD test mode !!! */ |
|||
DSI_IO_WriteCmd(0, (uint8_t *)ShortRegData6); |
|||
DSI_IO_WriteCmd(0, (uint8_t *)ShortRegData7); |
|||
|
|||
/* PWR_CTRL2 - 0xC590h - 146th parameter - Default 0x79 */ |
|||
/* Set pump 4 vgh voltage */ |
|||
/* -> from 15.0v down to 13.0v */ |
|||
/* Set pump 5 vgh voltage */ |
|||
/* -> from -12.0v downto -9.0v */ |
|||
DSI_IO_WriteCmd(0, (uint8_t *)ShortRegData8); |
|||
DSI_IO_WriteCmd(0, (uint8_t *)ShortRegData9); |
|||
|
|||
/* P_DRV_M - 0xC0B4h - 181th parameter - Default 0x00 */ |
|||
/* -> Column inversion */ |
|||
DSI_IO_WriteCmd(0, (uint8_t *)ShortRegData10); |
|||
DSI_IO_WriteCmd(0, (uint8_t *)ShortRegData11); |
|||
|
|||
/* VCOMDC - 0xD900h - 1st parameter - Default 0x39h */ |
|||
/* VCOM Voltage settings */ |
|||
/* -> from -1.0000v downto -1.2625v */ |
|||
DSI_IO_WriteCmd(0, (uint8_t *)ShortRegData1); |
|||
DSI_IO_WriteCmd(0, (uint8_t *)ShortRegData12); |
|||
|
|||
/* Oscillator adjustment for Idle/Normal mode (LPDT only) set to 65Hz (default is 60Hz) */ |
|||
DSI_IO_WriteCmd(0, (uint8_t *)ShortRegData13); |
|||
DSI_IO_WriteCmd(0, (uint8_t *)ShortRegData14); |
|||
|
|||
/* Video mode internal */ |
|||
DSI_IO_WriteCmd(0, (uint8_t *)ShortRegData15); |
|||
DSI_IO_WriteCmd(0, (uint8_t *)ShortRegData16); |
|||
|
|||
/* PWR_CTRL2 - 0xC590h - 147h parameter - Default 0x00 */ |
|||
/* Set pump 4&5 x6 */ |
|||
/* -> ONLY VALID when PUMP4_EN_ASDM_HV = "0" */ |
|||
DSI_IO_WriteCmd(0, (uint8_t *)ShortRegData17); |
|||
DSI_IO_WriteCmd(0, (uint8_t *)ShortRegData18); |
|||
|
|||
/* PWR_CTRL2 - 0xC590h - 150th parameter - Default 0x33h */ |
|||
/* Change pump4 clock ratio */ |
|||
/* -> from 1 line to 1/2 line */ |
|||
DSI_IO_WriteCmd(0, (uint8_t *)ShortRegData19); |
|||
DSI_IO_WriteCmd(0, (uint8_t *)ShortRegData9); |
|||
|
|||
/* GVDD/NGVDD settings */ |
|||
DSI_IO_WriteCmd(0, (uint8_t *)ShortRegData1); |
|||
DSI_IO_WriteCmd( 2, (uint8_t *)lcdRegData5); |
|||
|
|||
/* PWR_CTRL2 - 0xC590h - 149th parameter - Default 0x33h */ |
|||
/* Rewrite the default value ! */ |
|||
DSI_IO_WriteCmd(0, (uint8_t *)ShortRegData20); |
|||
DSI_IO_WriteCmd(0, (uint8_t *)ShortRegData21); |
|||
|
|||
/* Panel display timing Setting 3 */ |
|||
DSI_IO_WriteCmd(0, (uint8_t *)ShortRegData22); |
|||
DSI_IO_WriteCmd(0, (uint8_t *)ShortRegData23); |
|||
|
|||
/* Power control 1 */ |
|||
DSI_IO_WriteCmd(0, (uint8_t *)ShortRegData24); |
|||
DSI_IO_WriteCmd(0, (uint8_t *)ShortRegData25); |
|||
|
|||
/* Source driver precharge */ |
|||
DSI_IO_WriteCmd(0, (uint8_t *)ShortRegData13); |
|||
DSI_IO_WriteCmd(0, (uint8_t *)ShortRegData26); |
|||
|
|||
DSI_IO_WriteCmd(0, (uint8_t *)ShortRegData15); |
|||
DSI_IO_WriteCmd(0, (uint8_t *)ShortRegData27); |
|||
|
|||
DSI_IO_WriteCmd(0, (uint8_t *)ShortRegData28); |
|||
DSI_IO_WriteCmd( 2, (uint8_t *)lcdRegData6); |
|||
|
|||
/* GOAVST */ |
|||
DSI_IO_WriteCmd(0, (uint8_t *)ShortRegData2); |
|||
DSI_IO_WriteCmd( 6, (uint8_t *)lcdRegData7); |
|||
|
|||
DSI_IO_WriteCmd(0, (uint8_t *)ShortRegData29); |
|||
DSI_IO_WriteCmd( 14, (uint8_t *)lcdRegData8); |
|||
|
|||
DSI_IO_WriteCmd(0, (uint8_t *)ShortRegData30); |
|||
DSI_IO_WriteCmd( 14, (uint8_t *)lcdRegData9); |
|||
|
|||
DSI_IO_WriteCmd(0, (uint8_t *)ShortRegData31); |
|||
DSI_IO_WriteCmd( 10, (uint8_t *)lcdRegData10); |
|||
|
|||
DSI_IO_WriteCmd(0, (uint8_t *)ShortRegData32); |
|||
DSI_IO_WriteCmd(0, (uint8_t *)ShortRegData46); |
|||
|
|||
DSI_IO_WriteCmd(0, (uint8_t *)ShortRegData2); |
|||
DSI_IO_WriteCmd( 10, (uint8_t *)lcdRegData11); |
|||
|
|||
DSI_IO_WriteCmd(0, (uint8_t *)ShortRegData33); |
|||
DSI_IO_WriteCmd( 15, (uint8_t *)lcdRegData12); |
|||
|
|||
DSI_IO_WriteCmd(0, (uint8_t *)ShortRegData29); |
|||
DSI_IO_WriteCmd( 15, (uint8_t *)lcdRegData13); |
|||
|
|||
DSI_IO_WriteCmd(0, (uint8_t *)ShortRegData30); |
|||
DSI_IO_WriteCmd( 10, (uint8_t *)lcdRegData14); |
|||
|
|||
DSI_IO_WriteCmd(0, (uint8_t *)ShortRegData31); |
|||
DSI_IO_WriteCmd( 15, (uint8_t *)lcdRegData15); |
|||
|
|||
DSI_IO_WriteCmd(0, (uint8_t *)ShortRegData32); |
|||
DSI_IO_WriteCmd( 15, (uint8_t *)lcdRegData16); |
|||
|
|||
DSI_IO_WriteCmd(0, (uint8_t *)ShortRegData34); |
|||
DSI_IO_WriteCmd( 10, (uint8_t *)lcdRegData17); |
|||
|
|||
DSI_IO_WriteCmd(0, (uint8_t *)ShortRegData35); |
|||
DSI_IO_WriteCmd( 10, (uint8_t *)lcdRegData18); |
|||
|
|||
DSI_IO_WriteCmd(0, (uint8_t *)ShortRegData2); |
|||
DSI_IO_WriteCmd( 10, (uint8_t *)lcdRegData19); |
|||
|
|||
DSI_IO_WriteCmd(0, (uint8_t *)ShortRegData33); |
|||
DSI_IO_WriteCmd( 15, (uint8_t *)lcdRegData20); |
|||
|
|||
DSI_IO_WriteCmd(0, (uint8_t *)ShortRegData29); |
|||
DSI_IO_WriteCmd( 15, (uint8_t *)lcdRegData21); |
|||