Files
TX/source/lcd.c

353 lines
8.9 KiB
C
Raw Normal View History

/*
* lcd.c
*
* Created on: May 27, 2022
* Author: Keith.Lloyd
*/
#include <stdio.h>
#include <math.h>
#include <stdbool.h>
#include <string.h>
#include <stdint.h>
#include <arm_math.h>
#include "fsl_gpio.h"
#include "spi.h"
#include "lcd.h"
#include "display.h"
#include "timer.h"
#include "mode.h"
#include "Graphics/graphicsLibrary.h"
#include "Fonts/fontLibrary.h"
#include "Graphics/testIconsMono.h"
#include "Graphics/icons.h"
#include "adc.h"
#include "main.h"
#include "ports.h"
#include "utils.h"
//Overview:
// LCD control / data line normally stays in the data state.
// Any function that changes to control MUST change the line back to data before exiting
/*******************************************************************************
* Definitions
******************************************************************************/
//Backlight GPIO
#define LCD_BL_PORT 2 //ToDo: Update this for LPC
#define LCD_BL_GPIO_PIN 30 //ToDo: Update this for LPC
//#define LCD_CD_PORT 0 //ToDo: Update this for LPC Port0 || Port1 208002
//#define LCD_CD_GPIO_PIN 6 //ToDo: Update this for LPC Bit position 208002
#define LCD_CD_PORT 1 //ToDo: Update this for LPC Port0 || Port1 208004
#define LCD_CD_GPIO_PIN 8 //ToDo: Update this for LPC Bit position 208004
/*******************************************************************************
* Variables
******************************************************************************/
// Frame buffer
//uint16_t mFrameBuffer[LCD_HEIGHT_PIXELS][LCD_WIDTH_PIXELS/16]; //y,x
//uint8_t mFrameBuffer[LCD_WIDTH_PIXELS][LCD_HEIGHT_PIXELS / 8]; //x,y
uint8_t mFrameBuffer[LCD_HEIGHT_PIXELS/8][LCD_WIDTH_PIXELS]; //x,y
extern uint8_t Power_Level, Over_Voltage_Flag, Task,Error;
extern uint8_t tempString[];
extern uint8_t frequency, Cur_Mode, Safe_Mode;
extern uint8_t Dds_Pot_Val[];
extern uint8_t Port_State[];
extern uint8_t Diag_Flag;
extern uint16_t Display_warning_tmr;
/*******************************************************************************
* Static Function Declarations
******************************************************************************/
static void SetBacklightPower(uint8_t state);
static void SetCommandDataLine(LCD_CDLINE_t state);
static void SendLcdCommand(uint8_t command, uint8_t data);
/*******************************************************************************
* Static Functions
******************************************************************************/
//Set Backlight GPIO to 'state'
static void SetBacklightPower(uint8_t state)
{
//ToDo This function Note backlight is now on Serial expander
GPIO_PinWrite(GPIO, LCD_BL_PORT, LCD_BL_GPIO_PIN, state);
}
//Set CD line GPIO high for LCD_CDLINE_DATA or low for LCD_CDLINE_CONTROL
static void SetCommandDataLine(LCD_CDLINE_t state)
{
//ToDo This function Done !!
GPIO_PinWrite(GPIO, LCD_CD_PORT, LCD_CD_GPIO_PIN, state);
}
//command is the #defined command
//data is optional arguments > zero if not used!
static void SendLcdCommand(uint8_t command, uint8_t data)
{
SetCommandDataLine(LCD_CDLINE_CONTROL);
uint8_t sendData = command | data;
SPI3_SendBytes(&sendData, 1); //send one byte via SPI
SetCommandDataLine(LCD_CDLINE_DATA);
}
//dedicated function for setting LCD gain and pot values
static void SetGainAndPot(uint8_t data)
{
SetCommandDataLine(LCD_CDLINE_CONTROL);
uint8_t sendData[2];
sendData[0] = LCD_SET_GAIN_AND_POT;
sendData[1] = data;
SPI3_SendBytes(&sendData[0], 2); //send one byte via SPI
SetCommandDataLine(LCD_CDLINE_DATA);
}
static void TestLCD(void)
{
//Alternate setting all pixels black, then white
while(1)
{
SendLcdCommand(LCD_SET_ALL_PIXELS, 1);
uint32_t delay = 50000000;
while(delay--);
SendLcdCommand(LCD_SET_ALL_PIXELS, 0);
delay = 50000000;
while(delay--);
// Delay_Ticks(500);
}
}
static void TestLCD2(void)
{
while(1)
{
//Draw vertical stripes in frameBuffer and output to LCD
for(uint32_t y = 0; y < LCD_HEIGHT_PIXELS; y++)
{
for(uint32_t x = 0; x < LCD_WIDTH_PIXELS / 16; x++)
{
mFrameBuffer[y][x] = 0xF0;
}
}
LCD_Update();
uint32_t delay = 50000000;
while(delay--);
//Draw horizontal striped in frameBuffer and output to LCD
for(uint32_t y = 0; y < LCD_HEIGHT_PIXELS; y++)
{
for(uint32_t x = 0; x < LCD_WIDTH_PIXELS / 16; x++)
{
if(y % 1 == 0) //every other row
{
mFrameBuffer[y][x] = 0xF0;
}
}
}
LCD_Update();
delay = 50000000;
while(delay--);
}
}
void LCD_Init(void)
{
SendLcdCommand(0, 0); // SET COLUMN LSB
SendLcdCommand(0b00010000, 0); // SET COLUMN MSB
SendLcdCommand(0b01000000, 0); // SET START LINE
SendLcdCommand(0b00100100, 0); // SET MUX & TEMP. COMPENSATION
SendLcdCommand(0b00101101, 0); // SET POWER CONTROL
SendLcdCommand(0b10000001, 0); // SET GAIN & POTENTIOMETER
SendLcdCommand(0b10000000, 0); // SET GAIN & POTENTIOMETER (second part)
SendLcdCommand(0b10001001, 0); // RAM CONTROL
SendLcdCommand(0b10100100, 0); // ALL PIX OFF
SendLcdCommand(0b10100100, 0); // ALL PIX OFF
SendLcdCommand(0b10101111, 0); // SLEEP MODE OFF
SendLcdCommand(0b11001000, 0); // MY=1 MX=0 MSF=0
// SendLcdCommand(0b11101010, 0); // BIAS=12 D1,D0 = BR[1:0]
SendLcdCommand(0b11101010, 0); // BIAS=12 D1,D0
SendLcdCommand(0b10010000, 0); // fixed line
}
void LCD_PowerOff(void)
{
//TODO: UC1608 Power down requirements: (see datasheet page 33)
//Reset command
//Wait 2mS
//Turn off VDD
}
/* Output frameBuffer data to LCD
*
*/
void LCD_Update(void)
{
SendLcdCommand(LCD_SET_COLUMN_LSB, 0);
SendLcdCommand(LCD_SET_COLUMN_MSB, 0);
SendLcdCommand(LCD_SET_PAGE_ADDRESS, 0);
//output framebuffer data via SPI
SPI3_SendBytes((uint8_t *)mFrameBuffer, sizeof(mFrameBuffer));
}
//Clear mFrameBuffer
void LCD_Clear(void)
{
//Clear Screen
memset(mFrameBuffer, 0, sizeof(mFrameBuffer));
}
//Write a pixel to the framebuffer in the specified location
void LCD_DrawPixel(int16_t x, int16_t y, LCD_DRAWMODE_t mode)
{
//ignore if outside LCD area
if(x < 0 || x > LCD_X_MAX)
return;
if(y < 0 || y > LCD_Y_MAX)
return;
//Flip LCD 180*
x = LCD_X_MAX - x;
y = LCD_Y_MAX - y;
//8-bit data in frameBuffer to read > modify > write
uint16_t page = y / LCD_Y_BITS_PER_PAGE;
uint8_t bitPosition = y%8;
uint8_t bitMask = 1 << bitPosition;
//Draw the pixel
switch(mode)
{
case LCD_DRAW_SET:
mFrameBuffer[page][x] |= bitMask;
break;
case LCD_DRAW_CLEAR:
mFrameBuffer[page][x] &= bitMask;
break;
case LCD_DRAW_XOR:
mFrameBuffer[page][x] ^= bitMask;
break;
}
}
//get a pixel from the framebuffer at the specified location
//returns 1 if pixel set, 0 otherwise
uint8_t LCD_GetPixel(int16_t x, int16_t y)
{
//Flip LCD 180*
x = LCD_X_MAX - x;
y = LCD_Y_MAX - y;
uint16_t page = y / LCD_Y_BITS_PER_PAGE;
uint8_t bitPosition = y%8;
uint8_t bitMask = 1 << bitPosition;
uint8_t byte = mFrameBuffer[page][x];
return (byte >> bitPosition) & 0x01; // right shift the bit of interest to the ones position, then mask
}
#if 0 //UC1608
/****************************************************************************/
/*** uc1608 ***/
/****************************************************************************/
/**
* uc1608_send send chunk over SPI
* @param spi config
* @param command or data array ptr
* @param size of command or data to send
* @param command or data mode
* @param io pin for data/cmd mode
* @author Matthieu Barreteau
* @date 04/26/2014
*/
int uc1608_send(struct spi_config *config,unsigned char *data, int len,uint8_t mode,uint8_t cmdPin)
{
delayMicroseconds(10);
if(mode == UC1608_DATA) {
GPIO_SET = 1<<cmdPin; // ToDo
} else {
GPIO_CLR = 1<<cmdPin; //ToDo
}
delayMicroseconds(75);
if(spi_write_data(config, data, len) == -1) {
fprintf (stderr, "Unable to send over SPI : %s\n", strerror (errno)) ;
return -1;
}
return 0;
}
/**
* uc1608_setup screen setup
* @param spi config
* @param io pin for data/cmd mode
* @author Matthieu Barreteau
* @date 04/26/2014
*/
void uc1608_setup(struct spi_config *config,uint8_t cmdPin)
{
unsigned char cmdToSend[14];
cmdToSend[0] = 0b11100010; // SYSTEM RESET
uc1608_send(config, cmdToSend, 1, UC1608_CMD, cmdPin) ;
delay(300);
cmdToSend[0] = 0b00000000; // SET COLUMN LSB
cmdToSend[1] = 0b00010000; // SET COLUMN MSB
cmdToSend[2] = 0b01000000; // SET START LINE
cmdToSend[3] = 0b00100100; // SET MUX & TEMP. COMPENSATION
cmdToSend[4] = 0b00101101; // SET POWER CONTROL
cmdToSend[5] = 0b10000001; // SET GAIN & POTENTIOMETER
cmdToSend[6] = 0b10000000; // SET GAIN & POTENTIOMETER (second part)
cmdToSend[7] = 0b10001001; // RAM CONTROL
cmdToSend[8] = 0b10100100; // ALL PIX OFF
cmdToSend[9] = 0b10100100; // ALL PIX OFF
cmdToSend[10] = 0b10101111; // SLEEP MODE OFF
cmdToSend[11] = 0b11001100; // MY=1 MX=1 MSF=0
cmdToSend[12] = 0b11101010; // BIAS=12
cmdToSend[13] = 0b10010000; // fixed line
uc1608_send(config, cmdToSend, 14, UC1608_CMD, cmdPin) ;
}
/* EOF */
#endif