Untitled

mail@pastecode.io avatar
unknown
c_cpp
17 days ago
9.2 kB
3
Indexable
Never
#include "ILI9341_STM32_Driver.h"
#include "SPI.h"

/* Global Variables ------------------------------------------------------------------*/
volatile uint16_t LCD_HEIGHT = ILI9341_SCREEN_HEIGHT;
volatile uint16_t LCD_WIDTH = ILI9341_SCREEN_WIDTH;

static volatile bool g_transfer_complete = false;

/* SPI callback function */
void spi_callback(spi_callback_args_t *p_args)
{
    if (SPI_EVENT_TRANSFER_COMPLETE == p_args->event)
    {
        g_transfer_complete = true;
    }
}

/* Initialize SPI */
void ILI9341_SPI_Init(void)
{
    fsp_err_t err = FSP_SUCCESS;
    R_IOPORT_PinWrite(&g_ioport_ctrl, LCDRESET, BSP_IO_LEVEL_HIGH);
    R_IOPORT_PinWrite(&g_ioport_ctrl, LCDCS, BSP_IO_LEVEL_HIGH);

    /* Initialize SPI driver */
    err = SPI_Init();

    if (FSP_SUCCESS != err)
    {
        // SPI module initialization failed
    }
}

/* Send data (char) to LCD */
void ILI9341_SPI_Send(unsigned char SPI_Data)
{
    fsp_err_t err = FSP_SUCCESS;

    static uint8_t g_master_tx_buff[1];   // Master Transmit Buffer
    g_master_tx_buff[0] = SPI_Data;
    /* Master send data to Slave */
    err = R_SPI_Write(&g_spi0_ctrl, g_master_tx_buff, 1, SPI_BIT_WIDTH_8_BITS);
    /* Error handling */
    if (FSP_SUCCESS != err)
    {
    }
}

/* Send command (char) to LCD */
void ILI9341_Write_Command(uint8_t Command)
{
    R_IOPORT_PinWrite(&g_ioport_ctrl, LCDCS, BSP_IO_LEVEL_LOW);
    R_BSP_SoftwareDelay(5, BSP_DELAY_UNITS_MICROSECONDS);
    ILI9341_SPI_Send(Command);
    R_BSP_SoftwareDelay(30, BSP_DELAY_UNITS_MICROSECONDS);
    R_IOPORT_PinWrite(&g_ioport_ctrl, LCDCS, BSP_IO_LEVEL_HIGH);
}

/* Send Data (char) to LCD */
void ILI9341_Write_Data(uint8_t Data)
{
    R_IOPORT_PinWrite(&g_ioport_ctrl, LCDCS, BSP_IO_LEVEL_LOW);
    R_BSP_SoftwareDelay(5, BSP_DELAY_UNITS_MICROSECONDS);
    ILI9341_SPI_Send(Data);
    R_BSP_SoftwareDelay(30, BSP_DELAY_UNITS_MICROSECONDS);
    R_IOPORT_PinWrite(&g_ioport_ctrl, LCDCS, BSP_IO_LEVEL_HIGH);
}

/* Set Address - Location block - to draw into */
void ILI9341_Set_Address(uint16_t X1, uint16_t Y1, uint16_t X2, uint16_t Y2)
{
    ILI9341_Write_Command(0x2A);
    ILI9341_Write_Data((uint8_t)(X1 >> 8));
    ILI9341_Write_Data((uint8_t)X1);
    ILI9341_Write_Data((uint8_t)(X2 >> 8));
    ILI9341_Write_Data((uint8_t)X2);

    ILI9341_Write_Command(0x2B);
    ILI9341_Write_Data((uint8_t)(Y1 >> 8));
    ILI9341_Write_Data((uint8_t)Y1);
    ILI9341_Write_Data((uint8_t)(Y2 >> 8));
    ILI9341_Write_Data((uint8_t)Y2);

    ILI9341_Write_Command(0x2C);
}

/* HARDWARE RESET */
void ILI9341_Reset(void)
{
    R_IOPORT_PinWrite(&g_ioport_ctrl, LCDRESET, BSP_IO_LEVEL_LOW);
    R_BSP_SoftwareDelay(200, BSP_DELAY_UNITS_MILLISECONDS);
    R_IOPORT_PinWrite(&g_ioport_ctrl, LCDCS, BSP_IO_LEVEL_LOW);
    R_BSP_SoftwareDelay(200, BSP_DELAY_UNITS_MILLISECONDS);
    R_IOPORT_PinWrite(&g_ioport_ctrl, LCDRESET, BSP_IO_LEVEL_HIGH);
    R_BSP_SoftwareDelay(200, BSP_DELAY_UNITS_MILLISECONDS);
    R_IOPORT_PinWrite(&g_ioport_ctrl, LCDCS, BSP_IO_LEVEL_LOW);
}

