800*320工程文件+初始demo提交

This commit is contained in:
2024-03-07 16:46:43 +08:00
parent 33e6eb45b3
commit 70ec3005bb
3306 changed files with 3374364 additions and 2563 deletions

View File

@ -0,0 +1,202 @@
/*
******************************************************************************
* @file driver_display.c
* @author FreqChip Firmware Team
* @version V1.0.0
* @date 2022
* @brief display abstract interfase.
******************************************************************************
* @attention
*
* Copyright (c) 2022 FreqChip.
* All rights reserved.
******************************************************************************
*/
#include <stdint.h>
#include "app_lvgl.h"
#include "app_config.h"
#include "driver_display.h"
#ifdef DISPLAY_TYPE_GC9C01
#include "driver_gc9c01.h"
#endif
#ifdef DISPLAY_TYPE_JD9854
#include "driver_jd9854.h"
#endif
#ifdef DISPLAY_TYPE_SH8601A
#include "driver_sh8601a.h"
#endif
#ifdef DISPLAY_TYPE_ICNA3310
#include "driver_icna3310.h"
#endif
#ifdef DISPLAY_TYPE_SH8601Z
#include "driver_sh8601z.h"
#endif
#ifdef DISPLAY_TYPE_NV3047_RGB
#include "driver_nv3047_rgb.h"
#endif
#ifdef DISPLAY_TYPE_ST7701_RGB
#include "driver_st7701_rgb.h"
#endif
#ifdef DISPLAY_TYPE_NV3041A
#include "driver_nv3041a.h"
#endif
void display_init(void)
{
#ifdef DISPLAY_TYPE_GC9C01
gc9c01_init();
#endif
#ifdef DISPLAY_TYPE_JD9854
jd9854_init();
#endif
#ifdef DISPLAY_TYPE_SH8601A
sh8601a_init();
#endif
#ifdef DISPLAY_TYPE_ICNA3310
icna3310_init();
#endif
#ifdef DISPLAY_TYPE_SH8601Z
sh8601z_init();
#endif
#ifdef DISPLAY_TYPE_NV3047_RGB
extern void* get_display_buffer1(void);
extern void rgb_display_controller_init(void);
rgb_display_controller_init();
rgb_display_init(get_display_buffer1());
#endif
#ifdef DISPLAY_TYPE_ST7701_RGB
extern void* get_display_buffer1(void);
st7701_init(get_display_buffer1());
#endif
#ifdef DISPLAY_TYPE_NV3041A
nv3041a_init();
#endif
}
void display_set_window(uint16_t x_s, uint16_t x_e, uint16_t y_s, uint16_t y_e)
{
#ifdef DISPLAY_TYPE_GC9C01
gc9c01_set_window(x_s, x_e, y_s, y_e);
#endif
#ifdef DISPLAY_TYPE_JD9854
jd9854_set_window(x_s, x_e, y_s, y_e);
#endif
#ifdef DISPLAY_TYPE_SH8601A
sh8601a_set_window(x_s, x_e, y_s, y_e);
#endif
#ifdef DISPLAY_TYPE_ICNA3310
icna3310_set_window(x_s, x_e, y_s, y_e);
#endif
#ifdef DISPLAY_TYPE_SH8601Z
sh8601z_set_window(x_s, x_e, y_s, y_e);
#endif
#ifdef DISPLAY_TYPE_NV3041A
nv3041a_set_window(x_s, x_e, y_s, y_e);
#endif
}
void display_update(uint32_t pixel_count, uint8_t pixel_width, void *data)
{
#ifdef DISPLAY_TYPE_GC9C01
gc9c01_display(pixel_count, pixel_width, data);
#endif
#ifdef DISPLAY_TYPE_JD9854
jd9854_display(pixel_count, pixel_width, data);
#endif
#ifdef DISPLAY_TYPE_SH8601A
sh8601a_display(pixel_count, pixel_width, data);
#endif
#ifdef DISPLAY_TYPE_ICNA3310
icna3310_display(pixel_count, pixel_width, data);
#endif
#ifdef DISPLAY_TYPE_SH8601Z
sh8601z_display(pixel_count, pixel_width, data);
#endif
#ifdef DISPLAY_TYPE_NV3041A
nv3041a_display(pixel_count, pixel_width, data);
#endif
}
void display_update_dma(uint32_t pixel_count, uint8_t pixel_width, void *data)
{
#ifdef DISPLAY_TYPE_GC9C01
gc9c01_display_dma(pixel_count, pixel_width, data);
#endif
#ifdef DISPLAY_TYPE_JD9854
jd9854_display_dma(pixel_count, pixel_width, data);
#endif
#ifdef DISPLAY_TYPE_SH8601A
sh8601a_display_dma(pixel_count, pixel_width, data);
#endif
#ifdef DISPLAY_TYPE_ICNA3310
icna3310_display_dma(pixel_count, pixel_width, data);
#endif
#ifdef DISPLAY_TYPE_SH8601Z
sh8601z_display_dma(pixel_count, pixel_width, data);
#endif
#ifdef DISPLAY_TYPE_NV3047_RGB
#endif
#ifdef DISPLAY_TYPE_ST7701_RGB
#endif
#ifdef DISPLAY_TYPE_NV3041A
nv3041a_display_dma(pixel_count, pixel_width, data);
#endif
}
void display_power_off(void)
{
#ifdef DISPLAY_TYPE_SH8601Z
sh8601z_power_off();
#endif
}
void display_power_on(void)
{
#ifdef DISPLAY_TYPE_SH8601Z
sh8601z_power_on();
#endif
}
void display_update_dma_isr(void)
{
#ifdef DISPLAY_TYPE_GC9C01
gc9c01_display_dma_isr();
#endif
#ifdef DISPLAY_TYPE_JD9854
jd9854_display_dma_isr();
#endif
#ifdef DISPLAY_TYPE_SH8601A
sh8601a_display_dma_isr();
#endif
#ifdef DISPLAY_TYPE_ICNA3310
icna3310_display_dma_isr();
#endif
#ifdef DISPLAY_TYPE_SH8601Z
sh8601z_display_dma_isr();
#endif
#ifdef DISPLAY_TYPE_ST7701_RGB
st7701_rgb_display_dma_irq();
#endif
#ifdef DISPLAY_TYPE_NV3041A
nv3041a_display_dma_isr();
#endif
}

View File

@ -0,0 +1,162 @@
#ifndef __DRIVER_DISPLAY_H__
#define __DRIVER_DISPLAY_H__
#include <stdint.h>
#include "driver_spi.h"
#include "driver_dma.h"
#ifdef __cplusplus
extern "C"
{
#endif
//*****************************************************************************
//
// Macro Variables definitions
//
//*****************************************************************************
#define __DISPLAY_CS_SET() display_cs_set()
#define __DISPLAY_CS_CLEAR() display_cs_clear()
#define __DISPLAY_RESET_SET() display_reset_set()
#define __DISPLAY_RESET_CLEAR() display_reset_clear()
#define __DISPLAY_VCI_SET() display_vci_set()
#define __DISPLAY_VCI_CLEAR() display_vci_clear()
#define __DISPLAY_DELAY_MS(counter) display_delay_ms(counter)
//*****************************************************************************
//
// Global Variables definitions
//
//*****************************************************************************
extern SPI_HandleTypeDef spi_display_handle;
extern DMA_HandleTypeDef dma_display_handle;
//*****************************************************************************
//
// External function definitions
//
//*****************************************************************************
/************************************************************************************
* @fn display_cs_set
*
* @brief Set display driver CS pin to HIGH, this function should be implemented by user when
* CS is controlled by software.
*/
void display_cs_set(void);
/************************************************************************************
* @fn display_cs_release
*
* @brief Set display driver CS pin to LOW, this function should be implemented by user when
* CS is controlled by software.
*/
void display_cs_clear(void);
/************************************************************************************
* @fn display_reset_set
*
* @brief Set display driver RESET pin to HIGH, this function should be implemented by user..
*/
void display_reset_set(void);
/************************************************************************************
* @fn display_reset_clear
*
* @brief Set display driver RESET pin to LOW, this function should be implemented by user.
*/
void display_reset_clear(void);
/************************************************************************************
* @fn display_vci_set
*
* @brief Set display driver VCI pin to HIGH, this function should be implemented by user..
*/
void display_vci_set(void);
/************************************************************************************
* @fn display_vci_clear
*
* @brief Set display driver VCI pin to LOW, this function should be implemented by user.
*/
void display_vci_clear(void);
/************************************************************************************
* @fn display_delay_ms
*
* @brief Used in display driver. co_delay_100us or vTaskDelay can be used for implementation
* by user.
*/
void display_delay_ms(uint32_t counter);
/************************************************************************************
* @fn display_init
*
* @brief Initial display drivers.
*/
void display_init(void);
/************************************************************************************
* @fn display_set_window
*
* @brief used to define area of frame memory where MCU can access.
*
* @param x_s: SC.
* x_e: EC.
* y_s: SP.
* y_e: EP.
*/
void display_set_window(uint16_t x_s, uint16_t x_e, uint16_t y_s, uint16_t y_e);
/************************************************************************************
* @fn display_update
*
* @brief transfer data to framebuffer of display controller in block mode.
*
* @param pixel_count: total pixels count to be sent.
* pixel_width: this parameter should be 16, 24.
* data: pointer to data buffer
*/
void display_update(uint32_t pixel_count, uint8_t pixel_width, void *data);
/************************************************************************************
* @fn display_update_dma
*
* @brief transfer data to framebuffer of display controller in DMA mode.
*
* @param pixel_count: total pixels count to be sent.
* pixel_width: this parameter should be 16, 24.
* data: pointer to data buffer
*/
void display_update_dma(uint32_t pixel_count, uint8_t pixel_width, void *data);
/************************************************************************************
* @fn display_update_dma_isr
*
* @brief this function will be called in DMA isr handler when dma transfer is done.
*/
void display_update_dma_isr(void);
/************************************************************************************
* @fn display_power_off
*
* @brief used to power off display to save power.
*/
void display_power_off(void);
/************************************************************************************
* @fn display_power_on
*
* @brief turn on display.
*/
void display_power_on(void);
#ifdef __cplusplus
}
#endif
#endif /* __DRIVER_DISPLAY_H__ */

View File

@ -0,0 +1,238 @@
#include "driver_display.h"
static void reg_write(uint8_t addr, uint8_t *value, uint8_t length)
{
uint8_t sdat[length + 4];
sdat[0] = 0x02;
sdat[1] = 0x00;
sdat[2] = addr;
sdat[3] = 0x00;
memcpy(&sdat[4], value, length);
__DISPLAY_CS_CLEAR();
spi_master_transmit_X1(&spi_display_handle, sdat, sizeof(sdat));
__DISPLAY_CS_SET();
}
static void reg_read(uint8_t addr, uint8_t *value, uint8_t length)
{
uint8_t sdat[4];
sdat[0] = 0x03;
sdat[1] = 0x00;
sdat[2] = addr;
sdat[3] = 0x00;
__DISPLAY_CS_CLEAR();
spi_master_transmit_X1(&spi_display_handle, sdat, sizeof(sdat));
spi_master_receive_X1(&spi_display_handle, value, length);
__DISPLAY_CS_SET();
}
void icna3310_init(void)
{
uint8_t buffer[4];
__DISPLAY_VCI_CLEAR();
__DISPLAY_RESET_CLEAR();
__DISPLAY_DELAY_MS(200);
__DISPLAY_VCI_SET();
__DISPLAY_DELAY_MS(50);
__DISPLAY_RESET_SET();
__DISPLAY_DELAY_MS(5);
__DISPLAY_RESET_CLEAR();
__DISPLAY_DELAY_MS(5);
__DISPLAY_RESET_SET();
__DISPLAY_DELAY_MS(5);
// __DISPLAY_VCI_CLEAR();
// __DISPLAY_RESET_CLEAR();
// __DISPLAY_DELAY_MS(20);
// __DISPLAY_RESET_SET();
// __DISPLAY_DELAY_MS(40);
// __DISPLAY_VCI_SET();
// __DISPLAY_DELAY_MS(80);
buffer[0] = 0x20;
reg_write(0xFE, &buffer[0], 1);
buffer[0] = 0x5a;
reg_write(0xF4, &buffer[0], 1);
buffer[0] = 0x59;
reg_write(0xF5, &buffer[0], 1);
buffer[0] = 0x40;
reg_write(0xFE, &buffer[0], 1);
buffer[0] = 0x0a;
reg_write(0x08, &buffer[0], 1);
buffer[0] = 0x00;
reg_write(0xFE, &buffer[0], 1);
buffer[0] = 0x80;
reg_write(0xC4, &buffer[0], 1);//SPI sram write enable
buffer[0] = 0x55;
reg_write(0x3A, &buffer[0], 1);//55 RGB565, 77 RGB888
buffer[0] = 0x00;
reg_write(0x35, &buffer[0], 1);
buffer[0] = 0x20;
reg_write(0x53, &buffer[0], 1);
buffer[0] = 0xFF;
reg_write(0x51, &buffer[0], 1);
buffer[0] = 0xFF;
reg_write(0x63, &buffer[0], 1);
buffer[0] = 0x00;
buffer[1] = 0x06;
buffer[2] = 0x01;
buffer[3] = 0xD7;
reg_write(0x2A, &buffer[0], 4); // paritial update:466RGB
buffer[0] = 0x00;
buffer[1] = 0x00;
buffer[2] = 0x01;
buffer[3] = 0xD1;
reg_write(0x2B, &buffer[0], 4); // partial update:466line
// buffer[0] = 0x00;
// reg_write(0xFE, &buffer[0], 1);
reg_write(0x11, NULL, 0);
__DISPLAY_DELAY_MS(120);
// buffer[0] = 0x00;
// reg_write(0xFE, &buffer[0], 1);
reg_write(0x29, NULL, 0);
__DISPLAY_DELAY_MS(50);
}
void icna3310_set_window(uint16_t x_s, uint16_t x_e, uint16_t y_s, uint16_t y_e)
{
uint8_t data[4];
x_s += 6;
x_e += 6;
data[0] = x_s >> 8;
data[1] = x_s & 0xff;
data[2] = x_e >> 8;
data[3] = x_e & 0xff;
reg_write(0x2A, &data[0], 4);
data[0] = y_s >> 8;
data[1] = y_s & 0xff;
data[2] = y_e >> 8;
data[3] = y_e & 0xff;
reg_write(0x2B, &data[0], 4);
// reg_write(0x2C, &data[0], 4);
}
void icna3310_adjust_brightness(uint8_t value) //Value 0x00 - 0xFF
{
uint8_t buffer[1];
buffer[0] = 0x00;
reg_write(0xFE, &buffer[0], 1);
buffer[0] = value;
reg_write(0x51, &buffer[0], 1);
}
void icna3310_display(uint32_t pixel_count, uint8_t pixel_width, void *data)
{
uint8_t frame_size;
if (pixel_width == 16) {
frame_size = SPI_FRAME_SIZE_16BIT;
}
else if (pixel_width == 32) {
frame_size = SPI_FRAME_SIZE_24BIT;
}
spi_display_handle.Init.Frame_Size = frame_size;
spi_display_handle.MultWireParam.Wire_X2X4X8 = Wire_X4;
spi_display_handle.MultWireParam.InstructLength = INST_8BIT;
spi_display_handle.MultWireParam.Instruct = 0x32;
spi_display_handle.MultWireParam.AddressLength = ADDR_24BIT;
spi_display_handle.MultWireParam.Address = 0x002C00;
__DISPLAY_CS_CLEAR();
spi_master_transmit_X2X4X8(&spi_display_handle, data, pixel_count);
__DISPLAY_CS_SET();
__SPI_DISABLE(spi_display_handle.SPIx);
__SPI_DATA_FRAME_SIZE(spi_display_handle.SPIx, SPI_FRAME_SIZE_8BIT);
}
void icna3310_display_dma(uint32_t pixel_count, uint8_t pixel_width, void *data)
{
uint8_t spi_trans_width;
uint32_t dma_sample_count;
switch (dma_display_handle.Init.Source_Width) {
case DMA_TRANSFER_WIDTH_32:
dma_sample_count = pixel_count * pixel_width / 32;
break;
case DMA_TRANSFER_WIDTH_16:
dma_sample_count = pixel_count * pixel_width / 16;
break;
case DMA_TRANSFER_WIDTH_8:
dma_sample_count = pixel_count * pixel_width / 8;
break;
default:
return;
}
switch (dma_display_handle.Init.Desination_Width) {
case DMA_TRANSFER_WIDTH_32:
spi_trans_width = SPI_FRAME_SIZE_32BIT;
break;
case DMA_TRANSFER_WIDTH_16:
spi_trans_width = SPI_FRAME_SIZE_16BIT;
break;
case DMA_TRANSFER_WIDTH_8:
spi_trans_width = SPI_FRAME_SIZE_8BIT;
break;
default:
return;
}
if (pixel_width != 32) {
spi_display_handle.Init.Frame_Size = spi_trans_width;
}
else {
spi_display_handle.Init.Frame_Size = SPI_FRAME_SIZE_24BIT;
}
spi_display_handle.MultWireParam.Wire_X2X4X8 = Wire_X4;
spi_display_handle.MultWireParam.InstructLength = INST_8BIT;
spi_display_handle.MultWireParam.Instruct = 0x32;
spi_display_handle.MultWireParam.AddressLength = ADDR_24BIT;
spi_display_handle.MultWireParam.Address = 0x002C00;
__DISPLAY_CS_CLEAR();
__SPI_DISABLE(spi_display_handle.SPIx);
__SPI_TX_ENDIAN_SET(spi_display_handle.SPIx, TX_RX_Endian_4321);
__SPI_ENABLE(spi_display_handle.SPIx);
spi_master_transmit_X2X4X8_DMA(&spi_display_handle);
__SPI_DISABLE(spi_display_handle.SPIx);
if ((spi_trans_width == SPI_FRAME_SIZE_32BIT)
&& (pixel_width != 32)) {
__SPI_TX_ENDIAN_SET(spi_display_handle.SPIx, TX_RX_Endian_2143);
}
else {
__SPI_TX_ENDIAN_SET(spi_display_handle.SPIx, TX_RX_Endian_4321);
}
__SPI_ENABLE(spi_display_handle.SPIx);
dma_start_IT(&dma_display_handle, (uint32_t)data, (uint32_t)&spi_display_handle.SPIx->DR, dma_sample_count);
}
void icna3310_display_dma_isr(void)
{
while(__SPI_IS_BUSY(spi_display_handle.SPIx));
// CS Release
__DISPLAY_CS_SET();
/* Clear Transfer complete status */
dma_clear_tfr_Status(&dma_display_handle);
/* channel Transfer complete interrupt disable */
dma_tfr_interrupt_disable(&dma_display_handle);
__SPI_DISABLE(spi_display_handle.SPIx);
__SPI_DATA_FRAME_SIZE(spi_display_handle.SPIx, SPI_FRAME_SIZE_8BIT);
__SPI_TX_ENDIAN_SET(spi_display_handle.SPIx, TX_RX_Endian_4321);
}

