/* lcd_port.c */
#include "app.h"

#include "lcd.h"

#define GPIO_LCD_CS_PORT_IDX     1u
#define GPIO_LCD_CS_PIN_IDX      1u

#define GPIO_LCD_BL_PORT_IDX     1u
#define GPIO_LCD_BL_PIN_IDX      5u

#define GPIO_LCD_DC_PORT_IDX     1u
#define GPIO_LCD_DC_PIN_IDX      9u

#define GPIO_SDCARD_CS_PORT_IDX  1u
#define GPIO_SDCARD_CS_PIN_IDX   4u

#define GPIO_TOUCH_CS_PORT_IDX   1u
#define GPIO_TOUCH_CS_PIN_IDX    7u

// 软件模拟SPI
#define GPIO_SPI_CLK_PORT_IDX     1u
#define GPIO_SPI_CLK_PIN_IDX      2u

#define GPIO_SPI_TX_PORT_IDX      0u
#define GPIO_SPI_TX_PIN_IDX       26u

volatile HSLSPI_Type *gHslspiBase = (HSLSPI_Type *)HSLSPI_NS;
volatile SYSCON_Type *gSysconBase = (SYSCON_Type *)SYSCON_NS;

void __LCD_delay_ms(uint32_t);
void __LCD_HW_INIT(void)
{
    //spi_master_config_t spiMasterConfig;
    gpio_pin_config_t   gpioPinConfig;
#if 0
    /* Init HS_SPI */

    /* clock source has already been setup in BOARD_InitHardware(). */
    /* pins has already been setup in BOARD_InitPins(). */
    gSysconBase->AHBCLKCTRLX[2] |= SYSCON_AHBCLKCTRL2_HS_LSPI_MASK; /* memory clock gate. */
#if 0
    /* attach FROHF_DIV clock to (SPI8 slave) */
    CLOCK_AttachClk(kFRO12M_to_HSLSPI);
    /* reset HSLSPI */
    RESET_PeripheralReset(kHSLSPI_RST_SHIFT_RSTn);
#endif
    gHslspiBase->CFG = HSLSPI_CFG_ENABLE_MASK
                | HSLSPI_CFG_MASTER_MASK
                | HSLSPI_CFG_CPHA_MASK
                | HSLSPI_CFG_CPOL_MASK
                ;
    gHslspiBase->DLY = HSLSPI_DLY_PRE_DELAY(0)
                | HSLSPI_DLY_POST_DELAY(0)
                | HSLSPI_DLY_FRAME_DELAY(0)
                | HSLSPI_DLY_TRANSFER_DELAY(0)
                ;
    gHslspiBase->INTENCLR = gHslspiBase->INTENSET; /* disable all interrupts. */
    gHslspiBase->DIV = HSLSPI_DIV_DIVVAL(0);  /* baudrate div=4, 96Mhz/4=24Mhz. */
    gHslspiBase->FIFOCFG = HSLSPI_FIFOCFG_ENABLETX_MASK /* enable tX fifo. Only 8-entry for SPI by default.*/
                    //| HSLSPI_FIFOCFG_ENABLERX_MASK
                    | HSLSPI_FIFOCFG_EMPTYTX_MASK  /* clear tx fifo. */
                    | HSLSPI_FIFOCFG_EMPTYRX_MASK  /* clear rx fifo. */
                    ;
    gHslspiBase->FIFOSTAT = gHslspiBase->FIFOSTAT;
#endif
     /* GPIO Pins. */
    CLOCK_EnableClock(kCLOCK_Gpio0);
    CLOCK_EnableClock(kCLOCK_Gpio1);

    gpioPinConfig.pinDirection = kGPIO_DigitalOutput;
    gpioPinConfig.outputLogic  = 1u; /* output high as default. */

    GPIO_PinInit(GPIO, GPIO_LCD_CS_PORT_IDX, GPIO_LCD_CS_PIN_IDX, &gpioPinConfig);
    GPIO_PinInit(GPIO, GPIO_LCD_BL_PORT_IDX, GPIO_LCD_BL_PIN_IDX, &gpioPinConfig);
    GPIO_PinInit(GPIO, GPIO_LCD_DC_PORT_IDX, GPIO_LCD_DC_PIN_IDX, &gpioPinConfig);
    GPIO_PinInit(GPIO, GPIO_SDCARD_CS_PORT_IDX, GPIO_SDCARD_CS_PIN_IDX, &gpioPinConfig);
    GPIO_PinInit(GPIO, GPIO_TOUCH_CS_PORT_IDX, GPIO_TOUCH_CS_PIN_IDX, &gpioPinConfig);

    // GPIO模拟SPI
    GPIO_PinInit(GPIO, GPIO_SPI_CLK_PORT_IDX, GPIO_SPI_CLK_PIN_IDX, &gpioPinConfig);
    GPIO_PinInit(GPIO, GPIO_SPI_TX_PORT_IDX, GPIO_SPI_TX_PIN_IDX, &gpioPinConfig);
}

