summaryrefslogtreecommitdiff
path: root/bsp/stm32
diff options
context:
space:
mode:
authorguozhanxin <[email protected]>2021-10-26 18:42:35 +0800
committerguozhanxin <[email protected]>2021-10-27 13:50:07 +0800
commitb7764f2aacd7ade8c24e4313c82599ec9c75524f (patch)
treeb1b964e4cbf68fd84cbe7d9e7d96606538ecbb43 /bsp/stm32
parent50bb6e33d13237f71812e81a6a13ba5ba0693c8f (diff)
[bsp][stm32f469-st-disco] add lvgl port.
Diffstat (limited to 'bsp/stm32')
-rw-r--r--bsp/stm32/stm32f469-st-disco/SConstruct3
-rw-r--r--bsp/stm32/stm32f469-st-disco/board/Kconfig10
-rw-r--r--bsp/stm32/stm32f469-st-disco/board/SConscript5
-rw-r--r--bsp/stm32/stm32f469-st-disco/board/ports/SConscript12
-rw-r--r--bsp/stm32/stm32f469-st-disco/board/ports/lvgl/SConscript9
-rw-r--r--bsp/stm32/stm32f469-st-disco/board/ports/lvgl/lv_conf.h17
-rw-r--r--bsp/stm32/stm32f469-st-disco/board/ports/lvgl/lv_demo.c100
-rw-r--r--bsp/stm32/stm32f469-st-disco/board/ports/lvgl/lv_port_disp.c214
-rw-r--r--bsp/stm32/stm32f469-st-disco/board/ports/lvgl/lv_port_disp.h23
-rw-r--r--bsp/stm32/stm32f469-st-disco/board/ports/lvgl/lv_port_indev.c46
-rw-r--r--bsp/stm32/stm32f469-st-disco/board/ports/lvgl/lv_port_indev.h28
-rw-r--r--bsp/stm32/stm32f469-st-disco/board/ports/touch/drv_touch.c12
-rw-r--r--bsp/stm32/stm32f469-st-disco/board/ports/touch/drv_touch_ft.c2
13 files changed, 476 insertions, 5 deletions
diff --git a/bsp/stm32/stm32f469-st-disco/SConstruct b/bsp/stm32/stm32f469-st-disco/SConstruct
index 1684dc06b0..d12fb5b0d1 100644
--- a/bsp/stm32/stm32f469-st-disco/SConstruct
+++ b/bsp/stm32/stm32f469-st-disco/SConstruct
@@ -56,5 +56,8 @@ objs.extend(SConscript(os.path.join(libraries_path_prefix, stm32_library, 'SCons
# include drivers
objs.extend(SConscript(os.path.join(libraries_path_prefix, 'HAL_Drivers', 'SConscript')))
+# include ports
+objs.extend(SConscript(os.path.join(os.getcwd(), 'board', 'ports', 'SConscript')))
+
# make a building
DoBuilding(TARGET, objs)
diff --git a/bsp/stm32/stm32f469-st-disco/board/Kconfig b/bsp/stm32/stm32f469-st-disco/board/Kconfig
index a1dd9ff7f7..c85eae3a19 100644
--- a/bsp/stm32/stm32f469-st-disco/board/Kconfig
+++ b/bsp/stm32/stm32f469-st-disco/board/Kconfig
@@ -8,6 +8,14 @@ config SOC_STM32F469NI
default y
menu "Onboard Peripheral Drivers"
+
+ config BSP_USING_LVGL
+ bool "Enable LVGL"
+ select BSP_USING_LCD_OTM8009A
+ select BSP_USING_TOUCH
+ select PKG_USING_LVGL
+ default n
+
config BSP_USING_SDRAM
bool "Enable SDRAM"
select BSP_USING_FMC
@@ -23,7 +31,7 @@ menu "Onboard Peripheral Drivers"
select BSP_USING_LTDC
select BSP_USING_LCD_MIPI
default n
-
+
config BSP_USING_QSPI_FLASH
bool "Enable QSPI FLASH (N25Q128A qspi1)"
select BSP_USING_QSPI
diff --git a/bsp/stm32/stm32f469-st-disco/board/SConscript b/bsp/stm32/stm32f469-st-disco/board/SConscript
index 9521cc5907..5f31252268 100644
--- a/bsp/stm32/stm32f469-st-disco/board/SConscript
+++ b/bsp/stm32/stm32f469-st-disco/board/SConscript
@@ -20,10 +20,7 @@ if GetDepend(['PKG_USING_FAL']):
if GetDepend(['BSP_USING_LCD_OTM8009A']):
src += ['ports/drv_otm8009a.c']
-
-if GetDepend(['BSP_USING_TOUCH']):
- src += Glob('ports/touch/*.c')
-
+
if GetDepend(['BSP_USING_SDCARD']):
src += ['ports/drv_sdcard.c']
diff --git a/bsp/stm32/stm32f469-st-disco/board/ports/SConscript b/bsp/stm32/stm32f469-st-disco/board/ports/SConscript
new file mode 100644
index 0000000000..3c57bc9c6d
--- /dev/null
+++ b/bsp/stm32/stm32f469-st-disco/board/ports/SConscript
@@ -0,0 +1,12 @@
+import os
+from building import *
+
+objs = []
+cwd = GetCurrentDir()
+
+list = os.listdir(cwd)
+for item in list:
+ if os.path.isfile(os.path.join(cwd, item, 'SConscript')):
+ objs = objs + SConscript(os.path.join(item, 'SConscript'))
+
+Return('objs')
diff --git a/bsp/stm32/stm32f469-st-disco/board/ports/lvgl/SConscript b/bsp/stm32/stm32f469-st-disco/board/ports/lvgl/SConscript
new file mode 100644
index 0000000000..cb74975f39
--- /dev/null
+++ b/bsp/stm32/stm32f469-st-disco/board/ports/lvgl/SConscript
@@ -0,0 +1,9 @@
+from building import *
+
+cwd = GetCurrentDir()
+
+src = Glob('*.c')
+CPPPATH = [cwd]
+
+group = DefineGroup('LVGL-port', src, depend = ['BSP_USING_LVGL'], CPPPATH = CPPPATH)
+Return('group')
diff --git a/bsp/stm32/stm32f469-st-disco/board/ports/lvgl/lv_conf.h b/bsp/stm32/stm32f469-st-disco/board/ports/lvgl/lv_conf.h
new file mode 100644
index 0000000000..ac9f12680a
--- /dev/null
+++ b/bsp/stm32/stm32f469-st-disco/board/ports/lvgl/lv_conf.h
@@ -0,0 +1,17 @@
+/*
+ * Copyright (c) 2006-2021, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2021-10-18 Meco Man First version
+ */
+
+#ifndef LV_CONF_H
+#define LV_CONF_H
+
+#define LV_USE_PERF_MONITOR 1
+#define LV_COLOR_DEPTH 32
+
+#endif
diff --git a/bsp/stm32/stm32f469-st-disco/board/ports/lvgl/lv_demo.c b/bsp/stm32/stm32f469-st-disco/board/ports/lvgl/lv_demo.c
new file mode 100644
index 0000000000..2818a4d8fa
--- /dev/null
+++ b/bsp/stm32/stm32f469-st-disco/board/ports/lvgl/lv_demo.c
@@ -0,0 +1,100 @@
+/*
+ * Copyright (c) 2006-2021, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2021-10-17 Meco Man First version
+ */
+#include <rtthread.h>
+#include <lvgl.h>
+#define DBG_TAG "LVGL"
+#define DBG_LVL DBG_INFO
+#include <rtdbg.h>
+#include <lcd_port.h>
+#include <lv_port_indev.h>
+
+#ifndef LV_THREAD_STACK_SIZE
+#define LV_THREAD_STACK_SIZE 4096
+#endif
+
+#ifndef LV_THREAD_PRIO
+#define LV_THREAD_PRIO (RT_THREAD_PRIORITY_MAX*2/3)
+#endif
+
+static void event_handler(lv_event_t * e)
+{
+ lv_event_code_t code = lv_event_get_code(e);
+ lv_obj_t * obj = lv_event_get_target(e);
+
+ if(code == LV_EVENT_VALUE_CHANGED) {
+ lv_calendar_date_t date;
+ if(lv_calendar_get_pressed_date(obj, &date)) {
+ LV_LOG_USER("Clicked date: %02d.%02d.%d", date.day, date.month, date.year);
+ }
+ }
+}
+
+void lv_example_calendar_1(void)
+{
+ lv_obj_t * calendar = lv_calendar_create(lv_scr_act());
+ lv_obj_set_size(calendar, LCD_WIDTH, LCD_HEIGHT);
+ lv_obj_align(calendar, LV_ALIGN_CENTER, 0, 60);
+ lv_obj_add_event_cb(calendar, event_handler, LV_EVENT_ALL, NULL);
+
+ lv_calendar_set_today_date(calendar, 2021, 02, 23);
+ lv_calendar_set_showed_date(calendar, 2021, 02);
+
+ /*Highlight a few days*/
+ static lv_calendar_date_t highlighted_days[3]; /*Only its pointer will be saved so should be static*/
+ highlighted_days[0].year = 2021;
+ highlighted_days[0].month = 02;
+ highlighted_days[0].day = 6;
+
+ highlighted_days[1].year = 2021;
+ highlighted_days[1].month = 02;
+ highlighted_days[1].day = 11;
+
+ highlighted_days[2].year = 2022;
+ highlighted_days[2].month = 02;
+ highlighted_days[2].day = 22;
+
+ lv_calendar_set_highlighted_dates(calendar, highlighted_days, 3);
+
+#if LV_USE_CALENDAR_HEADER_DROPDOWN
+ lv_calendar_header_dropdown_create(lv_scr_act());
+#elif LV_USE_CALENDAR_HEADER_ARROW
+ lv_calendar_header_arrow_create(lv_scr_act(), calendar, 25);
+#endif
+}
+
+static void lvgl_thread(void *parameter)
+{
+ /*assign buttons to coordinates*/
+ const lv_point_t points_array[] = {{200,35},{0,0},{70,35},{0,0}};
+ lv_indev_set_button_points(button_indev, points_array);
+
+ lv_example_calendar_1();
+
+ while(1)
+ {
+ lv_task_handler();
+ rt_thread_mdelay(10);
+ }
+}
+
+static int lvgl_demo_init(void)
+{
+ rt_thread_t tid;
+
+ tid = rt_thread_create("LVGL", lvgl_thread, RT_NULL, LV_THREAD_STACK_SIZE, LV_THREAD_PRIO, 0);
+ if(tid == RT_NULL)
+ {
+ LOG_E("Fail to create 'LVGL' thread");
+ }
+ rt_thread_startup(tid);
+
+ return 0;
+}
+INIT_APP_EXPORT(lvgl_demo_init);
diff --git a/bsp/stm32/stm32f469-st-disco/board/ports/lvgl/lv_port_disp.c b/bsp/stm32/stm32f469-st-disco/board/ports/lvgl/lv_port_disp.c
new file mode 100644
index 0000000000..c8f1a48230
--- /dev/null
+++ b/bsp/stm32/stm32f469-st-disco/board/ports/lvgl/lv_port_disp.c
@@ -0,0 +1,214 @@
+/*
+ * Copyright (c) 2006-2021, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2021-10-18 Meco Man The first version
+ */
+#include <lvgl.h>
+#include <lcd_port.h>
+
+/*A static or global variable to store the buffers*/
+static lv_disp_draw_buf_t disp_buf;
+
+rt_device_t lcd_device = 0;
+static struct rt_device_graphic_info info;
+
+static lv_disp_drv_t disp_drv; /*Descriptor of a display driver*/
+
+typedef struct
+{
+ uint8_t blue;
+ uint8_t green;
+ uint8_t red;
+} lv_color24_t;
+
+static void color_to16_maybe(lv_color16_t *dst, lv_color_t *src)
+{
+#if (LV_COLOR_DEPTH == 16)
+ dst->full = src->full;
+#else
+ dst->ch.blue = src->ch.blue;
+ dst->ch.green = src->ch.green;
+ dst->ch.red = src->ch.red;
+#endif
+}
+
+static void color_to24(lv_color24_t *dst, lv_color_t *src)
+{
+ dst->blue = src->ch.blue;
+ dst->green = src->ch.green;
+ dst->red = src->ch.red;
+}
+
+/*Flush the content of the internal buffer the specific area on the display
+ *You can use DMA or any hardware acceleration to do this operation in the background but
+ *'lv_disp_flush_ready()' has to be called when finished.*/
+static void lcd_fb_flush(lv_disp_drv_t *disp_drv, const lv_area_t *area, lv_color_t *color_p)
+{
+ int x1, x2, y1, y2;
+
+ x1 = area->x1;
+ x2 = area->x2;
+ y1 = area->y1;
+ y2 = area->y2;
+
+ /*Return if the area is out the screen*/
+ if (x2 < 0)
+ return;
+ if (y2 < 0)
+ return;
+ if (x1 > info.width - 1)
+ return;
+ if (y1 > info.height - 1)
+ return;
+
+ /*Truncate the area to the screen*/
+ int32_t act_x1 = x1 < 0 ? 0 : x1;
+ int32_t act_y1 = y1 < 0 ? 0 : y1;
+ int32_t act_x2 = x2 > info.width - 1 ? info.width - 1 : x2;
+ int32_t act_y2 = y2 > info.height - 1 ? info.height - 1 : y2;
+
+ uint32_t x;
+ uint32_t y;
+ long int location = 0;
+
+ /* 8 bit per pixel */
+ if (info.bits_per_pixel == 8)
+ {
+ uint8_t *fbp8 = (uint8_t *)info.framebuffer;
+ //TODO color convert maybe
+ for (y = act_y1; y <= act_y2; y++)
+ {
+ for (x = act_x1; x <= act_x2; x++)
+ {
+ location = (x) + (y)*info.width;
+ fbp8[location] = color_p->full;
+ color_p++;
+ }
+
+ color_p += x2 - act_x2;
+ }
+ }
+
+ /* 16 bit per pixel */
+ else if (info.bits_per_pixel == 16)
+ {
+ lv_color16_t *fbp16 = (lv_color16_t *)info.framebuffer;
+
+ for (y = act_y1; y <= act_y2; y++)
+ {
+ for (x = act_x1; x <= act_x2; x++)
+ {
+ location = (x) + (y)*info.width;
+ color_to16_maybe(&fbp16[location], color_p);
+ color_p++;
+ }
+
+ color_p += x2 - act_x2;
+ }
+ }
+
+ /* 24 bit per pixel */
+ else if (info.bits_per_pixel == 24)
+ {
+ lv_color24_t *fbp24 = (lv_color24_t *)info.framebuffer;
+
+ for (y = act_y1; y <= act_y2; y++)
+ {
+ for (x = act_x1; x <= act_x2; x++)
+ {
+ location = (x) + (y)*info.width;
+ color_to24(&fbp24[location], color_p);
+ color_p++;
+ }
+
+ color_p += x2 - act_x2;
+ }
+ }
+
+ /* 32 bit per pixel */
+ else if (info.bits_per_pixel == 32)
+ {
+ uint32_t *fbp32 = (uint32_t *)info.framebuffer;
+ //TODO
+ for (y = act_y1; y <= act_y2; y++)
+ {
+ for (x = act_x1; x <= act_x2; x++)
+ {
+ location = (x) + (y)*info.width;
+ fbp32[location] = color_p->full;
+ color_p++;
+ }
+
+ color_p += x2 - act_x2;
+ }
+ }
+
+ struct rt_device_rect_info rect_info;
+
+ rect_info.x = x1;
+ rect_info.y = y1;
+ rect_info.width = x2 - x1 + 1;
+ rect_info.height = y2 - y1 + 1;
+ rt_device_control(lcd_device, RTGRAPHIC_CTRL_RECT_UPDATE, &rect_info);
+
+ lv_disp_flush_ready(disp_drv);
+}
+
+void lv_port_disp_init(void)
+{
+ rt_err_t result;
+ lv_color_t *fbuf;
+
+ lcd_device = rt_device_find("lcd");
+ if (lcd_device == 0)
+ {
+ rt_kprintf("error!\n");
+ return;
+ }
+ result = rt_device_open(lcd_device, 0);
+ if (result != RT_EOK)
+ {
+ rt_kprintf("error!\n");
+ return;
+ }
+ /* get framebuffer address */
+ result = rt_device_control(lcd_device, RTGRAPHIC_CTRL_GET_INFO, &info);
+ if (result != RT_EOK)
+ {
+ rt_kprintf("error!\n");
+ /* get device information failed */
+ return;
+ }
+
+ RT_ASSERT(info.bits_per_pixel == 8 || info.bits_per_pixel == 16 ||
+ info.bits_per_pixel == 24 || info.bits_per_pixel == 32);
+
+ fbuf = rt_malloc(info.width * info.height / 10);
+ if (!fbuf)
+ {
+ rt_kprintf("Error: alloc disp buf fail\n");
+ return;
+ }
+
+ /*Initialize `disp_buf` with the buffer(s). With only one buffer use NULL instead buf_2 */
+ lv_disp_draw_buf_init(&disp_buf, fbuf, RT_NULL, info.width * 10);
+
+ lv_disp_drv_init(&disp_drv); /*Basic initialization*/
+
+ /*Set the resolution of the display*/
+ disp_drv.hor_res = info.width;
+ disp_drv.ver_res = info.height;
+
+ /*Set a display buffer*/
+ disp_drv.draw_buf = &disp_buf;
+
+ /*Used to copy the buffer's content to the display*/
+ disp_drv.flush_cb = lcd_fb_flush;
+
+ /*Finally register the driver*/
+ lv_disp_drv_register(&disp_drv);
+}
diff --git a/bsp/stm32/stm32f469-st-disco/board/ports/lvgl/lv_port_disp.h b/bsp/stm32/stm32f469-st-disco/board/ports/lvgl/lv_port_disp.h
new file mode 100644
index 0000000000..ef39eb03cd
--- /dev/null
+++ b/bsp/stm32/stm32f469-st-disco/board/ports/lvgl/lv_port_disp.h
@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) 2006-2021, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2021-10-18 Meco Man The first version
+ */
+#ifndef LV_PORT_DISP_H
+#define LV_PORT_DISP_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void lv_port_disp_init(void);
+
+#ifdef __cplusplus
+} /*extern "C"*/
+#endif
+
+#endif
diff --git a/bsp/stm32/stm32f469-st-disco/board/ports/lvgl/lv_port_indev.c b/bsp/stm32/stm32f469-st-disco/board/ports/lvgl/lv_port_indev.c
new file mode 100644
index 0000000000..b190a32a91
--- /dev/null
+++ b/bsp/stm32/stm32f469-st-disco/board/ports/lvgl/lv_port_indev.c
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2006-2021, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2021-10-18 Meco Man The first version
+ */
+#include <lvgl.h>
+#include <stdbool.h>
+#include <rtdevice.h>
+
+#include <lcd_port.h>
+
+static lv_indev_state_t last_state = LV_INDEV_STATE_REL;
+static rt_int16_t last_x = 0;
+static rt_int16_t last_y = 0;
+
+static void input_read(lv_indev_drv_t *indev_drv, lv_indev_data_t *data)
+{
+ data->point.x = last_x;
+ data->point.y = last_y;
+ data->state = last_state;
+}
+
+void lv_port_indev_input(rt_int16_t x, rt_int16_t y, lv_indev_state_t state)
+{
+ last_state = state;
+ last_x = x;
+ last_y = LCD_HEIGHT - y;
+}
+
+lv_indev_t * button_indev;
+
+void lv_port_indev_init(void)
+{
+ static lv_indev_drv_t indev_drv;
+
+ lv_indev_drv_init(&indev_drv); /*Basic initialization*/
+ indev_drv.type = LV_INDEV_TYPE_POINTER;
+ indev_drv.read_cb = input_read;
+
+ /*Register the driver in LVGL and save the created input device object*/
+ button_indev = lv_indev_drv_register(&indev_drv);
+}
diff --git a/bsp/stm32/stm32f469-st-disco/board/ports/lvgl/lv_port_indev.h b/bsp/stm32/stm32f469-st-disco/board/ports/lvgl/lv_port_indev.h
new file mode 100644
index 0000000000..d15f0e5cfa
--- /dev/null
+++ b/bsp/stm32/stm32f469-st-disco/board/ports/lvgl/lv_port_indev.h
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2006-2021, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2021-10-18 Meco Man The first version
+ */
+#ifndef LV_PORT_INDEV_H
+#define LV_PORT_INDEV_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <lv_hal_indev.h>
+
+extern lv_indev_t * button_indev;
+
+void lv_port_indev_init(void);
+void lv_port_indev_input(rt_int16_t x, rt_int16_t y, lv_indev_state_t state);
+
+#ifdef __cplusplus
+} /*extern "C"*/
+#endif
+
+#endif
diff --git a/bsp/stm32/stm32f469-st-disco/board/ports/touch/drv_touch.c b/bsp/stm32/stm32f469-st-disco/board/ports/touch/drv_touch.c
index 53437f34ef..3dd47068ee 100644
--- a/bsp/stm32/stm32f469-st-disco/board/ports/touch/drv_touch.c
+++ b/bsp/stm32/stm32f469-st-disco/board/ports/touch/drv_touch.c
@@ -16,6 +16,10 @@
#include <rtgui/rtgui_server.h>
#elif defined(PKG_USING_LITTLEVGL2RTT)
#include <littlevgl2rtt.h>
+#elif defined(PKG_USING_LVGL)
+#include <lvgl.h>
+#include <lv_port_indev.h>
+static rt_bool_t touch_down = RT_FALSE;
#endif
#define BSP_TOUCH_SAMPLE_HZ (50)
@@ -50,6 +54,9 @@ static void post_down_event(rt_uint16_t x, rt_uint16_t y, rt_tick_t ts)
rtgui_server_post_event(&emouse.parent, sizeof(emouse));
#elif defined(PKG_USING_LITTLEVGL2RTT)
littlevgl2rtt_send_input_event(x, y, LITTLEVGL2RTT_INPUT_DOWN);
+#elif defined(PKG_USING_LVGL)
+ touch_down = RT_TRUE;
+ lv_port_indev_input(x, y, (touch_down == RT_TRUE) ? LV_INDEV_STATE_PR : LV_INDEV_STATE_REL);
#endif
}
@@ -70,6 +77,8 @@ static void post_motion_event(rt_uint16_t x, rt_uint16_t y, rt_tick_t ts)
rtgui_server_post_event(&emouse.parent, sizeof(emouse));
#elif defined(PKG_USING_LITTLEVGL2RTT)
littlevgl2rtt_send_input_event(x, y, LITTLEVGL2RTT_INPUT_MOVE);
+#elif defined(PKG_USING_LVGL)
+ lv_port_indev_input(x, y, (touch_down == RT_TRUE) ? LV_INDEV_STATE_PR : LV_INDEV_STATE_REL);
#endif
}
@@ -90,6 +99,9 @@ static void post_up_event(rt_uint16_t x, rt_uint16_t y, rt_tick_t ts)
rtgui_server_post_event(&emouse.parent, sizeof(emouse));
#elif defined(PKG_USING_LITTLEVGL2RTT)
littlevgl2rtt_send_input_event(x, y, LITTLEVGL2RTT_INPUT_MOVE);
+#elif defined(PKG_USING_LVGL)
+ touch_down = RT_FALSE;
+ lv_port_indev_input(x, y, (touch_down == RT_TRUE) ? LV_INDEV_STATE_PR : LV_INDEV_STATE_REL);
#endif
}
diff --git a/bsp/stm32/stm32f469-st-disco/board/ports/touch/drv_touch_ft.c b/bsp/stm32/stm32f469-st-disco/board/ports/touch/drv_touch_ft.c
index e85e793573..bd2db859ba 100644
--- a/bsp/stm32/stm32f469-st-disco/board/ports/touch/drv_touch_ft.c
+++ b/bsp/stm32/stm32f469-st-disco/board/ports/touch/drv_touch_ft.c
@@ -13,6 +13,8 @@
#include <rthw.h>
#include <rtdevice.h>
#include "drv_touch.h"
+
+#include <stdint.h>
#include <string.h>
#ifdef BSP_USING_TOUCH