View File

@ -0,0 +1,16 @@
#ifndef __DRIVER_ICNA3310_H
#define __DRIVER_ICNA3310_H
#include <stdint.h>
void icna3310_init(void);
void icna3310_set_window(uint16_t x_s, uint16_t x_e, uint16_t y_s, uint16_t y_e);
void icna3310_display(uint32_t pixel_count, uint8_t pixel_width, void *data);
void icna3310_display_dma(uint32_t pixel_count, uint8_t pixel_width, void *data);
void icna3310_display_dma_isr(void);
#endif // __DRIVER_ICNA3310_H

View File

@ -0,0 +1,556 @@
#include "driver_display.h"
#include "driver_nv3041a.h"
#include "driver_parallel_interface.h"
extern PARALLEL_HandTypeDef hparallel;
static void WriteComm(uint8_t reg)
{
__PARALLEL_CS_SET(hparallel.PARALLELx);
/* writer cmd */
Parallel_write_cmd(&hparallel,reg);
__PARALLEL_CS_RELEASE(hparallel.PARALLELx);
}
static void WriteData(uint8_t data)
{
__PARALLEL_CS_SET(hparallel.PARALLELx);
/* writer cmd */
Parallel_write_param(&hparallel,data);
__PARALLEL_CS_RELEASE(hparallel.PARALLELx);
}
static void LCD_READ_DATA(uint8_t reg)
{
static uint16_t data=0;
__PARALLEL_CS_SET(hparallel.PARALLELx);
/* writer cmd */
//Parallel_write_cmd(&hparallel,reg);
// Parallel_read_data_cmd(&hparallel,reg,&data,1);
printf("reg_param:0x%x\r\n",data);
__PARALLEL_CS_RELEASE(hparallel.PARALLELx);
}
void display_backlight_set(void)
{
gpio_write_pin(GPIOA, GPIO_PIN_4, GPIO_PIN_SET);
}
void display_backlight_clear(void)
{
gpio_write_pin(GPIOA, GPIO_PIN_4, GPIO_PIN_CLEAR);
}
void nv3041a_set_window(uint16_t x_s, uint16_t x_e, uint16_t y_s, uint16_t y_e)
{
WriteComm(0x2a);//列地址设置
WriteData(x_s>>8);
WriteData(x_s&0xff);
WriteData(x_e>>8);
WriteData(x_e&0xff);
WriteComm(0x2b);//行地址设置
WriteData(y_s>>8);
WriteData(y_s&0xff);
WriteData(y_e>>8);
WriteData(y_e&0xff);
WriteComm(0x2c);//储存器写
// write_cmd(0x2c);
}
void LCD_Fill(uint16_t xsta,uint16_t ysta,uint16_t xend,uint16_t yend,uint16_t color)
{
uint16_t i,j,size;
nv3041a_set_window(xsta,xend-1,ysta,yend-1);//设置显示范围
__PARALLEL_CS_SET(hparallel.PARALLELx);
if(hparallel.Init.DataBusSelect == DATA_BUS_8_BIT)
{
size=2;
}else{
size=2;
}
for(i=ysta;i<yend;i++)
{
for(j=xsta;j<xend;j++)
{
// LCD_WR_DATA(color);
/* writer data */
Parallel_write_data(&hparallel,(uint32_t *)&color,size);
}
}
__PARALLEL_CS_RELEASE(hparallel.PARALLELx);
}
void nv3041a_display(uint32_t pixel_count, uint8_t pixel_width, void *data)
{
uint32_t frame_size=0;
if (pixel_width == 8) {
frame_size = (pixel_count*4);
}
if (pixel_width == 16) {
// frame_size = SPI_FRAME_SIZE_16BIT;
frame_size = (pixel_count*2);
}
else if (pixel_width == 32) {
frame_size = (pixel_count);
}
__PARALLEL_CS_SET(hparallel.PARALLELx);
//Parallel_write_param(&hparallel,data);
Parallel_write_data(&hparallel,data,(frame_size));
//while(__PARALLEL_IS_BUS_BUSY(hparallel.PARALLELx));
__PARALLEL_CS_RELEASE(hparallel.PARALLELx);
}
void nv3041a_display_dma(uint32_t pixel_count, uint8_t pixel_width, void *data)
{
uint8_t dma_trans_width=0;
uint32_t dma_sample_count=0;
switch (dma_display_handle.Init.Source_Width) {
case DMA_TRANSFER_WIDTH_32:
//272x480 16
dma_sample_count = pixel_count * pixel_width / 32;
//dma_sample_count=dma_sample_count*4;
break;
case DMA_TRANSFER_WIDTH_16:
dma_sample_count = pixel_count * pixel_width / 16;
// dma_sample_count=dma_sample_count*2;
break;
case DMA_TRANSFER_WIDTH_8:
dma_sample_count = pixel_count * pixel_width / 8;
// dma_sample_count=dma_sample_count;
break;
default:
return;
}
// switch(hparallel.Init.DataBusSelect)
// {
// case DATA_BUS_8_BIT:
// dma_trans_width = 2;
// break;
//
// case DATA_BUS_16_BIT:
// dma_trans_width=2;
// break;
// }
dma_sample_count=dma_sample_count*2;
__PARALLEL_CS_SET(hparallel.PARALLELx);
__PARALLEL_SET_WR_LEN(hparallel.PARALLELx,dma_sample_count);
dma_start_IT(&dma_display_handle, (uint32_t)data, (uint32_t)&hparallel.PARALLELx->TX_FIFO, (dma_sample_count));
}
void nv3041a_display_dma_isr(void)
{
#if 0
while(__SPI_IS_BUSY(spi_display_handle.SPIx));
// CS Release
__DISPLAY_CS_SET();
/* Clear Transfer complete status */
dma_clear_tfr_Status(&dma_display_handle);
/* channel Transfer complete interrupt disable */
dma_tfr_interrupt_disable(&dma_display_handle);
__SPI_DISABLE(spi_display_handle.SPIx);
__SPI_TX_ENDIAN_SET(spi_display_handle.SPIx, TX_RX_Endian_4321);
__SPI_DATA_FRAME_SIZE(spi_display_handle.SPIx, SPI_FRAME_SIZE_8BIT);
#endif
//printf("nv3041a_display_dma_isr1\r\n");
while(!( __PARALLEL_INT_STATUS(hparallel.PARALLELx)&INT_TXFIFO_EMPTY));
__PARALLEL_CS_RELEASE(hparallel.PARALLELx);
/* Clear Transfer complete status */
dma_clear_tfr_Status(&dma_display_handle);
/* channel Transfer complete interrupt disable */
dma_tfr_interrupt_disable(&dma_display_handle);
//printf("nv3041a_display_dma_isr2\r\n");
}
#define pixel_size 100*100
uint16_t color_buffer[pixel_size]={0};
void nv3041a_init(void)
{
#define TFT_43 0
display_backlight_clear();
#if TFT_43 == 1
WriteComm(0xff);
WriteData(0xa5);
WriteComm(0xE7);//TE_output_en
WriteData(0x10);
WriteComm(0x35);//TE_ interface_en
WriteData(0x01);
WriteComm(0x3A);
WriteData(0x01);//00---666//01--565
WriteComm(0x40);
WriteData(0x01); //01:IPS/00:TN
WriteComm(0x41);
WriteData(0x03);//01--8bit//03--16bit
WriteComm(0x55);
WriteData(0x01);
WriteComm(0x44);//VBP
WriteData(0x15);//21NVu NV3041A-01
WriteComm(0x45);//VFP
WriteData(0x15);//21
WriteComm(0x7d);//vdds_trim[2:0]
WriteData(0x03);//2.07V
WriteComm(0xc1);//avdd_clp_en avdd_clp[1:0] avcl_clp_en avcl_clp[1:0]
WriteData(0xab);//6.74V/-5.16V
WriteComm(0xc2);//vgh_clp_en vgl_clp[2:0]
WriteData(0x17);
WriteComm(0xc3);//vgl_clp_en vgl_clp[2:0]
WriteData(0x10);//-10.951
WriteComm(0xc6);//avdd_ratio_sel avcl_ratio_sel vgh_ratio_sel[1:0] vgl_ratio_sel[1:0]
WriteData(0x3a);//35
WriteComm(0xc7);//mv_clk_sel[1:0] avdd_clk_sel[1:0] avcl_clk_sel[1:0]
WriteData(0x25); //2e
WriteComm(0xc8);// VGL_CLK_sel
WriteData(0x11);
WriteComm(0x6f);// user_gvdd
WriteData(0x2f);
WriteComm(0x78);// user_gvcl
WriteData(0x4b);
//WriteComm(0x7a);// user_vgsp
//WriteData(0x5f);
//test
WriteComm(0x7a);// user_vgsp
WriteData(0x49);
WriteComm(0xc9);
WriteData(0x00);
//gate_ed
WriteComm(0x51);//gate_st_o[7:0]
//WriteData(0x4b);
WriteData(0x20);
WriteComm(0x52);//gate_ed_o[7:0]
WriteData(0x7c);
WriteComm(0x53);//gate_st_e[7:0]
//WriteData(0x45);
WriteData(0x1c);
WriteComm(0x54);//gate_ed_e[7:0]
WriteData(0x77);
////sorce oldNVu NV3041A-01
WriteComm(0x46);//fsm_hbp_o[5:0]
WriteData(0x0a);
WriteComm(0x47);//fsm_hfp_o[5:0]
WriteData(0x2a);
WriteComm(0x48);//fsm_hbp_e[5:0]
WriteData(0x0a);
WriteComm(0x49);//fsm_hfp_e[5:0]
WriteData(0x1a);
WriteComm(0x56);//src_ld_wd[1:0] src_ld_st[5:0]
WriteData(0x43);
WriteComm(0x57);//pn_cs_en src_cs_st[5:0]
WriteData(0x42);
WriteComm(0x58);//src_cs_p_wd[6:0]
WriteData(0x3c);
WriteComm(0x59);//src_cs_n_wd[6:0]
WriteData(0x64);
WriteComm(0x5a);//src_pchg_st_o[6:0]
WriteData(0x41);
WriteComm(0x5b);//src_pchg_wd_o[6:0]
WriteData(0x3c);
WriteComm(0x5c);//src_pchg_st_e[6:0]
WriteData(0x02);
WriteComm(0x5d);//src_pchg_wd_e[6:0]
WriteData(0x3c);
WriteComm(0x5e);//src_pol_sw[7:0]
WriteData(0x1f);
WriteComm(0x60);//src_op_st_o[7:0]
WriteData(0x80);
WriteComm(0x61);//src_op_st_e[7:0]
WriteData(0x3f);
WriteComm(0x62);//src_op_ed_o[9:8] src_op_ed_e[9:8]
WriteData(0x21);
WriteComm(0x63);//src_op_ed_o[7:0]
WriteData(0x07);
WriteComm(0x64);//src_op_ed_e[7:0]
WriteData(0xe0);
WriteComm(0x65);//chopper
WriteData(0x01);//01-A2,02--A1NVu NV3041A-01
//WriteComm(0x67);
//WriteData(0x33);//01
WriteComm(0xca); //avdd_mux_st_o[7:0]
WriteData(0x20);
WriteComm(0xcb); //avdd_mux_ed_o[7:0]
WriteData(0x52);
WriteComm(0xcc); //avdd_mux_st_e[7:0]
WriteData(0x10);
WriteComm(0xcD); //avdd_mux_ed_e[7:0]
WriteData(0x42);
WriteComm(0xD0); //avcl_mux_st_o[7:0]
WriteData(0x20);
WriteComm(0xD1); //avcl_mux_ed_o[7:0]
WriteData(0x52);
WriteComm(0xD2); //avcl_mux_st_e[7:0]
WriteData(0x10);
WriteComm(0xD3); //avcl_mux_ed_e[7:0]
WriteData(0x42);
WriteComm(0xD4); //vgh_mux_st[7:0]
WriteData(0x0a);
WriteComm(0xD5); //vgh_mux_ed[7:0]
WriteData(0x32);
WriteComm(0xe5); //DVDD_TRIM
WriteData(0x05); //1.65 05
WriteComm(0xe6); //ESD_CTRL
WriteData(0x00);
WriteComm(0x6e); //LVD_en
WriteData(0x14);
//gammma 01
WriteComm(0x80); //gam_vrp0 63
WriteData(0x04);
WriteComm(0xA0); //gam_VRN0 63
WriteData(0x00);
WriteComm(0x81); //gam_vrp1 62
WriteData(0x07);
WriteComm(0xA1); //gam_VRN1 62-
WriteData(0x05);
WriteComm(0x82); //gam_vrp2 61
WriteData(0x06);
WriteComm(0xA2); //gam_VRN2 61-NVu NV3041A-01
WriteData(0x04);
WriteComm(0x83); //gam_vrp3 2
WriteData(0x39);
WriteComm(0xA3); //gam_VRN3 2-
WriteData(0x39);
WriteComm(0x84); //gam_vrp4 1
WriteData(0x3a);
WriteComm(0xA4); //gam_VRN4 1-
WriteData(0x3a);
WriteComm(0x85); //gam_vrp5 0
WriteData(0x3f); //2a~39-0.43
WriteComm(0xA5); //gam_VRN5 0-
WriteData(0x3f);
WriteComm(0x86); //gam_prp0 50
WriteData(0x2c); //33
WriteComm(0xA6); //gam_PRN0 50-
WriteData(0x2a); //2a
//WriteComm(0x87); //gam_prp1 14
//WriteData(0x46); //2d
//WriteComm(0xA7); //gam_PRN1 14-
//WriteData(0x44); //2d
WriteComm(0x87); //gam_prp1 14
WriteData(0x43); //2d
WriteComm(0xA7); //gam_PRN1 14-
WriteData(0x47); //2d
WriteComm(0x88); //gam_pkp0 59
WriteData(0x08); //0b
WriteComm(0xA8); //gam_PKN0 59-
WriteData(0x08); //0b
WriteComm(0x89); //gam_pkp1 57
WriteData(0x0f); //14
WriteComm(0xA9); //gam_PKN1 57-
WriteData(0x0f); //14
WriteComm(0x8a); //gam_pkp2 54
WriteData(0x17); //1a
WriteComm(0xAa); //gam_PKN2 54-
WriteData(0x17); //1a
WriteComm(0x8b); //gam_PKP3 44
WriteData(0x10);
WriteComm(0xAb); //gam_PKN3 44-
WriteData(0x10);
WriteComm(0x8c); //gam_PKP4 38
WriteData(0x16);
WriteComm(0xAc); //gam_PKN4 38-
WriteData(0x16);//NVu NV3041A-01
WriteComm(0x8d); //gam_PKP5 32
WriteData(0x14);
WriteComm(0xAd); //gam_PKN5 32-
WriteData(0x14);
WriteComm(0x8e); //gam_PKP6 26
WriteData(0x11); //16
WriteComm(0xAe); //gam_PKN6 26-
WriteData(0x11); //13
WriteComm(0x8f); //gam_PKP7 20
WriteData(0x14); //1c
WriteComm(0xAf); //gam_PKN7 20-
WriteData(0x14); //0a
WriteComm(0x90); //gam_PKP8 10
WriteData(0x06);
WriteComm(0xB0); //gam_PKN8 10-
WriteData(0x06);
WriteComm(0x91); //gam_PKP9 6
WriteData(0x0f);
WriteComm(0xB1); //gam_PKN9 6-
WriteData(0x0f);
WriteComm(0x92); //gam_PKP10 4
WriteData(0x16);
WriteComm(0xB2); //gam_PKN10 4-
WriteData(0x16);
WriteComm(0xff);
WriteData(0x00);
WriteComm(0x11);
WriteComm(0x36);
WriteData(0x00);
system_delay_us(120*1000);
WriteComm(0x29);
system_delay_us(20*1000);
#else
WriteComm(0xF7);
WriteData(0xA9);
WriteData(0x51);
WriteData(0X2C);
WriteData(0X82);
WriteComm(0xC0);
WriteData(0x0F);
WriteData(0x0f);
// VGH = 5VCI VGL = -3VCI
WriteComm(0xC1);
WriteData(0x47);
WriteComm(0xC5);
WriteData(0x00);
WriteData(0x4D);
WriteData(0x80);
WriteComm(0xB1);
WriteData(0xB0);
WriteData(0X11);
WriteComm(0xB1);
WriteData(0xA0);
WriteComm(0xB4);
WriteData(0x02);
WriteComm(0x36);
WriteData(0x28);
WriteComm(0x3A);
WriteData(0x55); //RGB565
WriteComm(0x20);
WriteData(0x00); //IPS
WriteComm(0xE9);
WriteData(0x00);
WriteComm(0xF7);
WriteData(0xA9);
WriteData(0x51);
WriteData(0x2C);
WriteData(0x82);
WriteComm(0xE0);
WriteData(0x00);
WriteData(0x07);
WriteData(0x0B);
WriteData(0x03);
WriteData(0x0F);
WriteData(0x05);
WriteData(0x30);
WriteData(0x56);
WriteData(0x47);
WriteData(0x04);
WriteData(0x0B);
WriteData(0x0A);
WriteData(0x2D);
WriteData(0x37);
WriteData(0x0F);
WriteComm(0xE1);
WriteData(0x00);
WriteData(0x0E);
WriteData(0x13);
WriteData(0x04);
WriteData(0x11);
WriteData(0x07);
WriteData(0x39);
WriteData(0x45);
WriteData(0x50);
WriteData(0x07);
WriteData(0x10);
WriteData(0x0D);
WriteData(0x32);
WriteData(0x36);
WriteData(0x0F);
WriteComm(0x11);
system_delay_us(120*1000);
// Delay(480);
WriteComm(0x29);
#endif
// LCD_READ_DATA(0x36);
// for(uint32_t i=0;i<pixel_size;i++)
// {
// color_buffer[i]=0xf800;
// }
// nv3041a_set_window(0,240-1,0,320-1);
// __PARALLEL_CS_SET(hparallel.PARALLELx);
// /* writer data */
// Parallel_write_data(&hparallel,(uint32_t *)&color_buffer,(pixel_size));
// __PARALLEL_CS_RELEASE(hparallel.PARALLELx);
// system_delay_us(2000*1000);
#if 0
for(uint32_t i=0;i<pixel_size;i++)
{
color_buffer[i]=0xf800;
}
nv3041a_set_window(0,100-1,0,100-1);
__PARALLEL_CS_SET(hparallel.PARALLELx);
/* writer data */
Parallel_write_data(&hparallel,(uint32_t *)&color_buffer,(pixel_size));
system_delay_us(100);
__PARALLEL_CS_RELEASE(hparallel.PARALLELx);
system_delay_us(1000*1000);
#if 0
extern uint32_t *user_get_display_framebuffer(void);
uint16_t *buf = (uint16_t*)user_get_display_framebuffer();
nv3041a_set_window(0,100-1,0,100-1);
for(uint32_t i=0;i<pixel_size;i++)
{
color_buffer[i]=0x001f;
}
nv3041a_display_dma(pixel_size,16,color_buffer);
system_delay_us(2000*1000);
uint16_t color_buf[16]={
0xf800,0x001f,0x01e0,0xffff,0x0fff,
};
static uint8_t index=0;
while(1)
{
for(uint32_t i=0;i<480*272;i++)
{
buf[i]=color_buf[index];
}
++index;
index%=4;
nv3041a_set_window(0,480-1,0,272-1);
nv3041a_display_dma((480*272),16,buf);
system_delay_us(2000*1000);
if(index==0)break;
}
for(uint32_t i=0;i<480*272;i++)
{
buf[i]=0xf800;
}
nv3041a_set_window(0,480-1,0,272-1);
nv3041a_display_dma((480*272),16,buf);
system_delay_us(2000*1000);
#endif
// LCD_Fill(0,0,240,320,0x001f);
// system_delay_us(2000*1000);
// LCD_Fill(0,0,240,320,0x01e0);
// system_delay_us(2000*1000);
// LCD_Fill(0,0,240,320,0xffff);
printf("LCD_Fill\r\n");
#endif
}

