
#include "Display.h"
#include "stm32f3xx_hal.h"


extern SPI_HandleTypeDef hspi2;

#include "Display.h"

Display::Display() {
    // Constructor implementation
}

Display::~Display() {
    // Destructor implementation
}

// Function to set the DC pin to LOW (tells the device whether commands are being sent or data)
void Display::DC_L() {
    HAL_GPIO_WritePin(GPIOA, GPIO_PIN_2, GPIO_PIN_RESET);
}

// Function to set the DC pin to HIGH (tells the device whether commands are being sent or data)
void Display::DC_H() {
    HAL_GPIO_WritePin(GPIOA, GPIO_PIN_2, GPIO_PIN_SET);
}

// Function to set the RESET pin to LOW
void Display::RESET_L() {
    HAL_GPIO_WritePin(GPIOA, GPIO_PIN_3, GPIO_PIN_RESET);
}

// Function to set the RESET pin to HIGH
void Display::RESET_H() {
	HAL_GPIO_WritePin(GPIOA, GPIO_PIN_3, GPIO_PIN_SET);
}

// Function to set the CS pin to LOW (Chip-Select)
void Display::CS_Active() {
	HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_RESET);
}

// Function to set the CS pin to HIGH (Chip-Select)
void Display::CS_Inactive() {
	HAL_GPIO_WritePin(GPIOA, GPIO_PIN_4, GPIO_PIN_SET);
}

// Function to set the LED pin to LOW
void Display::LED_L(){
	HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_RESET);
}

// Function to set the LED pin to HIGH
void Display::LED_H(){
	HAL_GPIO_WritePin(GPIOA, GPIO_PIN_5, GPIO_PIN_SET);
}

// Function to write data to the register
void Display::LCD_WR_REG(uint8_t data) {
    DC_L();
	RESET_L();
    CS_Active();
    HAL_SPI_Transmit(&hspi2, &data, 1, 1000);  // Pass the address of the data
    CS_Inactive();
}

// Function to write data
void Display::LCD_WR_DATA(uint8_t data) {
    DC_H();
	RESET_L();
    CS_Active();
    HAL_SPI_Transmit(&hspi2, &data, 1, 1000);  // Pass the address of the data
    CS_Inactive();
}



void Display::ILI9341_Reset(void)
{
	RESET_L();
	HAL_Delay(10);
	RESET_H();
	CS_Active();
	LED_H();
}

// Software reset (closes applications and clears any data in random access memory (RAM))
void Display::ILI9341_SoftReset(void)
{
	CS_Inactive();
	uint8_t cmd;
	cmd = 0x01;
	DC_L();
	HAL_SPI_Transmit(&hspi2, &cmd, sizeof(cmd), 1000);
}

// Function to set the addressable window
void Display::SetWindow(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1) {
    // column address set
	CS_Active();
    LCD_WR_REG(0x2A);
    {
        LCD_WR_DATA((x0 >> 8) & 0xFF);
        LCD_WR_DATA(x0 & 0xFF);
        LCD_WR_DATA((x1 >> 8) & 0xFF);
        LCD_WR_DATA(x1 & 0xFF);
    }

    // row address set
    LCD_WR_REG(0x2B);
    {
        LCD_WR_DATA((y0 >> 8) & 0xFF);
        LCD_WR_DATA(y0 & 0xFF);
        LCD_WR_DATA((y1 >> 8) & 0xFF);
        LCD_WR_DATA(y1 & 0xFF);
    }

    // write to RAM
    LCD_WR_REG(0x2C);
}

void Display::DrawPixel(uint16_t x, uint16_t y, uint16_t color) {
	CS_Active();
	SetWindow(x, y, x+1, y+1);
    LCD_WR_DATA((color >> 8) & 0xFF);
    CS_Inactive();
}

void Display::InvertColorOn(){
	LCD_WR_REG(0x21);
}

