/*******************************************************************************
  Title: LCBI non TFT module

  Implementation of the LCBI non TFT mode 8 bit Adafruit MI0283QT.

*/

/*******************************************************************************
  Section: Includes
*/

#include "r_typedefs.h" /* Renesas basic types, e.g. uint32_t */
#include "LCD_MonoTFT.h"
#include "LCD_BUS.h"
#include "r_bsp_api.h"
#include "r_dev_api.h"
#include "r_lcbi_api.h"
#include "r_dma_api.h"
#include "r_gpio_api.h"
#include "LCBI_DMA.h"
#include "r_config_lcbi.h"
#include "api_tft.h"
#include "r_gpio_api.h"
#include "r_gpio_sys.h"

#define DISPLAY_WIDTH  240
#define DISPLAY_HEIGHT 320

/* RST pin just use a GPIO for this */
#define RST_PORT (45)
#define RST_PIN  (5)

static void loc_SetAddrWindow(uint16_t starPage, uint16_t endPage);

uint32_t *LCDPanelGraphicRAM;
/*-------------------------------------------------------------------------
* Function Name  : bsp_LCD_DelayUs
* Description    :
* Input          : None
* Output         : None
* Return         : None
* onther         :
--------------------------------------------------------------------------*/
void bsp_LCD_DelayUs(uint32_t waitTime)
{
    uint32_t i = 0;
    for ( i = 0; i < waitTime; i++ )
    {
        ;
    }
}
uint16_t LCD_ActiveCheckTime = 0;

