/* * lcd.c * * Created on: May 27, 2022 * Author: Keith.Lloyd */ #include #include #include #include #include #include #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 Display_Update(void) { LCD_Clear(); //clear the frameBuffer Display_USB_Status(); LCD_Update(); } 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<