[feat][lcd] add st7789v support, demo used sipeed m1sdock
This commit is contained in:
parent
223589e8d9
commit
9ad915ef1f
@ -10,41 +10,6 @@ endif()
|
|||||||
sdk_add_include_directories(ethernet/)
|
sdk_add_include_directories(ethernet/)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(CONFIG_LUA)
|
|
||||||
sdk_library_add_sources(lua/lua_start.c)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# fatfs
|
|
||||||
if(CONFIG_FATFS)
|
|
||||||
|
|
||||||
# fatfs use sdcard over sdio
|
|
||||||
if(CONFIG_BSP_FATFS_SDH_SDCARD)
|
|
||||||
sdk_add_compile_definitions(-DCONFIG_BSP_FATFS_SDH_SDCARD)
|
|
||||||
sdk_library_add_sources(fatfs/fatfs_sdh_sdcard.c)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# fatfs use sdcard over spi
|
|
||||||
if(CONFIG_BSP_FATFS_SPI_SDCARD)
|
|
||||||
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# fatfs use psram
|
|
||||||
if(CONFIG_BSP_FATFS_PSRAM)
|
|
||||||
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# fatfs use flash
|
|
||||||
if(CONFIG_BSP_FATFS_FLASH)
|
|
||||||
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# fatfs use usb host msc
|
|
||||||
if(CONFIG_BSP_FATFS_USBH)
|
|
||||||
|
|
||||||
endif()
|
|
||||||
|
|
||||||
endif()
|
|
||||||
|
|
||||||
# sdh sdcard driver
|
# sdh sdcard driver
|
||||||
if(CONFIG_BSP_SDH_SDCARD)
|
if(CONFIG_BSP_SDH_SDCARD)
|
||||||
sdk_add_compile_definitions(-DCONFIG_BSP_SDH_SDCARD)
|
sdk_add_compile_definitions(-DCONFIG_BSP_SDH_SDCARD)
|
||||||
@ -64,15 +29,14 @@ sdk_library_add_sources(lcd/font.c)
|
|||||||
sdk_library_add_sources(lcd/spi/ili9341_spi.c)
|
sdk_library_add_sources(lcd/spi/ili9341_spi.c)
|
||||||
sdk_library_add_sources(lcd/spi/ili9488_spi.c)
|
sdk_library_add_sources(lcd/spi/ili9488_spi.c)
|
||||||
sdk_library_add_sources(lcd/spi/st7796_spi.c)
|
sdk_library_add_sources(lcd/spi/st7796_spi.c)
|
||||||
sdk_add_include_directories(lcd)
|
sdk_library_add_sources(lcd/spi/st7789v_spi.c)
|
||||||
|
sdk_add_include_directories(lcd/)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# lvgl port
|
# image sensor driver
|
||||||
if(CONFIG_LVGL)
|
if(CONFIG_BSP_IMAGE_SENSOR)
|
||||||
sdk_library_add_sources(lvgl/lv_port_disp.c)
|
sdk_library_add_sources(image_sensor/image_sensor.c)
|
||||||
# sdk_library_add_sources(lvgl/lv_port_fs.c)
|
sdk_add_include_directories(image_sensor/)
|
||||||
# sdk_library_add_sources(lvgl/lv_port_indev.c)
|
|
||||||
sdk_add_include_directories(lvgl)
|
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
endif()
|
endif()
|
@ -105,7 +105,7 @@ void ili9341_spi_dma_flush_callback(void *arg)
|
|||||||
}
|
}
|
||||||
|
|
||||||
while (ili9341_spi_draw_is_busy()) {
|
while (ili9341_spi_draw_is_busy()) {
|
||||||
__NOP();
|
__ASM volatile("nop");
|
||||||
};
|
};
|
||||||
|
|
||||||
if (ili9341_spi_async_callback != NULL) {
|
if (ili9341_spi_async_callback != NULL) {
|
||||||
@ -253,7 +253,7 @@ int ili9341_spi_draw_is_busy(void)
|
|||||||
} else {
|
} else {
|
||||||
/* Wait for the SPI bus to be idle */
|
/* Wait for the SPI bus to be idle */
|
||||||
while (bflb_spi_isbusy(ili9341_spi)) {
|
while (bflb_spi_isbusy(ili9341_spi)) {
|
||||||
__NOP();
|
__ASM volatile("nop");
|
||||||
};
|
};
|
||||||
/* Switch the SPI to non-DMA mode */
|
/* Switch the SPI to non-DMA mode */
|
||||||
bflb_spi_link_txdma(ili9341_spi, false);
|
bflb_spi_link_txdma(ili9341_spi, false);
|
||||||
@ -475,7 +475,7 @@ void ili9341_spi_draw_area(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, i
|
|||||||
|
|
||||||
/* Wait to finish, and cs high */
|
/* Wait to finish, and cs high */
|
||||||
while (ili9341_spi_draw_is_busy()) {
|
while (ili9341_spi_draw_is_busy()) {
|
||||||
__NOP();
|
__ASM volatile("nop");
|
||||||
};
|
};
|
||||||
|
|
||||||
/* enable src_addr_inc */
|
/* enable src_addr_inc */
|
||||||
@ -537,7 +537,7 @@ void ili9341_spi_draw_picture_blocking(uint16_t x1, uint16_t y1, uint16_t x2, ui
|
|||||||
|
|
||||||
ili9341_spi_draw_picture_nonblocking(x1, y1, x2, y2, picture);
|
ili9341_spi_draw_picture_nonblocking(x1, y1, x2, y2, picture);
|
||||||
while (ili9341_spi_draw_is_busy()) {
|
while (ili9341_spi_draw_is_busy()) {
|
||||||
__NOP();
|
__ASM volatile("nop");
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -100,7 +100,7 @@ void ili9488_spi_dma_flush_callback(void *args)
|
|||||||
}
|
}
|
||||||
|
|
||||||
while (ili9488_spi_draw_is_busy()) {
|
while (ili9488_spi_draw_is_busy()) {
|
||||||
__NOP();
|
__ASM volatile("nop");
|
||||||
};
|
};
|
||||||
|
|
||||||
if (ili9488_spi_async_callback != NULL) {
|
if (ili9488_spi_async_callback != NULL) {
|
||||||
@ -248,7 +248,7 @@ int ili9488_spi_draw_is_busy(void)
|
|||||||
} else {
|
} else {
|
||||||
/* Wait for the SPI bus to be idle */
|
/* Wait for the SPI bus to be idle */
|
||||||
while (bflb_spi_isbusy(ili9488_spi)) {
|
while (bflb_spi_isbusy(ili9488_spi)) {
|
||||||
__NOP();
|
__ASM volatile("nop");
|
||||||
};
|
};
|
||||||
/* Switch the SPI to non-DMA mode */
|
/* Switch the SPI to non-DMA mode */
|
||||||
bflb_spi_link_txdma(ili9488_spi, false);
|
bflb_spi_link_txdma(ili9488_spi, false);
|
||||||
@ -467,7 +467,7 @@ void ili9488_spi_draw_area(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, i
|
|||||||
|
|
||||||
/* Wait to finish, and cs high */
|
/* Wait to finish, and cs high */
|
||||||
while (ili9488_spi_draw_is_busy()) {
|
while (ili9488_spi_draw_is_busy()) {
|
||||||
__NOP();
|
__ASM volatile("nop");
|
||||||
};
|
};
|
||||||
|
|
||||||
/* enable src_addr_inc */
|
/* enable src_addr_inc */
|
||||||
|
518
bsp/common/lcd/spi/st7789v_spi.c
Normal file
518
bsp/common/lcd/spi/st7789v_spi.c
Normal file
@ -0,0 +1,518 @@
|
|||||||
|
/**
|
||||||
|
* @file st7789v_spi.c
|
||||||
|
* @brief
|
||||||
|
*
|
||||||
|
* Copyright (c) 2021 Bouffalolab team
|
||||||
|
*
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||||
|
* contributor license agreements. See the NOTICE file distributed with
|
||||||
|
* this work for additional information regarding copyright ownership. The
|
||||||
|
* ASF licenses this file to you under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance with the
|
||||||
|
* License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
* License for the specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "../lcd.h"
|
||||||
|
|
||||||
|
#if defined(LCD_SPI_ST7789V)
|
||||||
|
|
||||||
|
#include "bflb_mtimer.h"
|
||||||
|
#include "bflb_spi.h"
|
||||||
|
#include "bflb_dma.h"
|
||||||
|
#include "bflb_gpio.h"
|
||||||
|
#include "bflb_l1c.h"
|
||||||
|
#include "st7789v_spi.h"
|
||||||
|
|
||||||
|
#if (defined(BL808) || defined(BL606P)) && defined(CPU_D0)
|
||||||
|
#define ST7789V_SPI_ID 1
|
||||||
|
#define ST7789V_SPI_NAME "spi1"
|
||||||
|
#define ST7789V_SPI_DMA_NAME "dma2_ch0"
|
||||||
|
#else
|
||||||
|
#define ST7789V_SPI_ID 0
|
||||||
|
#define ST7789V_SPI_NAME "spi0"
|
||||||
|
#define ST7789V_SPI_DMA_NAME "dma0_ch3"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define ST7789V_DMA_LLI_NUM (ST7789V_SPI_W * ST7789V_SPI_H / 4064 + 1)
|
||||||
|
|
||||||
|
/* asynchronous flush interrupt callback */
|
||||||
|
typedef void (*st7789v_spi_callback)(void);
|
||||||
|
static volatile st7789v_spi_callback st7789v_spi_async_callback = NULL;
|
||||||
|
static volatile bool st7789v_spi_sync_flush_flag = 0;
|
||||||
|
|
||||||
|
static struct bflb_device_s *st7789v_gpio;
|
||||||
|
static struct bflb_device_s *st7789v_spi;
|
||||||
|
static struct bflb_device_s *st7789v_dma_spi_tx;
|
||||||
|
|
||||||
|
/* The memory space of DMA */
|
||||||
|
static struct bflb_dma_channel_lli_pool_s dam_tx_llipool[ST7789V_DMA_LLI_NUM];
|
||||||
|
static struct bflb_dma_channel_lli_transfer_s dma_tx_transfers[1];
|
||||||
|
|
||||||
|
const st7789v_spi_init_cmd_t st7789v_spi_init_cmds[] = {
|
||||||
|
{ 0x01, NULL, 0 },
|
||||||
|
{ 0xFF, NULL, 10 },
|
||||||
|
{ 0x11, NULL, 0 }, /* Exit sleep */
|
||||||
|
{ 0xFF, NULL, 120 },
|
||||||
|
|
||||||
|
{ 0x3A, "\x55", 1 }, /* pixel format */
|
||||||
|
{ 0x21, NULL, 0 },
|
||||||
|
{ 0x29, NULL, 0 },
|
||||||
|
{ 0x36, "\x00", 1 },
|
||||||
|
{ 0xC6, "\x00", 1 },
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief st7789v_spi_dma_flush_callback
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
void st7789v_spi_dma_flush_callback(void *args)
|
||||||
|
{
|
||||||
|
if (st7789v_spi_sync_flush_flag == true) {
|
||||||
|
st7789v_spi_sync_flush_flag = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (lcd_draw_is_busy()) {
|
||||||
|
};
|
||||||
|
|
||||||
|
if (st7789v_spi_async_callback != NULL) {
|
||||||
|
st7789v_spi_async_callback();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief st7789v_spi_async_callback_register
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
void st7789v_spi_async_callback_register(void (*callback)(void))
|
||||||
|
{
|
||||||
|
st7789v_spi_async_callback = callback;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief st7789v_spi_init
|
||||||
|
*
|
||||||
|
* @return int 0:succes 1:error
|
||||||
|
*/
|
||||||
|
static int st7789v_spi_peripheral_init(void)
|
||||||
|
{
|
||||||
|
/* spi */
|
||||||
|
struct bflb_spi_config_s spi_cfg = {
|
||||||
|
.freq = 80 * 1000 * 1000,
|
||||||
|
.role = SPI_ROLE_MASTER,
|
||||||
|
.mode = SPI_MODE3,
|
||||||
|
.data_width = SPI_DATA_WIDTH_8BIT,
|
||||||
|
.bit_order = SPI_BIT_MSB,
|
||||||
|
.byte_order = SPI_BYTE_LSB,
|
||||||
|
.tx_fifo_threshold = 0,
|
||||||
|
.rx_fifo_threshold = 0,
|
||||||
|
};
|
||||||
|
|
||||||
|
/* dma */
|
||||||
|
struct bflb_dma_channel_config_s dma_spi_tx_cfg = {
|
||||||
|
.direction = DMA_MEMORY_TO_PERIPH,
|
||||||
|
.src_req = DMA_REQUEST_NONE,
|
||||||
|
.dst_req = DMA_REQUEST_SPI0_TX,
|
||||||
|
.src_addr_inc = DMA_ADDR_INCREMENT_ENABLE,
|
||||||
|
.dst_addr_inc = DMA_ADDR_INCREMENT_DISABLE,
|
||||||
|
.src_burst_count = DMA_BURST_INCR1,
|
||||||
|
.dst_burst_count = DMA_BURST_INCR1,
|
||||||
|
.src_width = DMA_DATA_WIDTH_16BIT,
|
||||||
|
.dst_width = DMA_DATA_WIDTH_16BIT,
|
||||||
|
};
|
||||||
|
|
||||||
|
/* CS and DC pin init */
|
||||||
|
st7789v_gpio = bflb_device_get_by_name("gpio");
|
||||||
|
bflb_gpio_init(st7789v_gpio, ST7789V_SPI_CS_PIN, GPIO_OUTPUT | GPIO_PULLUP | GPIO_SMT_EN | GPIO_DRV_1);
|
||||||
|
bflb_gpio_init(st7789v_gpio, ST7789V_SPI_DC_PIN, GPIO_OUTPUT | GPIO_PULLUP | GPIO_SMT_EN | GPIO_DRV_1);
|
||||||
|
ST7789V_SPI_CS_HIGH;
|
||||||
|
ST7789V_SPI_DC_HIGH;
|
||||||
|
|
||||||
|
#if (SPI_FIFO_WIDTH_VARIABLE_SUPPORT) && (SPI_FIFO_BYTE_NUM_MAX > (2 * 4))
|
||||||
|
/* SPI support burst*4 */
|
||||||
|
spi_cfg.tx_fifo_threshold = 2 * 4 - 1;
|
||||||
|
spi_cfg.rx_fifo_threshold = 2 * 4 - 1;
|
||||||
|
#elif (!SPI_FIFO_WIDTH_VARIABLE_SUPPORT) && (SPI_FIFO_WORD_NUM_MAX > 4)
|
||||||
|
/* SPI support burst*4 */
|
||||||
|
spi_cfg.tx_fifo_threshold = 4 - 1;
|
||||||
|
spi_cfg.rx_fifo_threshold = 4 - 1;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if (SPI_FIFO_WIDTH_VARIABLE_SUPPORT)
|
||||||
|
spi_cfg.byte_order = SPI_BYTE_MSB;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* spi init */
|
||||||
|
st7789v_spi = bflb_device_get_by_name(ST7789V_SPI_NAME);
|
||||||
|
bflb_spi_init(st7789v_spi, &spi_cfg);
|
||||||
|
|
||||||
|
/* spi enabled continuous mode */
|
||||||
|
bflb_spi_feature_control(st7789v_spi, SPI_CMD_SET_CS_INTERVAL, true);
|
||||||
|
|
||||||
|
#if (ST7789V_SPI_ID == 0)
|
||||||
|
dma_spi_tx_cfg.dst_req = DMA_REQUEST_SPI0_TX;
|
||||||
|
#elif (ST7789V_SPI_ID == 1)
|
||||||
|
dma_spi_tx_cfg.dst_req = DMA_REQUEST_SPI1_TX;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if (SPI_FIFO_WIDTH_VARIABLE_SUPPORT) && (SPI_FIFO_BYTE_NUM_MAX > (2 * 4))
|
||||||
|
/* DMA support burst*4 */
|
||||||
|
dma_spi_tx_cfg.src_burst_count = DMA_BURST_INCR4;
|
||||||
|
dma_spi_tx_cfg.dst_burst_count = DMA_BURST_INCR4;
|
||||||
|
#elif (!SPI_FIFO_WIDTH_VARIABLE_SUPPORT) && (SPI_FIFO_WORD_NUM_MAX > 4)
|
||||||
|
/* DMA support burst*4 */
|
||||||
|
dma_spi_tx_cfg.src_burst_count = DMA_BURST_INCR4;
|
||||||
|
dma_spi_tx_cfg.dst_burst_count = DMA_BURST_INCR4;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* dma init */
|
||||||
|
st7789v_dma_spi_tx = bflb_device_get_by_name(ST7789V_SPI_DMA_NAME);
|
||||||
|
bflb_dma_channel_init(st7789v_dma_spi_tx, &dma_spi_tx_cfg);
|
||||||
|
|
||||||
|
/* dma int cfg */
|
||||||
|
bflb_dma_channel_irq_attach(st7789v_dma_spi_tx, st7789v_spi_dma_flush_callback, NULL);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief st7789v_spi_write_cmd
|
||||||
|
*
|
||||||
|
* @param cmd
|
||||||
|
* @return int 0:succes 1:error
|
||||||
|
*/
|
||||||
|
static int st7789v_spi_write_cmd(uint8_t cmd)
|
||||||
|
{
|
||||||
|
ST7789V_SPI_DC_LOW;
|
||||||
|
ST7789V_SPI_CS_LOW;
|
||||||
|
bflb_spi_poll_send(st7789v_spi, cmd);
|
||||||
|
ST7789V_SPI_CS_HIGH;
|
||||||
|
ST7789V_SPI_DC_HIGH;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief st7789v_spi_write_data_byte
|
||||||
|
*
|
||||||
|
* @param data
|
||||||
|
* @return int 0:succes 1:error
|
||||||
|
*/
|
||||||
|
static int st7789v_spi_write_data_byte(uint8_t data)
|
||||||
|
{
|
||||||
|
ST7789V_SPI_CS_LOW;
|
||||||
|
bflb_spi_poll_send(st7789v_spi, data);
|
||||||
|
ST7789V_SPI_CS_HIGH;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief st7789v_spi_draw_is_busy, After the call st7789v_spi_draw_picture_dma must check this,
|
||||||
|
* if st7789v_spi_draw_is_busy() == 1, Don't allow other draw !!
|
||||||
|
* can run in the DMA interrupt callback function.
|
||||||
|
*
|
||||||
|
* @return int 0:draw end; 1:Being draw
|
||||||
|
*/
|
||||||
|
int st7789v_spi_draw_is_busy(void)
|
||||||
|
{
|
||||||
|
if (bflb_dma_channel_isbusy(st7789v_dma_spi_tx)) {
|
||||||
|
return 1;
|
||||||
|
} else {
|
||||||
|
/* Wait for the SPI bus to be idle */
|
||||||
|
while (bflb_spi_isbusy(st7789v_spi)) {
|
||||||
|
__ASM volatile("nop");
|
||||||
|
};
|
||||||
|
/* Switch the SPI to non-DMA mode */
|
||||||
|
bflb_spi_link_txdma(st7789v_spi, false);
|
||||||
|
/* clear rx fifo */
|
||||||
|
bflb_spi_feature_control(st7789v_spi, SPI_CMD_CLEAR_RX_FIFO, 0);
|
||||||
|
/* */
|
||||||
|
ST7789V_SPI_CS_HIGH;
|
||||||
|
/* 8-bit data */
|
||||||
|
bflb_spi_feature_control(st7789v_spi, SPI_CMD_SET_DATA_WIDTH, SPI_DATA_WIDTH_8BIT);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief st7789v_spi_init
|
||||||
|
*
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
int st7789v_spi_init()
|
||||||
|
{
|
||||||
|
int res = st7789v_spi_peripheral_init();
|
||||||
|
if (res < 0) {
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (uint16_t i = 0; i < (sizeof(st7789v_spi_init_cmds) / sizeof(st7789v_spi_init_cmd_t)); i++) {
|
||||||
|
if (st7789v_spi_init_cmds[i].cmd == 0xFF && st7789v_spi_init_cmds[i].data == NULL) {
|
||||||
|
bflb_mtimer_delay_ms(st7789v_spi_init_cmds[i].databytes);
|
||||||
|
} else {
|
||||||
|
/* send register address */
|
||||||
|
st7789v_spi_write_cmd(st7789v_spi_init_cmds[i].cmd);
|
||||||
|
|
||||||
|
/* send register data */
|
||||||
|
for (uint8_t j = 0; j < (st7789v_spi_init_cmds[i].databytes); j++) {
|
||||||
|
st7789v_spi_write_data_byte(st7789v_spi_init_cmds[i].data[j]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
st7789v_spi_set_draw_window(0, 0, ST7789V_SPI_H, ST7789V_SPI_W);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if (SPI_FIFO_WIDTH_VARIABLE_SUPPORT == 0)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief lcd_swap_color_data16
|
||||||
|
*
|
||||||
|
* @param dst destination
|
||||||
|
* @param src source
|
||||||
|
* @param color_num color num
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
static int lcd_swap_color_data16(uint16_t *dst, uint16_t *src, uint32_t color_num)
|
||||||
|
{
|
||||||
|
for (size_t i = 0; i < color_num; i++) {
|
||||||
|
dst[i] = (src[i] << 8) | (src[i] >> 8);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief
|
||||||
|
*
|
||||||
|
* @param dir
|
||||||
|
* @param mir_flag
|
||||||
|
*/
|
||||||
|
int st7789v_spi_set_dir(uint8_t dir, uint8_t mir_flag)
|
||||||
|
{
|
||||||
|
uint8_t param;
|
||||||
|
switch (dir) {
|
||||||
|
case 0:
|
||||||
|
if (!mir_flag)
|
||||||
|
param = 0x08;
|
||||||
|
else
|
||||||
|
param = 0x48;
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
if (!mir_flag)
|
||||||
|
param = 0x28;
|
||||||
|
else
|
||||||
|
param = 0xA8;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
if (!mir_flag)
|
||||||
|
param = 0x88;
|
||||||
|
else
|
||||||
|
param = 0xC8;
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
if (!mir_flag)
|
||||||
|
param = 0xE8;
|
||||||
|
else
|
||||||
|
param = 0x68;
|
||||||
|
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return -1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
st7789v_spi_write_cmd(0x36);
|
||||||
|
st7789v_spi_write_data_byte(param);
|
||||||
|
return dir;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief st7789v_spi_set_draw_window
|
||||||
|
*
|
||||||
|
* @param x1
|
||||||
|
* @param y1
|
||||||
|
* @param x2
|
||||||
|
* @param y2
|
||||||
|
*/
|
||||||
|
void st7789v_spi_set_draw_window(uint32_t x1, uint32_t y1, uint32_t x2, uint32_t y2)
|
||||||
|
{
|
||||||
|
#if ST7789V_SPI_OFFSET_X
|
||||||
|
x1 += ST7789V_SPI_OFFSET_X;
|
||||||
|
x2 += ST7789V_SPI_OFFSET_X;
|
||||||
|
#endif
|
||||||
|
#if ST7789V_SPI_OFFSET_Y
|
||||||
|
y1 += ST7789V_SPI_OFFSET_Y;
|
||||||
|
y2 += ST7789V_SPI_OFFSET_Y;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
st7789v_spi_write_cmd(0x2a);
|
||||||
|
st7789v_spi_write_data_byte(x1 >> 8);
|
||||||
|
st7789v_spi_write_data_byte(x1);
|
||||||
|
st7789v_spi_write_data_byte(x2 >> 8);
|
||||||
|
st7789v_spi_write_data_byte(x2);
|
||||||
|
|
||||||
|
st7789v_spi_write_cmd(0x2b);
|
||||||
|
st7789v_spi_write_data_byte(y1 >> 8);
|
||||||
|
st7789v_spi_write_data_byte(y1);
|
||||||
|
st7789v_spi_write_data_byte(y2 >> 8);
|
||||||
|
st7789v_spi_write_data_byte(y2);
|
||||||
|
|
||||||
|
st7789v_spi_write_cmd(0x2c);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief st7789v_spi_draw_point
|
||||||
|
*
|
||||||
|
* @param x
|
||||||
|
* @param y
|
||||||
|
* @param color
|
||||||
|
*/
|
||||||
|
void st7789v_spi_draw_point(uint16_t x, uint16_t y, st7789v_spi_color_t color)
|
||||||
|
{
|
||||||
|
#if (SPI_FIFO_WIDTH_VARIABLE_SUPPORT == 0)
|
||||||
|
color = ((color >> 8) & 0xFF) | color << 8;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
st7789v_spi_set_draw_window(x, y, x, y);
|
||||||
|
ST7789V_SPI_DC_HIGH;
|
||||||
|
ST7789V_SPI_CS_LOW;
|
||||||
|
bflb_spi_poll_send(st7789v_spi, color & 0x00ff);
|
||||||
|
bflb_spi_poll_send(st7789v_spi, (color >> 8) & 0x00ff);
|
||||||
|
ST7789V_SPI_CS_HIGH;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief st7789v_draw_area
|
||||||
|
*
|
||||||
|
* @param x1
|
||||||
|
* @param y1
|
||||||
|
* @param x2
|
||||||
|
* @param y2
|
||||||
|
* @param color
|
||||||
|
*/
|
||||||
|
void st7789v_spi_draw_area(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, st7789v_spi_color_t color)
|
||||||
|
{
|
||||||
|
uint32_t pixelDataSize, PixelCount = (x2 - x1 + 1) * (y2 - y1 + 1);
|
||||||
|
uint32_t __attribute__((aligned(64))) color_src;
|
||||||
|
|
||||||
|
#if (SPI_FIFO_WIDTH_VARIABLE_SUPPORT)
|
||||||
|
color_src = color;
|
||||||
|
#else
|
||||||
|
color_src = ((color >> 8) & 0xFF) | color << 8;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* clean cache */
|
||||||
|
bflb_l1c_dcache_clean_range((void *)&color_src, sizeof(color_src));
|
||||||
|
|
||||||
|
/* set window */
|
||||||
|
st7789v_spi_set_draw_window(x1, y1, x2, y2);
|
||||||
|
|
||||||
|
/* get pixel Data Size */
|
||||||
|
pixelDataSize = PixelCount * 2;
|
||||||
|
|
||||||
|
/* spi 16-bit mode */
|
||||||
|
bflb_spi_feature_control(st7789v_spi, SPI_CMD_SET_DATA_WIDTH, SPI_DATA_WIDTH_16BIT);
|
||||||
|
|
||||||
|
/* enable spi dma mode */
|
||||||
|
bflb_spi_link_txdma(st7789v_spi, true);
|
||||||
|
|
||||||
|
ST7789V_SPI_CS_LOW;
|
||||||
|
|
||||||
|
/* sync mode flag, temporary shutdown interrupt */
|
||||||
|
st7789v_spi_sync_flush_flag = true;
|
||||||
|
|
||||||
|
/* disable dma src_addr_inc */
|
||||||
|
bflb_dma_feature_control(st7789v_dma_spi_tx, DMA_CMD_SET_SRCADDR_INCREMENT, false);
|
||||||
|
|
||||||
|
/* cfg and start dma */
|
||||||
|
dma_tx_transfers[0].src_addr = (uint32_t)(uintptr_t)&color_src;
|
||||||
|
#if (defined(BL808) || defined(BL606P)) && defined(CPU_D0)
|
||||||
|
dma_tx_transfers[0].dst_addr = (uint32_t)DMA_ADDR_SPI1_TDR;
|
||||||
|
#else
|
||||||
|
dma_tx_transfers[0].dst_addr = (uint32_t)DMA_ADDR_SPI0_TDR;
|
||||||
|
#endif
|
||||||
|
dma_tx_transfers[0].nbytes = pixelDataSize;
|
||||||
|
|
||||||
|
bflb_dma_channel_lli_reload(st7789v_dma_spi_tx, dam_tx_llipool, ST7789V_DMA_LLI_NUM, dma_tx_transfers, 1);
|
||||||
|
bflb_dma_channel_start(st7789v_dma_spi_tx);
|
||||||
|
|
||||||
|
/* Wait to finish, and cs high */
|
||||||
|
while (st7789v_spi_draw_is_busy()) {
|
||||||
|
__ASM volatile("nop");
|
||||||
|
};
|
||||||
|
|
||||||
|
/* enable src_addr_inc */
|
||||||
|
bflb_dma_feature_control(st7789v_dma_spi_tx, DMA_CMD_SET_SRCADDR_INCREMENT, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief st7789v_draw_picture_dma, Non-blocking! Using DMA acceleration, Not waiting for the draw end
|
||||||
|
* After the call, No other operations are allowed until (st7789v_draw_is_busy()==0)
|
||||||
|
*
|
||||||
|
* @param x1
|
||||||
|
* @param y1
|
||||||
|
* @param x2
|
||||||
|
* @param y2
|
||||||
|
* @param picture
|
||||||
|
*/
|
||||||
|
void st7789v_spi_draw_picture_nonblocking(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, st7789v_spi_color_t *picture)
|
||||||
|
{
|
||||||
|
size_t picture_size = (x2 - x1 + 1) * (y2 - y1 + 1);
|
||||||
|
|
||||||
|
st7789v_spi_set_draw_window(x1, y1, x2, y2);
|
||||||
|
|
||||||
|
#if (SPI_FIFO_WIDTH_VARIABLE_SUPPORT == 0)
|
||||||
|
lcd_swap_color_data16(picture, picture, picture_size);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* clean dcache */
|
||||||
|
bflb_l1c_dcache_clean_range((void *)(picture), (picture_size * 2));
|
||||||
|
|
||||||
|
/* spi 16-bit data mode */
|
||||||
|
bflb_spi_feature_control(st7789v_spi, SPI_CMD_SET_DATA_WIDTH, SPI_DATA_WIDTH_16BIT);
|
||||||
|
|
||||||
|
/* spi dma mode enable */
|
||||||
|
bflb_spi_link_txdma(st7789v_spi, true);
|
||||||
|
|
||||||
|
ST7789V_SPI_CS_LOW;
|
||||||
|
|
||||||
|
/* dma cfg and start */
|
||||||
|
dma_tx_transfers[0].src_addr = (uint32_t)(uintptr_t)picture;
|
||||||
|
dma_tx_transfers[0].dst_addr = (uint32_t)DMA_ADDR_SPI0_TDR;
|
||||||
|
dma_tx_transfers[0].nbytes = picture_size * 2;
|
||||||
|
bflb_dma_channel_lli_reload(st7789v_dma_spi_tx, dam_tx_llipool, sizeof(dam_tx_llipool) / sizeof(dam_tx_llipool[0]), dma_tx_transfers, 1);
|
||||||
|
bflb_dma_channel_start(st7789v_dma_spi_tx);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief st7789v_draw_picture,Blocking,Using DMA acceleration,Waiting for the draw end
|
||||||
|
*
|
||||||
|
* @param x1
|
||||||
|
* @param y1
|
||||||
|
* @param x2
|
||||||
|
* @param y2
|
||||||
|
* @param picture
|
||||||
|
*/
|
||||||
|
void st7789v_spi_draw_picture_blocking(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, st7789v_spi_color_t *picture)
|
||||||
|
{
|
||||||
|
/* sync mode, temporary shutdown interrupt */
|
||||||
|
st7789v_spi_sync_flush_flag = true;
|
||||||
|
|
||||||
|
st7789v_spi_draw_picture_nonblocking(x1, y1, x2, y2, picture);
|
||||||
|
while (st7789v_spi_draw_is_busy()) {
|
||||||
|
__ASM volatile("nop");
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
63
bsp/common/lcd/spi/st7789v_spi.h
Normal file
63
bsp/common/lcd/spi/st7789v_spi.h
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
/**
|
||||||
|
* @file st7789v.h
|
||||||
|
* @brief
|
||||||
|
*
|
||||||
|
* Copyright (c) 2021 Bouffalolab team
|
||||||
|
*
|
||||||
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
||||||
|
* contributor license agreements. See the NOTICE file distributed with
|
||||||
|
* this work for additional information regarding copyright ownership. The
|
||||||
|
* ASF licenses this file to you under the Apache License, Version 2.0 (the
|
||||||
|
* "License"); you may not use this file except in compliance with the
|
||||||
|
* License. You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
* License for the specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _ST7789V_SPI_H_
|
||||||
|
#define _ST7789V_SPI_H_
|
||||||
|
|
||||||
|
#include "bflb_core.h"
|
||||||
|
|
||||||
|
#define ST7789V_SPI_CS_PIN GPIO_PIN_12
|
||||||
|
#define ST7789V_SPI_DC_PIN GPIO_PIN_13
|
||||||
|
|
||||||
|
#define ST7789V_SPI_CS_HIGH bflb_gpio_set(st7789v_gpio, ST7789V_SPI_CS_PIN)
|
||||||
|
#define ST7789V_SPI_CS_LOW bflb_gpio_reset(st7789v_gpio, ST7789V_SPI_CS_PIN)
|
||||||
|
#define ST7789V_SPI_DC_HIGH bflb_gpio_set(st7789v_gpio, ST7789V_SPI_DC_PIN)
|
||||||
|
#define ST7789V_SPI_DC_LOW bflb_gpio_reset(st7789v_gpio, ST7789V_SPI_DC_PIN)
|
||||||
|
|
||||||
|
#define ST7789V_SPI_W 240 /* ST7789V LCD width */
|
||||||
|
#define ST7789V_SPI_H 280 /* ST7789V LCD height */
|
||||||
|
|
||||||
|
#define ST7789V_SPI_OFFSET_X 0
|
||||||
|
#define ST7789V_SPI_OFFSET_Y 20
|
||||||
|
|
||||||
|
#define ST7789V_SPI_COLOR_DEPTH 16
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint8_t cmd; /* 0xFF : delay(databytes)ms */
|
||||||
|
const char *data;
|
||||||
|
uint8_t databytes; /* Num of data in data; or delay time */
|
||||||
|
} st7789v_spi_init_cmd_t;
|
||||||
|
|
||||||
|
typedef uint16_t st7789v_spi_color_t;
|
||||||
|
|
||||||
|
int st7789v_spi_init();
|
||||||
|
void st7789v_spi_async_callback_register(void (*callback)(void));
|
||||||
|
int st7789v_spi_set_dir(uint8_t dir, uint8_t mir_flag);
|
||||||
|
void st7789v_spi_set_draw_window(uint32_t x1, uint32_t y1, uint32_t x2, uint32_t y2);
|
||||||
|
void st7789v_spi_draw_point(uint16_t x, uint16_t y, st7789v_spi_color_t color);
|
||||||
|
void st7789v_spi_draw_area(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, st7789v_spi_color_t color);
|
||||||
|
void st7789v_spi_draw_picture_nonblocking(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, st7789v_spi_color_t *picture);
|
||||||
|
void st7789v_spi_draw_picture_blocking(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, st7789v_spi_color_t *picture);
|
||||||
|
int st7789v_spi_draw_is_busy(void);
|
||||||
|
|
||||||
|
#endif
|
@ -248,7 +248,7 @@ int st7796_spi_draw_is_busy(void)
|
|||||||
} else {
|
} else {
|
||||||
/* Wait for the SPI bus to be idle */
|
/* Wait for the SPI bus to be idle */
|
||||||
while (bflb_spi_isbusy(st7796_spi)) {
|
while (bflb_spi_isbusy(st7796_spi)) {
|
||||||
__NOP();
|
__ASM volatile("nop");
|
||||||
};
|
};
|
||||||
/* Switch the SPI to non-DMA mode */
|
/* Switch the SPI to non-DMA mode */
|
||||||
bflb_spi_link_txdma(st7796_spi, false);
|
bflb_spi_link_txdma(st7796_spi, false);
|
||||||
@ -467,7 +467,7 @@ void st7796_spi_draw_area(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, st
|
|||||||
|
|
||||||
/* Wait to finish, and cs high */
|
/* Wait to finish, and cs high */
|
||||||
while (st7796_spi_draw_is_busy()) {
|
while (st7796_spi_draw_is_busy()) {
|
||||||
__NOP();
|
__ASM volatile("nop");
|
||||||
};
|
};
|
||||||
|
|
||||||
/* enable src_addr_inc */
|
/* enable src_addr_inc */
|
||||||
@ -529,7 +529,7 @@ void st7796_spi_draw_picture_blocking(uint16_t x1, uint16_t y1, uint16_t x2, uin
|
|||||||
|
|
||||||
st7796_spi_draw_picture_nonblocking(x1, y1, x2, y2, picture);
|
st7796_spi_draw_picture_nonblocking(x1, y1, x2, y2, picture);
|
||||||
while (st7796_spi_draw_is_busy()) {
|
while (st7796_spi_draw_is_busy()) {
|
||||||
__NOP();
|
__ASM volatile("nop");
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -49,16 +49,35 @@ void lv_log_print_g_cb(const char *buf)
|
|||||||
printf("[LVGL] %s", buf);
|
printf("[LVGL] %s", buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief spi gpio init
|
||||||
|
*
|
||||||
|
* Please modify lcd pin: cs/dc/clk/mosi with your own board. Default spi mapping is for BL808.
|
||||||
|
* Default lcd type is st7789v with 240 * 280
|
||||||
|
*/
|
||||||
static void gpio_init(void)
|
static void gpio_init(void)
|
||||||
{
|
{
|
||||||
struct bflb_device_s *gpio;
|
struct bflb_device_s *gpio;
|
||||||
gpio = bflb_device_get_by_name("gpio");
|
gpio = bflb_device_get_by_name("gpio");
|
||||||
|
|
||||||
/* lcd spi clk and data pin */
|
/* lcd cs, see in bsp/common/lcd/spi/xxx_spi.h */
|
||||||
// bflb_gpio_init(gpio, GPIO_PIN_16, GPIO_FUNC_SPI0 | GPIO_ALTERNATE | GPIO_PULLUP | GPIO_SMT_EN | GPIO_DRV_2);
|
// bflb_gpio_init(gpio, GPIO_PIN_12, GPIO_OUTPUT | GPIO_PULLUP | GPIO_SMT_EN | GPIO_DRV_2);
|
||||||
bflb_gpio_init(gpio, GPIO_PIN_17, GPIO_FUNC_SPI0 | GPIO_ALTERNATE | GPIO_PULLUP | GPIO_SMT_EN | GPIO_DRV_2);
|
|
||||||
// bflb_gpio_init(gpio, GPIO_PIN_18, GPIO_FUNC_SPI0 | GPIO_ALTERNATE | GPIO_PULLUP | GPIO_SMT_EN | GPIO_DRV_2);
|
/* lcd dc, see in bsp/common/lcd/spi/xxx_spi.h */
|
||||||
|
// bflb_gpio_init(gpio, GPIO_PIN_13, GPIO_OUTPUT | GPIO_PULLUP | GPIO_SMT_EN | GPIO_DRV_2);
|
||||||
|
|
||||||
|
/* lcd spi mosi */
|
||||||
|
bflb_gpio_init(gpio, GPIO_PIN_25, GPIO_FUNC_SPI0 | GPIO_ALTERNATE | GPIO_PULLUP | GPIO_SMT_EN | GPIO_DRV_2);
|
||||||
|
|
||||||
|
/* lcd spi clock */
|
||||||
bflb_gpio_init(gpio, GPIO_PIN_19, GPIO_FUNC_SPI0 | GPIO_ALTERNATE | GPIO_PULLUP | GPIO_SMT_EN | GPIO_DRV_2);
|
bflb_gpio_init(gpio, GPIO_PIN_19, GPIO_FUNC_SPI0 | GPIO_ALTERNATE | GPIO_PULLUP | GPIO_SMT_EN | GPIO_DRV_2);
|
||||||
|
|
||||||
|
/* backlight pin */
|
||||||
|
bflb_gpio_init(gpio, GPIO_PIN_11, GPIO_OUTPUT | GPIO_PULLUP | GPIO_SMT_EN | GPIO_DRV_2);
|
||||||
|
bflb_gpio_set(gpio, GPIO_PIN_11);
|
||||||
|
/* reset pin */
|
||||||
|
bflb_gpio_init(gpio, GPIO_PIN_24, GPIO_OUTPUT | GPIO_PULLUP | GPIO_SMT_EN | GPIO_DRV_2);
|
||||||
|
bflb_gpio_set(gpio, GPIO_PIN_24);
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(void)
|
int main(void)
|
||||||
|
Reference in New Issue
Block a user