Add lvgl_8.1.0 support for raspberry_pi pico
This commit is contained in:
parent
ea9c6c94e0
commit
814c15cdbc
|
@ -17,6 +17,7 @@ config PKGS_DIR
|
|||
|
||||
source "$RTT_DIR/Kconfig"
|
||||
source "$PKGS_DIR/Kconfig"
|
||||
source "libraries/Kconfig"
|
||||
|
||||
config SOC_RP2040
|
||||
bool
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
||||
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')
|
|
@ -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')
|
|
@ -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
|
|
@ -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);
|
|
@ -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;
|
||||
}
|
|
@ -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
|
|
@ -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);
|
||||
}
|
|
@ -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
|
|
@ -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')
|
|
@ -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
|
||||
}
|
|
@ -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')
|
|
@ -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')
|
|
@ -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;
|
||||
}
|
|
@ -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
|
|
@ -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
|
||||
|
||||
|
||||
|
|
@ -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',
|
||||
|
|
Loading…
Reference in New Issue