| /** | |
| * @file hal_lcd.c | |
| * | |
| * Copyright 2010 Texas Instruments, Inc. | |
| ***************************************************************************/ | |
| #include "msp430.h" | |
| #include "hal_MSP-EXP430F5438.h" | |
| #include "hal_lcd_fonts.h" | |
| unsigned char LcdInitMacro[]={ | |
| 0x74,0x00,0x00,0x76,0x00,0x01, // R00 start oscillation | |
| 0x74,0x00,0x01,0x76,0x00,0x0D, // R01 driver output control | |
| 0x74,0x00,0x02,0x76,0x00,0x4C, // R02 LCD - driving waveform control | |
| 0x74,0x00,0x03,0x76,0x12,0x14, // R03 Power control | |
| 0x74,0x00,0x04,0x76,0x04,0x66, // R04 Contrast control | |
| 0x74,0x00,0x05,0x76,0x00,0x10, // R05 Entry mode | |
| 0x74,0x00,0x06,0x76,0x00,0x00, // R06 RAM data write mask | |
| 0x74,0x00,0x07,0x76,0x00,0x15, // R07 Display control | |
| 0x74,0x00,0x08,0x76,0x00,0x03, // R08 Cursor Control | |
| 0x74,0x00,0x09,0x76,0x00,0x00, // R09 RAM data write mask | |
| 0x74,0x00,0x0A,0x76,0x00,0x15, // R0A | |
| 0x74,0x00,0x0B,0x76,0x00,0x03, // R0B Horizontal Cursor Position | |
| 0x74,0x00,0x0C,0x76,0x00,0x03, // R0C Vertical Cursor Position | |
| 0x74,0x00,0x0D,0x76,0x00,0x00, // R0D | |
| 0x74,0x00,0x0E,0x76,0x00,0x15, // R0E | |
| 0x74,0x00,0x0F,0x76,0x00,0x03, // R0F | |
| 0x74,0x00,0x10,0x76,0x00,0x15, // R0E | |
| 0x74,0x00,0x11,0x76,0x00,0x03, // R0F | |
| }; | |
| unsigned char Read_Block_Address_Macro[]= {0x74,0x00,0x12,0x77,0x00,0x00}; | |
| unsigned char Draw_Block_Value_Macro[]={0x74,0x00,0x12,0x76,0xFF,0xFF}; | |
| unsigned char Draw_Block_Address_Macro[]={0x74,0x00,0x11,0x76,0x00,0x00}; | |
| unsigned int LcdAddress = 0, LcdTableAddress = 0; | |
| unsigned char contrast = 0x66; | |
| unsigned char backlight = 8; | |
| int LCD_MEM[110*17]; //This array stores a copy of all data on the LCD | |
| //screen. If memory is an issue though, this array | |
| //can be eliminated and the halLcdReadBlock() | |
| //command can be used instead whenever you are | |
| //manipulating the currently displayed data. | |
| /**********************************************************************//** | |
| * @brief Sends 3+3 bytes of data to the LCD using the format specified | |
| * by the LCD Guide. | |
| * | |
| * @param Data[] Data array for transmission | |
| * | |
| * @return none | |
| *************************************************************************/ | |
| void halLcdSendCommand(unsigned char Data[]) | |
| { | |
| unsigned char i; | |
| LCD_CS_RST_OUT &= ~LCD_CS_PIN; //CS = 0 --> Start Transfer | |
| for ( i = 0; i < 6; i++ ) | |
| { | |
| while (!(UCB2IFG & UCTXIFG)); // Wait for TXIFG | |
| UCB2TXBUF = Data[i]; // Load data | |
| if (i == 2) //Pull CS up after 3 bytes | |
| { | |
| while (UCB2STAT & UCBUSY); | |
| LCD_CS_RST_OUT |= LCD_CS_PIN; //CS = 1 --> Stop Transfer | |
| LCD_CS_RST_OUT &= ~LCD_CS_PIN; //CS = 0 --> Start Transfer | |
| } | |
| } | |
| while (UCB2STAT & UCBUSY); | |
| LCD_CS_RST_OUT |= LCD_CS_PIN; //CS = 1 --> Stop Transfer | |
| } | |
| /**********************************************************************//** | |
| * @brief Initializes the USCI module, LCD device for communication. | |
| * | |
| * - Sets up the SPI2C Communication Module | |
| * - Performs Hitachi LCD Initialization Procedure | |
| * | |
| * @param none | |
| * | |
| * @return none | |
| *************************************************************************/ | |
| void halLcdInit(void) | |
| { | |
| volatile unsigned int i=0; | |
| LCD_CS_RST_OUT |= LCD_CS_PIN | LCD_RESET_PIN ; | |
| LCD_CS_RST_DIR |= LCD_CS_PIN | LCD_RESET_PIN ; | |
| LCD_BACKLT_SEL |= LCD_BACKLIGHT_PIN; | |
| LCD_CS_RST_OUT &= ~LCD_RESET_PIN; // Reset LCD | |
| __delay_cycles(0x47FF); //Reset Pulse | |
| LCD_CS_RST_OUT |= LCD_RESET_PIN; | |
| // UCLK,MOSI setup, SOMI cleared | |
| LCD_SPI_SEL |= LCD_MOSI_PIN + LCD_CLK_PIN; | |
| LCD_SPI_SEL &= ~LCD_MISO_PIN; | |
| LCD_SPI_DIR &= ~(LCD_MISO_PIN + LCD_MOSI_PIN); // Pin direction controlled by module, | |
| // Set both pins to input as default | |
| // Initialize the USCI_B2 module for SPI operation | |
| UCB2CTL1 = UCSWRST; // Hold USCI in SW reset mode while configuring it | |
| UCB2CTL0 = UCMST+UCSYNC+UCCKPL+UCMSB; // 3-pin, 8-bit SPI master | |
| UCB2CTL1 |= UCSSEL_2; // SMCLK | |
| UCB2BR0 = 4; // Note: Do not exceed D/S spec for UCLK! | |
| UCB2BR1 = 0; | |
| UCB2CTL1 &= ~UCSWRST; // Release USCI state machine | |
| UCB2IFG &= ~UCRXIFG; | |
| // Wake-up the LCD as per datasheet specifications | |
| halLcdActive(); | |
| // LCD Initialization Routine Using Predefined Macros | |
| halLcdSendCommand(&LcdInitMacro[ 1 * 6 ]); | |
| halLcdSendCommand(&LcdInitMacro[ 2 * 6 ]); | |
| halLcdSendCommand(&LcdInitMacro[ 4 * 6 ]); | |
| halLcdSendCommand(&LcdInitMacro[ 5 * 6 ]); | |
| halLcdSendCommand(&LcdInitMacro[ 6 * 6 ]); | |
| halLcdSendCommand(&LcdInitMacro[ 7 * 6 ]); | |
| } | |
| /**********************************************************************//** | |
| * @brief Shuts down the LCD display and hdisables the USCI communication. | |
| * | |
| * @param none | |
| * | |
| * @return none | |
| *************************************************************************/ | |
| void halLcdShutDown(void) | |
| { | |
| halLcdStandby(); | |
| LCD_CS_RST_DIR |= LCD_CS_PIN | LCD_RESET_PIN ; | |
| LCD_CS_RST_OUT &= ~(LCD_CS_PIN | LCD_RESET_PIN ); | |
| LCD_CS_RST_OUT &= ~LCD_RESET_PIN; | |
| LCD_SPI_SEL &= ~(LCD_MOSI_PIN + LCD_CLK_PIN + LCD_MISO_PIN); | |
| LCD_CS_RST_DIR |= LCD_MOSI_PIN + LCD_CLK_PIN + LCD_MISO_PIN; | |
| LCD_CS_RST_OUT &= ~(LCD_MOSI_PIN + LCD_CLK_PIN + LCD_MISO_PIN); | |
| UCB2CTL0 = UCSWRST; | |
| } | |
| /**********************************************************************//** | |
| * @brief Initializes the LCD backlight PWM signal. | |
| * | |
| * @param none | |
| * | |
| * @return none | |
| * | |
| *************************************************************************/ | |
| void halLcdBackLightInit(void) | |
| { | |
| LCD_BACKLT_DIR |= LCD_BACKLIGHT_PIN; | |
| LCD_BACKLT_OUT |= LCD_BACKLIGHT_PIN; | |
| LCD_BACKLT_SEL |= LCD_BACKLIGHT_PIN; | |
| TA0CCTL3 = OUTMOD_7; | |
| TA0CCR3 = TA0CCR0 >> 1 ; | |
| backlight = 8; | |
| TA0CCR0 = 400; | |
| TA0CTL = TASSEL_2+MC_1; | |
| } | |
| /**********************************************************************//** | |
| * @brief Get function for the backlight PWM's duty cycle. | |
| * | |
| * @param none | |
| * | |
| * @return backlight One of the the 17 possible settings - valued 0 to 16. | |
| * | |
| *************************************************************************/ | |
| unsigned int halLcdGetBackLight(void) | |
| { | |
| return backlight; | |
| } | |
| /**********************************************************************//** | |
| * @brief Set function for the backlight PWM's duty cycle | |
| * | |
| * @param BackLightLevel The target backlight duty cycle - valued 0 to 16. | |
| * | |
| * @return none | |
| *************************************************************************/ | |
| void halLcdSetBackLight(unsigned char BackLightLevel) | |
| { | |
| unsigned int dutyCycle = 0, i, dummy; | |
| if (BackLightLevel > 0) | |
| { | |
| TA0CCTL3 = OUTMOD_7; | |
| dummy = (TA0CCR0 >> 4); | |
| for (i = 0; i < BackLightLevel; i++) | |
| dutyCycle += dummy; | |
| TA0CCR3 = dutyCycle; | |
| // If the backlight was previously turned off, turn it on. | |
| if (!backlight) | |
| TA0CTL |= MC0; | |
| } | |
| else | |
| { | |
| TA0CCTL3 = 0; | |
| TA0CTL &= ~MC0; | |
| } | |
| backlight = BackLightLevel; | |
| } | |
| /**********************************************************************//** | |
| * @brief Turns off the backlight. | |
| * | |
| * Clears the respective GPIO and timer settings. | |
| * | |
| * @param none | |
| * | |
| * @return none | |
| *************************************************************************/ | |
| void halLcdShutDownBackLight(void) | |
| { | |
| LCD_BACKLT_DIR |= LCD_BACKLIGHT_PIN; | |
| LCD_BACKLT_OUT &= ~(LCD_BACKLIGHT_PIN); | |
| LCD_BACKLT_SEL &= ~LCD_BACKLIGHT_PIN; | |
| TA0CCTL3 = 0; | |
| TA0CTL = 0; | |
| backlight = 0; | |
| } | |
| /**********************************************************************//** | |
| * @brief Set function for the contrast level of the LCD. | |
| * | |
| * @param ContrastLevel The target contrast level | |
| * | |
| * @return none | |
| *************************************************************************/ | |
| void halLcdSetContrast(unsigned char ContrastLevel) | |
| { | |
| if (ContrastLevel > 127) ContrastLevel = 127; | |
| if (ContrastLevel < 70) ContrastLevel = 70; | |
| LcdInitMacro[ 0x04 * 6 + 5 ] = ContrastLevel; | |
| halLcdSendCommand(&LcdInitMacro[ 0x04 * 6 ]); | |
| } | |
| /**********************************************************************//** | |
| * @brief Get function for the contrast level of the LCD. | |
| * | |
| * @param none | |
| * | |
| * @return ContrastLevel The LCD constrast level | |
| *************************************************************************/ | |
| unsigned char halLcdGetContrast(void) | |
| { | |
| return LcdInitMacro[ 0x04 * 6 + 5 ] ; | |
| } | |
| /**********************************************************************//** | |
| * @brief Turns the LCD cursor on at the current text position. | |
| * | |
| * @param none | |
| * | |
| * @return none | |
| *************************************************************************/ | |
| void halLcdCursor(void) | |
| { | |
| LcdInitMacro[ 8 * 6 + 5 ] ^= BIT2; | |
| halLcdSendCommand(&LcdInitMacro[ 8 * 6 ]); | |
| LcdInitMacro[ 0x0B * 6 + 5 ] = ((LcdAddress & 0x1F) << 3) ; | |
| LcdInitMacro[ 0x0B * 6 + 4 ] = ( (LcdAddress & 0x1F) << 3 ) + 3; | |
| LcdInitMacro[ 0x0C * 6 + 5 ] = (LcdAddress >> 5); | |
| LcdInitMacro[ 0x0C * 6 + 4 ] = (LcdAddress >> 5) + 7; | |
| halLcdSendCommand(&LcdInitMacro[ 0x0B * 6 ]); | |
| halLcdSendCommand(&LcdInitMacro[ 0x0C * 6 ]); | |
| halLcdSetAddress(LcdAddress); | |
| } | |
| /**********************************************************************//** | |
| * @brief Turns off the LCD cursor. | |
| * | |
| * @param none | |
| * | |
| * @return none | |
| *************************************************************************/ | |
| void halLcdCursorOff(void) | |
| { | |
| LcdInitMacro[ 8 * 6 + 5 ] &= ~BIT2; | |
| halLcdSendCommand(&LcdInitMacro[ 8 * 6 ]); | |
| } | |
| /**********************************************************************//** | |
| * @brief Inverts the grayscale values of the LCD display (Black <> white). | |
| * | |
| * @param none | |
| * | |
| * @return none | |
| *************************************************************************/ | |
| void halLcdReverse(void) | |
| { | |
| LcdInitMacro[ 7 * 6 + 5 ] ^= BIT1; | |
| halLcdSendCommand(&LcdInitMacro[ 7 * 6 ]); | |
| } | |
| /**********************************************************************//** | |
| * @brief Sets the LCD in standby mode to reduce power consumption. | |
| * | |
| * @param none | |
| * | |
| * @return none | |
| *************************************************************************/ | |
| void halLcdStandby(void) | |
| { | |
| LcdInitMacro[ 3 * 6 + 5 ] &= (~BIT3) & (~BIT2); | |
| LcdInitMacro[ 3 * 6 + 5 ] |= BIT0; | |
| halLcdSendCommand(&LcdInitMacro[ 3 * 6 ]); | |
| } | |
| /**********************************************************************//** | |
| * @brief Puts the LCD into active mode. | |
| * | |
| * @param none | |
| * | |
| * @return none | |
| *************************************************************************/ | |
| void halLcdActive(void) | |
| { | |
| halLcdSendCommand(LcdInitMacro); // R00 start oscillation | |
| // Wait a minimum of 25ms after issuing "start oscillation" | |
| // command (to accomodate for MCLK up to 25MHz) | |
| __delay_cycles(250000); | |
| LcdInitMacro[ 3 * 6 + 5 ] |= BIT3; | |
| LcdInitMacro[ 3 * 6 + 5 ] &= ~BIT0; | |
| halLcdSendCommand(&LcdInitMacro[ 3 * 6 ]); // R03 Power control | |
| } | |
| /**********************************************************************//** | |
| * @brief Sets the pointer location in the LCD. | |
| * | |
| * - LcdAddress = Address | |
| * - LcdTableAddress = Correct Address Row + Column | |
| * = (Address / 0x20)* 17 + Column | |
| * | |
| * @param Address The target pointer location in the LCD. | |
| * | |
| * @return none | |
| *************************************************************************/ | |
| void halLcdSetAddress(int Address) | |
| { | |
| int temp; | |
| Draw_Block_Address_Macro[4] = Address >> 8; | |
| Draw_Block_Address_Macro[5] = Address & 0xFF; | |
| halLcdSendCommand(Draw_Block_Address_Macro); | |
| LcdAddress = Address; | |
| temp = Address >> 5; // Divided by 0x20 | |
| temp = temp + (temp << 4); | |
| //Multiplied by (1+16) and added by the offset | |
| LcdTableAddress = temp + (Address & 0x1F); | |
| } | |
| /**********************************************************************//** | |
| * @brief Draws a block at the specified LCD address. | |
| * | |
| * A block is the smallest addressable memory on the LCD and is | |
| * equivalent to 8 pixels, each of which is represented by 2 bits | |
| * that represent a grayscale value between 00b and 11b. | |
| * | |
| * @param Address The address at which to draw the block. | |
| * | |
| * @param Value The value of the block | |
| * | |
| * @return none | |
| *************************************************************************/ | |
| void halLcdDrawBlock(unsigned int Address, unsigned int Value) | |
| { | |
| halLcdSetAddress(Address); | |
| halLcdDrawCurrentBlock(Value); | |
| } | |
| /**********************************************************************//** | |
| * @brief Writes Value to LCD CGram and MSP430 internal LCD table. | |
| * | |
| * Also updates the LcdAddress and LcdTableAddress to the correct values. | |
| * | |
| * @param Value The value of the block to be written to the LCD. | |
| * | |
| * @return none | |
| *************************************************************************/ | |
| void halLcdDrawCurrentBlock(unsigned int Value) | |
| { | |
| int temp; | |
| Draw_Block_Value_Macro[4] = Value >> 8; | |
| Draw_Block_Value_Macro[5] = Value & 0xFF; | |
| LCD_MEM[ LcdTableAddress ] = Value; | |
| halLcdSendCommand(Draw_Block_Value_Macro); | |
| LcdAddress++; | |
| temp = LcdAddress >> 5; // Divided by 0x20 | |
| temp = temp + (temp << 4); | |
| // Multiplied by (1+16) and added by the offset | |
| LcdTableAddress = temp + (LcdAddress & 0x1F); | |
| // If LcdAddress gets off the right edge, move to next line | |
| if ((LcdAddress & 0x1F) > 0x11) | |
| halLcdSetAddress( (LcdAddress & 0xFFE0) + 0x20 ); | |
| if (LcdAddress == LCD_Size) | |
| halLcdSetAddress( 0 ); | |
| } | |
| /**********************************************************************//** | |
| * @brief Returns the LCD CGRAM value at location Address. | |
| * | |
| * @param Address The address of the block to be read from the LCD. | |
| * | |
| * @return Value The value held at the specified address. | |
| *************************************************************************/ | |
| int halLcdReadBlock(unsigned int Address) | |
| { | |
| int i = 0, Value = 0, ReadData[7]; | |
| halLcdSetAddress( Address ); | |
| halLcdSendCommand(Read_Block_Address_Macro); | |
| LCD_CS_RST_OUT &= ~LCD_CS_PIN; // start transfer CS=0 | |
| UCB2TXBUF = 0x77; // Transmit first character 0x77 | |
| while (!(UCB2IFG & UCTXIFG)); | |
| while (UCB2STAT & UCBUSY); | |
| //Read 5 dummies values and 2 valid address data | |
| LCD_SPI_SEL &= ~LCD_MOSI_PIN; //Change SPI2C Dir | |
| LCD_SPI_SEL |= LCD_MISO_PIN; | |
| for (i = 0; i < 7; i ++ ) | |
| { | |
| UCB2IFG &= ~UCRXIFG; | |
| UCB2TXBUF = 1; // load dummy byte 1 for clk | |
| while (!(UCB2IFG & UCRXIFG)); | |
| ReadData[i] = UCB2RXBUF; | |
| } | |
| LCD_CS_RST_OUT |= LCD_CS_PIN; // Stop Transfer CS = 1 | |
| LCD_SPI_SEL |= LCD_MOSI_PIN; //Change SPI2C Dir | |
| LCD_SPI_SEL &= ~LCD_MISO_PIN; | |
| LCD_CS_RST_DIR |= LCD_MOSI_PIN + LCD_CLK_PIN; | |
| LCD_CS_RST_DIR &= ~LCD_MISO_PIN; | |
| Value = (ReadData[5] << 8) + ReadData[6]; | |
| return Value; | |
| } | |
| /**********************************************************************//** | |
| * @brief Draw a Pixel of grayscale at coordinate (x,y) to LCD | |
| * | |
| * @param x x-coordinate for grayscale value | |
| * | |
| * @param y y-coordinate for grayscale value | |
| * | |
| * @param GrayScale The intended grayscale value of the pixel - one of | |
| * four possible settings. | |
| * | |
| * @return none | |
| *************************************************************************/ | |
| void halLcdPixel( int x, int y, unsigned char GrayScale) | |
| { | |
| int Address, Value; | |
| unsigned char offset; | |
| //Each line increments by 0x20 | |
| if ( (x>=0 ) && (x<LCD_COL) && (y>=0) && (y<LCD_ROW)) | |
| { | |
| Address = (y << 5) + (x >> 3) ; //Narrow down to 8 possible pixels | |
| Value = LCD_MEM[(y << 4)+ y + (x>>3)]; //y * 17 --> row. x>>3 --> column | |
| offset = (x & 0x07) << 1; //3 LSBs = pos. within the 8 columns | |
| Value &= ~ (3 << offset); //clear out the corresponding bits | |
| Value |= GrayScale << offset; //set pixel to GrayScale level | |
| halLcdDrawBlock( Address, Value ); | |
| } | |
| } | |
| /**********************************************************************//** | |
| * @brief Clears entire LCD CGRAM as well as LCD_MEM. | |
| * | |
| * @param none | |
| * | |
| * @return none | |
| *************************************************************************/ | |
| void halLcdClearScreen(void) | |
| { | |
| int i, j, k, Current_Location = 0; | |
| halLcdSetAddress(0); | |
| for (i=0; i < 110; i++) | |
| { | |
| //prepare to send image | |
| LCD_CS_RST_OUT &= ~LCD_CS_PIN; //CS = 0 --> Start Transfer | |
| for ( k = 0; k < 3; k++ ) | |
| { | |
| while (!(UCB2IFG & UCTXIFG)); // Wait for TXIFG | |
| UCB2TXBUF = Draw_Block_Value_Macro[k]; // Load data | |
| } | |
| while (UCB2STAT & UCBUSY); | |
| LCD_CS_RST_OUT |= LCD_CS_PIN; //CS = 1 --> Stop Transfer | |
| LCD_CS_RST_OUT &= ~LCD_CS_PIN; //CS = 0 --> Start Transfer | |
| while (!(UCB2IFG & UCTXIFG)); // Wait for TXIFG | |
| UCB2TXBUF = Draw_Block_Value_Macro[3]; // Load data | |
| //send blank line | |
| for (j=0; j < 17; j++) | |
| { | |
| LCD_MEM[ LcdTableAddress++ ] = 0x00; | |
| while (!(UCB2IFG & UCTXIFG)); // Wait for TXIFG | |
| UCB2TXBUF = 0x00; // Load data | |
| while (!(UCB2IFG & UCTXIFG)); // Wait for TXIFG | |
| UCB2TXBUF = 0x00; // Load data | |
| } | |
| //Clear the partially visible block at the edge of the screen | |
| while (!(UCB2IFG & UCTXIFG)); // Wait for TXIFG | |
| UCB2TXBUF = 0x00; // Load data | |
| while (!(UCB2IFG & UCTXIFG)); // Wait for TXIFG | |
| UCB2TXBUF = 0x00; // Load data | |
| while (UCB2STAT & UCBUSY); | |
| LCD_CS_RST_OUT |= LCD_CS_PIN; //CS = 1 --> Stop Transfer | |
| Current_Location += 0x20; | |
| halLcdSetAddress(Current_Location ); | |
| } | |
| halLcdSetAddress(0); | |
| } | |
| /**********************************************************************//** | |
| * @brief Loads an image of size = rows * columns, starting at the | |
| * coordinate (x,y). | |
| * | |
| * @param Image[] The image to be loaded | |
| * | |
| * @param Rows The number of rows in the image. Size = Rows * Columns. | |
| * | |
| * @param Columns The number of columns in the image. Size = Rows * Columns. | |
| * | |
| * @param x x-coordinate of the image's starting location | |
| * | |
| * @param y y-coordinate of the image's starting location | |
| * | |
| * @return none | |
| *************************************************************************/ | |
| void halLcdImage(const unsigned int Image[], int Columns, int Rows, int x, int y) | |
| { | |
| int i, CurrentLocation; | |
| CurrentLocation = (y << 5) + (x >> 3); | |
| halLcdSetAddress(CurrentLocation); | |
| for (i=0; i < Rows; i++) | |
| { | |
| halLcdDrawCurrentLine(Image, Columns); | |
| Image += Columns; | |
| CurrentLocation += 0x20; | |
| halLcdSetAddress(CurrentLocation); | |
| } | |
| } | |
| /**********************************************************************//** | |
| * @brief Writes Value to LCD CGram and MSP430 internal LCD table. | |
| * | |
| * Also updates the LcdAddress and LcdTableAddress to the correct values. | |
| * | |
| * @param *value Pointer to the line to be written to the LCD. | |
| * | |
| * @return none | |
| *************************************************************************/ | |
| void halLcdDrawCurrentLine(const unsigned int *value, int Columns) | |
| { | |
| unsigned char i; | |
| //prepare to send image | |
| LCD_CS_RST_OUT &= ~LCD_CS_PIN; //CS = 0 --> Start Transfer | |
| for ( i = 0; i < 3; i++ ) | |
| { | |
| while (!(UCB2IFG & UCTXIFG)); // Wait for TXIFG | |
| UCB2TXBUF = Draw_Block_Value_Macro[i]; // Load data | |
| } | |
| while (UCB2STAT & UCBUSY); | |
| LCD_CS_RST_OUT |= LCD_CS_PIN; //CS = 1 --> Stop Transfer | |
| LCD_CS_RST_OUT &= ~LCD_CS_PIN; //CS = 0 --> Start Transfer | |
| while (!(UCB2IFG & UCTXIFG)); // Wait for TXIFG | |
| UCB2TXBUF = Draw_Block_Value_Macro[3]; // Load data | |
| //send the image | |
| for ( i = 0; i < Columns; i++ ) | |
| { | |
| // Make sure we are not writing outside LCD_MEM[] | |
| if (LcdTableAddress >= sizeof(LCD_MEM)) { | |
| break; | |
| } | |
| LCD_MEM[ LcdTableAddress++ ] = *value; | |
| while (!(UCB2IFG & UCTXIFG)); // Wait for TXIFG | |
| UCB2TXBUF = (*value) >> 8; // Load data | |
| while (!(UCB2IFG & UCTXIFG)); // Wait for TXIFG | |
| UCB2TXBUF = (*value++) & 0xFF; // Load data | |
| } | |
| while (UCB2STAT & UCBUSY); | |
| LCD_CS_RST_OUT |= LCD_CS_PIN; //CS = 1 --> Stop Transfer | |
| } | |
| /**********************************************************************//** | |
| * @brief Clears an image of size rows x columns starting at (x, y). | |
| * | |
| * @param Columns The size, in columns, of the image to be cleared. | |
| * | |
| * @param Rows The size, in rows, of the image to be cleared. | |
| * | |
| * @param x x-coordinate of the image to be cleared | |
| * | |
| * @param y y-coordinate of the image to be cleared | |
| * | |
| * @return none | |
| *************************************************************************/ | |
| void halLcdClearImage(int Columns, int Rows, int x, int y) | |
| { | |
| int i,j,k, Current_Location; | |
| Current_Location = (y << 5) + (x >> 3); | |
| halLcdSetAddress( Current_Location ); | |
| for (i=0; i < Rows; i++) | |
| { | |
| //prepare to send image | |
| LCD_CS_RST_OUT &= ~LCD_CS_PIN; //CS = 0 --> Start Transfer | |
| for ( k = 0; k < 3; k++ ) | |
| { | |
| while (!(UCB2IFG & UCTXIFG)); // Wait for TXIFG | |
| UCB2TXBUF = Draw_Block_Value_Macro[k]; // Load data | |
| } | |
| while (UCB2STAT & UCBUSY); | |
| LCD_CS_RST_OUT |= LCD_CS_PIN; //CS = 1 --> Stop Transfer | |
| LCD_CS_RST_OUT &= ~LCD_CS_PIN; //CS = 0 --> Start Transfer | |
| while (!(UCB2IFG & UCTXIFG)); // Wait for TXIFG | |
| UCB2TXBUF = Draw_Block_Value_Macro[3]; // Load data | |
| //send blank line | |
| for (j=0; j < Columns; j++) | |
| { | |
| LCD_MEM[ LcdTableAddress++ ] = 0x00; | |
| while (!(UCB2IFG & UCTXIFG)); // Wait for TXIFG | |
| UCB2TXBUF = 0x00; // Load data | |
| while (!(UCB2IFG & UCTXIFG)); // Wait for TXIFG | |
| UCB2TXBUF = 0x00; // Load data | |
| } | |
| while (UCB2STAT & UCBUSY); | |
| LCD_CS_RST_OUT |= LCD_CS_PIN; //CS = 1 --> Stop Transfer | |
| Current_Location += 0x20; | |
| halLcdSetAddress(Current_Location ); | |
| } | |
| } | |
| /**********************************************************************//** | |
| * @brief Writes Value to LCD CGRAM. Pointers internal to the LCD | |
| * are also updated. | |
| * | |
| * @param Value The value to be written to the current LCD pointer | |
| * | |
| * @return none | |
| *************************************************************************/ | |
| void halLcdDrawTextBlock(unsigned int Value) | |
| { | |
| int temp; | |
| Draw_Block_Value_Macro[4] = Value >> 8; | |
| Draw_Block_Value_Macro[5] = Value & 0xFF; | |
| LCD_MEM[ LcdTableAddress ] = Value; | |
| halLcdSendCommand(Draw_Block_Value_Macro); | |
| LcdAddress++; | |
| temp = LcdAddress >> 5; // Divided by 0x20 | |
| temp = temp + (temp << 4); | |
| //Multiplied by (1+16) and added by the offset | |
| LcdTableAddress = temp + (LcdAddress & 0x1F); | |
| // If LcdAddress gets off the right edge, move to next line | |
| if ((LcdAddress & 0x1F) > 0x10) | |
| halLcdSetAddress( (LcdAddress & 0xFFE0) + 0x20 ); | |
| if (LcdAddress >= LCD_Size) | |
| halLcdSetAddress( 0 ); | |
| } | |
| /**********************************************************************//** | |
| * @brief Displays the string to the LCD starting at current location. | |
| * | |
| * Writes all the data to LCD_MEM first, then updates all corresponding | |
| * LCD CGRAM locations at once, in a continuous fashion. | |
| * | |
| * @param String[] The string to be displayed on LCD. | |
| * | |
| * @param TextStyle Value that specifies whether the string is to be | |
| * inverted or overwritten. | |
| * - Invert = 0x01 | |
| * - Overwrite = 0x04 | |
| * | |
| * @return none | |
| *************************************************************************/ | |
| void halLcdPrint( char String[], unsigned char TextStyle) | |
| { | |
| int i, j, Counter=0, BlockValue; | |
| int Address, LCD_MEM_Add, ActualAddress; | |
| int temp; | |
| char LookUpChar; | |
| ActualAddress = LcdAddress; | |
| Counter = LcdAddress & 0x1F; | |
| i=0; | |
| while (String[i]!=0) // Stop on null character | |
| { | |
| LookUpChar = fonts_lookup[String[i]]; | |
| for (j=0;j < FONT_HEIGHT ;j++) | |
| { | |
| Address = ActualAddress + j*0x20; | |
| temp = Address >> 5; | |
| temp += (temp <<4); | |
| LCD_MEM_Add = temp + (Address & 0x1F); | |
| BlockValue = LCD_MEM[ LCD_MEM_Add ]; | |
| if(TextStyle & GRAYSCALE_TEXT) | |
| { | |
| if (TextStyle & INVERT_TEXT) | |
| if (TextStyle & OVERWRITE_TEXT) | |
| BlockValue = 0xAAAA - GrayScale_fonts[LookUpChar*(FONT_HEIGHT+1) +j]; | |
| else | |
| BlockValue |= 0xAAAA - GrayScale_fonts[LookUpChar*(FONT_HEIGHT+1) +j]; | |
| else | |
| if (TextStyle & OVERWRITE_TEXT) | |
| BlockValue = GrayScale_fonts[LookUpChar*(FONT_HEIGHT+1) +j]; | |
| else | |
| BlockValue |= GrayScale_fonts[LookUpChar*(FONT_HEIGHT+1) +j]; | |
| } | |
| else | |
| { | |
| if (TextStyle & INVERT_TEXT) | |
| if (TextStyle & OVERWRITE_TEXT) | |
| BlockValue = 0xFFFF - fonts[LookUpChar*13+j]; | |
| else | |
| BlockValue |= 0xFFFF - fonts[LookUpChar*13+j]; | |
| else | |
| if (TextStyle & OVERWRITE_TEXT) | |
| BlockValue = fonts[LookUpChar*(FONT_HEIGHT+1) +j]; | |
| else | |
| BlockValue |= fonts[LookUpChar*(FONT_HEIGHT+1) +j]; | |
| } | |
| halLcdDrawBlock( Address, BlockValue); | |
| } | |
| Counter++; | |
| if (Counter == 17) | |
| { | |
| Counter = 0; | |
| ActualAddress += 0x20*FONT_HEIGHT - 16; | |
| if (ActualAddress > LCD_Last_Pixel-0x20*FONT_HEIGHT ) | |
| ActualAddress = 0; | |
| } | |
| else | |
| ActualAddress++; | |
| i++; | |
| } | |
| halLcdSetAddress(ActualAddress); | |
| } | |
| /**********************************************************************//** | |
| * @brief Displays the string to the LCD starting at (x,y) location. | |
| * | |
| * Writes all the data to LCD_MEM first, then updates all corresponding | |
| * LCD CGRAM locations at once, in a continuous fashion. | |
| * | |
| * @param String[] String to be displayed on LCD | |
| * | |
| * @param x x-coordinate of the write location on the LCD | |
| * | |
| * @param y y-coordinate of the write location on the LCD | |
| * | |
| * @param TextStyle Value that specifies whether the string is to be | |
| * inverted or overwritten. | |
| * - Invert = 0x01 | |
| * - Overwrite = 0x04 | |
| *************************************************************************/ | |
| void halLcdPrintXY( char String[], int x, int y, unsigned char TextStyle) | |
| { | |
| //Each line increments by 0x20 | |
| halLcdSetAddress( (y << 5) + (x >> 3)) ; //Narrow down to 8 possible pixels | |
| halLcdPrint(String, TextStyle); | |
| } | |
| /**********************************************************************//** | |
| * @brief Displays a string on the LCD on the specified line. | |
| * | |
| * @param String[] The string to be displayed on LCD. | |
| * | |
| * @param Line The line on the LCD on which to print the string. | |
| * | |
| * @param TextStyle Value that specifies whether the string is to be | |
| * inverted or overwritten. | |
| * - Invert = 0x01 | |
| * - Overwrite = 0x04 | |
| * | |
| * @return none | |
| *************************************************************************/ | |
| void halLcdPrintLine(char String[], unsigned char Line, unsigned char TextStyle) | |
| { | |
| int temp; | |
| temp = Line * FONT_HEIGHT ; | |
| halLcdSetAddress( temp << 5 ) ; // 0x20 = 2^5 | |
| halLcdPrint(String, TextStyle); | |
| } | |
| /**********************************************************************//** | |
| * @brief Prints a string beginning on a given line and column. | |
| * | |
| * @param String[] The string to be displayed on LCD. | |
| * | |
| * @param Line The line on which to print the string of text | |
| * | |
| * @param Col The column on which to print the string of text | |
| * | |
| * @param TextStyle Value that specifies whether the string is to be | |
| * inverted or overwritten. | |
| * - Invert = 0x01 | |
| * - Overwrite = 0x04 | |
| * | |
| * @return none | |
| *************************************************************************/ | |
| void halLcdPrintLineCol(char String[], unsigned char Line, unsigned char Col, | |
| unsigned char TextStyle) | |
| { | |
| int temp; | |
| temp = Line * FONT_HEIGHT; | |
| temp <<= 5; | |
| temp += Col; | |
| halLcdSetAddress( temp ) ; // 0x20 = 2^5 | |
| halLcdPrint(String, TextStyle); | |
| } | |
| /**********************************************************************//** | |
| * @brief Draws a horizontral line from (x1,y) to (x2,y) of GrayScale level | |
| * | |
| * @param x1 x-coordinate of the first point | |
| * | |
| * @param x2 x-coordinate of the second point | |
| * | |
| * @param y y-coordinate of both points | |
| * | |
| * @param GrayScale Grayscale level of the horizontal line | |
| * | |
| * @return none | |
| *************************************************************************/ | |
| void halLcdHLine( int x1, int x2, int y, unsigned char GrayScale) | |
| { | |
| int x_dir, x; | |
| if ( x1 < x2 ) | |
| x_dir = 1; | |
| else | |
| x_dir = -1; | |
| x = x1; | |
| while (x != x2) | |
| { | |
| halLcdPixel( x,y, GrayScale); | |
| x += x_dir; | |
| } | |
| } | |
| /**********************************************************************//** | |
| * @brief Draws a vertical line from (x,y1) to (x,y2) of GrayScale level | |
| * | |
| * @param x x-coordinate of both points | |
| * | |
| * @param y1 y-coordinate of the first point | |
| * | |
| * @param y2 y-coordinate of the second point | |
| * | |
| * @param GrayScale GrayScale level of the vertical line | |
| * | |
| * @return none | |
| *************************************************************************/ | |
| void halLcdVLine( int x, int y1, int y2, unsigned char GrayScale) | |
| { | |
| int y_dir, y; | |
| if ( y1 < y2 ) | |
| y_dir = 1; | |
| else | |
| y_dir = -1; | |
| y = y1; | |
| while (y != y2) | |
| { | |
| halLcdPixel( x,y, GrayScale); | |
| y += y_dir; | |
| } | |
| } | |
| /**********************************************************************//** | |
| * @brief Draws a line from (x1,y1) to (x2,y2) of GrayScale level. | |
| * | |
| * Uses Bresenham's line algorithm. | |
| * | |
| * @param x1 x-coordinate of the first point | |
| * | |
| * @param y1 y-coordinate of the first point | |
| * | |
| * @param x2 x-coordinate of the second point | |
| * | |
| * @param y2 y-coordinate of the second point | |
| * | |
| * @param GrayScale Grayscale level of the line | |
| * | |
| * @return none | |
| *************************************************************************/ | |
| void halLcdLine( int x1, int y1, int x2, int y2, unsigned char GrayScale) | |
| { | |
| int x, y, deltay, deltax, d; | |
| int x_dir, y_dir; | |
| if ( x1 == x2 ) | |
| halLcdVLine( x1, y1, y2, GrayScale ); | |
| else | |
| { | |
| if ( y1 == y2 ) | |
| halLcdHLine( x1, x2, y1, GrayScale ); | |
| else // a diagonal line | |
| { | |
| if (x1 > x2) | |
| x_dir = -1; | |
| else x_dir = 1; | |
| if (y1 > y2) | |
| y_dir = -1; | |
| else y_dir = 1; | |
| x = x1; | |
| y = y1; | |
| deltay = ABS(y2 - y1); | |
| deltax = ABS(x2 - x1); | |
| if (deltax >= deltay) | |
| { | |
| d = (deltay << 1) - deltax; | |
| while (x != x2) | |
| { | |
| halLcdPixel(x, y, GrayScale); | |
| if ( d < 0 ) | |
| d += (deltay << 1); | |
| else | |
| { | |
| d += ((deltay - deltax) << 1); | |
| y += y_dir; | |
| } | |
| x += x_dir; | |
| } | |
| } | |
| else | |
| { | |
| d = (deltax << 1) - deltay; | |
| while (y != y2) | |
| { | |
| halLcdPixel(x, y, GrayScale); | |
| if ( d < 0 ) | |
| d += (deltax << 1); | |
| else | |
| { | |
| d += ((deltax - deltay) << 1); | |
| x += x_dir; | |
| } | |
| y += y_dir; | |
| } | |
| } | |
| } | |
| } | |
| } | |
| /**********************************************************************//** | |
| * @brief Draw a circle of Radius with center at (x,y) of GrayScale level. | |
| * | |
| * Uses Bresenham's circle algorithm | |
| * | |
| * @param x x-coordinate of the circle's center point | |
| * | |
| * @param y y-coordinate of the circle's center point | |
| * | |
| * @param Radius Radius of the circle | |
| * | |
| * @param GrayScale Grayscale level of the circle | |
| *************************************************************************/ | |
| void halLcdCircle(int x, int y, int Radius, int GrayScale) | |
| { | |
| int xx, yy, ddF_x, ddF_y, f; | |
| ddF_x = 0; | |
| ddF_y = -(2 * Radius); | |
| f = 1 - Radius; | |
| xx = 0; | |
| yy = Radius; | |
| halLcdPixel(x + xx, y + yy, GrayScale); | |
| halLcdPixel(x + xx, y - yy, GrayScale); | |
| halLcdPixel(x - xx, y + yy, GrayScale); | |
| halLcdPixel(x - xx, y - yy, GrayScale); | |
| halLcdPixel(x + yy, y + xx, GrayScale); | |
| halLcdPixel(x + yy, y - xx, GrayScale); | |
| halLcdPixel(x - yy, y + xx, GrayScale); | |
| halLcdPixel(x - yy, y - xx, GrayScale); | |
| while (xx < yy) | |
| { | |
| if (f >= 0) | |
| { | |
| yy--; | |
| ddF_y += 2; | |
| f += ddF_y; | |
| } | |
| xx++; | |
| ddF_x += 2; | |
| f += ddF_x + 1; | |
| halLcdPixel(x + xx, y + yy, GrayScale); | |
| halLcdPixel(x + xx, y - yy, GrayScale); | |
| halLcdPixel(x - xx, y + yy, GrayScale); | |
| halLcdPixel(x - xx, y - yy, GrayScale); | |
| halLcdPixel(x + yy, y + xx, GrayScale); | |
| halLcdPixel(x + yy, y - xx, GrayScale); | |
| halLcdPixel(x - yy, y + xx, GrayScale); | |
| halLcdPixel(x - yy, y - xx, GrayScale); | |
| } | |
| } | |
| /**********************************************************************//** | |
| * @brief Scrolls a single row of pixels one column to the left. | |
| * | |
| * The column that is scrolled out of the left side of the LCD will be | |
| * displayed the right side of the LCD. | |
| * | |
| * @param y The row of pixels to scroll. y = 0 is at the top-left | |
| * corner of the LCD. | |
| * | |
| * @return none | |
| *************************************************************************/ | |
| void halLcdScrollRow(int y) | |
| { | |
| int i, Address, LcdTableAddressTemp; | |
| unsigned int temp; | |
| Address = y << 5; | |
| halLcdSetAddress( Address ); | |
| //Multiplied by (1+16) and added by the offset | |
| LcdTableAddressTemp = y + (y << 4); | |
| temp = ((LCD_MEM[LcdTableAddressTemp] & 0x0003) <<14); | |
| for (i = 0; i < 0x10; i++) | |
| halLcdDrawCurrentBlock( ( (LCD_MEM[LcdTableAddressTemp+i] & 0xFFFC ) >> 2 ) \ | |
| + ((LCD_MEM[LcdTableAddressTemp+i+1] & 0x0003) << 14 )); | |
| halLcdDrawCurrentBlock( (( LCD_MEM[LcdTableAddressTemp + 0x10] & 0xFFFC ) >> 2) + temp); | |
| } | |
| /**********************************************************************//** | |
| * @brief Scrolls multiple rows of pixels, yStart to yEnd, | |
| * one column to the left. | |
| * | |
| * The column that is scrolled out of the left side of the LCD will be | |
| * displayed the right side of the LCD. y = 0 is at the top-left of the | |
| * LCD screen. | |
| * | |
| * @param yStart The beginning row to be scrolled | |
| * | |
| * @param yEnd The last row to be scrolled | |
| * | |
| * @return none | |
| *************************************************************************/ | |
| void halLcdHScroll(int yStart, int yEnd) | |
| { | |
| int i ; | |
| for (i = yStart; i < yEnd+1; i++) | |
| halLcdScrollRow(i); | |
| } | |
| /**********************************************************************//** | |
| * @brief Scrolls a line of text one column to the left. | |
| * | |
| * @param Line The line of text to be scrolled. | |
| * | |
| * @return none | |
| *************************************************************************/ | |
| void halLcdScrollLine(int Line) | |
| { | |
| int i, Row ; | |
| Row = Line * FONT_HEIGHT; | |
| for (i = Row; i < Row + FONT_HEIGHT ; i++) | |
| halLcdScrollRow(i); | |
| } |