464 lines
10 KiB
C
464 lines
10 KiB
C
/*
|
|
******************************************************************************
|
|
* @file rgb565.c
|
|
* @author FreqChip Firmware Team
|
|
* @version V1.0.0
|
|
* @date 2023
|
|
* @brief rgb565 IC driver.
|
|
* This file provides firmware functions to manage the following
|
|
* functionalities of the 8080 SPI Timer and DMA norflash driver for rgb565.
|
|
* @ Initialization and de-initialization functions
|
|
* @ IO operation functions
|
|
* @ Peripheral Control functions
|
|
******************************************************************************
|
|
* @attention
|
|
*
|
|
* Copyright (c) 2023 FreqChip.
|
|
* All rights reserved.
|
|
******************************************************************************
|
|
*/
|
|
#include "rgb565.h"
|
|
#include "app_config.h"
|
|
|
|
#if BOARD_SEL == BOARD_EVB_FR3092E_RGB
|
|
|
|
#ifdef RGB56_LCD_INIT_CONFIG
|
|
static void rgb_reg_writer(uint16_t *fp_data, uint32_t size)
|
|
{
|
|
__RGB_SPI_CS_SET();
|
|
/* fp_Data[0] stores command, while others store data
|
|
Bit8 set to 1 as data, otherwise it is a command
|
|
*/
|
|
for(int i = 1; i < size; i++)
|
|
{
|
|
fp_data[i] = fp_data[i] + 0x100;
|
|
}
|
|
|
|
__SPI_WRITE_DATA(fp_data,size);
|
|
|
|
__RGB_SPI_CS_RELEASE();
|
|
}
|
|
#endif
|
|
static void rgb_idle_clock(uint32_t count)
|
|
{
|
|
/* 8080 hits idle Clocks */
|
|
__8080_DATA_WR_LEN(count);
|
|
for(int i = 0; i < count/2; i++)
|
|
__8080_WRITE_BLANK();
|
|
}
|
|
|
|
static void Line_porch_set(uint32_t count)
|
|
{
|
|
for(int i = 0; i < count; i++)
|
|
{
|
|
__RGB_LCD_HSYNC__RELEASE();
|
|
//__RGB_LCD_DENABLE_RELEASE();
|
|
__RGB_LCD_DENABLE_SET();
|
|
rgb_idle_clock(4);
|
|
|
|
__RGB_LCD_HSYNC_SET();
|
|
rgb_idle_clock(RGB_ROW);
|
|
}
|
|
}
|
|
|
|
static void Vertical_back_porch_set(void)
|
|
{
|
|
__RGB_LCD_HSYNC__RELEASE();
|
|
__RGB_LCD_DENABLE_SET();
|
|
rgb_idle_clock(4);
|
|
|
|
__RGB_LCD_HSYNC_SET();
|
|
|
|
rgb_idle_clock(4);
|
|
|
|
while(!(__8080_TXFIFO_EMPTY()));
|
|
}
|
|
|
|
static void Vertical_front_porch_set(void)
|
|
{
|
|
__RGB_LCD_HSYNC_SET();
|
|
__RGB_LCD_DENABLE_SET();
|
|
|
|
rgb_idle_clock(4);
|
|
|
|
while(!(__8080_TXFIFO_EMPTY()));
|
|
}
|
|
|
|
void rgb_init(void)
|
|
{
|
|
uint16_t WBuffer[20];
|
|
|
|
__RGB_LCD_RESET_RELEASE();
|
|
system_delay_us(50 * 1000);
|
|
__RGB_LCD_RESET_SET();
|
|
system_delay_us(1000 * 120);
|
|
|
|
#ifdef RGB56_LCD_INIT_CONFIG
|
|
WBuffer[0] = 0xFF;
|
|
WBuffer[1] = 0x77;
|
|
WBuffer[2] = 0x01;
|
|
WBuffer[3] = 0x00;
|
|
WBuffer[4] = 0x00;
|
|
WBuffer[5] = 0x10;
|
|
rgb_reg_writer(WBuffer, 6);
|
|
|
|
WBuffer[0] = 0xC0;
|
|
WBuffer[1] = 0x3B;
|
|
WBuffer[2] = 0x00;
|
|
rgb_reg_writer(WBuffer, 3);
|
|
|
|
WBuffer[0] = 0xC1;
|
|
WBuffer[1] = 0x10;
|
|
WBuffer[2] = 0x0C;
|
|
rgb_reg_writer(WBuffer, 3);
|
|
|
|
WBuffer[0] = 0xC2;
|
|
WBuffer[1] = 0x21;
|
|
WBuffer[2] = 0x0A;
|
|
rgb_reg_writer(WBuffer, 3);
|
|
|
|
WBuffer[0] = 0xB0;
|
|
WBuffer[1] = 0x40;
|
|
WBuffer[2] = 0x09;
|
|
WBuffer[3] = 0x4F;
|
|
WBuffer[4] = 0x0B;
|
|
WBuffer[5] = 0x10;
|
|
WBuffer[6] = 0x07;
|
|
WBuffer[7] = 0x00;
|
|
WBuffer[8] = 0x08;
|
|
WBuffer[9] = 0x06;
|
|
WBuffer[10] = 0x20;
|
|
WBuffer[11] = 0x02;
|
|
WBuffer[12] = 0x12;
|
|
WBuffer[13] = 0x0F;
|
|
WBuffer[14] = 0x67;
|
|
WBuffer[15] = 0x2E;
|
|
WBuffer[16] = 0xDF;
|
|
rgb_reg_writer(WBuffer, 17);
|
|
|
|
WBuffer[0] = 0xB1;
|
|
WBuffer[1] = 0x4F;
|
|
WBuffer[2] = 0x18;
|
|
WBuffer[3] = 0x60;
|
|
WBuffer[4] = 0x0E;
|
|
WBuffer[5] = 0x10;
|
|
WBuffer[6] = 0x04;
|
|
WBuffer[7] = 0x0C;
|
|
WBuffer[8] = 0x08;
|
|
WBuffer[9] = 0x09;
|
|
WBuffer[10] = 0x26;
|
|
WBuffer[11] = 0x07;
|
|
WBuffer[12] = 0x13;
|
|
WBuffer[13] = 0x11;
|
|
WBuffer[14] = 0x71;
|
|
WBuffer[15] = 0x39;
|
|
WBuffer[16] = 0xDF;
|
|
rgb_reg_writer(WBuffer, 17);
|
|
|
|
WBuffer[0] = 0xFF;
|
|
WBuffer[1] = 0x77;
|
|
WBuffer[2] = 0x01;
|
|
WBuffer[3] = 0x00;
|
|
WBuffer[4] = 0x00;
|
|
WBuffer[5] = 0x11;
|
|
rgb_reg_writer(WBuffer, 6);
|
|
|
|
WBuffer[0] = 0xB0;
|
|
WBuffer[1] = 0x4D;
|
|
rgb_reg_writer(WBuffer, 2);
|
|
|
|
WBuffer[0] = 0xB1;
|
|
WBuffer[1] = 0x41;
|
|
rgb_reg_writer(WBuffer, 2);
|
|
|
|
WBuffer[0] = 0xB2;
|
|
WBuffer[1] = 0x87;
|
|
rgb_reg_writer(WBuffer, 2);
|
|
|
|
WBuffer[0] = 0xB3;
|
|
WBuffer[1] = 0x80;
|
|
rgb_reg_writer(WBuffer, 2);
|
|
|
|
WBuffer[0] = 0xB5;
|
|
WBuffer[1] = 0x49;
|
|
rgb_reg_writer(WBuffer, 2);
|
|
|
|
WBuffer[0] = 0xB7;
|
|
WBuffer[1] = 0x87;
|
|
rgb_reg_writer(WBuffer, 2);
|
|
|
|
WBuffer[0] = 0xB8;
|
|
WBuffer[1] = 0x23;
|
|
rgb_reg_writer(WBuffer, 2);
|
|
|
|
WBuffer[0] = 0xC0;
|
|
WBuffer[1] = 0x07;
|
|
rgb_reg_writer(WBuffer, 2);
|
|
|
|
WBuffer[0] = 0xC1;
|
|
WBuffer[1] = 0x78;
|
|
rgb_reg_writer(WBuffer, 2);
|
|
|
|
WBuffer[0] = 0xC2;
|
|
WBuffer[1] = 0x78;
|
|
rgb_reg_writer(WBuffer, 2);
|
|
|
|
WBuffer[0] = 0xD0;
|
|
WBuffer[1] = 0x88;
|
|
rgb_reg_writer(WBuffer, 2);
|
|
|
|
system_delay_us(100 * 1000);
|
|
|
|
WBuffer[0] = 0xE0;
|
|
WBuffer[1] = 0x00;
|
|
WBuffer[2] = 0x00;
|
|
WBuffer[3] = 0x00;
|
|
WBuffer[4] = 0x00;
|
|
rgb_reg_writer(WBuffer, 5);
|
|
|
|
WBuffer[0] = 0xE1;
|
|
WBuffer[1] = 0x04;
|
|
WBuffer[2] = 0xA0;
|
|
WBuffer[3] = 0x06;
|
|
WBuffer[4] = 0xA0;
|
|
WBuffer[5] = 0x05;
|
|
WBuffer[6] = 0xA0;
|
|
WBuffer[7] = 0x07;
|
|
WBuffer[8] = 0xA0;
|
|
WBuffer[9] = 0x00;
|
|
WBuffer[10] = 0x44;
|
|
WBuffer[11] = 0x44;
|
|
rgb_reg_writer(WBuffer, 12);
|
|
|
|
WBuffer[0] = 0xE2;
|
|
WBuffer[1] = 0x11;
|
|
WBuffer[2] = 0x11;
|
|
WBuffer[3] = 0x44;
|
|
WBuffer[4] = 0x44;
|
|
WBuffer[5] = 0xE9;
|
|
WBuffer[6] = 0xA0;
|
|
WBuffer[7] = 0xEB;
|
|
WBuffer[8] = 0xA0;
|
|
WBuffer[9] = 0xEA;
|
|
WBuffer[10] = 0xA0;
|
|
WBuffer[11] = 0xEC;
|
|
WBuffer[12] = 0xA0;
|
|
WBuffer[13] = 0x00;
|
|
rgb_reg_writer(WBuffer, 14);
|
|
|
|
WBuffer[0] = 0xE3;
|
|
WBuffer[1] = 0x00;
|
|
WBuffer[2] = 0x00;
|
|
WBuffer[3] = 0x11;
|
|
WBuffer[4] = 0x11;
|
|
rgb_reg_writer(WBuffer, 5);
|
|
|
|
WBuffer[0] = 0xE4;
|
|
WBuffer[1] = 0x44;
|
|
WBuffer[2] = 0x44;
|
|
rgb_reg_writer(WBuffer, 3);
|
|
|
|
WBuffer[0] = 0xE5;
|
|
WBuffer[1] = 0x06;
|
|
WBuffer[2] = 0xEA;
|
|
WBuffer[3] = 0xA0;
|
|
WBuffer[4] = 0xA0;
|
|
WBuffer[5] = 0x08;
|
|
WBuffer[6] = 0xEC;
|
|
WBuffer[7] = 0xA0;
|
|
WBuffer[8] = 0xA0;
|
|
WBuffer[9] = 0x0A;
|
|
WBuffer[10] = 0xEE;
|
|
WBuffer[11] = 0xA0;
|
|
WBuffer[12] = 0xA0;
|
|
WBuffer[13] = 0x0C;
|
|
WBuffer[14] = 0xF0;
|
|
WBuffer[15] = 0xA0;
|
|
WBuffer[16] = 0xA0;
|
|
rgb_reg_writer(WBuffer, 17);
|
|
|
|
WBuffer[0] = 0xE6;
|
|
WBuffer[1] = 0x00;
|
|
WBuffer[2] = 0x00;
|
|
WBuffer[3] = 0x11;
|
|
WBuffer[4] = 0x11;
|
|
rgb_reg_writer(WBuffer, 5);
|
|
|
|
WBuffer[0] = 0xE7;
|
|
WBuffer[1] = 0x44;
|
|
WBuffer[2] = 0x44;
|
|
rgb_reg_writer(WBuffer, 3);
|
|
|
|
WBuffer[0] = 0xE8;
|
|
WBuffer[1] = 0x07;
|
|
WBuffer[2] = 0xEB;
|
|
WBuffer[3] = 0xA0;
|
|
WBuffer[4] = 0xA0;
|
|
WBuffer[5] = 0x09;
|
|
WBuffer[6] = 0xED;
|
|
WBuffer[7] = 0xA0;
|
|
WBuffer[8] = 0xA0;
|
|
WBuffer[9] = 0x0B;
|
|
WBuffer[10] = 0xEF;
|
|
WBuffer[11] = 0xA0;
|
|
WBuffer[12] = 0xA0;
|
|
WBuffer[13] = 0x0D;
|
|
WBuffer[14] = 0xF1;
|
|
WBuffer[15] = 0xA0;
|
|
WBuffer[16] = 0xA0;
|
|
rgb_reg_writer(WBuffer, 17);
|
|
|
|
WBuffer[0] = 0xE9;
|
|
WBuffer[1] = 0x36;
|
|
WBuffer[2] = 0x00;
|
|
rgb_reg_writer(WBuffer, 3);
|
|
|
|
WBuffer[0] = 0xEB;
|
|
WBuffer[1] = 0x00;
|
|
WBuffer[2] = 0x00;
|
|
WBuffer[3] = 0x4E;
|
|
WBuffer[4] = 0x4E;
|
|
WBuffer[5] = 0xEE;
|
|
WBuffer[6] = 0x44;
|
|
WBuffer[7] = 0x40;
|
|
rgb_reg_writer(WBuffer, 8);
|
|
|
|
WBuffer[0] = 0xED;
|
|
WBuffer[1] = 0xFF;
|
|
WBuffer[2] = 0xFF;
|
|
WBuffer[3] = 0x76;
|
|
WBuffer[4] = 0x54;
|
|
WBuffer[5] = 0xC1;
|
|
WBuffer[6] = 0x0F;
|
|
WBuffer[7] = 0xB2;
|
|
WBuffer[8] = 0x3F;
|
|
WBuffer[9] = 0x32;
|
|
WBuffer[10] = 0xBF;
|
|
WBuffer[11] = 0x01;
|
|
WBuffer[12] = 0xC4;
|
|
WBuffer[13] = 0x56;
|
|
WBuffer[14] = 0x7F;
|
|
WBuffer[15] = 0xFF;
|
|
WBuffer[16] = 0xFF;
|
|
rgb_reg_writer(WBuffer, 17);
|
|
|
|
WBuffer[0] = 0xFF;
|
|
WBuffer[1] = 0x77;
|
|
WBuffer[2] = 0x01;
|
|
WBuffer[3] = 0x00;
|
|
WBuffer[4] = 0x00;
|
|
WBuffer[5] = 0x00;
|
|
rgb_reg_writer(WBuffer, 6);
|
|
|
|
WBuffer[0] = 0x35;
|
|
WBuffer[1] = 0x00;
|
|
rgb_reg_writer(WBuffer, 2);
|
|
|
|
WBuffer[0] = 0x36;
|
|
WBuffer[1] = 0x00;
|
|
rgb_reg_writer(WBuffer, 2);
|
|
|
|
WBuffer[0] = 0x3A;
|
|
WBuffer[1] = 0x66;
|
|
rgb_reg_writer(WBuffer, 2);
|
|
|
|
WBuffer[0] = 0x11;
|
|
rgb_reg_writer(WBuffer,1);
|
|
|
|
system_delay_us(200 * 1000);
|
|
|
|
WBuffer[0] = 0x29;
|
|
rgb_reg_writer(WBuffer,1);
|
|
#endif
|
|
|
|
system_delay_us(50 * 1000);
|
|
}
|
|
|
|
void rgb_display_start(struct_Timer_t *TIMERx, struct_RGB_TypeDef_t *hrgb, uint32_t fps, unsigned char *Imagedata)
|
|
{
|
|
__TIMER_INIT(TIMERx, fps);
|
|
__TIMER_INT_ENABLE(TIMERx);
|
|
|
|
hrgb->rgb_TxData = Imagedata;
|
|
hrgb->VerticalSignalCount = 0;
|
|
|
|
__TIMER_START(TIMERx);
|
|
}
|
|
|
|
volatile uint32_t time_cnt1=0;
|
|
volatile uint32_t time_cnt2=0;
|
|
extern uint32_t get_system_dwt_value();
|
|
|
|
void rgb_timer_IRQHandler(struct_Timer_t *TIMERx, struct_RGB_TypeDef_t *hrgb)
|
|
{
|
|
__TIMER_CLEAR_IQR(TIMERx);
|
|
|
|
/* If the previous frame is not completed ,return */
|
|
if(hrgb->VerticalSignalCount != 0)
|
|
{
|
|
return;
|
|
}
|
|
|
|
//printf("t:%d\r\n",(get_system_dwt_value()-time_cnt1)/192);
|
|
/* Vertical signal Start*/
|
|
__RGB_LCD_VSYNC__RELEASE();
|
|
Line_porch_set(4);
|
|
__RGB_LCD_VSYNC_SET();
|
|
Line_porch_set(8);
|
|
|
|
/* set Vertical back porch signal */
|
|
Vertical_back_porch_set();
|
|
|
|
/* send First Row */
|
|
__RGB_LCD_DENABLE_RELEASE();
|
|
__8080_DATA_WR_LEN(RGB_ROW);
|
|
|
|
__DMA_TO_8080_START_IT(&hrgb->rgb_TxData[0], RGB_ROW / 2);
|
|
time_cnt1 = get_system_dwt_value();
|
|
|
|
}
|
|
|
|
volatile uint8_t te_sign;
|
|
|
|
|
|
void rgb_dma_IRQHandler(struct_RGB_TypeDef_t *hrgb)
|
|
{
|
|
if (__DMA_GET_TFR_STATUS())
|
|
{
|
|
__DMA_CLEAR_TFR_STATUS();
|
|
|
|
hrgb->VerticalSignalCount++;
|
|
}
|
|
|
|
while(!(__8080_TXFIFO_EMPTY()));
|
|
|
|
/* Row *Column End of one frame transmission */
|
|
if(hrgb->VerticalSignalCount == RGB_COLUMN) //12ms
|
|
{
|
|
te_sign = 0;
|
|
hrgb->VerticalSignalCount = 0;
|
|
|
|
__RGB_LCD_VSYNC_SET();
|
|
|
|
Line_porch_set(8);
|
|
|
|
return;
|
|
}
|
|
// else if(hrgb->VerticalSignalCount == 360)
|
|
else if(hrgb->VerticalSignalCount == 180)
|
|
{
|
|
te_sign = 1;
|
|
}
|
|
|
|
/* set Vertical back porch signal and back porch signal */
|
|
Vertical_front_porch_set();
|
|
Vertical_back_porch_set();
|
|
|
|
/* send next Row */
|
|
__RGB_LCD_DENABLE_RELEASE();
|
|
__8080_DATA_WR_LEN(RGB_ROW);
|
|
__DMA_TO_8080_START_IT(&hrgb->rgb_TxData[RGB_ROW * hrgb->VerticalSignalCount * 2], RGB_ROW / 2);
|
|
}
|
|
|
|
#endif
|