View File

@ -0,0 +1,14 @@
#ifndef __DRIVER_NV3041A_H
#define __DRIVER_NV3041A_H
#include <stdint.h>
void nv3041a_init(void);
void nv3041a_display_dma_isr(void);
void nv3041a_display_dma(uint32_t pixel_count, uint8_t pixel_width, void *data);
void nv3041a_set_window(uint16_t x_s, uint16_t x_e, uint16_t y_s, uint16_t y_e);
void nv3041a_display(uint32_t pixel_count, uint8_t pixel_width, void *data);
#endif // __DRIVER_SH8601A_H

View File

@ -0,0 +1,201 @@
/*
******************************************************************************
* @file RGB_demo.c
* @author FreqChip Firmware Team
* @version V1.0.0
* @date 2023
* @brief RGB interface module Demo.
******************************************************************************
* @attention
*
* Copyright (c) 2023 FreqChip.
* All rights reserved.
******************************************************************************
*/
#include "driver_nv3047_rgb.h"
#if (BOARD_SEL == BOARD_EVB_FR3092E_RGB)
static GPIO_InitTypeDef GPIO_Handle;
PARALLEL_HandTypeDef hparallel;
SPI_HandleTypeDef spi_handle;
DMA_HandleTypeDef dma_handle;
DMA_HandleTypeDef dma1_handle;
struct_RGB_TypeDef_t rgb_handle;
unsigned char *coply = NULL;
void timer0_irq(void);
/************************************************************************************
* @fn rgb_display_controller_init
*
* @brief rgb_display_controller_init
*
*/
void rgb_display_controller_init(void)
{
/* init parallel CLOCK */
__SYSTEM_PARALLEL_CLK_ENABLE();
__SYSTEM_PARALLEL_CLK_SELECT_SPLL();
__SYSTEM_GPIOA_CLK_ENABLE();
__SYSTEM_GPIOB_CLK_ENABLE();
__SYSTEM_GPIOC_CLK_ENABLE();
__SYSTEM_GPIOD_CLK_ENABLE();
__SYSTEM_DMA0_CLK_ENABLE();
__SYSTEM_DMA1_CLK_ENABLE();
__SYSTEM_TIMER0_CLK_ENABLE();
//__SYSTEM_SPI_MASTER1_X8_CLK_ENABLE();
__SYSTEM_SPI_MASTER0_X8_CLK_ENABLE();
printf("parallel clock:%d\r\n", system_get_peripheral_clock( PER_CLK_PARALLEL));
/* RGB io init */
/*
D0~D15 PC0~15
DCLK PB13
*/
GPIO_Handle.Alternate = GPIO_FUNCTION_8;
GPIO_Handle.Mode = GPIO_MODE_AF_PP;
GPIO_Handle.Pin = RGB565_LCD_DATA_GPIO;
GPIO_Handle.Pull = GPIO_PULLUP;
gpio_init(RGB565_LCD_DATA_PORT, &GPIO_Handle);
GPIO_Handle.Alternate = GPIO_FUNCTION_8;
GPIO_Handle.Mode = GPIO_MODE_AF_PP;
GPIO_Handle.Pin = RGB565_LCD_DCLK_GPIO;
GPIO_Handle.Pull = GPIO_PULLUP;
gpio_init(RGB565_LCD_DCLK_PORT, &GPIO_Handle);
GPIO_Handle.Alternate = GPIO_FUNCTION_8;
GPIO_Handle.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_Handle.Pin = RGB565_LCD_VSYNC_GPIO;
GPIO_Handle.Pull = GPIO_PULLUP;
gpio_init(RGB565_LCD_VSYNC_PORT, &GPIO_Handle);
GPIO_Handle.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_Handle.Pin = RGB565_LCD_HSYNC_GPIO;
GPIO_Handle.Pull = GPIO_PULLUP;
gpio_init(RGB565_LCD_HSYNC_PORT, &GPIO_Handle);
GPIO_Handle.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_Handle.Pin = RGB565_LCD_DE_EN_GPIO;
GPIO_Handle.Pull = GPIO_PULLUP;
gpio_init(RGB565_LCD_DE_EN_PORT, &GPIO_Handle);
GPIO_Handle.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_Handle.Pin = RGB565_LCD_RESET_GPIO;
GPIO_Handle.Pull = GPIO_PULLUP;
gpio_init(RGB565_LCD_RESET_PORT, &GPIO_Handle);
GPIO_Handle.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_Handle.Pin = GPIO_PIN_13;
GPIO_Handle.Pull = GPIO_PULLUP;
gpio_init(GPIOD, &GPIO_Handle);
rgb_lcd_reset_release();
/* backlight */
GPIO_Handle.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_Handle.Pin = RGB565_LCD_BACKLIGHT_GPIO;
GPIO_Handle.Pull = GPIO_PULLUP;
gpio_init(RGB565_LCD_BACKLIGHT_PORT, &GPIO_Handle);
rgb_lcd_backlight_set();
rgb_lcd_disp_set();//Display control / standby mode selection. Internal pull low.DISP = “Low” : Standby.DISP = “High” : Normal display.
system_delay_us(1000 * 20);
#ifdef RGB56_LCD_INIT_CONFIG
/* SPI CS */
GPIO_Handle.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_Handle.Pin = RGB565_LCD_SPI_CS_GPIO;
GPIO_Handle.Pull = GPIO_PULLUP;
gpio_init(RGB565_LCD_SPI_CS_PORT, &GPIO_Handle);
/* SPI io init */
// B0,B2 B3
GPIO_Handle.Alternate = GPIO_FUNCTION_7;
GPIO_Handle.Mode = GPIO_MODE_AF_PP;
GPIO_Handle.Pin = RGB565_LCD_SPI_CLK_GPIO|RGB565_LCD_SPI_MOSI_GPIO|RGB565_LCD_SPI_MISO_GPIO;
GPIO_Handle.Pull = GPIO_PULLUP;
gpio_init(RGB565_LCD_SPI_CLK_PORT, &GPIO_Handle);
/* SPI init */
spi_handle.SPIx = SPIMX8_0;
spi_handle.Init.Work_Mode = SPI_WORK_MODE_3;
spi_handle.Init.Frame_Size = SPI_FRAME_SIZE_9BIT;
spi_handle.Init.BaudRate_Prescaler = 100;
spi_handle.Init.TxFIFOEmpty_Threshold = 0;
spi_handle.Init.RxFIFOFull_Threshold = 0;
spi_master_init(&spi_handle);
#endif
/* PARALLEL Init */
hparallel.PARALLELx = PARALLEL0;
hparallel.Init.DataBusSelect = DATA_BUS_16_BIT;
hparallel.Init.ParallelMode = MODE_6800;
hparallel.PARALLELx->DATA_CFG.DATA_TRANS_SEQ_0 = 0;
hparallel.PARALLELx->DATA_CFG.DATA_TRANS_SEQ_1 = 1;
hparallel.PARALLELx->DATA_CFG.DATA_TRANS_SEQ_2 = 2;
hparallel.PARALLELx->DATA_CFG.DATA_TRANS_SEQ_3 = 3;
hparallel.Init.ReadClock = WDCLK_DIV_4;
hparallel.Init.WriteClock = WDCLK_DIV_2;
parallel_init(&hparallel);
hparallel.PARALLELx->CRM.WR_L_LEN = 2;
hparallel.PARALLELx->CRM.WR_H_LEN = 2;
__PARALLEL_CS_SET(hparallel.PARALLELx);
/* DMA Init */
system_dmac_request_id_config(PARALLEL_INTERFACE,DMA0_REQUEST_ID_3);
dma_handle.DMAx = DMA0;
dma_handle.Channel = DMA_Channel2;
dma_handle.Init.Data_Flow = DMA_M2P_DMAC;
dma_handle.Init.Request_ID = DMA0_REQUEST_ID_3;
dma_handle.Init.Source_Master_Sel = DMA_AHB_MASTER_3;
dma_handle.Init.Desination_Master_Sel = DMA_AHB_MASTER_1;
dma_handle.Init.Source_Inc = DMA_ADDR_INC_INC;
dma_handle.Init.Desination_Inc = DMA_ADDR_INC_NO_CHANGE;
dma_handle.Init.Source_Width = DMA_TRANSFER_WIDTH_32;
dma_handle.Init.Desination_Width = DMA_TRANSFER_WIDTH_32;
dma_handle.Init.Source_Burst_Len = DMA_BURST_LEN_16;
dma_handle.Init.Desination_Burst_Len = DMA_BURST_LEN_16;
dma_init(&dma_handle);
}
/************************************************************************************
* @fn rgb_display_init
*
* @brief rgb_display_init
*
*/
void rgb_display_init(void* buffer)
{
coply = buffer;
/* rgb init */
rgb_init();
NVIC_ClearPendingIRQ(TIMER0_IRQn);
NVIC_EnableIRQ(TIMER0_IRQn);
NVIC_ClearPendingIRQ(DMA0_IRQn);
NVIC_EnableIRQ(DMA0_IRQn);
rgb_display_start(Timer0, &rgb_handle, 2, coply);
printf("%s:%d\r\n", __func__, __LINE__);
}
void timer0_irq(void)
{
rgb_timer_IRQHandler(Timer0, &rgb_handle);
}
__RAM_CODE void rgb_display_dma_irq(void)
{
if (dma_get_tfr_Status(&dma_handle))
{
rgb_dma_IRQHandler(&rgb_handle);
dma_clear_tfr_Status(&dma_handle);
}
}
#endif

View File

@ -0,0 +1,91 @@
#ifndef __DRIVER_NV3047_RGB_H__
#define __DRIVER_NV3047_RGB_H__
#include "fr30xx.h"
#include "app_config.h"
#include "rgb565.h"
#define RGB_ROW 480
#define RGB_COLUMN 272
#define RGB565_LCD_DCLK_PORT GPIOB
#define RGB565_LCD_DCLK_GPIO GPIO_PIN_14
#define RGB565_LCD_VSYNC_PORT GPIOB
#define RGB565_LCD_VSYNC_GPIO GPIO_PIN_13
#define RGB565_LCD_HSYNC_PORT GPIOB
#define RGB565_LCD_HSYNC_GPIO GPIO_PIN_15
#define RGB565_LCD_DISP_PORT GPIOD
#define RGB565_LCD_DISP_GPIO GPIO_PIN_12
#define RGB565_LCD_DE_EN_PORT GPIOB
#define RGB565_LCD_DE_EN_GPIO GPIO_PIN_12
#define RGB565_LCD_DATA_PORT GPIOC
#define RGB565_LCD_DATA_GPIO 0xFFFF //GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3|GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7
#define RGB565_LCD_RESET_PORT GPIOA
#define RGB565_LCD_RESET_GPIO GPIO_PIN_4
#define RGB565_LCD_BACKLIGHT_PORT GPIOA
#define RGB565_LCD_BACKLIGHT_GPIO GPIO_PIN_4
#define RGB565_LCD_SPI_SEL SPIM0
#ifdef RGB565_LCD_TE_EN
#define RGB565_LCD_TE_PORT GPIO_B
#define RGB565_LCD_TE_GPIO GPIO_PIN_7
#endif
//#define RGB56_LCD_INIT_CONFIG
#ifdef RGB56_LCD_INIT_CONFIG
#define RGB565_LCD_SPI_CS_PORT GPIOD
#define RGB565_LCD_SPI_CS_GPIO GPIO_PIN_12
#define RGB565_LCD_SPI_CLK_PORT GPIOB
#define RGB565_LCD_SPI_CLK_GPIO GPIO_PIN_0
#define RGB565_LCD_SPI_MOSI_PORT GPIOB
#define RGB565_LCD_SPI_MOSI_GPIO GPIO_PIN_2
#define RGB565_LCD_SPI_MISO_PORT GPIOB
#define RGB565_LCD_SPI_MISO_GPIO GPIO_PIN_3
#define rgb_spi_cs_set() gpio_write_pin(RGB565_LCD_SPI_CS_PORT,RGB565_LCD_SPI_CS_GPIO,GPIO_PIN_SET)
#define rgb_spi_cs_release() gpio_write_pin(RGB565_LCD_SPI_CS_PORT,RGB565_LCD_SPI_CS_GPIO,GPIO_PIN_CLEAR)
#endif
/* signal drive*/
#define rgb_lcd_enable_set() gpio_write_pin(RGB565_LCD_DE_EN_PORT,RGB565_LCD_DE_EN_GPIO,GPIO_PIN_SET)
#define rgb_lcd_enable_release() gpio_write_pin(RGB565_LCD_DE_EN_PORT,RGB565_LCD_DE_EN_GPIO,GPIO_PIN_CLEAR)
#define rgb_lcd_vsync_set() gpio_write_pin(RGB565_LCD_VSYNC_PORT,RGB565_LCD_VSYNC_GPIO,GPIO_PIN_SET)
#define rgb_lcd_vsync_release() gpio_write_pin(RGB565_LCD_VSYNC_PORT,RGB565_LCD_VSYNC_GPIO,GPIO_PIN_CLEAR)
#define rgb_lcd_hsync_set() gpio_write_pin(RGB565_LCD_HSYNC_PORT,RGB565_LCD_HSYNC_GPIO,GPIO_PIN_SET)
#define rgb_lcd_hsync_release() gpio_write_pin(RGB565_LCD_HSYNC_PORT,RGB565_LCD_HSYNC_GPIO,GPIO_PIN_CLEAR)
#define rgb_lcd_reset_set() gpio_write_pin(RGB565_LCD_RESET_PORT,RGB565_LCD_RESET_GPIO,GPIO_PIN_SET)
#define rgb_lcd_reset_release() gpio_write_pin(RGB565_LCD_RESET_PORT,RGB565_LCD_RESET_GPIO,GPIO_PIN_CLEAR)
#define rgb_lcd_disp_set() gpio_write_pin(RGB565_LCD_DISP_PORT,RGB565_LCD_DISP_GPIO,GPIO_PIN_SET)
#define rgb_lcd_disp_release() gpio_write_pin(RGB565_LCD_DISP_PORT,RGB565_LCD_DISP_GPIO,GPIO_PIN_CLEAR)
#define rgb_lcd_backlight_set() gpio_write_pin(RGB565_LCD_BACKLIGHT_PORT,RGB565_LCD_BACKLIGHT_GPIO,GPIO_PIN_SET)
#define rgb_lcd_backlight_release() gpio_write_pin(RGB565_LCD_BACKLIGHT_PORT,RGB565_LCD_BACKLIGHT_GPIO,GPIO_PIN_CLEAR)
/* Exported functions --------------------------------------------------------*/
/* rgb_demo */
void rgb_display_init(void* buffer);
void rgb_display_controller_init(void);
__RAM_CODE void rgb_display_dma_irq(void);
#endif

View File