/* Set rotation of the screen - changes x0 and y0 */
void ILI9341_Set_Rotation(uint8_t Rotation)
{
    uint8_t screen_rotation = Rotation;

    ILI9341_Write_Command(0x36);
    R_BSP_SoftwareDelay(1, BSP_DELAY_UNITS_MILLISECONDS);

    switch (screen_rotation)
    {
        case SCREEN_VERTICAL_1:
            ILI9341_Write_Data(0x40 | 0x08);
            LCD_WIDTH = 240;
            LCD_HEIGHT = 320;
            break;
        case SCREEN_HORIZONTAL_1:
            ILI9341_Write_Data(0x20 | 0x08);
            LCD_WIDTH = 320;
            LCD_HEIGHT = 240;
            break;
        case SCREEN_VERTICAL_2:
            ILI9341_Write_Data(0x80 | 0x08);
            LCD_WIDTH = 240;
            LCD_HEIGHT = 320;
            break;
        case SCREEN_HORIZONTAL_2:
            ILI9341_Write_Data(0x40 | 0x80 | 0x20 | 0x08);
            LCD_WIDTH = 320;
            LCD_HEIGHT = 240;
            break;
        default:
            // Exit if screen rotation not valid!
            break;
    }
}

/* Enable LCD display */
void ILI9341_Enable(void)
{
    R_IOPORT_PinWrite(&g_ioport_ctrl, LCDRESET, BSP_IO_LEVEL_HIGH);
}

/* Initialize LCD display */
void ILI9341_Init(void)
{
    ILI9341_Enable();
    ILI9341_SPI_Init();
    ILI9341_Reset();

    // SOFTWARE RESET
    R_IOPORT_PinWrite(&g_ioport_ctrl, LCDCS, BSP_IO_LEVEL_HIGH);

    ILI9341_Write_Command(0x01);
    R_BSP_SoftwareDelay(1000, BSP_DELAY_UNITS_MILLISECONDS);

    // POWER CONTROL A
    ILI9341_Write_Command(0xCB);
    ILI9341_Write_Data(0x39);
    ILI9341_Write_Data(0x2C);
    ILI9341_Write_Data(0x00);
    ILI9341_Write_Data(0x34);
    ILI9341_Write_Data(0x02);

    // POWER CONTROL B
    ILI9341_Write_Command(0xCF);
    ILI9341_Write_Data(0x00);
    ILI9341_Write_Data(0xC1);
    ILI9341_Write_Data(0x30);

    // DRIVER TIMING CONTROL A
    ILI9341_Write_Command(0xE8);
    ILI9341_Write_Data(0x85);
    ILI9341_Write_Data(0x00);
    ILI9341_Write_Data(0x78);

    // DRIVER TIMING CONTROL B
    ILI9341_Write_Command(0xEA);
    ILI9341_Write_Data(0x00);
    ILI9341_Write_Data(0x00);

    // POWER ON SEQUENCE CONTROL
    ILI9341_Write_Command(0xED);
    ILI9341_Write_Data(0x64);
    ILI9341_Write_Data(0x03);
    ILI9341_Write_Data(0x12);
    ILI9341_Write_Data(0x81);

    // PUMP RATIO CONTROL
    ILI9341_Write_Command(0xF7);
    ILI9341_Write_Data(0x20);

    // POWER CONTROL, VRH[5:0]
    ILI9341_Write_Command(0xC0);
    ILI9341_Write_Data(0x23);

    // POWER CONTROL, SAP[2:0]; BT[3:0]
    ILI9341_Write_Command(0xC1);
    ILI9341_Write_Data(0x10);

    // VCM CONTROL
    ILI9341_Write_Command(0xC5);
    ILI9341_Write_Data(0x3E);
    ILI9341_Write_Data(0x28);

    // VCM CONTROL 2
    ILI9341_Write_Command(0xC7);
    ILI9341_Write_Data(0x86);

    // MEMORY ACCESS CONTROL
    ILI9341_Write_Command(0x36);
    ILI9341_Write_Data(0x48);

    // PIXEL FORMAT
    ILI9341_Write_Command(0x3A);
    ILI9341_Write_Data(0x66); // 18-bit color format

    // FRAME RATIO CONTROL, STANDARD RGB COLOR
    ILI9341_Write_Command(0xB1);
    ILI9341_Write_Data(0x00);
    ILI9341_Write_Data(0x18);

    // DISPLAY FUNCTION CONTROL
    ILI9341_Write_Command(0xB6);
    ILI9341_Write_Data(0x08);
    ILI9341_Write_Data(0x82);
    ILI9341_Write_Data(0x27);

    // 3GAMMA FUNCTION DISABLE
    ILI9341_Write_Command(0xF2);
    ILI9341_Write_Data(0x00);

    // GAMMA CURVE SELECTED
    ILI9341_Write_Command(0x26);
    ILI9341_Write_Data(0x01);

    // POSITIVE GAMMA CORRECTION
    ILI9341_Write_Command(0xE0);
    ILI9341_Write_Data(0x0F);
    ILI9341_Write_Data(0x31);
    ILI9341_Write_Data(0x2B);
    ILI9341_Write_Data(0x0C);
    ILI9341_Write_Data(0x0E);
    ILI9341_Write_Data(0x08);
    ILI9341_Write_Data(0x4E);
    ILI9341_Write_Data(0xF1);
    ILI9341_Write_Data(0x37);
    ILI9341_Write_Data(0x07);
    ILI9341_Write_Data(0x10);
    ILI9341_Write_Data(0x03);
    ILI9341_Write_Data(0x0E);
    ILI9341_Write_Data(0x09);
    ILI9341_Write_Data(0x00);

    // NEGATIVE GAMMA CORRECTION
    ILI9341_Write_Command(0xE1);
    ILI9341_Write_Data(0x00);
    ILI9341_Write_Data(0x0E);
    ILI9341_Write_Data(0x14);
    ILI9341_Write_Data(0x03);
    ILI9341_Write_Data(0x11);
    ILI9341_Write_Data(0x07);
    ILI9341_Write_Data(0x31);
    ILI9341_Write_Data(0xC1);
    ILI9341_Write_Data(0x48);
    ILI9341_Write_Data(0x08);
    ILI9341_Write_Data(0x0F);
    ILI9341_Write_Data(0x0C);
    ILI9341_Write_Data(0x31);
    ILI9341_Write_Data(0x36);
    ILI9341_Write_Data(0x0F);

    // EXIT SLEEP
    ILI9341_Write_Command(0x11);
    R_BSP_SoftwareDelay(120, BSP_DELAY_UNITS_MILLISECONDS);

    // TURN ON DISPLAY
    ILI9341_Write_Command(0x29);

    // STARTING ROTATION
    ILI9341_Set_Rotation(SCREEN_VERTICAL_1);
}

