summaryrefslogtreecommitdiff
path: root/bsp/raspberry-pico
diff options
context:
space:
mode:
authorRbb666 <[email protected]>2022-01-12 18:56:35 +0800
committerRbb666 <[email protected]>2022-01-12 18:56:37 +0800
commit814c15cdbc292e69a2d0ca2b49a0b5a0a5aca189 (patch)
tree47dfc3a2cba0ffb9e8718068c26342b2bc91ad49 /bsp/raspberry-pico
parentea9c6c94e0460b38195b7bb9c4ae0e63ece09d0f (diff)
Add lvgl_8.1.0 support for raspberry_pi pico
Diffstat (limited to 'bsp/raspberry-pico')
-rw-r--r--bsp/raspberry-pico/Kconfig1
-rw-r--r--bsp/raspberry-pico/SConstruct2
-rw-r--r--bsp/raspberry-pico/applications/SConscript18
-rw-r--r--bsp/raspberry-pico/applications/lvgl/SConscript16
-rw-r--r--bsp/raspberry-pico/applications/lvgl/lv_conf.h26
-rw-r--r--bsp/raspberry-pico/applications/lvgl/lv_demo.c49
-rw-r--r--bsp/raspberry-pico/applications/lvgl/lv_port_disp.c57
-rw-r--r--bsp/raspberry-pico/applications/lvgl/lv_port_disp.h23
-rw-r--r--bsp/raspberry-pico/applications/lvgl/lv_port_indev.c105
-rw-r--r--bsp/raspberry-pico/applications/lvgl/lv_port_indev.h28
-rw-r--r--bsp/raspberry-pico/board/SConscript20
-rw-r--r--bsp/raspberry-pico/board/board.c (renamed from bsp/raspberry-pico/drivers/board.c)6
-rw-r--r--bsp/raspberry-pico/board/board.h (renamed from bsp/raspberry-pico/drivers/board.h)0
-rw-r--r--bsp/raspberry-pico/board/ports/SConscript12
-rw-r--r--bsp/raspberry-pico/board/ports/lcd/SConscript10
-rw-r--r--bsp/raspberry-pico/board/ports/lcd/drv_lcd.c444
-rw-r--r--bsp/raspberry-pico/board/ports/lcd/drv_lcd.h75
-rw-r--r--bsp/raspberry-pico/libraries/Kconfig23
-rw-r--r--bsp/raspberry-pico/libraries/SConscript7
19 files changed, 915 insertions, 7 deletions
diff --git a/bsp/raspberry-pico/Kconfig b/bsp/raspberry-pico/Kconfig
index c9666bbc93..b8ba681346 100644
--- a/bsp/raspberry-pico/Kconfig
+++ b/bsp/raspberry-pico/Kconfig
@@ -17,6 +17,7 @@ config PKGS_DIR
source "$RTT_DIR/Kconfig"
source "$PKGS_DIR/Kconfig"
+source "libraries/Kconfig"
config SOC_RP2040
bool
diff --git a/bsp/raspberry-pico/SConstruct b/bsp/raspberry-pico/SConstruct
index 79821f993a..26b423a1d8 100644
--- a/bsp/raspberry-pico/SConstruct
+++ b/bsp/raspberry-pico/SConstruct
@@ -27,5 +27,7 @@ Export('rtconfig')
# prepare building environment
objs = PrepareBuilding(env, RTT_ROOT)
+objs.extend(SConscript(os.path.join(os.getcwd(), 'board', 'ports', 'SConscript')))
+
# make a building
DoBuilding(TARGET, objs)
diff --git a/bsp/raspberry-pico/applications/SConscript b/bsp/raspberry-pico/applications/SConscript
index 01eb940dfb..d0723dfea1 100644
--- a/bsp/raspberry-pico/applications/SConscript
+++ b/bsp/raspberry-pico/applications/SConscript
@@ -1,11 +1,17 @@
-Import('RTT_ROOT')
-Import('rtconfig')
from building import *
+import os
-cwd = os.path.join(str(Dir('#')), 'applications')
-src = Glob('*.c')
-CPPPATH = [cwd, str(Dir('#'))]
+cwd = GetCurrentDir()
+
+src = ['main.c']
+
+CPPPATH = [cwd]
group = DefineGroup('Applications', src, depend = [''], CPPPATH = CPPPATH)
-Return('group')
+list = os.listdir(cwd)
+for item in list:
+ if os.path.isfile(os.path.join(cwd, item, 'SConscript')):
+ group = group + SConscript(os.path.join(item, 'SConscript'))
+
+Return('group') \ No newline at end of file
diff --git a/bsp/raspberry-pico/applications/lvgl/SConscript b/bsp/raspberry-pico/applications/lvgl/SConscript
new file mode 100644
index 0000000000..0292c8d9d0
--- /dev/null
+++ b/bsp/raspberry-pico/applications/lvgl/SConscript
@@ -0,0 +1,16 @@
+from building import *
+import os
+
+cwd = GetCurrentDir()
+group = []
+src = Glob('*.c')
+CPPPATH = [cwd]
+
+list = os.listdir(cwd)
+for d in list:
+ path = os.path.join(cwd, d)
+ if os.path.isfile(os.path.join(path, 'SConscript')):
+ group = group + SConscript(os.path.join(d, 'SConscript'))
+
+group += DefineGroup('LVGL-port', src, depend = ['BSP_USING_LVGL'], CPPPATH = CPPPATH)
+Return('group')
diff --git a/bsp/raspberry-pico/applications/lvgl/lv_conf.h b/bsp/raspberry-pico/applications/lvgl/lv_conf.h
new file mode 100644
index 0000000000..a5e6be8a2a
--- /dev/null
+++ b/bsp/raspberry-pico/applications/lvgl/lv_conf.h
@@ -0,0 +1,26 @@
+/*
+ * 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 16
+#define LV_COLOR_16_SWAP 1
+
+/* music player demo */
+#define LV_HOR_RES_MAX 240
+#define LV_VER_RES_MAX 240
+#define LV_USE_DEMO_RTT_MUSIC 1
+#define LV_DEMO_RTT_MUSIC_AUTO_PLAY 1
+#define LV_FONT_MONTSERRAT_12 1
+#define LV_FONT_MONTSERRAT_16 1
+
+#endif
diff --git a/bsp/raspberry-pico/applications/lvgl/lv_demo.c b/bsp/raspberry-pico/applications/lvgl/lv_demo.c
new file mode 100644
index 0000000000..95e047d541
--- /dev/null
+++ b/bsp/raspberry-pico/applications/lvgl/lv_demo.c
@@ -0,0 +1,49 @@
+/*
+ * 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>
+#include <lv_port_indev.h>
+#define DBG_TAG "LVGL.demo"
+#define DBG_LVL DBG_INFO
+#include <rtdbg.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 lvgl_thread(void *parameter)
+{
+ extern void lv_demo_music(void);
+ lv_demo_music();
+ while (1)
+ {
+ lv_task_handler();
+ rt_thread_mdelay(5);
+ }
+}
+
+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/raspberry-pico/applications/lvgl/lv_port_disp.c b/bsp/raspberry-pico/applications/lvgl/lv_port_disp.c
new file mode 100644
index 0000000000..48a922cc9e
--- /dev/null
+++ b/bsp/raspberry-pico/applications/lvgl/lv_port_disp.c
@@ -0,0 +1,57 @@
+/*
+ * 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
+ * 2021-12-24 Rb Refresh using dma2d
+ */
+#include <lvgl.h>
+#include "drv_lcd.h"
+
+/*A static or global variable to store the buffers*/
+static lv_disp_draw_buf_t disp_buf;
+static lv_disp_drv_t disp_drv; /*Descriptor of a display driver*/
+
+#define DISP_BUF_SIZE (LV_HOR_RES_MAX * LV_VER_RES_MAX)
+
+static const lv_color_t * buf_to_flush;
+
+static lv_disp_drv_t g_disp_drv;
+static lv_color_t lv_disp_buf1[DISP_BUF_SIZE];
+
+static void lcd_fb_flush(lv_disp_drv_t *disp_drv, const lv_area_t *area, lv_color_t *color_p)
+{
+ LCD_DisplayWindows(area->x1, area->y1, area->x2, area->y2, (uint16_t*) color_p);
+ lv_disp_flush_ready(disp_drv);
+}
+
+void lv_port_disp_init(void)
+{
+ rt_err_t result;
+
+ SPI_Init();
+ LCD_Init(HORIZONTAL);
+
+ /*Initialize `disp_buf` with the buffer(s).*/
+ lv_disp_draw_buf_init(&disp_buf, lv_disp_buf1, 0x00, DISP_BUF_SIZE);
+
+ lv_disp_drv_init(&disp_drv); /*Basic initialization*/
+
+ /*Set the resolution of the display*/
+ disp_drv.hor_res = LV_VER_RES_MAX;
+ disp_drv.ver_res = LV_HOR_RES_MAX;
+
+ /*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);
+
+ g_disp_drv = disp_drv;
+}
diff --git a/bsp/raspberry-pico/applications/lvgl/lv_port_disp.h b/bsp/raspberry-pico/applications/lvgl/lv_port_disp.h
new file mode 100644
index 0000000000..ef39eb03cd
--- /dev/null
+++ b/bsp/raspberry-pico/applications/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/raspberry-pico/applications/lvgl/lv_port_indev.c b/bsp/raspberry-pico/applications/lvgl/lv_port_indev.c
new file mode 100644
index 0000000000..0beae12763
--- /dev/null
+++ b/bsp/raspberry-pico/applications/lvgl/lv_port_indev.c
@@ -0,0 +1,105 @@
+/*
+ * 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>
+
+#define UP_KEY 2
+#define DOWN_KEY 18
+#define LEFT_KEY 16
+#define RIGHT_KEY 20
+#define CRTL_KEY 3
+
+#define BUTTON0_PIN 2
+#define BUTTON1_PIN 18
+#define BUTTON2_PIN 16
+#define BUTTON_WKUP_PIN 20
+
+/*Test if `id` button is pressed or not*/
+static bool button_is_pressed(uint8_t id)
+{
+ switch(id)
+ {
+ case 0:
+ if(rt_pin_read(BUTTON0_PIN) == PIN_LOW)
+ return true;
+ break;
+ case 1:
+ if(rt_pin_read(BUTTON1_PIN) == PIN_LOW)
+ return true;
+ break;
+ case 2:
+ if(rt_pin_read(BUTTON2_PIN) == PIN_LOW)
+ return true;
+ break;
+ case 3:
+ if(rt_pin_read(BUTTON_WKUP_PIN) == PIN_LOW)
+ return true;
+ break;
+ }
+
+ return false;
+}
+
+static int8_t button_get_pressed_id(void)
+{
+ uint8_t i;
+
+ /*Check to buttons see which is being pressed*/
+ for(i = 0; i < 4; i++)
+ {
+ /*Return the pressed button's ID*/
+ if(button_is_pressed(i))
+ {
+ return i;
+ }
+ }
+
+ /*No button pressed*/
+ return -1;
+}
+
+void button_read(lv_indev_drv_t * drv, lv_indev_data_t*data)
+{
+ static uint32_t last_btn = 0; /*Store the last pressed button*/
+ int btn_pr = button_get_pressed_id(); /*Get the ID (0,1,2...) of the pressed button*/
+ if(btn_pr >= 0)
+ { /*Is there a button press? (E.g. -1 indicated no button was pressed)*/
+ last_btn = btn_pr; /*Save the ID of the pressed button*/
+ data->state = LV_INDEV_STATE_PRESSED; /*Set the pressed state*/
+ }
+ else
+ {
+ data->state = LV_INDEV_STATE_RELEASED; /*Set the released state*/
+ }
+
+ data->btn_id = last_btn; /*Save the last button*/
+}
+
+
+lv_indev_t * button_indev;
+
+void lv_port_indev_init(void)
+{
+ static lv_indev_drv_t indev_drv;
+
+ /* Initialize the on-board buttons */
+ rt_pin_mode(BUTTON0_PIN, PIN_MODE_INPUT);
+ rt_pin_mode(BUTTON1_PIN, PIN_MODE_INPUT);
+ rt_pin_mode(BUTTON2_PIN, PIN_MODE_INPUT);
+ rt_pin_mode(BUTTON_WKUP_PIN, PIN_MODE_INPUT);
+
+ lv_indev_drv_init(&indev_drv); /*Basic initialization*/
+ indev_drv.type = LV_INDEV_TYPE_BUTTON;
+ indev_drv.read_cb = button_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/raspberry-pico/applications/lvgl/lv_port_indev.h b/bsp/raspberry-pico/applications/lvgl/lv_port_indev.h
new file mode 100644
index 0000000000..d15f0e5cfa
--- /dev/null
+++ b/bsp/raspberry-pico/applications/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/raspberry-pico/board/SConscript b/bsp/raspberry-pico/board/SConscript
new file mode 100644
index 0000000000..17c3b776a3
--- /dev/null
+++ b/bsp/raspberry-pico/board/SConscript
@@ -0,0 +1,20 @@
+import os
+import rtconfig
+from building import *
+
+cwd = GetCurrentDir()
+
+# add general drivers
+src = Split('''
+board.c
+''')
+
+path = [cwd]
+path += [cwd + '/ports/lcd']
+
+if GetDepend(['BSP_USING_LVGL']):
+ path += [cwd + '/ports/lcd']
+
+group = DefineGroup('Drivers', src, depend = [''], CPPPATH = path)
+
+Return('group')
diff --git a/bsp/raspberry-pico/drivers/board.c b/bsp/raspberry-pico/board/board.c
index 3d0a58a588..f95a197769 100644
--- a/bsp/raspberry-pico/drivers/board.c
+++ b/bsp/raspberry-pico/board/board.c
@@ -16,6 +16,8 @@
#include "board.h"
#include "hardware/structs/systick.h"
+#define PLL_SYS_KHZ (133 * 1000)
+
void isr_systick(void)
{
/* enter interrupt */
@@ -43,6 +45,8 @@ uint32_t systick_config(uint32_t ticks)
void rt_hw_board_init()
{
+ set_sys_clock_khz(PLL_SYS_KHZ, true);
+
rt_system_heap_init(HEAP_BEGIN, HEAP_END);
alarm_pool_init_default();
@@ -65,7 +69,7 @@ void rt_hw_board_init()
stdio_init_all();
rt_hw_uart_init();
-#if defined(RT_USING_CONSOLE) && defined(RT_USING_DEVICE)
+#ifdef RT_USING_CONSOLE
rt_console_set_device(RT_CONSOLE_DEVICE_NAME);
#endif
}
diff --git a/bsp/raspberry-pico/drivers/board.h b/bsp/raspberry-pico/board/board.h
index 0c418d5c4e..0c418d5c4e 100644
--- a/bsp/raspberry-pico/drivers/board.h
+++ b/bsp/raspberry-pico/board/board.h
diff --git a/bsp/raspberry-pico/board/ports/SConscript b/bsp/raspberry-pico/board/ports/SConscript
new file mode 100644
index 0000000000..3c57bc9c6d
--- /dev/null
+++ b/bsp/raspberry-pico/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/raspberry-pico/board/ports/lcd/SConscript b/bsp/raspberry-pico/board/ports/lcd/SConscript
new file mode 100644
index 0000000000..ab60ebfecf
--- /dev/null
+++ b/bsp/raspberry-pico/board/ports/lcd/SConscript
@@ -0,0 +1,10 @@
+from building import *
+import os
+
+cwd = GetCurrentDir()
+src = ['drv_lcd.c']
+CPPPATH = [cwd]
+
+group = DefineGroup('Drivers', src, depend = ['BSP_USING_LVGL'], CPPPATH = CPPPATH)
+
+Return('group')
diff --git a/bsp/raspberry-pico/board/ports/lcd/drv_lcd.c b/bsp/raspberry-pico/board/ports/lcd/drv_lcd.c
new file mode 100644
index 0000000000..30808f97d4
--- /dev/null
+++ b/bsp/raspberry-pico/board/ports/lcd/drv_lcd.c
@@ -0,0 +1,444 @@
+#include <drv_lcd.h>
+#include <stdlib.h>
+
+#define SPI_PORT spi1
+
+uint slice_num;
+LCD_ATTRIBUTES LCD;
+
+/******************************************************************************
+ function : Hardware reset
+ parameter:
+ ******************************************************************************/
+static void LCD_Reset(void)
+{
+ DEV_Digital_Write(LCD_RST_PIN, 1);
+ rt_thread_mdelay(100);
+ DEV_Digital_Write(LCD_RST_PIN, 0);
+ rt_thread_mdelay(100);
+ DEV_Digital_Write(LCD_RST_PIN, 1);
+ rt_thread_mdelay(100);
+}
+
+/******************************************************************************
+ function : send command
+ parameter:
+ Reg : Command register
+ ******************************************************************************/
+static void LCD_SendCommand(UBYTE Reg)
+{
+ DEV_Digital_Write(LCD_DC_PIN, 0);
+ DEV_Digital_Write(LCD_CS_PIN, 0);
+ DEV_SPI_WriteByte(Reg);
+ DEV_Digital_Write(LCD_CS_PIN, 1);
+}
+
+/******************************************************************************
+ function : send data
+ parameter:
+ Data : Write data
+ ******************************************************************************/
+static void LCD_SendData_8Bit(UBYTE Data)
+{
+ DEV_Digital_Write(LCD_DC_PIN, 1);
+ DEV_Digital_Write(LCD_CS_PIN, 0);
+ DEV_SPI_WriteByte(Data);
+ DEV_Digital_Write(LCD_CS_PIN, 1);
+}
+
+/******************************************************************************
+ function : send data
+ parameter:
+ Data : Write data
+ ******************************************************************************/
+static void LCD_SendData_16Bit(UWORD Data)
+{
+ DEV_Digital_Write(LCD_DC_PIN, 1);
+ DEV_Digital_Write(LCD_CS_PIN, 0);
+ DEV_SPI_WriteByte((Data >> 8) & 0xFF);
+ DEV_SPI_WriteByte(Data & 0xFF);
+ DEV_Digital_Write(LCD_CS_PIN, 1);
+}
+
+/******************************************************************************
+ function : Initialize the lcd register
+ parameter:
+ ******************************************************************************/
+static void LCD_InitReg(void)
+{
+ LCD_SendCommand(0x3A);
+ LCD_SendData_8Bit(0x05);
+
+ LCD_SendCommand(0xB2);
+ LCD_SendData_8Bit(0x0C);
+ LCD_SendData_8Bit(0x0C);
+ LCD_SendData_8Bit(0x00);
+ LCD_SendData_8Bit(0x33);
+ LCD_SendData_8Bit(0x33);
+
+ LCD_SendCommand(0xB7); // Gate Control
+ LCD_SendData_8Bit(0x35);
+
+ LCD_SendCommand(0xBB); // VCOM Setting
+ LCD_SendData_8Bit(0x19);
+
+ LCD_SendCommand(0xC0); // LCM Control
+ LCD_SendData_8Bit(0x2C);
+
+ LCD_SendCommand(0xC2); // VDV and VRH Command Enable
+ LCD_SendData_8Bit(0x01);
+ LCD_SendCommand(0xC3); // VRH Set
+ LCD_SendData_8Bit(0x12);
+ LCD_SendCommand(0xC4); // VDV Set
+ LCD_SendData_8Bit(0x20);
+
+ LCD_SendCommand(0xC6); // Frame Rate Control in Normal Mode
+ LCD_SendData_8Bit(0x01); // 110hz
+
+ LCD_SendCommand(0xD0); // Power Control 1
+ LCD_SendData_8Bit(0xA4);
+ LCD_SendData_8Bit(0xA1);
+
+ LCD_SendCommand(0xE0); // Positive Voltage Gamma Control
+ LCD_SendData_8Bit(0xD0);
+ LCD_SendData_8Bit(0x04);
+ LCD_SendData_8Bit(0x0D);
+ LCD_SendData_8Bit(0x11);
+ LCD_SendData_8Bit(0x13);
+ LCD_SendData_8Bit(0x2B);
+ LCD_SendData_8Bit(0x3F);
+ LCD_SendData_8Bit(0x54);
+ LCD_SendData_8Bit(0x4C);
+ LCD_SendData_8Bit(0x18);
+ LCD_SendData_8Bit(0x0D);
+ LCD_SendData_8Bit(0x0B);
+ LCD_SendData_8Bit(0x1F);
+ LCD_SendData_8Bit(0x23);
+
+ LCD_SendCommand(0xE1); // Negative Voltage Gamma Control
+ LCD_SendData_8Bit(0xD0);
+ LCD_SendData_8Bit(0x04);
+ LCD_SendData_8Bit(0x0C);
+ LCD_SendData_8Bit(0x11);
+ LCD_SendData_8Bit(0x13);
+ LCD_SendData_8Bit(0x2C);
+ LCD_SendData_8Bit(0x3F);
+ LCD_SendData_8Bit(0x44);
+ LCD_SendData_8Bit(0x51);
+ LCD_SendData_8Bit(0x2F);
+ LCD_SendData_8Bit(0x1F);
+ LCD_SendData_8Bit(0x1F);
+ LCD_SendData_8Bit(0x20);
+ LCD_SendData_8Bit(0x23);
+
+ LCD_SendCommand(0x21); // Display Inversion On
+
+ LCD_SendCommand(0x11); // Sleep Out
+
+ LCD_SendCommand(0x29); // Display On
+}
+
+/********************************************************************************
+ function: Set the resolution and scanning method of the screen
+ parameter:
+ Scan_dir: Scan direction
+ ********************************************************************************/
+static void LCD_SetAttributes(UBYTE Scan_dir)
+{
+ // Get the screen scan direction
+ LCD.SCAN_DIR = Scan_dir;
+ UBYTE MemoryAccessReg = 0x00;
+
+ // Get GRAM and LCD width and height
+ if (Scan_dir == HORIZONTAL)
+ {
+ LCD.HEIGHT = LCD_WIDTH;
+ LCD.WIDTH = LCD_HEIGHT;
+ MemoryAccessReg = 0X70;
+ }
+ else
+ {
+ LCD.HEIGHT = LCD_HEIGHT;
+ LCD.WIDTH = LCD_WIDTH;
+ MemoryAccessReg = 0X00;
+ }
+
+ // Set the read / write scan direction of the frame memory
+ LCD_SendCommand(0x36); // MX, MY, RGB mode
+ LCD_SendData_8Bit(MemoryAccessReg); // 0x08 set RGB
+}
+
+/********************************************************************************
+ function : Initialize the lcd
+ parameter:
+ ********************************************************************************/
+void LCD_Init(UBYTE Scan_dir)
+{
+ DEV_SET_PWM(50);
+
+ // Hardware reset
+ LCD_Reset();
+
+ // Set the resolution and scanning method of the screen
+ LCD_SetAttributes(Scan_dir);
+
+ // Set the initialization register
+ LCD_InitReg();
+}
+
+void LCD_SetWindows(UWORD Xstart, UWORD Ystart, UWORD Xend, UWORD Yend)
+{
+ // set the X coordinates
+ LCD_SendCommand(0x2A);
+ LCD_SendData_8Bit((Xstart >> 8) & 0xFF);
+ LCD_SendData_8Bit(Xstart & 0xFF);
+ LCD_SendData_8Bit(((Xend - 1) >> 8) & 0xFF);
+ LCD_SendData_8Bit((Xend - 1) & 0xFF);
+
+ // set the Y coordinates
+ LCD_SendCommand(0x2B);
+ LCD_SendData_8Bit((Ystart >> 8) & 0xFF);
+ LCD_SendData_8Bit(Ystart & 0xFF);
+ LCD_SendData_8Bit(((Yend - 1) >> 8) & 0xFF);
+ LCD_SendData_8Bit((Yend - 1) & 0xFF);
+
+ LCD_SendCommand(0X2C);
+}
+
+/******************************************************************************
+ function : Clear screen
+ parameter:
+ ******************************************************************************/
+void LCD_Clear(UWORD Color)
+{
+ UWORD j, i;
+ UWORD Image[LCD.WIDTH * LCD.HEIGHT];
+
+ Color = ((Color << 8) & 0xff00) | (Color >> 8);
+
+ for (j = 0; j < LCD.HEIGHT * LCD.WIDTH; j++)
+ {
+ Image[j] = Color;
+ }
+
+ LCD_SetWindows(0, 0, LCD.WIDTH, LCD.HEIGHT);
+ DEV_Digital_Write(LCD_DC_PIN, 1);
+ DEV_Digital_Write(LCD_CS_PIN, 0);
+ for (j = 0; j < LCD.HEIGHT; j++)
+ {
+ DEV_SPI_Write_nByte((uint8_t *) &Image[j * LCD.WIDTH], LCD.WIDTH * 2);
+ }
+ DEV_Digital_Write(LCD_CS_PIN, 1);
+}
+
+/******************************************************************************
+ function : Sends the image buffer in RAM to displays
+ parameter:
+ ******************************************************************************/
+void LCD_Display(UWORD *Image)
+{
+ UWORD j;
+ LCD_SetWindows(0, 0, LCD.WIDTH, LCD.HEIGHT);
+ DEV_Digital_Write(LCD_DC_PIN, 1);
+ DEV_Digital_Write(LCD_CS_PIN, 0);
+ for (j = 0; j < LCD.HEIGHT; j++)
+ {
+ DEV_SPI_Write_nByte((uint8_t *) &Image[j * LCD.WIDTH], LCD.WIDTH * 2);
+ }
+ DEV_Digital_Write(LCD_CS_PIN, 1);
+ LCD_SendCommand(0x29);
+}
+
+/******************************************************************************
+ function : Sends the image buffer in RAM to displays
+ parameter:
+ Xstart : X direction Start coordinates
+ Ystart : Y direction Start coordinates
+ Xend : X direction end coordinates
+ Yend : Y direction end coordinates
+ Image : Written content
+ ******************************************************************************/
+void LCD_DisplayWindows(UWORD Xstart, UWORD Ystart, UWORD Xend, UWORD Yend, UWORD *Image)
+{
+ // display
+ UDOUBLE Addr = 0;
+
+ UWORD j;
+ LCD_SetWindows(Xstart, Ystart, Xend, Yend);
+ DEV_Digital_Write(LCD_DC_PIN, 1);
+ DEV_Digital_Write(LCD_CS_PIN, 0);
+ for (j = Ystart; j < Yend - 1; j++)
+ {
+ Addr = Xstart + j * LCD.WIDTH;
+ DEV_SPI_Write_nByte((uint8_t *) &Image[Addr], (Xend - Xstart) * 2);
+ }
+ DEV_Digital_Write(LCD_CS_PIN, 1);
+}
+
+/******************************************************************************
+ function : Change the color of a point
+ parameter:
+ X : X coordinates
+ Y : Y coordinates
+ Color : Color
+ ******************************************************************************/
+void LCD_DisplayPoint(UWORD X, UWORD Y, UWORD Color)
+{
+ LCD_SetWindows(X, Y, X, Y);
+ LCD_SendData_16Bit(Color);
+}
+
+void Handler_LCD(int signo)
+{
+ // System Exit
+ rt_kprintf("\r\nHandler:Program stop\r\n");
+ DEV_Module_Exit();
+ exit(0);
+}
+
+/**
+ * GPIO read and write
+ **/
+void DEV_Digital_Write(UWORD Pin, UBYTE Value)
+{
+ gpio_put(Pin, Value);
+}
+
+UBYTE DEV_Digital_Read(UWORD Pin)
+{
+ return gpio_get(Pin);
+}
+
+/**
+ * GPIO Mode
+ **/
+void DEV_GPIO_Mode(UWORD Pin, UWORD Mode)
+{
+ gpio_init(Pin);
+ if (Mode == 0 || Mode == GPIO_IN)
+ {
+ gpio_set_dir(Pin, GPIO_IN);
+ }
+ else
+ {
+ gpio_set_dir(Pin, GPIO_OUT);
+ }
+}
+
+/**
+ * SPI
+ **/
+void DEV_SPI_WriteByte(UBYTE Value)
+{
+ spi_write_blocking(SPI_PORT, &Value, 1);
+}
+
+void DEV_SPI_Write_nByte(UBYTE pData[], UDOUBLE Len)
+{
+ spi_write_blocking(SPI_PORT, pData, Len);
+}
+
+void DEV_GPIO_Init(void)
+{
+ DEV_GPIO_Mode(LCD_RST_PIN, 1);
+ DEV_GPIO_Mode(LCD_DC_PIN, 1);
+ DEV_GPIO_Mode(LCD_CS_PIN, 1);
+ DEV_GPIO_Mode(LCD_BL_PIN, 1);
+
+ DEV_Digital_Write(LCD_CS_PIN, 1);
+ DEV_Digital_Write(LCD_DC_PIN, 0);
+ DEV_Digital_Write(LCD_BL_PIN, 1);
+}
+
+/******************************************************************************
+ function: Module Initialize, the library and initialize the pins, SPI protocol
+ parameter:
+ Info:
+ ******************************************************************************/
+UBYTE DEV_Module_Init(void)
+{
+ // SPI Config
+ spi_init(SPI_PORT, 80000 * 1000);
+ gpio_set_function(LCD_CLK_PIN, GPIO_FUNC_SPI);
+ gpio_set_function(LCD_MOSI_PIN, GPIO_FUNC_SPI);
+
+ // GPIO Config
+ DEV_GPIO_Init();
+
+ // PWM Config
+ gpio_set_function(LCD_BL_PIN, GPIO_FUNC_PWM);
+ slice_num = pwm_gpio_to_slice_num(LCD_BL_PIN);
+ pwm_set_wrap(slice_num, 100);
+ pwm_set_chan_level(slice_num, PWM_CHAN_B, 1);
+ pwm_set_clkdiv(slice_num, 50);
+ pwm_set_enabled(slice_num, true);
+
+ rt_kprintf("DEV_Module_Init OK \r\n");
+
+ return 0;
+}
+
+void DEV_SET_PWM(UBYTE Value)
+{
+ if (Value < 0 || Value > 100)
+ {
+ rt_kprintf("DEV_SET_PWM Error \r\n");
+ }
+ else
+ {
+ pwm_set_chan_level(slice_num, PWM_CHAN_B, Value);
+ }
+}
+
+UBYTE SPI_Init(void)
+{
+ DEV_Module_Init();
+ return 0;
+}
+
+bool _swapBytes;
+UDOUBLE dma_tx_channel;
+dma_channel_config dma_tx_config;
+
+/***************************************************************************************
+ ** Function name: dmaWait
+ ** Description: Wait until DMA is over (blocking!)
+ ***************************************************************************************/
+void dmaWait(void)
+{
+ while (dma_channel_is_busy(dma_tx_channel))
+ ;
+
+ // For SPI must also wait for FIFO to flush and reset format
+ while (spi_get_hw(SPI_PORT)->sr & SPI_SSPSR_BSY_BITS)
+ {
+ };
+ spi_set_format(SPI_PORT, 16, (spi_cpol_t) 0, (spi_cpha_t) 0, SPI_MSB_FIRST);
+}
+
+/***************************************************************************************
+ ** Function name: pushPixelsDMA
+ ** Description: Push pixels to TFT
+ ***************************************************************************************/
+void pushPixelsDMA(UWORD* image, UDOUBLE len)
+{
+ if ((len == 0))
+ return;
+
+ dmaWait();
+
+ channel_config_set_bswap(&dma_tx_config, !_swapBytes);
+
+ dma_channel_configure(dma_tx_channel, &dma_tx_config, &spi_get_hw(SPI_PORT)->dr, (UWORD*) image, len, true);
+}
+
+bool initDMA(bool ctrl_cs)
+{
+ dma_tx_channel = dma_claim_unused_channel(true);
+ dma_tx_config = dma_channel_get_default_config(dma_tx_channel);
+
+ channel_config_set_transfer_data_size(&dma_tx_config, DMA_SIZE_16);
+ channel_config_set_dreq(&dma_tx_config, spi_get_index(SPI_PORT) ? DREQ_SPI1_TX : DREQ_SPI0_TX);
+
+ return true;
+}
diff --git a/bsp/raspberry-pico/board/ports/lcd/drv_lcd.h b/bsp/raspberry-pico/board/ports/lcd/drv_lcd.h
new file mode 100644
index 0000000000..090c4013bc
--- /dev/null
+++ b/bsp/raspberry-pico/board/ports/lcd/drv_lcd.h
@@ -0,0 +1,75 @@
+#ifndef __DRV_LCD_H
+#define __DRV_LCD_H
+
+#include <stdint.h>
+#include <rtdevice.h>
+
+#include "pico/stdlib.h"
+#include "hardware/spi.h"
+#include "hardware/i2c.h"
+#include "hardware/pwm.h"
+#include "hardware/dma.h"
+
+#define LCD_HEIGHT 240
+#define LCD_WIDTH 240
+
+#define HORIZONTAL 0
+#define VERTICAL 1
+
+/**
+ * data
+ **/
+#define UBYTE uint8_t
+#define UWORD uint16_t
+#define UDOUBLE uint32_t
+
+/**
+ * GPIOI config
+ **/
+#define LCD_RST_PIN 12
+#define LCD_DC_PIN 8
+#define LCD_BL_PIN 13
+
+#define LCD_CS_PIN 9
+#define LCD_CLK_PIN 10
+#define LCD_MOSI_PIN 11
+
+typedef struct
+{
+ UWORD WIDTH;UWORD HEIGHT;UBYTE SCAN_DIR;
+} LCD_ATTRIBUTES;
+extern LCD_ATTRIBUTES LCD;
+
+/*------------------------------------------------------------------------------------------------------*/
+void DEV_Digital_Write(UWORD Pin, UBYTE Value);
+UBYTE DEV_Digital_Read(UWORD Pin);
+
+void DEV_GPIO_Mode(UWORD Pin, UWORD Mode);
+void DEV_KEY_Config(UWORD Pin);
+void DEV_Digital_Write(UWORD Pin, UBYTE Value);
+UBYTE DEV_Digital_Read(UWORD Pin);
+
+void DEV_SPI_WriteByte(UBYTE Value);
+void DEV_SPI_Write_nByte(UBYTE *pData, UDOUBLE Len);
+
+void DEV_SET_PWM(UBYTE Value);
+
+UBYTE SPI_Init(void);
+UBYTE DEV_Module_Init(void);
+void DEV_Module_Exit(void);
+
+/********************************************************************************
+ function:
+ Macro definition variable name
+ ********************************************************************************/
+bool initDMA(bool ctrl_cs);
+void LCD_Init(UBYTE Scan_dir);
+void LCD_Clear(UWORD Color);
+void LCD_Display(UWORD *Image);
+void LCD_SetWindows(UWORD Xstart, UWORD Ystart, UWORD Xend, UWORD Yend);
+void LCD_DisplayWindows(UWORD Xstart, UWORD Ystart, UWORD Xend, UWORD Yend, UWORD *Image);
+void pushPixelsDMA(UWORD* image, UDOUBLE len);
+void LCD_DisplayPoint(UWORD X, UWORD Y, UWORD Color);
+void Handler_LCD(int signo);
+
+#endif
diff --git a/bsp/raspberry-pico/libraries/Kconfig b/bsp/raspberry-pico/libraries/Kconfig
new file mode 100644
index 0000000000..9de45a9aa6
--- /dev/null
+++ b/bsp/raspberry-pico/libraries/Kconfig
@@ -0,0 +1,23 @@
+menu "Hardware Drivers Config"
+
+config SOC_RP2040
+ bool
+ select SOC_SERIES_RP2040_PICO
+ select RT_USING_COMPONENTS_INIT
+ default y
+
+menu "Onboard Peripheral Drivers"
+
+ config BSP_USING_LVGL
+ bool "Enable LVGL for LCD"
+ select PKG_USING_LVGL
+ select BSP_USING_SPI_LCD
+ select PKG_USING_LV_MUSIC_DEMO
+ default n
+
+endmenu
+
+endmenu
+
+
+
diff --git a/bsp/raspberry-pico/libraries/SConscript b/bsp/raspberry-pico/libraries/SConscript
index 8d45dee783..f0102b2cb5 100644
--- a/bsp/raspberry-pico/libraries/SConscript
+++ b/bsp/raspberry-pico/libraries/SConscript
@@ -13,6 +13,9 @@ pico-sdk/src/rp2_common/hardware_claim/claim.c
pico-sdk/src/rp2_common/hardware_sync/sync.c
pico-sdk/src/rp2_common/pico_platform/platform.c
pico-sdk/src/rp2_common/hardware_uart/uart.c
+pico-sdk/src/rp2_common/hardware_spi/spi.c
+pico-sdk/src/rp2_common/hardware_dma/dma.c
+pico-sdk/src/rp2_common/hardware_i2c/i2c.c
pico-sdk/src/common/pico_time/time.c
pico-sdk/src/common/pico_time/timeout_helper.c
pico-sdk/src/rp2_common/hardware_timer/timer.c
@@ -67,6 +70,10 @@ path = [
cwd + '/pico-sdk/src/rp2_common/hardware_claim/include',
cwd + '/pico-sdk/src/rp2_common/hardware_sync/include',
cwd + '/pico-sdk/src/rp2_common/hardware_uart/include',
+ cwd + '/pico-sdk/src/rp2_common/hardware_dma/include',
+ cwd + '/pico-sdk/src/rp2_common/hardware_spi/include',
+ cwd + '/pico-sdk/src/rp2_common/hardware_i2c/include',
+ cwd + '/pico-sdk/src/rp2_common/hardware_pwm/include',
cwd + '/pico-sdk/src/rp2_common/hardware_divider/include',
cwd + '/pico-sdk/src/common/pico_time/include',
cwd + '/pico-sdk/src/rp2_common/hardware_timer/include',