@ -0,0 +1,526 @@
#include "driver_display.h"
#include "driver_sh8601a.h"
#define SH8601A_MAX_PARA_COUNT (300)
#define SH8601A_QSPI_INST_CMD_WRITE (0x02)
#define SH8601A_QSPI_INST_CMD_READ (0x03)
#define SH8601A_QSPI_INST_1WIRE_PIXEL_WRITE (0x02)
#define SH8601A_QSPI_INST_4WIRE_PIXEL_WRITE_TYPE1 (0x32)
#define SH8601A_QSPI_INST_4WIRE_PIXEL_WRITE_TYPE2 (0x12)
#define SH8601A_QSPI_SEQ_FINISH_CODE (0x00)
typedef struct _SH8601A_CMD_DESC {
uint8_t instruction;
uint8_t index;
uint16_t delay;
uint16_t wordcount;
uint8_t payload[SH8601A_MAX_PARA_COUNT];
} SH8601A_CMD_DESC;
const SH8601A_CMD_DESC SH8601A_PRE_OTP_POWERON_SEQ_CMD[] = {
{SH8601A_QSPI_INST_CMD_WRITE, 0xC0, 1, 2, {0x5A, 0x5A}},
{SH8601A_QSPI_INST_CMD_WRITE, 0xC1, 1, 2, {0x5A, 0x5A}},
// {SH8601A_QSPI_INST_CMD_WRITE, 0xE4, 1, 1, {0x01}},
// {SH8601A_QSPI_INST_CMD_WRITE, 0x90, 1, 6, {0x33, 0x00, 0xC6, 0x01, 0xC6, 0x01}},
// {SH8601A_QSPI_INST_CMD_WRITE, 0x91, 1, 20, {0x65, 0x00, 0x00, 0xE2, 0x00, 0x00, 0x00, 0xE2, 0x00, 0xE2, 0x00, 0xE2, 0x00, 0xE2, 0x00, 0x03, 0x00, 0x00, 0xFF, 0x11}},
// {SH8601A_QSPI_INST_CMD_WRITE, 0x92, 1, 20, {0x61, 0xE3, 0x00, 0xC5, 0x01, 0x00, 0x00, 0xE2, 0x00, 0xE3, 0x00, 0xE2, 0x00, 0xE2, 0x00, 0x03, 0x00, 0x00, 0xFF, 0x22}},
// {SH8601A_QSPI_INST_CMD_WRITE, 0x93, 1, 20, {0x69, 0x00, 0x00, 0xE2, 0x00, 0xE3, 0x00, 0xC5, 0x01, 0xE2, 0x00, 0xE3, 0x00, 0xE2, 0x00, 0x03, 0x00, 0x00, 0xFF, 0x33}},
// {SH8601A_QSPI_INST_CMD_WRITE, 0x94, 1, 20, {0x6D, 0xE3, 0x00, 0xC5, 0x01, 0xE3, 0x00, 0xC5, 0x01, 0xE3, 0x00, 0xE3, 0x00, 0xE2, 0x00, 0x03, 0x00, 0x00, 0xFF, 0x33}},
// {SH8601A_QSPI_INST_CMD_WRITE, 0x9D, 1, 168, {0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x03, 0x03, 0x03, 0x03, 0x04, 0x04, 0x04, 0x06, 0x0C, 0x12, 0x18, 0x1E, 0x24, 0x2A, 0x30, 0x36, 0x3C, 0x42, 0x48, 0x4E, 0x54, 0x5A, 0x60, 0x09, 0x0D, 0x12, 0x16, 0x1B, 0x24, 0x2D, 0x36, 0x3F, 0x5A, 0x63, 0x6C, 0x75, 0x7E, 0x87, 0x90, 0x05, 0x0A, 0x0F, 0x14, 0x19, 0x1E, 0x23, 0x28, 0x2D, 0x32, 0x37, 0x3C, 0x41, 0x46, 0x4B, 0x50, 0x0F, 0x1E, 0x2D, 0x3C, 0x4B, 0x5A, 0x69, 0x78, 0x87, 0x96, 0xA5, 0xB4, 0xC3, 0xD2, 0xE1, 0xF5, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0, 0x80, 0x60, 0x40, 0x20, 0x00, 0x00, 0x00, 0x00}},
// {SH8601A_QSPI_INST_CMD_WRITE, 0x9E, 1, 12, {0x3B, 0x00, 0x71, 0x00, 0xA3, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00}},
// {SH8601A_QSPI_INST_CMD_WRITE, 0xB1, 1, 51, {0x00, 0xC6, 0x01, 0xC6, 0x01, 0x05, 0x00, 0x05, 0x00, 0xA7, 0x00, 0xA7, 0x00, 0x05, 0x00, 0x05, 0x00, 0xA7, 0x00, 0xA7, 0x00, 0x00, 0x52, 0x00, 0x64, 0x00, 0x8A, 0x00, 0xB0, 0x00, 0x52, 0x00, 0x64, 0x00, 0x8A, 0x00, 0xB0, 0x00, 0x00, 0x10, 0x00, 0x00, 0xDF, 0x01, 0x00, 0x00, 0xDF, 0x01, 0x00, 0x00, 0x00}},
// {SH8601A_QSPI_INST_CMD_WRITE, 0xB2, 1, 68, {0x19, 0x14, 0x19, 0x14, 0x01, 0xEE, 0x02, 0x30, 0x02, 0xE4, 0x02, 0x3F, 0x02, 0x06, 0x76, 0x78, 0xE8, 0x04, 0x06, 0x00, 0x00, 0x31, 0x16, 0x15, 0x3D, 0x67, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF5, 0x10, 0xFF, 0xFF, 0xE0, 0xAA, 0xAA, 0xFF, 0xFF, 0x24, 0x14, 0x04, 0x14, 0x13, 0x14, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04}},
// {SH8601A_QSPI_INST_CMD_WRITE, 0xB3, 1, 44, {0x00, 0x0D, 0x00, 0x00, 0x0E, 0x00, 0x00, 0x0F, 0x00, 0x00, 0x00, 0x01, 0x00, 0x03, 0x1F, 0x02, 0x00, 0x0B, 0x00, 0x0C, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x12, 0x05, 0x00, 0x06, 0x13, 0x04, 0x00, 0x08, 0x15, 0x09, 0x00, 0x07}},
// {SH8601A_QSPI_INST_CMD_WRITE, 0xB4, 1, 65, {0x09, 0x02, 0x00, 0x00, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x40, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x03, 0x47, 0x8B, 0x30, 0x74, 0xB8, 0x12, 0x56, 0x9A, 0x21, 0x65, 0xA9, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x56, 0x9A, 0x21, 0x65, 0xA9, 0x03, 0x47, 0x8B, 0x30, 0x74, 0xB8, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00}},
// {SH8601A_QSPI_INST_CMD_WRITE, 0xB5, 1, 58, {0x4C, 0x09, 0x09, 0x09, 0x49, 0x40, 0x00, 0x01, 0x21, 0x00, 0x00, 0x00, 0x21, 0x00, 0x14, 0x03, 0x21, 0x00, 0x14, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x02, 0x00, 0x00, 0x03, 0x02, 0x52, 0x00, 0x21, 0x00, 0x21, 0x00, 0x14, 0x03, 0x00, 0x00, 0x00, 0x00, 0x21, 0x00, 0x14, 0x03, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x03, 0x00}},
// {SH8601A_QSPI_INST_CMD_WRITE, 0xB6, 1, 26, {0x00, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x40, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E, 0x1E}},
// {SH8601A_QSPI_INST_CMD_WRITE, 0xB7, 1, 51, {0x0C, 0x00, 0x01, 0x21, 0x00, 0x00, 0x00, 0x21, 0x00, 0x14, 0x03, 0x21, 0x00, 0x14, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x02, 0x00, 0x00, 0x03, 0x02, 0x52, 0x00, 0x21, 0x00, 0x21, 0x00, 0x14, 0x03, 0x00, 0x00, 0x00, 0x00, 0x21, 0x00, 0x14, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
// {SH8601A_QSPI_INST_CMD_WRITE, 0xB8, 1, 95, {0x00, 0x67, 0x31, 0x22, 0x22, 0x22, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x22, 0x22, 0x22, 0x22, 0x00, 0x00, 0x00, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x00, 0x00, 0x00, 0x22, 0x22, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x22, 0x22, 0x00, 0x22, 0x00, 0x22, 0x22, 0x22, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x22, 0x22, 0x22, 0x22, 0x00, 0x00, 0x00, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x00, 0x00, 0x00, 0x22, 0x22, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x22, 0x22, 0x00, 0x22, 0x00, 0x00, 0x00}},
// {SH8601A_QSPI_INST_CMD_WRITE, 0xBB, 1, 19, {0x01, 0x02, 0x07, 0x01, 0x46, 0x46, 0x46, 0xD9, 0x00, 0xAA, 0x00, 0x7D, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0x00}},
// {SH8601A_QSPI_INST_CMD_WRITE, 0xBD, 1, 22, {0x01, 0x00, 0x00, 0x64, 0x00, 0x62, 0x00, 0x04, 0x01, 0x15, 0x00, 0x00, 0x00, 0x00, 0x1D, 0x05, 0x00, 0x10, 0x16, 0x16, 0x00, 0x00}},
// {SH8601A_QSPI_INST_CMD_WRITE, 0xBE, 1, 106, {0x4B, 0x00, 0x69, 0x00, 0x87, 0x00, 0xA5, 0x00, 0xC3, 0x00, 0xE1, 0x00, 0xFF, 0x00, 0x7F, 0x00, 0xFF, 0x00, 0x64, 0x00, 0xAA, 0x00, 0x19, 0x00, 0x32, 0x00, 0x4B, 0x00, 0x4B, 0x00, 0x4B, 0x00, 0x4B, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x01, 0x01, 0x15, 0x00, 0x00, 0x00, 0x00, 0x8A, 0x00, 0x26, 0x01, 0xD0, 0x01, 0xD0, 0x01, 0xD0, 0x01, 0xD0, 0x01, 0xD0, 0x01, 0xD0, 0x01, 0x1C, 0x00, 0x64, 0x00, 0x00, 0x00, 0x89, 0x00, 0xD0, 0x01, 0xD0, 0x01, 0x4B, 0x00, 0x64, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
// {SH8601A_QSPI_INST_CMD_WRITE, 0xBF, 1, 35, {0x03, 0xF0, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x20, 0x00, 0x7F, 0x00, 0x7F, 0x00, 0x7F, 0x00, 0x7F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
// {SH8601A_QSPI_INST_CMD_WRITE, 0xC2, 1, 136, {0x00, 0x00, 0x84, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xDD, 0x00, 0x97, 0x00, 0x83, 0x00, 0xEE, 0x00, 0xA8, 0x00, 0x94, 0x00, 0x16, 0x01, 0xCF, 0x00, 0xBC, 0x00, 0x3B, 0x01, 0xF4, 0x00, 0xE1, 0x00, 0x61, 0x01, 0x12, 0x01, 0x08, 0x01, 0x94, 0x01, 0x46, 0x01, 0x41, 0x01, 0xB7, 0x01, 0x6D, 0x01, 0x6B, 0x01, 0xDE, 0x01, 0x93, 0x01, 0x9C, 0x01, 0xF7, 0x01, 0xAF, 0x01, 0xBB, 0x01, 0x27, 0x02, 0xE1, 0x01, 0xFC, 0x01, 0x52, 0x02, 0x0F, 0x02, 0x34, 0x02, 0x77, 0x02, 0x36, 0x02, 0x65, 0x02, 0xBE, 0x02, 0x7C, 0x02, 0xB9, 0x02, 0xFA, 0x02, 0xBA, 0x02, 0x08, 0x03, 0x31, 0x03, 0xF4, 0x02, 0x4F, 0x03, 0x63, 0x03, 0x29, 0x03, 0x8C, 0x03, 0x9E, 0x03, 0x5F, 0x03, 0xD1, 0x03, 0xFD, 0x03, 0xBC, 0x03, 0x4A, 0x04, 0x6E, 0x04, 0x28, 0x04, 0xC4, 0x04, 0xD1, 0x04, 0x91, 0x04, 0x49, 0x05, 0x3D, 0x05, 0xF1, 0x04, 0xC1, 0x05}},
// {SH8601A_QSPI_INST_CMD_WRITE, 0xC3, 1, 136, {0x00, 0x00, 0xFF, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xDD, 0x00, 0x97, 0x00, 0x83, 0x00, 0xEE, 0x00, 0xA8, 0x00, 0x94, 0x00, 0x16, 0x01, 0xCF, 0x00, 0xBC, 0x00, 0x3B, 0x01, 0xF4, 0x00, 0xE1, 0x00, 0x61, 0x01, 0x12, 0x01, 0x08, 0x01, 0x94, 0x01, 0x46, 0x01, 0x41, 0x01, 0xB7, 0x01, 0x6D, 0x01, 0x6B, 0x01, 0xDE, 0x01, 0x93, 0x01, 0x9C, 0x01, 0xF7, 0x01, 0xAF, 0x01, 0xBB, 0x01, 0x27, 0x02, 0xE1, 0x01, 0xFC, 0x01, 0x52, 0x02, 0x0F, 0x02, 0x34, 0x02, 0x77, 0x02, 0x36, 0x02, 0x65, 0x02, 0xBE, 0x02, 0x7C, 0x02, 0xB9, 0x02, 0xFA, 0x02, 0xBA, 0x02, 0x08, 0x03, 0x31, 0x03, 0xF4, 0x02, 0x4F, 0x03, 0x63, 0x03, 0x29, 0x03, 0x8C, 0x03, 0x9E, 0x03, 0x5F, 0x03, 0xD1, 0x03, 0xFD, 0x03, 0xBC, 0x03, 0x4A, 0x04, 0x6E, 0x04, 0x28, 0x04, 0xC4, 0x04, 0xD1, 0x04, 0x91, 0x04, 0x49, 0x05, 0x3D, 0x05, 0xF1, 0x04, 0xC1, 0x05}},
// {SH8601A_QSPI_INST_CMD_WRITE, 0xC5, 1, 136, {0x00, 0x00, 0x6A, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x00, 0x37, 0x00, 0x32, 0x00, 0x24, 0x01, 0xBD, 0x00, 0xAC, 0x00, 0x3D, 0x01, 0xD6, 0x00, 0xC5, 0x00, 0x50, 0x01, 0xE9, 0x00, 0xD8, 0x00, 0x66, 0x01, 0xFF, 0x00, 0xEE, 0x00, 0x95, 0x01, 0x2E, 0x01, 0x1E, 0x01, 0xB8, 0x01, 0x50, 0x01, 0x44, 0x01, 0xDB, 0x01, 0x73, 0x01, 0x68, 0x01, 0xF5, 0x01, 0x8E, 0x01, 0x84, 0x01, 0x21, 0x02, 0xBE, 0x01, 0xBA, 0x01, 0x4B, 0x02, 0xEB, 0x01, 0xEE, 0x01, 0x6B, 0x02, 0x0E, 0x02, 0x18, 0x02, 0xA9, 0x02, 0x51, 0x02, 0x6C, 0x02, 0xE2, 0x02, 0x8B, 0x02, 0xB2, 0x02, 0x0B, 0x03, 0xB7, 0x02, 0xE7, 0x02, 0x34, 0x03, 0xE5, 0x02, 0x1F, 0x03, 0x57, 0x03, 0x0A, 0x03, 0x4B, 0x03, 0xA3, 0x03, 0x52, 0x03, 0xA9, 0x03, 0xEB, 0x03, 0x9A, 0x03, 0x00, 0x04, 0x2F, 0x04, 0xDC, 0x03, 0x5A, 0x04, 0x64, 0x04, 0x14, 0x04, 0x9E, 0x04}},
// {SH8601A_QSPI_INST_CMD_WRITE, 0xC6, 1, 136, {0x00, 0x00, 0x6A, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x00, 0x4D, 0x00, 0x46, 0x00, 0x28, 0x01, 0xC1, 0x00, 0xB0, 0x00, 0x42, 0x01, 0xDB, 0x00, 0xCA, 0x00, 0x5C, 0x01, 0xF5, 0x00, 0xE4, 0x00, 0x77, 0x01, 0x10, 0x01, 0xFF, 0x00, 0xA9, 0x01, 0x42, 0x01, 0x35, 0x01, 0xCE, 0x01, 0x67, 0x01, 0x5B, 0x01, 0xF1, 0x01, 0x8A, 0x01, 0x80, 0x01, 0x0C, 0x02, 0xA7, 0x01, 0xA0, 0x01, 0x3D, 0x02, 0xDD, 0x01, 0xDD, 0x01, 0x66, 0x02, 0x08, 0x02, 0x11, 0x02, 0x8C, 0x02, 0x33, 0x02, 0x45, 0x02, 0xD0, 0x02, 0x79, 0x02, 0x9D, 0x02, 0x04, 0x03, 0xB0, 0x02, 0xDE, 0x02, 0x33, 0x03, 0xE5, 0x02, 0x1F, 0x03, 0x5D, 0x03, 0x11, 0x03, 0x53, 0x03, 0x89, 0x03, 0x3C, 0x03, 0x8A, 0x03, 0xDE, 0x03, 0x8D, 0x03, 0xF1, 0x03, 0x2F, 0x04, 0xDC, 0x03, 0x59, 0x04, 0x6F, 0x04, 0x20, 0x04, 0xAC, 0x04, 0xB3, 0x04, 0x64, 0x04, 0xFF, 0x04}},
// {SH8601A_QSPI_INST_CMD_WRITE, 0xC7, 1, 136, {0x00, 0x00, 0x6A, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9A, 0x00, 0x63, 0x00, 0x5A, 0x00, 0x2C, 0x01, 0xC5, 0x00, 0xB4, 0x00, 0x48, 0x01, 0xE1, 0x00, 0xD0, 0x00, 0x65, 0x01, 0xFE, 0x00, 0xED, 0x00, 0x87, 0x01, 0x20, 0x01, 0x0F, 0x01, 0xB5, 0x01, 0x4E, 0x01, 0x41, 0x01, 0xE5, 0x01, 0x7D, 0x01, 0x72, 0x01, 0x01, 0x02, 0x9B, 0x01, 0x93, 0x01, 0x1D, 0x02, 0xBA, 0x01, 0xB6, 0x01, 0x55, 0x02, 0xF5, 0x01, 0xFB, 0x01, 0x7C, 0x02, 0x21, 0x02, 0x2F, 0x02, 0xA4, 0x02, 0x4C, 0x02, 0x65, 0x02, 0xF0, 0x02, 0x99, 0x02, 0xC1, 0x02, 0x20, 0x03, 0xCE, 0x02, 0x04, 0x03, 0x51, 0x03, 0x04, 0x03, 0x44, 0x03, 0x83, 0x03, 0x36, 0x03, 0x82, 0x03, 0xB5, 0x03, 0x62, 0x03, 0xBF, 0x03, 0x0F, 0x04, 0xBD, 0x03, 0x2F, 0x04, 0x5C, 0x04, 0x0C, 0x04, 0x94, 0x04, 0xAB, 0x04, 0x5C, 0x04, 0xF5, 0x04, 0xFA, 0x04, 0xA8, 0x04, 0x50, 0x05}},
// {SH8601A_QSPI_INST_CMD_WRITE, 0xC8, 1, 136, {0x00, 0x00, 0x6A, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xBC, 0x00, 0x79, 0x00, 0x6E, 0x00, 0x2F, 0x01, 0xC8, 0x00, 0xB7, 0x00, 0x4D, 0x01, 0xE6, 0x00, 0xD5, 0x00, 0x6D, 0x01, 0x06, 0x01, 0xF5, 0x00, 0x8F, 0x01, 0x28, 0x01, 0x18, 0x01, 0xC1, 0x01, 0x5A, 0x01, 0x4E, 0x01, 0xEF, 0x01, 0x87, 0x01, 0x7D, 0x01, 0x0F, 0x02, 0xAB, 0x01, 0xA4, 0x01, 0x2F, 0x02, 0xCD, 0x01, 0xCB, 0x01, 0x63, 0x02, 0x04, 0x02, 0x0D, 0x02, 0x91, 0x02, 0x38, 0x02, 0x4A, 0x02, 0xBC, 0x02, 0x65, 0x02, 0x86, 0x02, 0x01, 0x03, 0xAC, 0x02, 0xD9, 0x02, 0x39, 0x03, 0xEA, 0x02, 0x25, 0x03, 0x6E, 0x03, 0x23, 0x03, 0x69, 0x03, 0xA4, 0x03, 0x53, 0x03, 0xAA, 0x03, 0xD7, 0x03, 0x85, 0x03, 0xE8, 0x03, 0x37, 0x04, 0xE5, 0x03, 0x64, 0x04, 0x8A, 0x04, 0x3C, 0x04, 0xCF, 0x04, 0xE0, 0x04, 0x8F, 0x04, 0x32, 0x05, 0x30, 0x05, 0xDF, 0x04, 0x92, 0x05}},
// {SH8601A_QSPI_INST_CMD_WRITE, 0xC9, 1, 136, {0x00, 0x00, 0x6A, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xDE, 0x00, 0x8F, 0x00, 0x82, 0x00, 0x33, 0x01, 0xCC, 0x00, 0xBB, 0x00, 0x52, 0x01, 0xEB, 0x00, 0xDA, 0x00, 0x76, 0x01, 0x0F, 0x01, 0xFE, 0x00, 0x98, 0x01, 0x31, 0x01, 0x22, 0x01, 0xCD, 0x01, 0x65, 0x01, 0x5A, 0x01, 0xF8, 0x01, 0x92, 0x01, 0x89, 0x01, 0x1B, 0x02, 0xB8, 0x01, 0xB2, 0x01, 0x3C, 0x02, 0xDB, 0x01, 0xDC, 0x01, 0x70, 0x02, 0x14, 0x02, 0x1F, 0x02, 0xA1, 0x02, 0x49, 0x02, 0x60, 0x02, 0xCF, 0x02, 0x78, 0x02, 0x9C, 0x02, 0x11, 0x03, 0xBE, 0x02, 0xF0, 0x02, 0x4D, 0x03, 0xFF, 0x02, 0x3E, 0x03, 0x87, 0x03, 0x3A, 0x03, 0x87, 0x03, 0xC1, 0x03, 0x6E, 0x03, 0xCD, 0x03, 0xF7, 0x03, 0xA6, 0x03, 0x10, 0x04, 0x56, 0x04, 0x05, 0x04, 0x8B, 0x04, 0xB2, 0x04, 0x63, 0x04, 0xFD, 0x04, 0x10, 0x05, 0xBE, 0x04, 0x6A, 0x05, 0x64, 0x05, 0x14, 0x05, 0xD2, 0x05}},
// {SH8601A_QSPI_INST_CMD_WRITE, 0xCA, 1, 136, {0x00, 0x00, 0x6A, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xA5, 0x00, 0x96, 0x00, 0x36, 0x01, 0xCF, 0x00, 0xBE, 0x00, 0x57, 0x01, 0xF0, 0x00, 0xDF, 0x00, 0x7E, 0x01, 0x17, 0x01, 0x06, 0x01, 0xA0, 0x01, 0x39, 0x01, 0x2B, 0x01, 0xD9, 0x01, 0x71, 0x01, 0x66, 0x01, 0x02, 0x02, 0x9C, 0x01, 0x94, 0x01, 0x26, 0x02, 0xC4, 0x01, 0xC1, 0x01, 0x49, 0x02, 0xE8, 0x01, 0xEB, 0x01, 0x7E, 0x02, 0x23, 0x02, 0x32, 0x02, 0xB1, 0x02, 0x59, 0x02, 0x76, 0x02, 0xDF, 0x02, 0x88, 0x02, 0xAF, 0x02, 0x22, 0x03, 0xD1, 0x02, 0x07, 0x03, 0x60, 0x03, 0x14, 0x03, 0x57, 0x03, 0x9F, 0x03, 0x4E, 0x03, 0xA4, 0x03, 0xDA, 0x03, 0x88, 0x03, 0xEC, 0x03, 0x13, 0x04, 0xC1, 0x03, 0x34, 0x04, 0x74, 0x04, 0x25, 0x04, 0xB3, 0x04, 0xD8, 0x04, 0x87, 0x04, 0x29, 0x05, 0x37, 0x05, 0xE7, 0x04, 0x9B, 0x05, 0x95, 0x05, 0x41, 0x05, 0x0B, 0x06}},
// {SH8601A_QSPI_INST_CMD_WRITE, 0xCB, 1, 136, {0x00, 0x00, 0x6A, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x22, 0x01, 0xBB, 0x00, 0xAA, 0x00, 0x3A, 0x01, 0xD3, 0x00, 0xC2, 0x00, 0x5C, 0x01, 0xF5, 0x00, 0xE4, 0x00, 0x87, 0x01, 0x20, 0x01, 0x0F, 0x01, 0xA9, 0x01, 0x42, 0x01, 0x35, 0x01, 0xE5, 0x01, 0x7D, 0x01, 0x72, 0x01, 0x0C, 0x02, 0xA7, 0x01, 0xA0, 0x01, 0x32, 0x02, 0xD1, 0x01, 0xCF, 0x01, 0x55, 0x02, 0xF5, 0x01, 0xFB, 0x01, 0x8C, 0x02, 0x33, 0x02, 0x44, 0x02, 0xC1, 0x02, 0x6A, 0x02, 0x8C, 0x02, 0xF0, 0x02, 0x99, 0x02, 0xC2, 0x02, 0x33, 0x03, 0xE4, 0x02, 0x1E, 0x03, 0x74, 0x03, 0x29, 0x03, 0x70, 0x03, 0xB6, 0x03, 0x63, 0x03, 0xC0, 0x03, 0xF3, 0x03, 0xA2, 0x03, 0x0A, 0x04, 0x2E, 0x04, 0xDB, 0x03, 0x58, 0x04, 0x93, 0x04, 0x45, 0x04, 0xDA, 0x04, 0xFE, 0x04, 0xAC, 0x04, 0x54, 0x05, 0x5F, 0x05, 0x0F, 0x05, 0xCC, 0x05, 0xC5, 0x05, 0x6E, 0x05, 0x43, 0x06}},
// {SH8601A_QSPI_INST_CMD_WRITE, 0xCC, 1, 136, {0x00, 0x00, 0x6A, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x72, 0x00, 0x49, 0x00, 0x43, 0x00, 0x27, 0x01, 0xC0, 0x00, 0xAF, 0x00, 0x42, 0x01, 0xDB, 0x00, 0xCA, 0x00, 0x5A, 0x01, 0xF3, 0x00, 0xE2, 0x00, 0x74, 0x01, 0x0D, 0x01, 0xFC, 0x00, 0xA6, 0x01, 0x3F, 0x01, 0x32, 0x01, 0xCA, 0x01, 0x63, 0x01, 0x57, 0x01, 0xEE, 0x01, 0x87, 0x01, 0x7D, 0x01, 0x08, 0x02, 0xA3, 0x01, 0x9C, 0x01, 0x39, 0x02, 0xD9, 0x01, 0xD8, 0x01, 0x62, 0x02, 0x03, 0x02, 0x0C, 0x02, 0x87, 0x02, 0x2D, 0x02, 0x3D, 0x02, 0xCB, 0x02, 0x74, 0x02, 0x97, 0x02, 0x00, 0x03, 0xAB, 0x02, 0xD8, 0x02, 0x2D, 0x03, 0xDD, 0x02, 0x16, 0x03, 0x56, 0x03, 0x09, 0x03, 0x4A, 0x03, 0x82, 0x03, 0x35, 0x03, 0x81, 0x03, 0xD5, 0x03, 0x83, 0x03, 0xE6, 0x03, 0x24, 0x04, 0xD1, 0x03, 0x4B, 0x04, 0x65, 0x04, 0x14, 0x04, 0x9E, 0x04, 0xA7, 0x04, 0x58, 0x04, 0xF1, 0x04}},
// {SH8601A_QSPI_INST_CMD_WRITE, 0xCD, 1, 136, {0x00, 0x00, 0x6A, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC1, 0x00, 0x7D, 0x00, 0x71, 0x00, 0x30, 0x01, 0xC9, 0x00, 0xB8, 0x00, 0x4E, 0x01, 0xE7, 0x00, 0xD6, 0x00, 0x6F, 0x01, 0x08, 0x01, 0xF7, 0x00, 0x91, 0x01, 0x2A, 0x01, 0x1A, 0x01, 0xC3, 0x01, 0x5C, 0x01, 0x50, 0x01, 0xF0, 0x01, 0x89, 0x01, 0x7F, 0x01, 0x11, 0x02, 0xAD, 0x01, 0xA7, 0x01, 0x32, 0x02, 0xD1, 0x01, 0xCE, 0x01, 0x65, 0x02, 0x07, 0x02, 0x10, 0x02, 0x93, 0x02, 0x3B, 0x02, 0x4E, 0x02, 0xC0, 0x02, 0x69, 0x02, 0x8B, 0x02, 0x03, 0x03, 0xAF, 0x02, 0xDD, 0x02, 0x3C, 0x03, 0xEE, 0x02, 0x2A, 0x03, 0x73, 0x03, 0x28, 0x03, 0x6F, 0x03, 0xA9, 0x03, 0x58, 0x03, 0xB0, 0x03, 0xDD, 0x03, 0x8B, 0x03, 0xEF, 0x03, 0x3C, 0x04, 0xEA, 0x03, 0x6A, 0x04, 0x92, 0x04, 0x44, 0x04, 0xD9, 0x04, 0xE9, 0x04, 0x98, 0x04, 0x3C, 0x05, 0x39, 0x05, 0xE8, 0x04, 0x9D, 0x05}},
// {SH8601A_QSPI_INST_CMD_WRITE, 0xCE, 1, 136, {0x00, 0x00, 0x6A, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x22, 0x01, 0xBB, 0x00, 0xAA, 0x00, 0x3A, 0x01, 0xD3, 0x00, 0xC2, 0x00, 0x5C, 0x01, 0xF5, 0x00, 0xE4, 0x00, 0x87, 0x01, 0x20, 0x01, 0x0F, 0x01, 0xA9, 0x01, 0x42, 0x01, 0x35, 0x01, 0xE5, 0x01, 0x7D, 0x01, 0x72, 0x01, 0x0C, 0x02, 0xA7, 0x01, 0xA0, 0x01, 0x32, 0x02, 0xD1, 0x01, 0xCF, 0x01, 0x55, 0x02, 0xF5, 0x01, 0xFB, 0x01, 0x8C, 0x02, 0x33, 0x02, 0x44, 0x02, 0xC1, 0x02, 0x6A, 0x02, 0x8C, 0x02, 0xF0, 0x02, 0x99, 0x02, 0xC2, 0x02, 0x33, 0x03, 0xE4, 0x02, 0x1E, 0x03, 0x74, 0x03, 0x29, 0x03, 0x70, 0x03, 0xB6, 0x03, 0x63, 0x03, 0xC0, 0x03, 0xF3, 0x03, 0xA2, 0x03, 0x0A, 0x04, 0x2E, 0x04, 0xDB, 0x03, 0x58, 0x04, 0x93, 0x04, 0x45, 0x04, 0xDA, 0x04, 0xFE, 0x04, 0xAC, 0x04, 0x54, 0x05, 0x5F, 0x05, 0x0F, 0x05, 0xCC, 0x05, 0xC5, 0x05, 0x6E, 0x05, 0x43, 0x06}},
// {SH8601A_QSPI_INST_CMD_WRITE, 0xD3, 1, 11, {0x11, 0xC6, 0x01, 0xC6, 0x01, 0x08, 0x08, 0x14, 0x14, 0x00, 0x00}},
// {SH8601A_QSPI_INST_CMD_WRITE, 0xD4, 1, 54, {0x02, 0x00, 0x2c, 0x00, 0x19, 0x00, 0x06, 0x00, 0x6c, 0x00, 0x3b, 0x00, 0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 0x19, 0x00, 0x2c, 0x00, 0x02, 0x00, 0x3b, 0x00, 0x6c, 0x00, 0x06, 0x00, 0x04, 0x00, 0x08, 0x00, 0x00, 0x00, 0x03, 0x00, 0x07, 0x00, 0x03, 0x00, 0x1e, 0x00, 0x7e, 0x00, 0x1e, 0x00, 0x08, 0x00, 0x29, 0x00, 0x08, 0x00}},
// {SH8601A_QSPI_INST_CMD_WRITE, 0xD5, 1, 54, {0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 0x06, 0x00, 0x6c, 0x00, 0x3b, 0x00, 0x02, 0x00, 0x2c, 0x00, 0x19, 0x00, 0x04, 0x00, 0x08, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x6c, 0x00, 0x06, 0x00, 0x19, 0x00, 0x2c, 0x00, 0x02, 0x00, 0x08, 0x00, 0x29, 0x00, 0x08, 0x00, 0x1e, 0x00, 0x7e, 0x00, 0x1e, 0x00, 0x03, 0x00, 0x07, 0x00, 0x03, 0x00}},
// {SH8601A_QSPI_INST_CMD_WRITE, 0xD6, 1, 54, {0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 0x06, 0x00, 0x6c, 0x00, 0x3b, 0x00, 0x02, 0x00, 0x2c, 0x00, 0x19, 0x00, 0x04, 0x00, 0x08, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x6c, 0x00, 0x06, 0x00, 0x19, 0x00, 0x2c, 0x00, 0x02, 0x00, 0x08, 0x00, 0x29, 0x00, 0x08, 0x00, 0x1e, 0x00, 0x7e, 0x00, 0x1e, 0x00, 0x03, 0x00, 0x07, 0x00, 0x03, 0x00}},
// {SH8601A_QSPI_INST_CMD_WRITE, 0xD7, 1, 54, {0x02, 0x00, 0x2c, 0x00, 0x19, 0x00, 0x06, 0x00, 0x6c, 0x00, 0x3b, 0x00, 0x00, 0x00, 0x08, 0x00, 0x04, 0x00, 0x19, 0x00, 0x2c, 0x00, 0x02, 0x00, 0x3b, 0x00, 0x6c, 0x00, 0x06, 0x00, 0x04, 0x00, 0x08, 0x00, 0x00, 0x00, 0x03, 0x00, 0x07, 0x00, 0x03, 0x00, 0x1e, 0x00, 0x7e, 0x00, 0x1e, 0x00, 0x08, 0x00, 0x29, 0x00, 0x08, 0x00}},
// {SH8601A_QSPI_INST_CMD_WRITE, 0xDF, 1, 19, {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x03}},
// {SH8601A_QSPI_INST_CMD_WRITE, 0xEE, 1, 44, {0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
// {SH8601A_QSPI_INST_CMD_WRITE, 0xF0, 1, 24, {0x10, 0x79, 0x77, 0x22, 0x4A, 0x25, 0x1C, 0x19, 0x00, 0x10, 0x0F, 0x11, 0x38, 0xAA, 0x20, 0x20, 0x2A, 0x22, 0x2A, 0xCA, 0x88, 0x10, 0x10, 0x00}},
// {SH8601A_QSPI_INST_CMD_WRITE, 0xF1, 1, 25, {0x10, 0x09, 0x03, 0x00, 0x4A, 0x25, 0x1C, 0x19, 0x00, 0x10, 0x0F, 0x00, 0x30, 0xAA, 0x20, 0x20, 0x2F, 0x23, 0x2F, 0x22, 0x2E, 0xCF, 0x88, 0x10, 0x10}},
// {SH8601A_QSPI_INST_CMD_WRITE, 0xF1, 1, 25, {0x10, 0x09, 0x03, 0x00, 0x4A, 0x25, 0x1C, 0x19, 0x00, 0x10, 0x0F, 0x11, 0x30, 0xAA, 0x10, 0x10, 0x26, 0x20, 0x25, 0x12, 0x16, 0xC5, 0x88, 0x10, 0x01}},
// {SH8601A_QSPI_INST_CMD_WRITE, 0xF2, 1, 34, {0xFF, 0x53, 0x00, 0x11, 0x19, 0x0A, 0x01, 0x03, 0x05, 0x07, 0x09, 0x0B, 0x0D, 0x0F, 0x00, 0x01, 0x01, 0xFF, 0x53, 0x10, 0x11, 0x19, 0x0A, 0x01, 0x03, 0x05, 0x07, 0x09, 0x0B, 0x0D, 0x0F, 0x01, 0x01, 0x01}},
// {SH8601A_QSPI_INST_CMD_WRITE, 0xF3, 1, 36, {0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x02, 0x02, 0x02, 0x03, 0x04, 0x04, 0x05, 0x05, 0x06, 0x06, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x08, 0x08, 0x08, 0x08, 0x08, 0x02, 0x03, 0x02, 0x02, 0x03, 0x01, 0x00, 0x00}},
// {SH8601A_QSPI_INST_CMD_WRITE, 0xF4, 1, 21, {0x99, 0x99, 0x99, 0x88, 0x88, 0x77, 0x66, 0x55, 0x55, 0x55, 0x55, 0x55, 0x44, 0x94, 0x01, 0x01, 0x04, 0x01, 0x01, 0x01, 0x01}},
// {SH8601A_QSPI_INST_CMD_WRITE, 0xF5, 1, 21, {0x66, 0x66, 0x56, 0x55, 0x45, 0x44, 0x33, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x62, 0x02, 0x02, 0x02, 0x00, 0x01, 0x01, 0x00}},
// {SH8601A_QSPI_INST_CMD_WRITE, 0xF8, 1, 16, {0x03, 0x22, 0x22, 0x77, 0x37, 0x00, 0x10, 0x10, 0x26, 0x20, 0x25, 0x12, 0x14, 0x05, 0x66, 0x66}},
{SH8601A_QSPI_INST_CMD_WRITE, 0x11, 10, 0, {0}},
{SH8601A_QSPI_INST_CMD_WRITE, 0x2A, 1, 4, {0x00, 0x00, 0x01, 0xC5}},
{SH8601A_QSPI_INST_CMD_WRITE, 0x2B, 1, 4, {0x00, 0x00, 0x01, 0xC5}},
{SH8601A_QSPI_INST_CMD_WRITE, 0x44, 1, 2, {0x01, 0xD1}},
{SH8601A_QSPI_INST_CMD_WRITE, 0x35, 1, 1, {0x00}},
// {SH8601A_QSPI_INST_CMD_WRITE, 0x51, 1, 1, {0xFF}},
// {SH8601A_QSPI_INST_CMD_WRITE, 0x4A, 1, 1, {0xFF}},
// {SH8601A_QSPI_INST_CMD_WRITE, 0x63, 1, 1, {0xFF}},
{SH8601A_QSPI_INST_CMD_WRITE, 0x53, 1, 1, {0x28}},
{SH8601A_QSPI_INST_CMD_WRITE, 0xC4, 50, 1, {0x84}},
{SH8601A_QSPI_INST_CMD_WRITE, 0x3A, 1, 1, {0x05}}, // 16bits pixel
{SH8601A_QSPI_INST_CMD_WRITE, 0x29, 1, 0, {0}},
// {SH8601A_QSPI_INST_CMD_WRITE, 0xBA, 1, 1, {0x81}},
// {SH8601A_QSPI_INST_CMD_WRITE, 0xB1, 1, 1, {0xC0}},
{SH8601A_QSPI_SEQ_FINISH_CODE, 0, 0, 0, {0}},
};
const SH8601A_CMD_DESC SH8601A_POST_OTP_POWERON_SEQ_CMD[] = {
// {SH8601A_QSPI_INST_CMD_WRITE, 0x11, 10, 0, {0}},
// {SH8601A_QSPI_INST_CMD_WRITE, 0x2A, 1, 4, {0x00, 0x00, 0x01, 0xC5}},
// {SH8601A_QSPI_INST_CMD_WRITE, 0x2B, 1, 4, {0x00, 0x00, 0x01, 0xC5}},
// {SH8601A_QSPI_INST_CMD_WRITE, 0x44, 1, 2, {0x01, 0xC2}},
// {SH8601A_QSPI_INST_CMD_WRITE, 0x35, 1, 1, {0x00}},
// {SH8601A_QSPI_INST_CMD_WRITE, 0x51, 1, 1, {0xFF}},
// {SH8601A_QSPI_INST_CMD_WRITE, 0x4A, 1, 1, {0xFF}},
// {SH8601A_QSPI_INST_CMD_WRITE, 0x63, 1, 1, {0xFF}},
// {SH8601A_QSPI_INST_CMD_WRITE, 0x53, 1, 1, {0x28}},
// {SH8601A_QSPI_INST_CMD_WRITE, 0xC4, 25, 1, {0x84}},
// {SH8601A_QSPI_INST_CMD_WRITE, 0x29, 1, 0, {0}},
// {SH8601A_QSPI_SEQ_FINISH_CODE, 0, 0, 0, {0}},
// {SH8601A_QSPI_INST_CMD_WRITE, 0xC0, 1, 2, {0x5A, 0x5A}},
// {SH8601A_QSPI_INST_CMD_WRITE, 0xC1, 1, 2, {0x5A, 0x5A}},
// {SH8601A_QSPI_INST_CMD_WRITE, 0x11, 10, 0, {0}},
// {SH8601A_QSPI_INST_CMD_WRITE, 0xB1, 1, 51, {0xC0, 0xC6, 0x01, 0xC6, 0x01, 0x05, 0x00, 0x05, 0x00, 0x2B, 0x01, 0x2B, 0x01, 0x05, 0x00, 0x05, 0x00, 0x2B, 0x01, 0x2B, 0x01, 0x00, 0x52, 0x00, 0x64, 0x00, 0x8A, 0x00, 0xB0, 0x00, 0x52, 0x00, 0x64, 0x00, 0x8A, 0x00, 0xB0, 0x00, 0x00, 0x10, 0x00, 0x00, 0xDF, 0x01, 0x00, 0x00, 0xDF, 0x01, 0x00, 0x00, 0x00}},
// {SH8601A_QSPI_INST_CMD_WRITE, 0xB4, 1, 65, {0x09, 0x02, 0x00, 0x00, 0x10, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x2C, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x02, 0x46, 0x8A, 0x13, 0x57, 0x9B, 0x31, 0x75, 0xB9, 0x20, 0x64, 0xA8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x64, 0xA8, 0x31, 0x75, 0xB9, 0x13, 0x57, 0x9B, 0x02, 0x46, 0x8A, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00}},
// {SH8601A_QSPI_INST_CMD_WRITE, 0xB5, 1, 58, {0x4C, 0x09, 0x09, 0x09, 0x49, 0x40, 0x00, 0x01, 0x2C, 0x00, 0x00, 0x00, 0x2C, 0x00, 0x1C, 0x04, 0x2C, 0x00, 0x1C, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x02, 0x00, 0x00, 0x03, 0x02, 0x6E, 0x00, 0x2C, 0x00, 0x2C, 0x00, 0x1C, 0x04, 0x00, 0x00, 0x00, 0x00, 0x2C, 0x00, 0x1C, 0x04, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x03, 0x00}},
// {SH8601A_QSPI_INST_CMD_WRITE, 0xB6, 1, 26, {0x00, 0x10, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x2C, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47}},
// {SH8601A_QSPI_INST_CMD_WRITE, 0xB7, 1, 51, {0x0C, 0x00, 0x01, 0x2C, 0x00, 0x00, 0x00, 0x2C, 0x00, 0x1C, 0x04, 0x2C, 0x00, 0x1C, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x02, 0x00, 0x00, 0x03, 0x02, 0x6E, 0x00, 0x2C, 0x00, 0x2C, 0x00, 0x1C, 0x04, 0x00, 0x00, 0x00, 0x00, 0x2C, 0x00, 0x1C, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
// {SH8601A_QSPI_INST_CMD_WRITE, 0xB8, 1, 95, {0x00, 0x67, 0x31, 0x22, 0x22, 0x22, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x22, 0x22, 0x22, 0x22, 0x00, 0x00, 0x00, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x00, 0x00, 0x00, 0x22, 0x22, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x22, 0x22, 0x00, 0x22, 0x00, 0x22, 0x22, 0x22, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x22, 0x22, 0x22, 0x22, 0x00, 0x00, 0x00, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x00, 0x00, 0x00, 0x22, 0x22, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x22, 0x22, 0x00, 0x22, 0x00, 0x00, 0x00}},
// {SH8601A_QSPI_INST_CMD_WRITE, 0x2A, 1, 4, {0x00, 0x00, 0x01, 0xC5}},
// {SH8601A_QSPI_INST_CMD_WRITE, 0x2B, 1, 4, {0x00, 0x00, 0x01, 0xC5}},
// {SH8601A_QSPI_INST_CMD_WRITE, 0x44, 1, 2, {0x01, 0xC2}},
// {SH8601A_QSPI_INST_CMD_WRITE, 0x35, 1, 1, {0x00}},
// {SH8601A_QSPI_INST_CMD_WRITE, 0x51, 1, 1, {0xFF}},
// {SH8601A_QSPI_INST_CMD_WRITE, 0x4A, 1, 1, {0xFF}},
// {SH8601A_QSPI_INST_CMD_WRITE, 0x63, 1, 1, {0xFF}},
// {SH8601A_QSPI_INST_CMD_WRITE, 0x53, 1, 1, {0x28}},
// {SH8601A_QSPI_INST_CMD_WRITE, 0xC4, 25, 1, {0x84}},
// {SH8601A_QSPI_INST_CMD_WRITE, 0x29, 1, 0, {0}},
// {SH8601A_QSPI_INST_CMD_WRITE, 0xBA, 1, 1, {0x80}}, // bist: 0x81, exit bist: 0x80
// {SH8601A_QSPI_INST_CMD_WRITE, 0xB1, 1, 1, {0xC0}},
// {SH8601A_QSPI_INST_CMD_WRITE, 0xC1, 1, 2, {0xA5, 0xA5}},
// {SH8601A_QSPI_INST_CMD_WRITE, 0xC0, 1, 2, {0xA5, 0xA5}},
// {SH8601A_QSPI_SEQ_FINISH_CODE, 0, 0, 0, {0}},
{SH8601A_QSPI_INST_CMD_WRITE, 0xC0, 1, 2, {0x5A, 0x5A}},
{SH8601A_QSPI_INST_CMD_WRITE, 0xC1, 1, 2, {0x5A, 0x5A}},
{SH8601A_QSPI_INST_CMD_WRITE, 0x11, 10, 0, {0}},
{SH8601A_QSPI_INST_CMD_WRITE, 0x2A, 1, 4, {0x00, 0x00, 0x01, 0xC5}},
{SH8601A_QSPI_INST_CMD_WRITE, 0x2B, 1, 4, {0x00, 0x00, 0x01, 0xC5}},
{SH8601A_QSPI_INST_CMD_WRITE, 0x44, 1, 2, {0x01, 0xC2}},
{SH8601A_QSPI_INST_CMD_WRITE, 0x35, 1, 1, {0x00}},
{SH8601A_QSPI_INST_CMD_WRITE, 0xB0, 1, 1, {0x16}},
{SH8601A_QSPI_INST_CMD_WRITE, 0xB1, 1, 9, {0x01, 0x05, 0x00, 0xA2, 0x00, 0xA7, 0x00, 0xA7, 0x00}}, // 0x01=45Hz, 0x00=60Hz
//{SH8601A_QSPI_INST_CMD_WRITE, 0x51, 1, 1, {0xFF}},
//{SH8601A_QSPI_INST_CMD_WRITE, 0x4A, 1, 1, {0xFF}},
//{SH8601A_QSPI_INST_CMD_WRITE, 0x63, 1, 1, {0xFF}},
{SH8601A_QSPI_INST_CMD_WRITE, 0x53, 1, 1, {0x28}},
{SH8601A_QSPI_INST_CMD_WRITE, 0xC4, 25, 1, {0x84}},
{SH8601A_QSPI_INST_CMD_WRITE, 0x29, 1, 0, {0}},
//{SH8601A_QSPI_INST_CMD_WRITE, 0xBA, 1, 1, {0x80}}, // bist: 0x81, exit bist: 0x80
{SH8601A_QSPI_INST_CMD_WRITE, 0xB1, 1, 1, {0xC0}},
{SH8601A_QSPI_INST_CMD_WRITE, 0xC0, 1, 2, {0xA5, 0xA5}},
{SH8601A_QSPI_INST_CMD_WRITE, 0xC1, 1, 2, {0xA5, 0xA5}},
{SH8601A_QSPI_SEQ_FINISH_CODE, 0, 0, 0, {0}},
};
const SH8601A_CMD_DESC SH8601A_POWEROFF_SEQ_CMD[] = {
{SH8601A_QSPI_INST_CMD_WRITE, 0x28, 25, 0, {0}},
{SH8601A_QSPI_INST_CMD_WRITE, 0x10, 50, 0, {0}},
{SH8601A_QSPI_SEQ_FINISH_CODE, 0, 0, 0, {0}},
};
const SH8601A_CMD_DESC SH8601A_OTP_WRITE[] = {
{SH8601A_QSPI_INST_CMD_WRITE, 0xD0, 1000, 2, {0x01}},
{SH8601A_QSPI_INST_CMD_WRITE, 0xD0, 10, 2, {0x00}},
{SH8601A_QSPI_SEQ_FINISH_CODE, 0, 0, 0, {0}},
};
static DMA_LLI_InitTypeDef *Link_Channel = (void *)0x1fffe000;
static void write_cmd(uint8_t cmd)
{
uint8_t spi_data[4];
spi_data[0] = SH8601A_QSPI_INST_CMD_WRITE;
spi_data[1] = 0x00;
spi_data[2] = cmd;
spi_data[3] = 0x00;
__DISPLAY_CS_CLEAR();
spi_master_transmit_X1(&spi_display_handle, (uint16_t *)spi_data, 4);
__DISPLAY_CS_SET();
}
static void write_buff(uint8_t *buffer, uint8_t len)
{
__DISPLAY_CS_CLEAR();
spi_master_transmit_X1(&spi_display_handle, (uint16_t *)buffer, len);
__DISPLAY_CS_SET();
}
static void read_reg(uint8_t reg, uint8_t *buffer, uint16_t len)
{
uint8_t spi_data[4];
spi_data[0] = SH8601A_QSPI_INST_CMD_READ;
spi_data[1] = 0x00;
spi_data[2] = reg;
spi_data[3] = 0x00;
__DISPLAY_CS_CLEAR();
spi_master_transmit_X1(&spi_display_handle, (uint16_t *)spi_data, 4);
spi_master_receive_X1(&spi_display_handle, buffer, len);
__DISPLAY_CS_SET();
}
static void SH8601A_Reg_Write(const SH8601A_CMD_DESC* cmd)
{
uint16_t idx = 0;
while (cmd[idx].instruction != SH8601A_QSPI_SEQ_FINISH_CODE)
{
uint8_t sdat[cmd[idx].wordcount + 4];
sdat[0] = cmd[idx].instruction;
sdat[1] = 0;
sdat[2] = cmd[idx].index; // Set in the middle 8 bits ADDR[15:8] of the 24 bits ADDR[23:0]
sdat[3] = 0;
for(uint16_t i=0; i<cmd[idx].wordcount; i++)
{
sdat[i+4] = cmd[idx].payload[i];
}
__DISPLAY_CS_CLEAR();
spi_master_transmit_X1(&spi_display_handle, sdat, sizeof(sdat));
__DISPLAY_CS_SET();
if (cmd[idx].delay != 0)
{
__DISPLAY_DELAY_MS(cmd[idx].delay);
}
idx++;
}
}
static void SH8601A_Init_Pre_OTP(void)
{
//pull low RESX
//power on VBAT: VBAT = 3.7V
//power on VDDI: VDDI = 1.8V
//pull high VCI_EN: enable VCI = 3.3V
//delay 10ms
//pull high RESX: IC reset
//delay 10ms
SH8601A_Reg_Write(SH8601A_PRE_OTP_POWERON_SEQ_CMD);
}
static void SH8601A_Init_Post_OTP(void)
{
//pull low RESX
//power on VBAT: VBAT = 3.7V
//power on VDDI: VDDI = 1.8V
//pull high VCI_EN: enable VCI = 3.3V
//delay 10ms
//pull high RESX: IC reset
//delay 10ms
SH8601A_Reg_Write(SH8601A_POST_OTP_POWERON_SEQ_CMD);
}
static void SH8601A_Power_Off(void)
{
SH8601A_Reg_Write(SH8601A_POWEROFF_SEQ_CMD);
//delay 100ms
//pull low RESX
//delay 10ms
//pull low VCI_EN: disable VCI
//power off VDDI
//power off VBAT
}
static void SH8601A_OTP_Write(void)
{
/*********************************************
* Register read:
* Index: 0xCF (OTP_STATUS)
* Para: 1 Byte read
* Check BANK_CHECK_MCS[1:0]:
* - 00h: No writen, 3 times writable
* - 01h: 1 time written, 2 times writable
* - 02h: 2 times written, 1 time writable
* - 03h: 3 time written, no longer be written
**********************************************/
//power on VOTP: VOTP = 6V external supply
//delay 20ms
SH8601A_Reg_Write(SH8601A_OTP_WRITE);
//power off VOTP
//delay 20ms
/*********************************************
* OTP status verification:
* Index: 0xCF (OTP_STATUS)
* Para: 3 Bytes read
* Check PRG_ERR_1:
* - 0: OK
* - 1: FAIL
OTP rewrite(power off -> power on -> rewrite)
* Check PRG_ERR_0:
* - 0: OK
* - 1: FAIL
Not rewrite OTP
**********************************************/
/* Go to power off sequence */
}
static void sh8601a_read_regs(void)
{
uint8_t buffer[6];
read_reg(0x90, buffer, 6);
read_reg(0x2A, buffer, 4);
read_reg(0x2B, buffer, 4);
}
void sh8601a_init(void)
{
__DISPLAY_VCI_CLEAR();
__DISPLAY_RESET_CLEAR();
__DISPLAY_DELAY_MS(20);
__DISPLAY_VCI_SET();
__DISPLAY_DELAY_MS(40);
__DISPLAY_RESET_SET();
__DISPLAY_DELAY_MS(80);
SH8601A_Init_Pre_OTP();
}
void sh8601a_set_window(uint16_t x_s, uint16_t x_e, uint16_t y_s, uint16_t y_e)
{
uint8_t data[8];
data[0] = 0x02;
data[1] = 0x00;
data[2] = 0x2A;
data[3] = 0x00;
data[4] = x_s >> 8;
data[5] = x_s & 0xff;
data[6] = x_e >> 8;
data[7] = x_e & 0xff;
write_buff(data, 8);
data[0] = 0x02;
data[1] = 0x00;
data[2] = 0x2B;
data[3] = 0x00;
data[4] = y_s >> 8;
data[5] = y_s & 0xff;
data[6] = y_e >> 8;
data[7] = y_e & 0xff;
write_buff(data, 8);
// write_cmd(0x2c);
}
void sh8601a_display(uint32_t pixel_count, uint8_t pixel_width, void *data)
{
uint8_t frame_size;
if (pixel_width == 16) {
frame_size = SPI_FRAME_SIZE_16BIT;
}
else if (pixel_width == 32) {
frame_size = SPI_FRAME_SIZE_24BIT;
}
spi_display_handle.Init.Frame_Size = frame_size;
spi_display_handle.MultWireParam.Wire_X2X4X8 = Wire_X4;
spi_display_handle.MultWireParam.InstructLength = INST_8BIT;
spi_display_handle.MultWireParam.Instruct = 0x32;
spi_display_handle.MultWireParam.AddressLength = ADDR_24BIT;
spi_display_handle.MultWireParam.Address = 0x002C00;
__DISPLAY_CS_CLEAR();
spi_master_transmit_X2X4X8(&spi_display_handle, data, pixel_count);
__DISPLAY_CS_SET();
__SPI_DISABLE(spi_display_handle.SPIx);
__SPI_DATA_FRAME_SIZE(spi_display_handle.SPIx, SPI_FRAME_SIZE_8BIT);
}
void sh8601a_display_dma(uint32_t pixel_count, uint8_t pixel_width, void *data)
{
//#define USE_DMA_LINK_MODE
uint8_t spi_trans_width;
uint32_t dma_sample_count;
#ifdef USE_DMA_LINK_MODE
#define DMA_SINGLE_TRANSFER_SIZE 20000
uint32_t link_count;
uint32_t i;
uint32_t link_trans_size;
dma_LinkParameter_t LinkParameter;
switch (dma_display_handle.Init.Source_Width) {
case DMA_TRANSFER_WIDTH_32:
dma_sample_count = pixel_count * pixel_width / 32;
link_trans_size = 4 * DMA_SINGLE_TRANSFER_SIZE;
break;
case DMA_TRANSFER_WIDTH_16:
dma_sample_count = pixel_count * pixel_width / 16;
link_trans_size = 2 * DMA_SINGLE_TRANSFER_SIZE;
break;
case DMA_TRANSFER_WIDTH_8:
dma_sample_count = pixel_count * pixel_width / 8;
link_trans_size = DMA_SINGLE_TRANSFER_SIZE;
break;
default:
return;
}
link_count = dma_sample_count / DMA_SINGLE_TRANSFER_SIZE;
if(dma_sample_count % DMA_SINGLE_TRANSFER_SIZE)
{
link_count++;
}
for (i = 0; i < link_count; i++)
{
uint8_t all_set = (dma_sample_count <= DMA_SINGLE_TRANSFER_SIZE);
LinkParameter.SrcAddr = (uint32_t)data + i * link_trans_size;
LinkParameter.DstAddr = (uint32_t)&spi_display_handle.SPIx->DR;
if(all_set)
{
LinkParameter.NextLink = 0;
}
else
{
LinkParameter.NextLink = (uint32_t)&Link_Channel[i + 1];
}
LinkParameter.Data_Flow = dma_display_handle.Init.Data_Flow;
LinkParameter.Request_ID = dma_display_handle.Init.Request_ID;
LinkParameter.Source_Master_Sel = dma_display_handle.Init.Source_Master_Sel;
LinkParameter.Desination_Master_Sel = dma_display_handle.Init.Desination_Master_Sel;
LinkParameter.Source_Inc = dma_display_handle.Init.Source_Inc;
LinkParameter.Desination_Inc = dma_display_handle.Init.Desination_Inc;
LinkParameter.Source_Width = dma_display_handle.Init.Source_Width;
LinkParameter.Desination_Width = dma_display_handle.Init.Desination_Width;
LinkParameter.Source_Burst_Len = dma_display_handle.Init.Source_Burst_Len;
LinkParameter.Desination_Burst_Len = dma_display_handle.Init.Desination_Burst_Len;
LinkParameter.Size = all_set ? dma_sample_count : DMA_SINGLE_TRANSFER_SIZE;
LinkParameter.gather_enable = 0;
LinkParameter.scatter_enable = 0;
dma_sample_count -= DMA_SINGLE_TRANSFER_SIZE;
dma_linked_list_init(&Link_Channel[i], &LinkParameter);
}
#else
switch (dma_display_handle.Init.Source_Width) {
case DMA_TRANSFER_WIDTH_32:
dma_sample_count = pixel_count * pixel_width / 32;
break;
case DMA_TRANSFER_WIDTH_16:
dma_sample_count = pixel_count * pixel_width / 16;
break;
case DMA_TRANSFER_WIDTH_8:
dma_sample_count = pixel_count * pixel_width / 8;
break;
default:
return;
}
#endif
switch (dma_display_handle.Init.Desination_Width) {
case DMA_TRANSFER_WIDTH_32:
spi_trans_width = SPI_FRAME_SIZE_32BIT;
break;
case DMA_TRANSFER_WIDTH_16:
spi_trans_width = SPI_FRAME_SIZE_16BIT;
break;
case DMA_TRANSFER_WIDTH_8:
spi_trans_width = SPI_FRAME_SIZE_8BIT;
break;
default:
return;
}
spi_display_handle.Init.Frame_Size = spi_trans_width;
spi_display_handle.MultWireParam.Wire_X2X4X8 = Wire_X4;
spi_display_handle.MultWireParam.InstructLength = INST_8BIT;
spi_display_handle.MultWireParam.Instruct = 0x32;
spi_display_handle.MultWireParam.AddressLength = ADDR_24BIT;
spi_display_handle.MultWireParam.Address = 0x002C00;
__DISPLAY_CS_CLEAR();
__SPI_DISABLE(spi_display_handle.SPIx);
__SPI_TX_ENDIAN_SET(spi_display_handle.SPIx, TX_RX_Endian_4321);
__SPI_ENABLE(spi_display_handle.SPIx);
spi_master_transmit_X2X4X8_DMA(&spi_display_handle);
__SPI_DISABLE(spi_display_handle.SPIx);
if (spi_trans_width == SPI_FRAME_SIZE_32BIT) {
__SPI_TX_ENDIAN_SET(spi_display_handle.SPIx, TX_RX_Endian_2143);
}
else {
__SPI_TX_ENDIAN_SET(spi_display_handle.SPIx, TX_RX_Endian_4321);
}
__SPI_ENABLE(spi_display_handle.SPIx);
#ifndef USE_DMA_LINK_MODE
dma_start_IT(&dma_display_handle, (uint32_t)data, (uint32_t)&spi_display_handle.SPIx->DR, dma_sample_count);
#else
dma_linked_list_start_IT(Link_Channel, &LinkParameter, &dma_display_handle);
#endif
}
void sh8601a_display_dma_isr(void)
{
while(__SPI_IS_BUSY(spi_display_handle.SPIx));
// CS Release
__DISPLAY_CS_SET();
/* Clear Transfer complete status */
dma_clear_tfr_Status(&dma_display_handle);
/* channel Transfer complete interrupt disable */
dma_tfr_interrupt_disable(&dma_display_handle);
__SPI_DISABLE(spi_display_handle.SPIx);
__SPI_DATA_FRAME_SIZE(spi_display_handle.SPIx, SPI_FRAME_SIZE_8BIT);
}