void Display::ILI9341_Init(void)
{
		CS_Inactive();
		CS_Active();

		// Power Control B (S-196)
		LCD_WR_REG(0xCF);
		LCD_WR_DATA(0x00);
		LCD_WR_DATA(0xC1);
		LCD_WR_DATA(0x02);
		// Power on sequence control (S-200)
		LCD_WR_REG(0xED);
		LCD_WR_DATA(0x64);
		LCD_WR_DATA(0x03);
		LCD_WR_DATA(0x12);
		LCD_WR_DATA(0x81);
		// Driver timing control A (S-197)
		LCD_WR_REG(0xE8);
		LCD_WR_DATA(0x85);
		LCD_WR_DATA(0x00);
		LCD_WR_DATA(0x78);
		// Power control A (S-195)
		LCD_WR_REG(0xCB);
		LCD_WR_DATA(0x39);
		LCD_WR_DATA(0x2C);
		LCD_WR_DATA(0x00);
		LCD_WR_DATA(0x34);
		LCD_WR_DATA(0x02);
		// Pump ratio control (S-202)
		LCD_WR_REG(0xF7);
		LCD_WR_DATA(0x20);
		// Driver timing control B (S-198)
		LCD_WR_REG(0xEA);
		LCD_WR_DATA(0x00);
		LCD_WR_DATA(0x00);
		// Power Control 1 (S-178)
		LCD_WR_REG(0xC0);
		LCD_WR_DATA(0x10);
		// Power Control 2 (S-179)
		LCD_WR_REG(0xC1);
		LCD_WR_DATA(0x00);
		// VMCTRL1 (S-180)
		LCD_WR_REG(0xC5);
		LCD_WR_DATA(0x30);
		LCD_WR_DATA(0x30);
		// VMCTRL2 (S-182)
		LCD_WR_REG(0xC7);
		LCD_WR_DATA(0xB7);
		// Pixel Format Set (S-134)
		LCD_WR_REG(0x3A);
		LCD_WR_DATA(0x55);
		// Memory Access Control (S-127)
		LCD_WR_REG(0x36);
		LCD_WR_DATA(0x08);
		// FRAME RATIO CONTROL, STANDARD RGB COLOR (S-155)
		LCD_WR_REG(0xB1);
		LCD_WR_DATA(0x00);
		LCD_WR_DATA(0x1A);
		// Display Function Control (S-164)
		LCD_WR_REG(0xB6);
		LCD_WR_DATA(0x08);
		LCD_WR_DATA(0x82);
		LCD_WR_DATA(0x27);
		/* 3GAMMA FUNCTION DISABLE */
		LCD_WR_REG(0xF2);
		LCD_WR_DATA(0x00);
		// Gamma curve selected
		LCD_WR_REG(0x26);
		LCD_WR_DATA(0x01);
		//Positive Gamma  Correction (S-188)
		LCD_WR_REG(0xE0);
		LCD_WR_DATA(0x0F);
		LCD_WR_DATA(0x2A);
		LCD_WR_DATA(0x28);
		LCD_WR_DATA(0x08);
		LCD_WR_DATA(0x54);
		LCD_WR_DATA(0xA9);
		LCD_WR_DATA(0x43);
		LCD_WR_DATA(0x0A);
		LCD_WR_DATA(0x0F);
		LCD_WR_DATA(0x00);
		LCD_WR_DATA(0x00);
		LCD_WR_DATA(0x00);
		LCD_WR_DATA(0x00);
		//Negative Gamma  Correction (S-189)
		LCD_WR_REG(0xE1);
		LCD_WR_DATA(0x00);
		LCD_WR_DATA(0x15);
		LCD_WR_DATA(0x17);
		LCD_WR_DATA(0x07);
		LCD_WR_DATA(0x11);
		LCD_WR_DATA(0x06);
		LCD_WR_DATA(0x2B);
		LCD_WR_DATA(0x56);
		LCD_WR_DATA(0x3C);
		LCD_WR_DATA(0x05);
		LCD_WR_DATA(0x10);
		LCD_WR_DATA(0x0F);
		LCD_WR_DATA(0x3F);
		LCD_WR_DATA(0x3F);
		LCD_WR_DATA(0x0F);

		// Page Address Set (S-112)
		LCD_WR_REG(0x2B);
		LCD_WR_DATA(0x00);
		LCD_WR_DATA(0x00);
		LCD_WR_DATA(0x01);
		LCD_WR_DATA(0x3f);

		// Column Address Set (S-110)
		LCD_WR_REG(0x2A);
		LCD_WR_DATA(0x00);
		LCD_WR_DATA(0x00);
		LCD_WR_DATA(0x00);
		LCD_WR_DATA(0xef);

		// EXIT SLEEP (S-101)
		LCD_WR_REG(0x11);

		CS_Inactive();
		HAL_Delay(120);
		CS_Active();

		// DISPLAY ON (S-109)
		LCD_WR_REG(0x29);
}