void LCD_Panel_Start_Up(void)
{
    uint8_t Para [ 4 ];
    LCDPanelGraphicRAM = Draw_GetVramAddress(0);
    Draw_TopClearVram(0);
    Draw_TopClearVram(1);
    Draw_ClearVram(0);
    Draw_ClearVram(1);

    // Reset Panel
    R_SYS_GPIO_SetPin(RST_PORT, RST_PIN, 0);
    bsp_LCD_DelayUs(wait_2000us);
    R_SYS_GPIO_SetPin(RST_PORT, RST_PIN, 1);
    bsp_LCD_DelayUs(wait_2000us);
    /* allow some time to settle */
    bsp_LCD_DelayUs(wait_20ms);

    // Panel Init
    Para [ 0 ] = 0xA5;
    Lcbi_WriteControlData(0x5E, Para, 1);
    bsp_LCD_DelayUs(wait_2000us);

    Para [ 0 ] = 0x0e;
    Para [ 1 ] = 0x00;
    Para [ 2 ] = 0x00;
    Para [ 3 ] = 0xa5;
    Lcbi_WriteControlData(0x49, Para, 4);    // VCOM OFFSET DATA

    Para [ 0 ] = 0x8f;
    Para [ 1 ] = 0x44;
    Para [ 2 ] = 0x02;
    Para [ 3 ] = 0xa5;
    Lcbi_WriteControlData(0x61, Para, 4);    // Power Control

    bsp_LCD_DelayUs(wait_20ms);

    Para [ 0 ] = 0x20;
    Para [ 1 ] = 0x71;
    Para [ 2 ] = 0xa5;
    Para [ 3 ] = 0xa5;
    Lcbi_WriteControlData(0x5a, Para, 4);    // Charge Pump Setting

    Para [ 0 ] = 0x3d;
    Para [ 1 ] = 0x0b;
    Para [ 2 ] = 0x0b;
    Para [ 3 ] = 0xA5;
    Lcbi_WriteControlData(0x71, Para, 4);    // Electronic Volume Set 1

    Para [ 0 ] = 0x19;
    Para [ 1 ] = 0x19;
    Para [ 2 ] = 0xa5;
    Para [ 3 ] = 0xa5;
    Lcbi_WriteControlData(0x72, Para, 4);    // Electronic Volume Set 2

    Para [ 0 ] = 0x01;
    Para [ 1 ] = 0x3F;
    Para [ 2 ] = 0x00;
    Para [ 3 ] = 0xEF;
    Lcbi_WriteControlData(0x91, Para, 4);    // DISAR

    Para [ 0 ] = 0x32;
    Para [ 1 ] = 0x46;    // 0x2F;//20220322
    Para [ 2 ] = 0x00;
    Para [ 3 ] = 0x00;
    Lcbi_WriteControlData(0x92, Para, 4);    // DISAR

    Para [ 0 ] = 0x01;
    Para [ 1 ] = 0xa5;
    Para [ 2 ] = 0xa5;
    Para [ 3 ] = 0xa5;
    Lcbi_WriteControlData(0x21, Para, 4);    // MADCTL

    Para [ 0 ] = 0x00;
    Para [ 1 ] = 0xa5;
    Para [ 2 ] = 0xa5;
    Para [ 3 ] = 0xa5;
    Lcbi_WriteControlData(0x24, Para, 4);    // STFRAME

    Para [ 0 ] = 0x03;
    Para [ 1 ] = 0xa5;
    Para [ 2 ] = 0xa5;
    Para [ 3 ] = 0xa5;
    Lcbi_WriteControlData(0x25, Para, 4);    // BPPSEL

    Para [ 0 ] = 0x00;
    Para [ 1 ] = 0x00;
    Para [ 2 ] = 0x00;
    Para [ 3 ] = 0xa5;
    Lcbi_WriteControlData(0x26, Para, 4);    // MDCTL

    Para [ 0 ] = 0x00;
    Para [ 1 ] = 0xa5;
    Para [ 2 ] = 0xa5;
    Para [ 3 ] = 0xa5;
    Lcbi_WriteControlData(0xA2, Para, 4);    // GATSET

    Para [ 0 ] = 0x00;
    Para [ 1 ] = 0xa5;
    Para [ 2 ] = 0xa5;
    Para [ 3 ] = 0xa5;
    Lcbi_WriteControlData(0x69, Para, 4);    // ACSET

    //---1
    Para [ 0 ] = 0x00;
    Para [ 1 ] = 0x16;
    Para [ 2 ] = 0x18;
    Para [ 3 ] = 0x1A;
    Lcbi_WriteControlData(0x81, Para, 4);    // Set Gamma Positive1

    Para [ 0 ] = 0x00;
    Para [ 1 ] = 0x16;
    Para [ 2 ] = 0x18;
    Para [ 3 ] = 0x1A;
    Lcbi_WriteControlData(0x89, Para, 4);    // Set Gamma Negative1

    //----2
    Para [ 0 ] = 0x1C;
    Para [ 1 ] = 0x1D;
    Para [ 2 ] = 0x1F;
    Para [ 3 ] = 0x21;
    Lcbi_WriteControlData(0x82, Para, 4);    // Set Gamma Positive2

    Para [ 0 ] = 0x1C;
    Para [ 1 ] = 0x1D;
    Para [ 2 ] = 0x1F;
    Para [ 3 ] = 0x21;
    Lcbi_WriteControlData(0x8A, Para, 4);    // Set Gamma Negative2

    //---3
    Para [ 0 ] = 0x23;
    Para [ 1 ] = 0x25;
    Para [ 2 ] = 0x27;
    Para [ 3 ] = 0x28;
    Lcbi_WriteControlData(0x83, Para, 4);    // Set Gamma Positive3

    Para [ 0 ] = 0x23;
    Para [ 1 ] = 0x25;
    Para [ 2 ] = 0x27;
    Para [ 3 ] = 0x29;
    Lcbi_WriteControlData(0x8B, Para, 4);    // Set Gamma Negative3

    //---4
    Para [ 0 ] = 0x2B;
    Para [ 1 ] = 0x30;
    Para [ 2 ] = 0x34;
    Para [ 3 ] = 0x3F;
    Lcbi_WriteControlData(0x84, Para, 4);    // Set Gamma Positive4

    Para [ 0 ] = 0x2D;
    Para [ 1 ] = 0x30;
    Para [ 2 ] = 0x35;
    Para [ 3 ] = 0x3F;
    Lcbi_WriteControlData(0x8C, Para, 4);    // Set Gamma Negative4

    Para [ 0 ] = 0xa5;
    Lcbi_WriteControlData(0x16, Para, 1);

    bsp_LCD_DelayUs(wait_2000us);

    Para [ 0 ] = 0xa5;
    Lcbi_WriteControlData(0x13, Para, 1);
    bsp_LCD_DelayUs(wait_2000us);

    LCD_ClearFullScreen(0xff);

    Para [ 0 ] = 0xa5;
    Lcbi_WriteControlData(0x12, Para, 1);
    LCD_ActiveCheckTime = 0;

    Lcbi_DMA_init( );
}