View File

@ -0,0 +1,16 @@
#ifndef __DRIVER_SH8601A_H
#define __DRIVER_SH8601A_H
#include <stdint.h>
void sh8601a_init(void);
void sh8601a_set_window(uint16_t x_s, uint16_t x_e, uint16_t y_s, uint16_t y_e);
void sh8601a_display(uint32_t pixel_count, uint8_t pixel_width, void *data);
void sh8601a_display_dma(uint32_t pixel_count, uint8_t pixel_width, void *data);
void sh8601a_display_dma_isr(void);
#endif // __DRIVER_SH8601A_H

View File

@ -0,0 +1,501 @@
#include "driver_display.h"
#include "driver_sh8601z.h"
#define SH8601A_MAX_PARA_COUNT (300)
#define SH8601A_QSPI_INST_CMD_WRITE (0x02)
#define SH8601A_QSPI_INST_CMD_READ (0x03)
#define SH8601A_QSPI_INST_1WIRE_PIXEL_WRITE (0x02)
#define SH8601A_QSPI_INST_4WIRE_PIXEL_WRITE_TYPE1 (0x32)
#define SH8601A_QSPI_INST_4WIRE_PIXEL_WRITE_TYPE2 (0x12)
#define SH8601A_QSPI_SEQ_FINISH_CODE (0x00)
typedef struct _SH8601A_CMD_DESC {
uint8_t instruction;
uint8_t index;
uint16_t delay;
uint16_t wordcount;
uint8_t payload[SH8601A_MAX_PARA_COUNT];
} SH8601A_CMD_DESC;
static const SH8601A_CMD_DESC SH8601A_PRE_OTP_POWERON_SEQ_CMD[] = {
{SH8601A_QSPI_INST_CMD_WRITE, 0x11, 10, 0, {0}},
{SH8601A_QSPI_INST_CMD_WRITE, 0x2A, 1, 4, {0x00, 0x00, 0x01, 0x6F}},
{SH8601A_QSPI_INST_CMD_WRITE, 0x2B, 1, 4, {0x00, 0x00, 0x01, 0xBF}},
{SH8601A_QSPI_INST_CMD_WRITE, 0x44, 1, 2, {0x01, 0xBF}},
{SH8601A_QSPI_INST_CMD_WRITE, 0x3A, 1, 1, {0x05}}, // 16bits pixel
{SH8601A_QSPI_INST_CMD_WRITE, 0x35, 1, 1, {0x00}},
{SH8601A_QSPI_INST_CMD_WRITE, 0x53, 25, 1, {0x20}},
{SH8601A_QSPI_INST_CMD_WRITE, 0x29, 1, 0, {0}},
// {SH8601A_QSPI_INST_CMD_WRITE, 0x51, 1, 1, {0xFF}},
{SH8601A_QSPI_SEQ_FINISH_CODE, 0, 0, 0, {0}},
};
static const SH8601A_CMD_DESC SH8601A_POST_OTP_POWERON_SEQ_CMD[] = {
// {SH8601A_QSPI_INST_CMD_WRITE, 0x11, 10, 0, {0}},
// {SH8601A_QSPI_INST_CMD_WRITE, 0x2A, 1, 4, {0x00, 0x00, 0x01, 0xC5}},
// {SH8601A_QSPI_INST_CMD_WRITE, 0x2B, 1, 4, {0x00, 0x00, 0x01, 0xC5}},
// {SH8601A_QSPI_INST_CMD_WRITE, 0x44, 1, 2, {0x01, 0xC2}},
// {SH8601A_QSPI_INST_CMD_WRITE, 0x35, 1, 1, {0x00}},
// {SH8601A_QSPI_INST_CMD_WRITE, 0x51, 1, 1, {0xFF}},
// {SH8601A_QSPI_INST_CMD_WRITE, 0x4A, 1, 1, {0xFF}},
// {SH8601A_QSPI_INST_CMD_WRITE, 0x63, 1, 1, {0xFF}},
// {SH8601A_QSPI_INST_CMD_WRITE, 0x53, 1, 1, {0x28}},
// {SH8601A_QSPI_INST_CMD_WRITE, 0xC4, 25, 1, {0x84}},
// {SH8601A_QSPI_INST_CMD_WRITE, 0x29, 1, 0, {0}},
// {SH8601A_QSPI_SEQ_FINISH_CODE, 0, 0, 0, {0}},
// {SH8601A_QSPI_INST_CMD_WRITE, 0xC0, 1, 2, {0x5A, 0x5A}},
// {SH8601A_QSPI_INST_CMD_WRITE, 0xC1, 1, 2, {0x5A, 0x5A}},
// {SH8601A_QSPI_INST_CMD_WRITE, 0x11, 10, 0, {0}},
// {SH8601A_QSPI_INST_CMD_WRITE, 0xB1, 1, 51, {0xC0, 0xC6, 0x01, 0xC6, 0x01, 0x05, 0x00, 0x05, 0x00, 0x2B, 0x01, 0x2B, 0x01, 0x05, 0x00, 0x05, 0x00, 0x2B, 0x01, 0x2B, 0x01, 0x00, 0x52, 0x00, 0x64, 0x00, 0x8A, 0x00, 0xB0, 0x00, 0x52, 0x00, 0x64, 0x00, 0x8A, 0x00, 0xB0, 0x00, 0x00, 0x10, 0x00, 0x00, 0xDF, 0x01, 0x00, 0x00, 0xDF, 0x01, 0x00, 0x00, 0x00}},
// {SH8601A_QSPI_INST_CMD_WRITE, 0xB4, 1, 65, {0x09, 0x02, 0x00, 0x00, 0x10, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x2C, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x02, 0x46, 0x8A, 0x13, 0x57, 0x9B, 0x31, 0x75, 0xB9, 0x20, 0x64, 0xA8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x64, 0xA8, 0x31, 0x75, 0xB9, 0x13, 0x57, 0x9B, 0x02, 0x46, 0x8A, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00}},
// {SH8601A_QSPI_INST_CMD_WRITE, 0xB5, 1, 58, {0x4C, 0x09, 0x09, 0x09, 0x49, 0x40, 0x00, 0x01, 0x2C, 0x00, 0x00, 0x00, 0x2C, 0x00, 0x1C, 0x04, 0x2C, 0x00, 0x1C, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x02, 0x00, 0x00, 0x03, 0x02, 0x6E, 0x00, 0x2C, 0x00, 0x2C, 0x00, 0x1C, 0x04, 0x00, 0x00, 0x00, 0x00, 0x2C, 0x00, 0x1C, 0x04, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x03, 0x00}},
// {SH8601A_QSPI_INST_CMD_WRITE, 0xB6, 1, 26, {0x00, 0x10, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x0C, 0x2C, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47, 0x47}},
// {SH8601A_QSPI_INST_CMD_WRITE, 0xB7, 1, 51, {0x0C, 0x00, 0x01, 0x2C, 0x00, 0x00, 0x00, 0x2C, 0x00, 0x1C, 0x04, 0x2C, 0x00, 0x1C, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x02, 0x00, 0x00, 0x03, 0x02, 0x6E, 0x00, 0x2C, 0x00, 0x2C, 0x00, 0x1C, 0x04, 0x00, 0x00, 0x00, 0x00, 0x2C, 0x00, 0x1C, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
// {SH8601A_QSPI_INST_CMD_WRITE, 0xB8, 1, 95, {0x00, 0x67, 0x31, 0x22, 0x22, 0x22, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x22, 0x22, 0x22, 0x22, 0x00, 0x00, 0x00, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x00, 0x00, 0x00, 0x22, 0x22, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x22, 0x22, 0x00, 0x22, 0x00, 0x22, 0x22, 0x22, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x22, 0x22, 0x22, 0x22, 0x00, 0x00, 0x00, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x00, 0x00, 0x00, 0x22, 0x22, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x22, 0x22, 0x00, 0x22, 0x00, 0x00, 0x00}},
// {SH8601A_QSPI_INST_CMD_WRITE, 0x2A, 1, 4, {0x00, 0x00, 0x01, 0xC5}},
// {SH8601A_QSPI_INST_CMD_WRITE, 0x2B, 1, 4, {0x00, 0x00, 0x01, 0xC5}},
// {SH8601A_QSPI_INST_CMD_WRITE, 0x44, 1, 2, {0x01, 0xC2}},
// {SH8601A_QSPI_INST_CMD_WRITE, 0x35, 1, 1, {0x00}},
// {SH8601A_QSPI_INST_CMD_WRITE, 0x51, 1, 1, {0xFF}},
// {SH8601A_QSPI_INST_CMD_WRITE, 0x4A, 1, 1, {0xFF}},
// {SH8601A_QSPI_INST_CMD_WRITE, 0x63, 1, 1, {0xFF}},
// {SH8601A_QSPI_INST_CMD_WRITE, 0x53, 1, 1, {0x28}},
// {SH8601A_QSPI_INST_CMD_WRITE, 0xC4, 25, 1, {0x84}},
// {SH8601A_QSPI_INST_CMD_WRITE, 0x29, 1, 0, {0}},
// {SH8601A_QSPI_INST_CMD_WRITE, 0xBA, 1, 1, {0x80}}, // bist: 0x81, exit bist: 0x80
// {SH8601A_QSPI_INST_CMD_WRITE, 0xB1, 1, 1, {0xC0}},
// {SH8601A_QSPI_INST_CMD_WRITE, 0xC1, 1, 2, {0xA5, 0xA5}},
// {SH8601A_QSPI_INST_CMD_WRITE, 0xC0, 1, 2, {0xA5, 0xA5}},
// {SH8601A_QSPI_SEQ_FINISH_CODE, 0, 0, 0, {0}},
{SH8601A_QSPI_INST_CMD_WRITE, 0xC0, 1, 2, {0x5A, 0x5A}},
{SH8601A_QSPI_INST_CMD_WRITE, 0xC1, 1, 2, {0x5A, 0x5A}},
{SH8601A_QSPI_INST_CMD_WRITE, 0x11, 10, 0, {0}},
{SH8601A_QSPI_INST_CMD_WRITE, 0x2A, 1, 4, {0x00, 0x00, 0x01, 0xC5}},
{SH8601A_QSPI_INST_CMD_WRITE, 0x2B, 1, 4, {0x00, 0x00, 0x01, 0xC5}},
{SH8601A_QSPI_INST_CMD_WRITE, 0x44, 1, 2, {0x01, 0xC2}},
{SH8601A_QSPI_INST_CMD_WRITE, 0x35, 1, 1, {0x00}},
{SH8601A_QSPI_INST_CMD_WRITE, 0xB0, 1, 1, {0x16}},
{SH8601A_QSPI_INST_CMD_WRITE, 0xB1, 1, 9, {0x01, 0x05, 0x00, 0xA2, 0x00, 0xA7, 0x00, 0xA7, 0x00}}, // 0x01=45Hz, 0x00=60Hz
//{SH8601A_QSPI_INST_CMD_WRITE, 0x51, 1, 1, {0xFF}},
//{SH8601A_QSPI_INST_CMD_WRITE, 0x4A, 1, 1, {0xFF}},
//{SH8601A_QSPI_INST_CMD_WRITE, 0x63, 1, 1, {0xFF}},
{SH8601A_QSPI_INST_CMD_WRITE, 0x53, 1, 1, {0x28}},
{SH8601A_QSPI_INST_CMD_WRITE, 0xC4, 25, 1, {0x84}},
{SH8601A_QSPI_INST_CMD_WRITE, 0x29, 1, 0, {0}},
//{SH8601A_QSPI_INST_CMD_WRITE, 0xBA, 1, 1, {0x80}}, // bist: 0x81, exit bist: 0x80
{SH8601A_QSPI_INST_CMD_WRITE, 0xB1, 1, 1, {0xC0}},
{SH8601A_QSPI_INST_CMD_WRITE, 0xC0, 1, 2, {0xA5, 0xA5}},
{SH8601A_QSPI_INST_CMD_WRITE, 0xC1, 1, 2, {0xA5, 0xA5}},
{SH8601A_QSPI_SEQ_FINISH_CODE, 0, 0, 0, {0}},
};
static const SH8601A_CMD_DESC SH8601A_POWEROFF_SEQ_CMD[] = {
{SH8601A_QSPI_INST_CMD_WRITE, 0x28, 15, 0, {0}},
{SH8601A_QSPI_INST_CMD_WRITE, 0x10, 0, 0, {0}},
{SH8601A_QSPI_SEQ_FINISH_CODE, 0, 0, 0, {0}},
};
static const SH8601A_CMD_DESC SH8601A_OTP_WRITE[] = {
{SH8601A_QSPI_INST_CMD_WRITE, 0xD0, 1000, 2, {0x01}},
{SH8601A_QSPI_INST_CMD_WRITE, 0xD0, 10, 2, {0x00}},
{SH8601A_QSPI_SEQ_FINISH_CODE, 0, 0, 0, {0}},
};
#ifdef USE_DMA_LINK_MODE
static DMA_LLI_InitTypeDef *Link_Channel = (void *)0x1fffe000;
#endif
static void write_cmd(uint8_t cmd)
{
uint8_t spi_data[4];
spi_data[0] = SH8601A_QSPI_INST_CMD_WRITE;
spi_data[1] = 0x00;
spi_data[2] = cmd;
spi_data[3] = 0x00;
__DISPLAY_CS_CLEAR();
spi_master_transmit_X1(&spi_display_handle, (uint16_t *)spi_data, 4);
__DISPLAY_CS_SET();
}
static void write_buff(uint8_t *buffer, uint8_t len)
{
__DISPLAY_CS_CLEAR();
spi_master_transmit_X1(&spi_display_handle, (uint16_t *)buffer, len);
__DISPLAY_CS_SET();
}
static void read_reg(uint8_t reg, uint8_t *buffer, uint16_t len)
{
uint8_t spi_data[4];
spi_data[0] = SH8601A_QSPI_INST_CMD_READ;
spi_data[1] = 0x00;
spi_data[2] = reg;
spi_data[3] = 0x00;
__DISPLAY_CS_CLEAR();
spi_master_transmit_X1(&spi_display_handle, (uint16_t *)spi_data, 4);
spi_master_receive_X1(&spi_display_handle, buffer, len);
__DISPLAY_CS_SET();
}
static void SH8601A_Reg_Write(const SH8601A_CMD_DESC* cmd)
{
uint16_t idx = 0;
while (cmd[idx].instruction != SH8601A_QSPI_SEQ_FINISH_CODE)
{
uint8_t sdat[cmd[idx].wordcount + 4];
sdat[0] = cmd[idx].instruction;
sdat[1] = 0;
sdat[2] = cmd[idx].index; // Set in the middle 8 bits ADDR[15:8] of the 24 bits ADDR[23:0]
sdat[3] = 0;
for(uint16_t i=0; i<cmd[idx].wordcount; i++)
{
sdat[i+4] = cmd[idx].payload[i];
}
__DISPLAY_CS_CLEAR();
spi_master_transmit_X1(&spi_display_handle, sdat, sizeof(sdat));
__DISPLAY_CS_SET();
if (cmd[idx].delay != 0)
{
__DISPLAY_DELAY_MS(cmd[idx].delay);
}
idx++;
}
}
static void SH8601A_Init_Pre_OTP(void)
{
//pull low RESX
//power on VBAT: VBAT = 3.7V
//power on VDDI: VDDI = 1.8V
//pull high VCI_EN: enable VCI = 3.3V
//delay 10ms
//pull high RESX: IC reset
//delay 10ms
SH8601A_Reg_Write(SH8601A_PRE_OTP_POWERON_SEQ_CMD);
}
static void SH8601A_Init_Post_OTP(void)
{
//pull low RESX
//power on VBAT: VBAT = 3.7V
//power on VDDI: VDDI = 1.8V
//pull high VCI_EN: enable VCI = 3.3V
//delay 10ms
//pull high RESX: IC reset
//delay 10ms
SH8601A_Reg_Write(SH8601A_POST_OTP_POWERON_SEQ_CMD);
}
static void SH8601A_Power_Off(void)
{
SH8601A_Reg_Write(SH8601A_POWEROFF_SEQ_CMD);
//delay 100ms
//pull low RESX
//delay 10ms
//pull low VCI_EN: disable VCI
//power off VDDI
//power off VBAT
}
static void SH8601A_OTP_Write(void)
{
/*********************************************
* Register read:
* Index: 0xCF (OTP_STATUS)
* Para: 1 Byte read
* Check BANK_CHECK_MCS[1:0]:
* - 00h: No writen, 3 times writable
* - 01h: 1 time written, 2 times writable
* - 02h: 2 times written, 1 time writable
* - 03h: 3 time written, no longer be written
**********************************************/
//power on VOTP: VOTP = 6V external supply
//delay 20ms
SH8601A_Reg_Write(SH8601A_OTP_WRITE);
//power off VOTP
//delay 20ms
/*********************************************
* OTP status verification:
* Index: 0xCF (OTP_STATUS)
* Para: 3 Bytes read
* Check PRG_ERR_1:
* - 0: OK
* - 1: FAIL
OTP rewrite(power off -> power on -> rewrite)
* Check PRG_ERR_0:
* - 0: OK
* - 1: FAIL
Not rewrite OTP
**********************************************/
/* Go to power off sequence */
}
static void sh8601a_read_regs(void)
{
uint8_t buffer[6];
read_reg(0x90, buffer, 6);
read_reg(0x2A, buffer, 4);
read_reg(0x2B, buffer, 4);
}
void sh8601z_init(void)
{
__DISPLAY_VCI_CLEAR();
__DISPLAY_RESET_CLEAR();
__DISPLAY_DELAY_MS(10);
__DISPLAY_VCI_SET();
__DISPLAY_DELAY_MS(10);
__DISPLAY_RESET_SET();
__DISPLAY_DELAY_MS(10);
SH8601A_Init_Pre_OTP();
}
void sh8601z_set_window(uint16_t x_s, uint16_t x_e, uint16_t y_s, uint16_t y_e)
{
uint8_t data[8];
x_s += 16;
x_e += 16;
data[0] = 0x02;
data[1] = 0x00;
data[2] = 0x2A;
data[3] = 0x00;
data[4] = x_s >> 8;
data[5] = x_s & 0xff;
data[6] = x_e >> 8;
data[7] = x_e & 0xff;
write_buff(data, 8);
data[0] = 0x02;
data[1] = 0x00;
data[2] = 0x2B;
data[3] = 0x00;
data[4] = y_s >> 8;
data[5] = y_s & 0xff;
data[6] = y_e >> 8;
data[7] = y_e & 0xff;
write_buff(data, 8);
// write_cmd(0x2c);
}
void sh8601z_display(uint32_t pixel_count, uint8_t pixel_width, void *data)
{
uint8_t frame_size;
if (pixel_width == 16) {
frame_size = SPI_FRAME_SIZE_16BIT;
}
else if (pixel_width == 32) {
frame_size = SPI_FRAME_SIZE_24BIT;
}
spi_display_handle.Init.Frame_Size = frame_size;
spi_display_handle.MultWireParam.Wire_X2X4X8 = Wire_X4;
spi_display_handle.MultWireParam.InstructLength = INST_8BIT;
spi_display_handle.MultWireParam.Instruct = 0x32;
spi_display_handle.MultWireParam.AddressLength = ADDR_24BIT;
spi_display_handle.MultWireParam.Address = 0x002C00;
__DISPLAY_CS_CLEAR();
spi_master_transmit_X2X4X8(&spi_display_handle, data, pixel_count);
__DISPLAY_CS_SET();
__SPI_DISABLE(spi_display_handle.SPIx);
__SPI_DATA_FRAME_SIZE(spi_display_handle.SPIx, SPI_FRAME_SIZE_8BIT);
}
void sh8601z_display_dma(uint32_t pixel_count, uint8_t pixel_width, void *data)
{
//#define USE_DMA_LINK_MODE
uint8_t spi_trans_width;
uint32_t dma_sample_count;
#ifdef USE_DMA_LINK_MODE
#define DMA_SINGLE_TRANSFER_SIZE 20000
uint32_t link_count;
uint32_t i;
uint32_t link_trans_size;
dma_LinkParameter_t LinkParameter;
switch (dma_display_handle.Init.Source_Width) {
case DMA_TRANSFER_WIDTH_32:
dma_sample_count = pixel_count * pixel_width / 32;
link_trans_size = 4 * DMA_SINGLE_TRANSFER_SIZE;
break;
case DMA_TRANSFER_WIDTH_16:
dma_sample_count = pixel_count * pixel_width / 16;
link_trans_size = 2 * DMA_SINGLE_TRANSFER_SIZE;
break;
case DMA_TRANSFER_WIDTH_8:
dma_sample_count = pixel_count * pixel_width / 8;
link_trans_size = DMA_SINGLE_TRANSFER_SIZE;
break;
default:
return;
}
link_count = dma_sample_count / DMA_SINGLE_TRANSFER_SIZE;
if(dma_sample_count % DMA_SINGLE_TRANSFER_SIZE)
{
link_count++;
}
for (i = 0; i < link_count; i++)
{
uint8_t all_set = (dma_sample_count <= DMA_SINGLE_TRANSFER_SIZE);
LinkParameter.SrcAddr = (uint32_t)data + i * link_trans_size;
LinkParameter.DstAddr = (uint32_t)&spi_display_handle.SPIx->DR;
if(all_set)
{
LinkParameter.NextLink = 0;
}
else
{
LinkParameter.NextLink = (uint32_t)&Link_Channel[i + 1];
}
LinkParameter.Data_Flow = dma_display_handle.Init.Data_Flow;
LinkParameter.Request_ID = dma_display_handle.Init.Request_ID;
LinkParameter.Source_Master_Sel = dma_display_handle.Init.Source_Master_Sel;
LinkParameter.Desination_Master_Sel = dma_display_handle.Init.Desination_Master_Sel;
LinkParameter.Source_Inc = dma_display_handle.Init.Source_Inc;
LinkParameter.Desination_Inc = dma_display_handle.Init.Desination_Inc;
LinkParameter.Source_Width = dma_display_handle.Init.Source_Width;
LinkParameter.Desination_Width = dma_display_handle.Init.Desination_Width;
LinkParameter.Source_Burst_Len = dma_display_handle.Init.Source_Burst_Len;
LinkParameter.Desination_Burst_Len = dma_display_handle.Init.Desination_Burst_Len;
LinkParameter.Size = all_set ? dma_sample_count : DMA_SINGLE_TRANSFER_SIZE;
LinkParameter.gather_enable = 0;
LinkParameter.scatter_enable = 0;
dma_sample_count -= DMA_SINGLE_TRANSFER_SIZE;
dma_linked_list_init(&Link_Channel[i], &LinkParameter);
}
#else
switch (dma_display_handle.Init.Source_Width) {
case DMA_TRANSFER_WIDTH_32:
dma_sample_count = pixel_count * pixel_width / 32;
break;
case DMA_TRANSFER_WIDTH_16:
dma_sample_count = pixel_count * pixel_width / 16;
break;
case DMA_TRANSFER_WIDTH_8:
dma_sample_count = pixel_count * pixel_width / 8;
break;
default:
return;
}
#endif
switch (dma_display_handle.Init.Desination_Width) {
case DMA_TRANSFER_WIDTH_32:
spi_trans_width = SPI_FRAME_SIZE_32BIT;
break;
case DMA_TRANSFER_WIDTH_16:
spi_trans_width = SPI_FRAME_SIZE_16BIT;
break;
case DMA_TRANSFER_WIDTH_8:
spi_trans_width = SPI_FRAME_SIZE_8BIT;
break;
default:
return;
}
spi_display_handle.Init.Frame_Size = spi_trans_width;
spi_display_handle.MultWireParam.Wire_X2X4X8 = Wire_X4;
spi_display_handle.MultWireParam.InstructLength = INST_8BIT;
spi_display_handle.MultWireParam.Instruct = 0x32;
spi_display_handle.MultWireParam.AddressLength = ADDR_24BIT;
spi_display_handle.MultWireParam.Address = 0x002C00;
__DISPLAY_CS_CLEAR();
__SPI_DISABLE(spi_display_handle.SPIx);
__SPI_TX_ENDIAN_SET(spi_display_handle.SPIx, TX_RX_Endian_4321);
__SPI_ENABLE(spi_display_handle.SPIx);
spi_master_transmit_X2X4X8_DMA(&spi_display_handle);
__SPI_DISABLE(spi_display_handle.SPIx);
if (spi_trans_width == SPI_FRAME_SIZE_32BIT) {
__SPI_TX_ENDIAN_SET(spi_display_handle.SPIx, TX_RX_Endian_2143);
}
else {
__SPI_TX_ENDIAN_SET(spi_display_handle.SPIx, TX_RX_Endian_4321);
}
__SPI_ENABLE(spi_display_handle.SPIx);
#ifndef USE_DMA_LINK_MODE
dma_start_IT(&dma_display_handle, (uint32_t)data, (uint32_t)&spi_display_handle.SPIx->DR, dma_sample_count);
#else
dma_linked_list_start_IT(Link_Channel, &LinkParameter, &dma_display_handle);
#endif
}
void sh8601z_power_off(void)
{
SH8601A_Power_Off();
__DISPLAY_DELAY_MS(100);
__DISPLAY_RESET_CLEAR();
__DISPLAY_DELAY_MS(10);
__DISPLAY_VCI_CLEAR();
}
void sh8601z_power_on(void)
{
__DISPLAY_VCI_CLEAR();
__DISPLAY_RESET_CLEAR();
__DISPLAY_DELAY_MS(10);
__DISPLAY_VCI_SET();
__DISPLAY_DELAY_MS(10);
__DISPLAY_RESET_SET();
__DISPLAY_DELAY_MS(10);
SH8601A_Init_Pre_OTP();
}
void sh8601z_display_dma_isr(void)
{
while(__SPI_IS_BUSY(spi_display_handle.SPIx));
// CS Release
__DISPLAY_CS_SET();
/* Clear Transfer complete status */
dma_clear_tfr_Status(&dma_display_handle);
/* channel Transfer complete interrupt disable */
dma_tfr_interrupt_disable(&dma_display_handle);
__SPI_DISABLE(spi_display_handle.SPIx);
__SPI_TX_ENDIAN_SET(spi_display_handle.SPIx, TX_RX_Endian_4321);
__SPI_DATA_FRAME_SIZE(spi_display_handle.SPIx, SPI_FRAME_SIZE_8BIT);
}