/* Draw color to the entire screen */
void ILI9341_Fill_Screen(uint16_t Colour)
{
    ILI9341_Set_Address(0, 0, LCD_WIDTH - 1, LCD_HEIGHT - 1);
    ILI9341_Draw_Colour_Burst(Colour, LCD_WIDTH * LCD_HEIGHT);
}

/* Draw color burst */
void ILI9341_Draw_Colour_Burst(uint16_t Colour, uint32_t Size)
{
    uint8_t burst_buffer[3] = {Colour >> 16, Colour >> 8, Colour}; // 18-bit color
    R_IOPORT_PinWrite(&g_ioport_ctrl, LCDCS, BSP_IO_LEVEL_LOW);

    for (uint32_t i = 0; i < Size; i++)
    {
        ILI9341_SPI_Send(burst_buffer[0]);
        ILI9341_SPI_Send(burst_buffer[1]);
        ILI9341_SPI_Send(burst_buffer[2]);
    }

    R_IOPORT_PinWrite(&g_ioport_ctrl, LCDCS, BSP_IO_LEVEL_HIGH);
}

/* Draw pixel */
void ILI9341_Draw_Pixel(uint16_t X, uint16_t Y, uint16_t Colour)
{
    if ((X >= LCD_WIDTH) || (Y >= LCD_HEIGHT)) return;
    ILI9341_Set_Address(X, Y, X, Y);
    ILI9341_Draw_Colour_Burst(Colour, 1);
}

/* Main function */
int main(void)
{
    ILI9341_Init();

    // Fill screen with a solid color
    ILI9341_Fill_Screen(0xF800); // Red

    // Draw a single pixel (example)
    ILI9341_Draw_Pixel(120, 160, 0x07E0); // Green pixel at (120, 160)

    while (1)
    {
        // Main loop
    }
}
Leave a Comment