/*-------------------------------------------------------------------------
* Function Name  : LCD_ClearFullScreen
* Description    :
* Input          :
* Output         : None
* Return         : None
* onther         :
--------------------------------------------------------------------------*/
void LCD_ClearFullScreen(uint8_t FullPixel)
{
    uint16_t i;
    uint8_t  Para [ 4 ];

    Para [ 0 ] = 0;
    Para [ 1 ] = 159;
    Para [ 2 ] = 0x00;
    Para [ 3 ] = 0xA5;
    Lcbi_WriteControlData(0x22, Para, 4);

    Para [ 0 ] = 0;
    Para [ 1 ] = 0;
    Para [ 2 ] = 0;
    Para [ 3 ] = 239;
    Lcbi_WriteControlData(0x23, Para, 4);

    Para [ 0 ] = 0xa5;
    Lcbi_WriteControlData(0x3A, Para, 1);

    for ( i = 0; i < 38400; i++ )
    {
        Lcbi_WriteData8(FullPixel);
    }
}

void LCD_Panel_Shut_Down(void)
{
    Eic_Disable( );    // Disable  VSYNC
    Draw_ClearVramCalFlag( );
}

void             LCD_Panel_Update_Req(uint16_t starPage, uint16_t endPage)
{
    uint16_t wTemp = 0;

    DMA_cycle_status_t DMA_cycle_status;
    uint8_t            Para [ 4 ];
    /*
    if(CheckSleep_handle())
    {
        return;
    }
    else if(LCDBUS_GetOperationStatus() == Notidle)
    {
        return;
    }
    else if(LCDBUS_Init == 0)
    {
        return;
    }
*/
    if ( (LCDPanelGraphicRAM != Draw_GetVramAddress(0)) && (LCDPanelGraphicRAM != Draw_GetVramAddress(1)) )
    {
        LCDPanelGraphicRAM = Draw_GetVramAddress(0);
    }

    DMA_cycle_status = DMA_GetTransferStatus( );
    if ( DMA_cycle_status == notOnGoing)
    {
        Para [ 0 ] = starPage;
        Para [ 1 ] = endPage - 1;
        Para [ 2 ] = 0x00;
        Para [ 3 ] = 0xa5;
        Lcbi_WriteControlData(0x22, Para, 4);

        Para [ 0 ] = 0;
        Para [ 1 ] = 0;
        Para [ 2 ] = ( uint8_t )(239 >> 8);
        Para [ 3 ] = ( uint8_t )239;
        Lcbi_WriteControlData(0x23, Para, 4);

        Para [ 0 ] = 0xa5;
        Lcbi_WriteControlData(0x3A, Para, 1);

        DMA_LoadChannel(0xFFFB0400, ( uint32_t )&LCDPanelGraphicRAM [ 0 ], 38400);
        DMA_SwTrigger( );
    }
}

/*******************************************************************************
  Function: Lcbi_ReadData

*/
static uint8_t Lcbi_ReadData(void)
{
    uint16_t val;

    /* read data */
    val = R_LCBI_ReadData8_A0S(LCBI_NUM);
    bsp_LCD_DelayUs(wait_1us);
    return val;
}

/*******************************************************************************
  Function: Lcbi_Read32

*/
static uint32_t Lcbi_Read32(uint8_t control_id)
{
    uint8_t  u8_temp0;
    uint8_t  u8_temp1;
    uint8_t  u8_temp2;
    uint8_t  u8_temp3;
    uint32_t u32_temp;

    Lcbi_WriteControl(control_id);
    Lcbi_ReadData( ); /* dummy */

    /* read 4 bytes */
    u8_temp0 = Lcbi_ReadData( );
    u8_temp1 = Lcbi_ReadData( );
    u8_temp2 = Lcbi_ReadData( );
    u8_temp3 = Lcbi_ReadData( );

    u32_temp = (u8_temp0 << 24) + (u8_temp1 << 16) + (u8_temp2 << 8) + u8_temp3;

    // R_BSP_STDIO_Printf("Index 0x%02x, data = 0x%08x\n", control_id, u32_temp);
    return u32_temp;
}

/*******************************************************************************
  Function: loc_SetAddrWindow

*/

static void loc_SetAddrWindow(uint16_t starPage, uint16_t endPage)
{
    uint8_t Para [ 4 ];

    Para [ 0 ] = starPage;
    Para [ 1 ] = endPage - 1;
    Para [ 2 ] = 0x00;
    Para [ 3 ] = 0xA5;
    Lcbi_WriteControlData(0x22, Para, 4);

    Para [ 0 ] = 0x00;
    Para [ 1 ] = 0x00;
    Para [ 2 ] = 0x00;
    Para [ 3 ] = 239;
    Lcbi_WriteControlData(0x23, Para, 4);
}