View File

@ -0,0 +1,20 @@
#ifndef __DRIVER_SH8601A_H
#define __DRIVER_SH8601A_H
#include <stdint.h>
void sh8601z_init(void);
void sh8601z_set_window(uint16_t x_s, uint16_t x_e, uint16_t y_s, uint16_t y_e);
void sh8601z_display(uint32_t pixel_count, uint8_t pixel_width, void *data);
void sh8601z_display_dma(uint32_t pixel_count, uint8_t pixel_width, void *data);
void sh8601z_power_off(void);
void sh8601z_power_on(void);
void sh8601z_display_dma_isr(void);
#endif // __DRIVER_SH8601A_H

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,139 @@
#ifndef __DRIVER_ST7701_RGB_H__
#define __DRIVER_ST7701_RGB_H__
#include "fr30xx.h"
#include "app_config.h"
#define RGB_ROW 480
#define RGB_COLUMN 480
/* Exported functions --------------------------------------------------------*/
typedef struct
{
uint32_t VerticalSignalCount;
unsigned char *rgb_TxData;
}struct_RGB_TypeDef_t;
#define RGB565_LCD_DCLK_PORT GPIOB
#define RGB565_LCD_DCLK_GPIO GPIO_PIN_13
#define RGB565_LCD_VSYNC_PORT GPIOB
#define RGB565_LCD_VSYNC_GPIO GPIO_PIN_14
#define RGB565_LCD_HSYNC_PORT GPIOB
#define RGB565_LCD_HSYNC_GPIO GPIO_PIN_15
#define RGB565_LCD_DISP_PORT GPIOA
#define RGB565_LCD_DISP_GPIO GPIO_PIN_6
#define RGB565_LCD_DE_EN_PORT GPIOB
#define RGB565_LCD_DE_EN_GPIO GPIO_PIN_12
#define RGB565_LCD_DATA_PORT GPIOC
#define RGB565_LCD_DATA_GPIO 0xFFFF //GPIO_PIN_0|GPIO_PIN_1|GPIO_PIN_2|GPIO_PIN_3|GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7
#define RGB565_LCD_RESET_PORT GPIOD
#define RGB565_LCD_RESET_GPIO GPIO_PIN_13
#define RGB565_LCD_BACKLIGHT_PORT GPIOA
#define RGB565_LCD_BACKLIGHT_GPIO GPIO_PIN_6
#ifdef RGB565_LCD_TE_EN
#define RGB565_LCD_TE_PORT GPIO_B
#define RGB565_LCD_TE_GPIO GPIO_PIN_7
#endif
#define RGB56_LCD_INIT_CONFIG
#ifdef RGB56_LCD_INIT_CONFIG
#define RGB565_LCD_SPI_CS_PORT GPIOD
#define RGB565_LCD_SPI_CS_GPIO GPIO_PIN_12
#define RGB565_LCD_SPI_CLK_PORT GPIOB
#define RGB565_LCD_SPI_CLK_GPIO GPIO_PIN_0
#define RGB565_LCD_SPI_MOSI_PORT GPIOB
#define RGB565_LCD_SPI_MOSI_GPIO GPIO_PIN_2
#define RGB565_LCD_SPI_MISO_PORT GPIOB
#define RGB565_LCD_SPI_MISO_GPIO GPIO_PIN_3
#define RGB565_LCD_SPI_SEL SPIM0
#define rgb_spi_cs_set() gpio_write_pin(RGB565_LCD_SPI_CS_PORT,RGB565_LCD_SPI_CS_GPIO,GPIO_PIN_CLEAR)
#define rgb_spi_cs_release() gpio_write_pin(RGB565_LCD_SPI_CS_PORT,RGB565_LCD_SPI_CS_GPIO,GPIO_PIN_SET)
#endif
/* signal drive*/
#define rgb_lcd_enable_set() gpio_write_pin(RGB565_LCD_DE_EN_PORT,RGB565_LCD_DE_EN_GPIO,GPIO_PIN_SET)
#define rgb_lcd_enable_release() gpio_write_pin(RGB565_LCD_DE_EN_PORT,RGB565_LCD_DE_EN_GPIO,GPIO_PIN_CLEAR)
#define rgb_lcd_vsync_set() gpio_write_pin(RGB565_LCD_VSYNC_PORT,RGB565_LCD_VSYNC_GPIO,GPIO_PIN_SET)
#define rgb_lcd_vsync_release() gpio_write_pin(RGB565_LCD_VSYNC_PORT,RGB565_LCD_VSYNC_GPIO,GPIO_PIN_CLEAR)
#define rgb_lcd_hsync_set() gpio_write_pin(RGB565_LCD_HSYNC_PORT,RGB565_LCD_HSYNC_GPIO,GPIO_PIN_SET)
#define rgb_lcd_hsync_release() gpio_write_pin(RGB565_LCD_HSYNC_PORT,RGB565_LCD_HSYNC_GPIO,GPIO_PIN_CLEAR)
#define rgb_lcd_reset_set() gpio_write_pin(RGB565_LCD_RESET_PORT,RGB565_LCD_RESET_GPIO,GPIO_PIN_SET)
#define rgb_lcd_reset_release() gpio_write_pin(RGB565_LCD_RESET_PORT,RGB565_LCD_RESET_GPIO,GPIO_PIN_CLEAR)
#define rgb_lcd_disp_set() gpio_write_pin(RGB565_LCD_DISP_PORT,RGB565_LCD_DISP_GPIO,GPIO_PIN_SET)
#define rgb_lcd_disp_release() gpio_write_pin(RGB565_LCD_DISP_PORT,RGB565_LCD_DISP_GPIO,GPIO_PIN_CLEAR)
#define rgb_lcd_backlight_set() gpio_write_pin(RGB565_LCD_BACKLIGHT_PORT,RGB565_LCD_BACKLIGHT_GPIO,GPIO_PIN_SET)
#define rgb_lcd_backlight_release() gpio_write_pin(RGB565_LCD_BACKLIGHT_PORT,RGB565_LCD_BACKLIGHT_GPIO,GPIO_PIN_CLEAR)
#define __RGB_LCD_DENABLE_SET rgb_lcd_enable_release
#define __RGB_LCD_DENABLE_RELEASE rgb_lcd_enable_set
#define __RGB_LCD_VSYNC_SET rgb_lcd_vsync_set
#define __RGB_LCD_VSYNC__RELEASE rgb_lcd_vsync_release
#define __RGB_LCD_HSYNC_SET rgb_lcd_hsync_set
#define __RGB_LCD_HSYNC__RELEASE rgb_lcd_hsync_release
#define __RGB_LCD_RESET_SET rgb_lcd_reset_set
#define __RGB_LCD_RESET_RELEASE rgb_lcd_reset_release
#define __RGB_SPI_CS_RELEASE rgb_spi_cs_release
#define __RGB_SPI_CS_SET rgb_spi_cs_set
#define __8080_DATA_WR_LEN(__LEVEL__) __PARALLEL_SET_WR_LEN(hparallel.PARALLELx,__LEVEL__)
#define __8080_TXFIFO_EMPTY() __PARALLEL_INT_STATUS(hparallel.PARALLELx)&INT_TXFIFO_EMPTY
#define __8080_WRITE_BLANK() hparallel.PARALLELx->TX_FIFO = 0
#define __TIMER_CLEAR_IQR(__TIMERx__) timer_int_clear(__TIMERx__)
#define __TIMER_INIT(__TIMERx__, __LoadCount__) timer_init(__TIMERx__, (24000 * __LoadCount__))
#define __TIMER_INT_ENABLE(__TIMERx__) timer_int_enable(__TIMERx__)
#define __TIMER_START(__TIMERx__) timer_start(__TIMERx__)
#define __DMA_GET_TFR_STATUS() dma_get_tfr_Status(&dma_handle)
#define __DMA_CLEAR_TFR_STATUS() dma_clear_tfr_Status(&dma_handle)
#define __DMA_TO_8080_START_IT(__BUFFER__,__SIZE__) dma_start_IT(&dma_handle, (uint32_t)__BUFFER__, (uint32_t)&hparallel.PARALLELx->TX_FIFO, __SIZE__)
#define __SPI_WRITE_DATA(__BUFFER__, __SIZE__) spi_master_transmit_X1(&spi_handle, (void *)__BUFFER__, __SIZE__)
/* Exported functions --------------------------------------------------------*/
/* rgb_display_start */
/* rgb_timer_IRQHandler */
/* rgb_dma_IRQHandler */
void rgb_display_start(struct_Timer_t *TIMERx, struct_RGB_TypeDef_t *hrgb, uint32_t fps, unsigned char *Imagedata);
void rgb_timer_IRQHandler(struct_Timer_t *TIMERx, struct_RGB_TypeDef_t *hrgb);
void rgb_dma_IRQHandler(struct_RGB_TypeDef_t *hrgb);
void st7701_init(void* buffer);
void st7701_rgb_display_dma_irq(void);
__RAM_CODE void rgb_display_dma_irq(void);
#endif