STM32F469i-Discovery board files

This commit is contained in:
Joel Bodenmann 2017-10-28 11:58:02 +02:00
parent 2a249e6140
commit 025bc66666
18 changed files with 3687 additions and 377 deletions

View File

@ -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);

View File

@ -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 */

View File

@ -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 */

View File

@ -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 */

View File

@ -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) }
}

View File

@ -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

View File

@ -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 */

View File

@ -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 */

View File

@ -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>&copy; 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);