/* 背光 */
void __LCD_BKL_SET(void)
{
    GPIO_PinWrite(GPIO, GPIO_LCD_BL_PORT_IDX, GPIO_LCD_BL_PIN_IDX, 1u);
}

/* 片选信号拉低 */
void __LCD_CS_CLR(void)
{
    GPIO_PinWrite(GPIO, GPIO_LCD_CS_PORT_IDX, GPIO_LCD_CS_PIN_IDX, 0u);
}

/* 片选信号拉高,放开片选 */
void __LCD_CS_SET(void)
{
    /* 等待数据发送完成 */
//    while (!(gHslspiBase->FIFOSTAT & HSLSPI_FIFOSTAT_TXEMPTY_MASK)) /* 等缓冲区空 */
//    {
//    }

    //while (0u == (gHslspiBase->STAT & HSLSPI_STAT_MSTIDLE_MASK)) /* 等移位器干净,数据完全上线 */
//    {
//    }
    //__LCD_delay_ms(1u);
    GPIO_PinWrite(GPIO, GPIO_LCD_CS_PORT_IDX, GPIO_LCD_CS_PIN_IDX, 1u);
//    __LCD_delay_ms(1u);
}

/* 数据命令信号拉低 */
void __LCD_DC_CLR(void)
{
    GPIO_PinWrite(GPIO, GPIO_LCD_DC_PORT_IDX, GPIO_LCD_DC_PIN_IDX, 0u);
}

/* 数据命令信号拉高 */
void __LCD_DC_SET(void)
{
    GPIO_PinWrite(GPIO, GPIO_LCD_DC_PORT_IDX, GPIO_LCD_DC_PIN_IDX, 1u);
}

void __LCD_WRITE_BYTE(uint8_t txDat)
{
#if 0
    //base->FIFOSTAT = SPI_FIFOSTAT_RXERR_MASK;
    /* Wait while the TX FIFO is Full. */
    while ( 0u == (gHslspiBase->FIFOSTAT & HSLSPI_FIFOSTAT_TXNOTFULL_MASK) )
    {}
    /* Fill data into FIFO. */
    gHslspiBase->FIFOWR = HSLSPI_FIFOWR_TXDATA(txDat)
                   | HSLSPI_FIFOWR_LEN(7) /* 8bit数据 */
                   | HSLSPI_FIFOWR_RXIGNORE_MASK /* 直接发,不管收 */
                   | HSLSPI_FIFOWR_TXSSEL0_N_MASK
                   | HSLSPI_FIFOWR_EOT_MASK /* end of transfer */
                   | HSLSPI_FIFOWR_EOF_MASK /* end of frame. */
                   ;
#else
    uint8_t i;
    //uint8_t j;

    GPIO_PinWrite(GPIO, GPIO_SPI_CLK_PORT_IDX, GPIO_SPI_CLK_PIN_IDX, 1u);
    GPIO_PinWrite(GPIO, GPIO_SPI_TX_PORT_IDX,  GPIO_SPI_TX_PIN_IDX, 1u);
    for(i=0; i<8; i++)
    {
      GPIO_PinWrite(GPIO, GPIO_SPI_CLK_PORT_IDX, GPIO_SPI_CLK_PIN_IDX, 0u);
      if (txDat&0x80)   GPIO_PinWrite(GPIO, GPIO_SPI_TX_PORT_IDX, GPIO_SPI_TX_PIN_IDX, 1u);
      else              GPIO_PinWrite(GPIO, GPIO_SPI_TX_PORT_IDX, GPIO_SPI_TX_PIN_IDX, 0u);
      //for(j=0; j<10; j++);
      GPIO_PinWrite(GPIO, GPIO_SPI_CLK_PORT_IDX, GPIO_SPI_CLK_PIN_IDX, 1u);
      txDat = txDat << 1;
      //for(j=0; j<10; j++);
    }
#endif
}


volatile uint32_t vu32DelayCount;

void __LCD_delay_ms(uint32_t dlyMs)
{
    for (vu32DelayCount = 0u; vu32DelayCount < 150 * dlyMs; vu32DelayCount++)
    {
        __NOP();
    }
}

void lcd_fill_screen_dma(uint16_t hwXpos, uint16_t hwYpos, uint8_t *datBuf)
{

}

/* EOF. */

