diff --git a/bsp/raspberry-pico/Kconfig b/bsp/raspberry-pico/Kconfig index c9666bbc938411c4747edaea233415d90a27608f..b8ba68134618f0bd9c5fe12658be4fadf9f4d5c9 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 79821f993af4b3920952317313df40581790be34..26b423a1d8d71d9ac55918f16fff84d4d778dced 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 01eb940dfb35f92c503a78b0b49a4354590f9f3a..d0723dfea1b95af36082613aea78760cb0e9009f 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 0000000000000000000000000000000000000000..0292c8d9d0d14c2b432e4de45c8e40d700f4a268 --- /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 0000000000000000000000000000000000000000..a5e6be8a2a0b916444f8cce5f06d61d16904230d --- /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 0000000000000000000000000000000000000000..95e047d541908e46795b5728f3827af062c811f7 --- /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 +#include +#include +#define DBG_TAG "LVGL.demo" +#define DBG_LVL DBG_INFO +#include + +#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 0000000000000000000000000000000000000000..48a922cc9e31cc6c4670ab0c3ce75c1513cdd29a --- /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 +#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 0000000000000000000000000000000000000000..ef39eb03cd4df06329528ca9f9717e9d5d8e86cd --- /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 0000000000000000000000000000000000000000..0beae12763a0af7d94ec7915b67cf12e0412d926 --- /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 +#include +#include + +#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 0000000000000000000000000000000000000000..d15f0e5cfafa763c12cb9ab82c367e58e335f19f --- /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 + +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 0000000000000000000000000000000000000000..17c3b776a3a2f04222c1e3723767d61f0457ce49 --- /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 similarity index 94% rename from bsp/raspberry-pico/drivers/board.c rename to bsp/raspberry-pico/board/board.c index 3d0a58a5888b520b1365d0092aac85b518ed3415..f95a197769554ba3a7418cd0fba3cb6f50b9ea0d 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 similarity index 100% rename from bsp/raspberry-pico/drivers/board.h rename to 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 0000000000000000000000000000000000000000..3c57bc9c6dbd1a52d9a6bdd1b87d6b461bd11f12 --- /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 0000000000000000000000000000000000000000..ab60ebfecf63dbc18b3a14dcb967e4c91c6a87ee --- /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 0000000000000000000000000000000000000000..30808f97d42f186037103a665867b4957d37284c --- /dev/null +++ b/bsp/raspberry-pico/board/ports/lcd/drv_lcd.c @@ -0,0 +1,444 @@ +#include +#include + +#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 0000000000000000000000000000000000000000..090c4013bccd065c6ffff13f3aaeed50c89b366b --- /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 +#include + +#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 0000000000000000000000000000000000000000..9de45a9aa61699d49876664ecdf408606ac87688 --- /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 8d45dee783e238ce3852be0b6a4da7c330ad3ddc..f0102b2cb5d19cc865932900c57e13bf7bb2d998 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',