-/** \r
+/**\r
* @file hal_lcd.c\r
- * \r
+ *\r
* Copyright 2010 Texas Instruments, Inc.\r
***************************************************************************/\r
\r
0x74,0x00,0x07,0x76,0x00,0x15, // R07 Display control\r
0x74,0x00,0x08,0x76,0x00,0x03, // R08 Cursor Control\r
0x74,0x00,0x09,0x76,0x00,0x00, // R09 RAM data write mask\r
- 0x74,0x00,0x0A,0x76,0x00,0x15, // R0A \r
+ 0x74,0x00,0x0A,0x76,0x00,0x15, // R0A\r
0x74,0x00,0x0B,0x76,0x00,0x03, // R0B Horizontal Cursor Position\r
0x74,0x00,0x0C,0x76,0x00,0x03, // R0C Vertical Cursor Position\r
- 0x74,0x00,0x0D,0x76,0x00,0x00, // R0D \r
- 0x74,0x00,0x0E,0x76,0x00,0x15, // R0E \r
- 0x74,0x00,0x0F,0x76,0x00,0x03, // R0F \r
- 0x74,0x00,0x10,0x76,0x00,0x15, // R0E \r
- 0x74,0x00,0x11,0x76,0x00,0x03, // R0F \r
+ 0x74,0x00,0x0D,0x76,0x00,0x00, // R0D\r
+ 0x74,0x00,0x0E,0x76,0x00,0x15, // R0E\r
+ 0x74,0x00,0x0F,0x76,0x00,0x03, // R0F\r
+ 0x74,0x00,0x10,0x76,0x00,0x15, // R0E\r
+ 0x74,0x00,0x11,0x76,0x00,0x03, // R0F\r
};\r
\r
-unsigned char Read_Block_Address_Macro[]= {0x74,0x00,0x12,0x77,0x00,0x00}; \r
+unsigned char Read_Block_Address_Macro[]= {0x74,0x00,0x12,0x77,0x00,0x00};\r
unsigned char Draw_Block_Value_Macro[]={0x74,0x00,0x12,0x76,0xFF,0xFF};\r
unsigned char Draw_Block_Address_Macro[]={0x74,0x00,0x11,0x76,0x00,0x00};\r
\r
unsigned int LcdAddress = 0, LcdTableAddress = 0;\r
unsigned char contrast = 0x66;\r
unsigned char backlight = 8;\r
-int LCD_MEM[110*17]; //This array stores a copy of all data on the LCD \r
- //screen. If memory is an issue though, this array \r
+int LCD_MEM[110*17]; //This array stores a copy of all data on the LCD\r
+ //screen. If memory is an issue though, this array\r
//can be eliminated and the halLcdReadBlock()\r
- //command can be used instead whenever you are \r
+ //command can be used instead whenever you are\r
//manipulating the currently displayed data.\r
\r
/**********************************************************************//**\r
* @brief Sends 3+3 bytes of data to the LCD using the format specified\r
* by the LCD Guide.\r
- * \r
- * @param Data[] Data array for transmission \r
- * \r
+ *\r
+ * @param Data[] Data array for transmission\r
+ *\r
* @return none\r
*************************************************************************/\r
-void halLcdSendCommand(unsigned char Data[]) \r
+void halLcdSendCommand(unsigned char Data[])\r
{\r
unsigned char i;\r
\r
LCD_CS_RST_OUT &= ~LCD_CS_PIN; //CS = 0 --> Start Transfer\r
for ( i = 0; i < 6; i++ )\r
{\r
- while (!(UCB2IFG & UCTXIFG)); // Wait for TXIFG \r
- UCB2TXBUF = Data[i]; // Load data \r
+ while (!(UCB2IFG & UCTXIFG)); // Wait for TXIFG\r
+ UCB2TXBUF = Data[i]; // Load data\r
\r
if (i == 2) //Pull CS up after 3 bytes\r
{\r
while (UCB2STAT & UCBUSY); \r
LCD_CS_RST_OUT |= LCD_CS_PIN; //CS = 1 --> Stop Transfer\r
- LCD_CS_RST_OUT &= ~LCD_CS_PIN; //CS = 0 --> Start Transfer \r
+ LCD_CS_RST_OUT &= ~LCD_CS_PIN; //CS = 0 --> Start Transfer \r
}\r
}\r
while (UCB2STAT & UCBUSY); \r
- LCD_CS_RST_OUT |= LCD_CS_PIN; //CS = 1 --> Stop Transfer \r
+ LCD_CS_RST_OUT |= LCD_CS_PIN; //CS = 1 --> Stop Transfer\r
}\r
\r
/**********************************************************************//**\r
- * @brief Initializes the USCI module, LCD device for communication. \r
- * \r
+ * @brief Initializes the USCI module, LCD device for communication.\r
+ *\r
* - Sets up the SPI2C Communication Module\r
* - Performs Hitachi LCD Initialization Procedure\r
- * \r
+ *\r
* @param none\r
- * \r
+ *\r
* @return none\r
*************************************************************************/\r
-void halLcdInit(void) \r
+void halLcdInit(void)\r
{\r
volatile unsigned int i=0;\r
\r
LCD_CS_RST_OUT |= LCD_CS_PIN | LCD_RESET_PIN ;\r
- LCD_CS_RST_DIR |= LCD_CS_PIN | LCD_RESET_PIN ; \r
+ LCD_CS_RST_DIR |= LCD_CS_PIN | LCD_RESET_PIN ;\r
\r
LCD_BACKLT_SEL |= LCD_BACKLIGHT_PIN;\r
\r
LCD_CS_RST_OUT &= ~LCD_RESET_PIN; // Reset LCD\r
__delay_cycles(0x47FF); //Reset Pulse\r
- LCD_CS_RST_OUT |= LCD_RESET_PIN; \r
+ LCD_CS_RST_OUT |= LCD_RESET_PIN;\r
\r
// UCLK,MOSI setup, SOMI cleared\r
LCD_SPI_SEL |= LCD_MOSI_PIN + LCD_CLK_PIN;\r
LCD_SPI_SEL &= ~LCD_MISO_PIN;\r
LCD_SPI_DIR &= ~(LCD_MISO_PIN + LCD_MOSI_PIN); // Pin direction controlled by module,\r
// Set both pins to input as default\r
- \r
- // Initialize the USCI_B2 module for SPI operation \r
+\r
+ // Initialize the USCI_B2 module for SPI operation\r
UCB2CTL1 = UCSWRST; // Hold USCI in SW reset mode while configuring it\r
UCB2CTL0 = UCMST+UCSYNC+UCCKPL+UCMSB; // 3-pin, 8-bit SPI master\r
UCB2CTL1 |= UCSSEL_2; // SMCLK\r
\r
// Wake-up the LCD as per datasheet specifications\r
halLcdActive();\r
- \r
+\r
// LCD Initialization Routine Using Predefined Macros\r
halLcdSendCommand(&LcdInitMacro[ 1 * 6 ]);\r
halLcdSendCommand(&LcdInitMacro[ 2 * 6 ]);\r
}\r
\r
/**********************************************************************//**\r
- * @brief Shuts down the LCD display and hdisables the USCI communication. \r
- * \r
+ * @brief Shuts down the LCD display and hdisables the USCI communication.\r
+ *\r
* @param none\r
- * \r
+ *\r
* @return none\r
*************************************************************************/\r
void halLcdShutDown(void)\r
{\r
- halLcdStandby(); \r
+ halLcdStandby();\r
\r
LCD_CS_RST_DIR |= LCD_CS_PIN | LCD_RESET_PIN ;\r
- LCD_CS_RST_OUT &= ~(LCD_CS_PIN | LCD_RESET_PIN ); \r
- LCD_CS_RST_OUT &= ~LCD_RESET_PIN; \r
- \r
+ LCD_CS_RST_OUT &= ~(LCD_CS_PIN | LCD_RESET_PIN );\r
+ LCD_CS_RST_OUT &= ~LCD_RESET_PIN;\r
+\r
LCD_SPI_SEL &= ~(LCD_MOSI_PIN + LCD_CLK_PIN + LCD_MISO_PIN);\r
LCD_CS_RST_DIR |= LCD_MOSI_PIN + LCD_CLK_PIN + LCD_MISO_PIN;\r
- LCD_CS_RST_OUT &= ~(LCD_MOSI_PIN + LCD_CLK_PIN + LCD_MISO_PIN); \r
- \r
- UCB2CTL0 = UCSWRST; \r
-} \r
+ LCD_CS_RST_OUT &= ~(LCD_MOSI_PIN + LCD_CLK_PIN + LCD_MISO_PIN);\r
+\r
+ UCB2CTL0 = UCSWRST;\r
+}\r
\r
/**********************************************************************//**\r
- * @brief Initializes the LCD backlight PWM signal. \r
- * \r
+ * @brief Initializes the LCD backlight PWM signal.\r
+ *\r
* @param none\r
- * \r
+ *\r
* @return none\r
- * \r
+ *\r
*************************************************************************/\r
void halLcdBackLightInit(void)\r
{\r
LCD_BACKLT_DIR |= LCD_BACKLIGHT_PIN;\r
- LCD_BACKLT_OUT |= LCD_BACKLIGHT_PIN; \r
+ LCD_BACKLT_OUT |= LCD_BACKLIGHT_PIN;\r
LCD_BACKLT_SEL |= LCD_BACKLIGHT_PIN;\r
\r
TA0CCTL3 = OUTMOD_7;\r
TA0CCR3 = TA0CCR0 >> 1 ;\r
backlight = 8;\r
- \r
+\r
TA0CCR0 = 400;\r
- TA0CTL = TASSEL_2+MC_1; \r
+ TA0CTL = TASSEL_2+MC_1;\r
}\r
\r
/**********************************************************************//**\r
- * @brief Get function for the backlight PWM's duty cycle. \r
- * \r
- * @param none \r
- * \r
- * @return backlight One of the the 17 possible settings - valued 0 to 16. \r
+ * @brief Get function for the backlight PWM's duty cycle.\r
+ *\r
+ * @param none\r
+ *\r
+ * @return backlight One of the the 17 possible settings - valued 0 to 16.\r
*\r
*************************************************************************/\r
unsigned int halLcdGetBackLight(void)\r
-{ \r
+{\r
return backlight;\r
}\r
\r
/**********************************************************************//**\r
- * @brief Set function for the backlight PWM's duty cycle \r
- * \r
+ * @brief Set function for the backlight PWM's duty cycle\r
+ *\r
* @param BackLightLevel The target backlight duty cycle - valued 0 to 16.\r
- * \r
+ *\r
* @return none\r
*************************************************************************/\r
void halLcdSetBackLight(unsigned char BackLightLevel)\r
-{ \r
- unsigned int dutyCycle = 0, i, dummy; \r
- \r
+{\r
+ unsigned int dutyCycle = 0, i, dummy;\r
+\r
if (BackLightLevel > 0)\r
{\r
TA0CCTL3 = OUTMOD_7;\r
dummy = (TA0CCR0 >> 4);\r
- \r
- for (i = 0; i < BackLightLevel; i++) \r
+\r
+ for (i = 0; i < BackLightLevel; i++)\r
dutyCycle += dummy;\r
- \r
+\r
TA0CCR3 = dutyCycle;\r
- \r
- // If the backlight was previously turned off, turn it on. \r
- if (!backlight) \r
- TA0CTL |= MC0; \r
+\r
+ // If the backlight was previously turned off, turn it on.\r
+ if (!backlight)\r
+ TA0CTL |= MC0;\r
}\r
else\r
{ \r
TA0CCTL3 = 0;\r
TA0CTL &= ~MC0;\r
- } \r
+ }\r
backlight = BackLightLevel;\r
}\r
\r
/**********************************************************************//**\r
- * @brief Turns off the backlight. \r
- * \r
+ * @brief Turns off the backlight.\r
+ *\r
* Clears the respective GPIO and timer settings.\r
- * \r
+ *\r
* @param none\r
- * \r
+ *\r
* @return none\r
*************************************************************************/\r
void halLcdShutDownBackLight(void)\r
{\r
LCD_BACKLT_DIR |= LCD_BACKLIGHT_PIN;\r
- LCD_BACKLT_OUT &= ~(LCD_BACKLIGHT_PIN); \r
+ LCD_BACKLT_OUT &= ~(LCD_BACKLIGHT_PIN);\r
LCD_BACKLT_SEL &= ~LCD_BACKLIGHT_PIN;\r
- \r
+\r
TA0CCTL3 = 0;\r
- TA0CTL = 0; \r
- \r
- backlight = 0; \r
+ TA0CTL = 0;\r
+\r
+ backlight = 0;\r
}\r
\r
/**********************************************************************//**\r
- * @brief Set function for the contrast level of the LCD. \r
- * \r
- * @param ContrastLevel The target contrast level \r
- * \r
- * @return none \r
+ * @brief Set function for the contrast level of the LCD.\r
+ *\r
+ * @param ContrastLevel The target contrast level\r
+ *\r
+ * @return none\r
*************************************************************************/\r
void halLcdSetContrast(unsigned char ContrastLevel)\r
{\r
if (ContrastLevel < 70) ContrastLevel = 70;\r
LcdInitMacro[ 0x04 * 6 + 5 ] = ContrastLevel;\r
halLcdSendCommand(&LcdInitMacro[ 0x04 * 6 ]);\r
-} \r
+}\r
\r
/**********************************************************************//**\r
- * @brief Get function for the contrast level of the LCD. \r
- * \r
+ * @brief Get function for the contrast level of the LCD.\r
+ *\r
* @param none\r
- * \r
+ *\r
* @return ContrastLevel The LCD constrast level\r
*************************************************************************/\r
unsigned char halLcdGetContrast(void)\r
\r
/**********************************************************************//**\r
* @brief Turns the LCD cursor on at the current text position.\r
- * \r
+ *\r
* @param none\r
- * \r
+ *\r
* @return none\r
*************************************************************************/\r
void halLcdCursor(void)\r
{\r
LcdInitMacro[ 8 * 6 + 5 ] ^= BIT2;\r
halLcdSendCommand(&LcdInitMacro[ 8 * 6 ]);\r
- \r
+\r
LcdInitMacro[ 0x0B * 6 + 5 ] = ((LcdAddress & 0x1F) << 3) ;\r
LcdInitMacro[ 0x0B * 6 + 4 ] = ( (LcdAddress & 0x1F) << 3 ) + 3;\r
LcdInitMacro[ 0x0C * 6 + 5 ] = (LcdAddress >> 5);\r
LcdInitMacro[ 0x0C * 6 + 4 ] = (LcdAddress >> 5) + 7;\r
halLcdSendCommand(&LcdInitMacro[ 0x0B * 6 ]);\r
halLcdSendCommand(&LcdInitMacro[ 0x0C * 6 ]);\r
- \r
+\r
halLcdSetAddress(LcdAddress);\r
}\r
\r
/**********************************************************************//**\r
* @brief Turns off the LCD cursor.\r
- * \r
+ *\r
* @param none\r
- * \r
+ *\r
* @return none\r
*************************************************************************/\r
void halLcdCursorOff(void)\r
}\r
\r
/**********************************************************************//**\r
- * @brief Inverts the grayscale values of the LCD display (Black <> white). \r
- * \r
+ * @brief Inverts the grayscale values of the LCD display (Black <> white).\r
+ *\r
* @param none\r
- * \r
+ *\r
* @return none\r
*************************************************************************/\r
void halLcdReverse(void)\r
\r
/**********************************************************************//**\r
* @brief Sets the LCD in standby mode to reduce power consumption.\r
- * \r
+ *\r
* @param none\r
- * \r
+ *\r
* @return none\r
*************************************************************************/\r
void halLcdStandby(void)\r
\r
/**********************************************************************//**\r
* @brief Puts the LCD into active mode.\r
- * \r
+ *\r
* @param none\r
- * \r
+ *\r
* @return none\r
*************************************************************************/\r
void halLcdActive(void)\r
{\r
halLcdSendCommand(LcdInitMacro); // R00 start oscillation\r
- \r
+\r
// Wait a minimum of 25ms after issuing "start oscillation"\r
- // command (to accomodate for MCLK up to 25MHz) \r
- __delay_cycles(250000); \r
- \r
+ // command (to accomodate for MCLK up to 25MHz)\r
+ __delay_cycles(250000);\r
+\r
LcdInitMacro[ 3 * 6 + 5 ] |= BIT3;\r
LcdInitMacro[ 3 * 6 + 5 ] &= ~BIT0;\r
halLcdSendCommand(&LcdInitMacro[ 3 * 6 ]); // R03 Power control\r
}\r
\r
/**********************************************************************//**\r
- * @brief Sets the pointer location in the LCD. \r
- * \r
- * - LcdAddress = Address \r
- * - LcdTableAddress = Correct Address Row + Column \r
- * = (Address / 0x20)* 17 + Column \r
- * \r
+ * @brief Sets the pointer location in the LCD.\r
+ *\r
+ * - LcdAddress = Address \r
+ * - LcdTableAddress = Correct Address Row + Column\r
+ * = (Address / 0x20)* 17 + Column\r
+ *\r
* @param Address The target pointer location in the LCD.\r
- * \r
+ *\r
* @return none\r
*************************************************************************/\r
void halLcdSetAddress(int Address)\r
{\r
int temp;\r
- \r
+\r
Draw_Block_Address_Macro[4] = Address >> 8;\r
Draw_Block_Address_Macro[5] = Address & 0xFF;\r
halLcdSendCommand(Draw_Block_Address_Macro);\r
LcdAddress = Address;\r
temp = Address >> 5; // Divided by 0x20\r
- temp = temp + (temp << 4); \r
+ temp = temp + (temp << 4);\r
//Multiplied by (1+16) and added by the offset\r
- LcdTableAddress = temp + (Address & 0x1F); \r
+ LcdTableAddress = temp + (Address & 0x1F);\r
}\r
\r
/**********************************************************************//**\r
- * @brief Draws a block at the specified LCD address. \r
- * \r
+ * @brief Draws a block at the specified LCD address.\r
+ *\r
* A block is the smallest addressable memory on the LCD and is\r
* equivalent to 8 pixels, each of which is represented by 2 bits\r
- * that represent a grayscale value between 00b and 11b. \r
- * \r
+ * that represent a grayscale value between 00b and 11b.\r
+ *\r
* @param Address The address at which to draw the block.\r
- * \r
- * @param Value The value of the block \r
- * \r
+ *\r
+ * @param Value The value of the block\r
+ *\r
* @return none\r
*************************************************************************/\r
void halLcdDrawBlock(unsigned int Address, unsigned int Value)\r
}\r
\r
/**********************************************************************//**\r
- * @brief Writes Value to LCD CGram and MSP430 internal LCD table. \r
- * \r
+ * @brief Writes Value to LCD CGram and MSP430 internal LCD table.\r
+ *\r
* Also updates the LcdAddress and LcdTableAddress to the correct values.\r
- * \r
- * @param Value The value of the block to be written to the LCD. \r
- * \r
+ *\r
+ * @param Value The value of the block to be written to the LCD.\r
+ *\r
* @return none\r
*************************************************************************/\r
void halLcdDrawCurrentBlock(unsigned int Value)\r
-{ \r
+{\r
int temp;\r
\r
Draw_Block_Value_Macro[4] = Value >> 8;\r
Draw_Block_Value_Macro[5] = Value & 0xFF;\r
LCD_MEM[ LcdTableAddress ] = Value;\r
- \r
+\r
halLcdSendCommand(Draw_Block_Value_Macro);\r
- \r
+\r
LcdAddress++;\r
temp = LcdAddress >> 5; // Divided by 0x20\r
- temp = temp + (temp << 4); \r
+ temp = temp + (temp << 4);\r
// Multiplied by (1+16) and added by the offset\r
- LcdTableAddress = temp + (LcdAddress & 0x1F); \r
- \r
+ LcdTableAddress = temp + (LcdAddress & 0x1F);\r
+\r
// If LcdAddress gets off the right edge, move to next line\r
if ((LcdAddress & 0x1F) > 0x11)\r
halLcdSetAddress( (LcdAddress & 0xFFE0) + 0x20 );\r
if (LcdAddress == LCD_Size)\r
- halLcdSetAddress( 0 ); \r
+ halLcdSetAddress( 0 );\r
}\r
\r
/**********************************************************************//**\r
* @brief Returns the LCD CGRAM value at location Address.\r
- * \r
- * @param Address The address of the block to be read from the LCD. \r
- * \r
+ *\r
+ * @param Address The address of the block to be read from the LCD.\r
+ *\r
* @return Value The value held at the specified address.\r
*************************************************************************/\r
int halLcdReadBlock(unsigned int Address)\r
{\r
- int i = 0, Value = 0, ReadData[7]; \r
- \r
- halLcdSetAddress( Address ); \r
- halLcdSendCommand(Read_Block_Address_Macro); \r
- \r
+ int i = 0, Value = 0, ReadData[7];\r
+\r
+ halLcdSetAddress( Address );\r
+ halLcdSendCommand(Read_Block_Address_Macro);\r
+\r
LCD_CS_RST_OUT &= ~LCD_CS_PIN; // start transfer CS=0\r
UCB2TXBUF = 0x77; // Transmit first character 0x77\r
- \r
- while (!(UCB2IFG & UCTXIFG)); \r
+\r
+ while (!(UCB2IFG & UCTXIFG));\r
while (UCB2STAT & UCBUSY);\r
- \r
- //Read 5 dummies values and 2 valid address data \r
+\r
+ //Read 5 dummies values and 2 valid address data\r
LCD_SPI_SEL &= ~LCD_MOSI_PIN; //Change SPI2C Dir\r
- LCD_SPI_SEL |= LCD_MISO_PIN; \r
- \r
+ LCD_SPI_SEL |= LCD_MISO_PIN;\r
+\r
for (i = 0; i < 7; i ++ )\r
{\r
UCB2IFG &= ~UCRXIFG;\r
UCB2TXBUF = 1; // load dummy byte 1 for clk\r
- while (!(UCB2IFG & UCRXIFG)); \r
- ReadData[i] = UCB2RXBUF; \r
- } \r
+ while (!(UCB2IFG & UCRXIFG));\r
+ ReadData[i] = UCB2RXBUF;\r
+ }\r
LCD_CS_RST_OUT |= LCD_CS_PIN; // Stop Transfer CS = 1\r
- \r
+\r
LCD_SPI_SEL |= LCD_MOSI_PIN; //Change SPI2C Dir\r
LCD_SPI_SEL &= ~LCD_MISO_PIN;\r
LCD_CS_RST_DIR |= LCD_MOSI_PIN + LCD_CLK_PIN;\r
LCD_CS_RST_DIR &= ~LCD_MISO_PIN;\r
- \r
- Value = (ReadData[5] << 8) + ReadData[6]; \r
+\r
+ Value = (ReadData[5] << 8) + ReadData[6];\r
return Value;\r
}\r
\r
/**********************************************************************//**\r
- * @brief Draw a Pixel of grayscale at coordinate (x,y) to LCD \r
- * \r
- * @param x x-coordinate for grayscale value \r
- * \r
+ * @brief Draw a Pixel of grayscale at coordinate (x,y) to LCD\r
+ *\r
+ * @param x x-coordinate for grayscale value\r
+ *\r
* @param y y-coordinate for grayscale value\r
- * \r
- * @param GrayScale The intended grayscale value of the pixel - one of \r
+ *\r
+ * @param GrayScale The intended grayscale value of the pixel - one of\r
* four possible settings.\r
- * \r
+ *\r
* @return none\r
*************************************************************************/\r
void halLcdPixel( int x, int y, unsigned char GrayScale)\r
{\r
int Address, Value;\r
unsigned char offset;\r
- \r
+\r
//Each line increments by 0x20\r
if ( (x>=0 ) && (x<LCD_COL) && (y>=0) && (y<LCD_ROW))\r
{\r
- Address = (y << 5) + (x >> 3) ; //Narrow down to 8 possible pixels \r
- \r
+ Address = (y << 5) + (x >> 3) ; //Narrow down to 8 possible pixels\r
+\r
Value = LCD_MEM[(y << 4)+ y + (x>>3)]; //y * 17 --> row. x>>3 --> column\r
- \r
+\r
offset = (x & 0x07) << 1; //3 LSBs = pos. within the 8 columns\r
Value &= ~ (3 << offset); //clear out the corresponding bits\r
Value |= GrayScale << offset; //set pixel to GrayScale level\r
- \r
+\r
halLcdDrawBlock( Address, Value );\r
}\r
}\r
\r
/**********************************************************************//**\r
* @brief Clears entire LCD CGRAM as well as LCD_MEM.\r
- * \r
+ *\r
* @param none\r
- * \r
+ *\r
* @return none\r
*************************************************************************/\r
void halLcdClearScreen(void)\r
{\r
int i, j, k, Current_Location = 0;\r
- halLcdSetAddress(0); \r
- \r
+ halLcdSetAddress(0);\r
+\r
for (i=0; i < 110; i++)\r
{\r
//prepare to send image\r
LCD_CS_RST_OUT &= ~LCD_CS_PIN; //CS = 0 --> Start Transfer\r
for ( k = 0; k < 3; k++ )\r
{\r
- while (!(UCB2IFG & UCTXIFG)); // Wait for TXIFG \r
+ while (!(UCB2IFG & UCTXIFG)); // Wait for TXIFG\r
UCB2TXBUF = Draw_Block_Value_Macro[k]; // Load data\r
}\r
while (UCB2STAT & UCBUSY); \r
LCD_CS_RST_OUT |= LCD_CS_PIN; //CS = 1 --> Stop Transfer\r
LCD_CS_RST_OUT &= ~LCD_CS_PIN; //CS = 0 --> Start Transfer \r
- while (!(UCB2IFG & UCTXIFG)); // Wait for TXIFG \r
+ while (!(UCB2IFG & UCTXIFG)); // Wait for TXIFG\r
UCB2TXBUF = Draw_Block_Value_Macro[3]; // Load data\r
- \r
+\r
//send blank line\r
for (j=0; j < 17; j++)\r
{\r
LCD_MEM[ LcdTableAddress++ ] = 0x00;\r
- while (!(UCB2IFG & UCTXIFG)); // Wait for TXIFG \r
+ while (!(UCB2IFG & UCTXIFG)); // Wait for TXIFG\r
UCB2TXBUF = 0x00; // Load data\r
- while (!(UCB2IFG & UCTXIFG)); // Wait for TXIFG \r
+ while (!(UCB2IFG & UCTXIFG)); // Wait for TXIFG\r
UCB2TXBUF = 0x00; // Load data\r
- } \r
- //Clear the partially visible block at the edge of the screen \r
- while (!(UCB2IFG & UCTXIFG)); // Wait for TXIFG \r
+ }\r
+ //Clear the partially visible block at the edge of the screen\r
+ while (!(UCB2IFG & UCTXIFG)); // Wait for TXIFG\r
UCB2TXBUF = 0x00; // Load data\r
- while (!(UCB2IFG & UCTXIFG)); // Wait for TXIFG \r
+ while (!(UCB2IFG & UCTXIFG)); // Wait for TXIFG\r
UCB2TXBUF = 0x00; // Load data\r
while (UCB2STAT & UCBUSY); \r
LCD_CS_RST_OUT |= LCD_CS_PIN; //CS = 1 --> Stop Transfer\r
- \r
+\r
Current_Location += 0x20;\r
halLcdSetAddress(Current_Location );\r
}\r
- \r
+\r
halLcdSetAddress(0);\r
}\r
\r
/**********************************************************************//**\r
- * @brief Loads an image of size = rows * columns, starting at the \r
+ * @brief Loads an image of size = rows * columns, starting at the\r
* coordinate (x,y).\r
- * \r
+ *\r
* @param Image[] The image to be loaded\r
- * \r
+ *\r
* @param Rows The number of rows in the image. Size = Rows * Columns.\r
- * \r
+ *\r
* @param Columns The number of columns in the image. Size = Rows * Columns.\r
- * \r
- * @param x x-coordinate of the image's starting location \r
- * \r
- * @param y y-coordinate of the image's starting location \r
- * \r
+ *\r
+ * @param x x-coordinate of the image's starting location\r
+ *\r
+ * @param y y-coordinate of the image's starting location\r
+ *\r
* @return none\r
*************************************************************************/\r
void halLcdImage(const unsigned int Image[], int Columns, int Rows, int x, int y)\r
-{ \r
+{\r
int i, CurrentLocation;\r
- \r
+\r
CurrentLocation = (y << 5) + (x >> 3);\r
halLcdSetAddress(CurrentLocation);\r
for (i=0; i < Rows; i++)\r
}\r
\r
/**********************************************************************//**\r
- * @brief Writes Value to LCD CGram and MSP430 internal LCD table. \r
- * \r
+ * @brief Writes Value to LCD CGram and MSP430 internal LCD table.\r
+ *\r
* Also updates the LcdAddress and LcdTableAddress to the correct values.\r
- * \r
- * @param *value Pointer to the line to be written to the LCD. \r
- * \r
+ *\r
+ * @param *value Pointer to the line to be written to the LCD.\r
+ *\r
* @return none\r
*************************************************************************/\r
void halLcdDrawCurrentLine(const unsigned int *value, int Columns)\r
-{ \r
+{\r
unsigned char i;\r
- \r
+\r
//prepare to send image\r
LCD_CS_RST_OUT &= ~LCD_CS_PIN; //CS = 0 --> Start Transfer\r
for ( i = 0; i < 3; i++ )\r
{\r
- while (!(UCB2IFG & UCTXIFG)); // Wait for TXIFG \r
+ while (!(UCB2IFG & UCTXIFG)); // Wait for TXIFG\r
UCB2TXBUF = Draw_Block_Value_Macro[i]; // Load data\r
}\r
while (UCB2STAT & UCBUSY); \r
LCD_CS_RST_OUT |= LCD_CS_PIN; //CS = 1 --> Stop Transfer\r
LCD_CS_RST_OUT &= ~LCD_CS_PIN; //CS = 0 --> Start Transfer \r
- while (!(UCB2IFG & UCTXIFG)); // Wait for TXIFG \r
+ while (!(UCB2IFG & UCTXIFG)); // Wait for TXIFG\r
UCB2TXBUF = Draw_Block_Value_Macro[3]; // Load data\r
- \r
+\r
//send the image\r
for ( i = 0; i < Columns; i++ )\r
{ \r
break;\r
}\r
LCD_MEM[ LcdTableAddress++ ] = *value;\r
- while (!(UCB2IFG & UCTXIFG)); // Wait for TXIFG \r
+ while (!(UCB2IFG & UCTXIFG)); // Wait for TXIFG\r
UCB2TXBUF = (*value) >> 8; // Load data\r
- while (!(UCB2IFG & UCTXIFG)); // Wait for TXIFG \r
+ while (!(UCB2IFG & UCTXIFG)); // Wait for TXIFG\r
UCB2TXBUF = (*value++) & 0xFF; // Load data\r
}\r
\r
while (UCB2STAT & UCBUSY); \r
- LCD_CS_RST_OUT |= LCD_CS_PIN; //CS = 1 --> Stop Transfer \r
+ LCD_CS_RST_OUT |= LCD_CS_PIN; //CS = 1 --> Stop Transfer\r
}\r
\r
/**********************************************************************//**\r
- * @brief Clears an image of size rows x columns starting at (x, y). \r
- * \r
+ * @brief Clears an image of size rows x columns starting at (x, y).\r
+ *\r
* @param Columns The size, in columns, of the image to be cleared.\r
- * \r
+ *\r
* @param Rows The size, in rows, of the image to be cleared.\r
- * \r
+ *\r
* @param x x-coordinate of the image to be cleared\r
- * \r
+ *\r
* @param y y-coordinate of the image to be cleared\r
- * \r
+ *\r
* @return none\r
*************************************************************************/\r
void halLcdClearImage(int Columns, int Rows, int x, int y)\r
int i,j,k, Current_Location;\r
Current_Location = (y << 5) + (x >> 3);\r
halLcdSetAddress( Current_Location );\r
- \r
+\r
for (i=0; i < Rows; i++)\r
{\r
//prepare to send image\r
LCD_CS_RST_OUT &= ~LCD_CS_PIN; //CS = 0 --> Start Transfer\r
for ( k = 0; k < 3; k++ )\r
{\r
- while (!(UCB2IFG & UCTXIFG)); // Wait for TXIFG \r
+ while (!(UCB2IFG & UCTXIFG)); // Wait for TXIFG\r
UCB2TXBUF = Draw_Block_Value_Macro[k]; // Load data\r
}\r
while (UCB2STAT & UCBUSY); \r
LCD_CS_RST_OUT |= LCD_CS_PIN; //CS = 1 --> Stop Transfer\r
LCD_CS_RST_OUT &= ~LCD_CS_PIN; //CS = 0 --> Start Transfer \r
- while (!(UCB2IFG & UCTXIFG)); // Wait for TXIFG \r
+ while (!(UCB2IFG & UCTXIFG)); // Wait for TXIFG\r
UCB2TXBUF = Draw_Block_Value_Macro[3]; // Load data\r
- \r
+\r
//send blank line\r
for (j=0; j < Columns; j++)\r
{\r
LCD_MEM[ LcdTableAddress++ ] = 0x00;\r
- while (!(UCB2IFG & UCTXIFG)); // Wait for TXIFG \r
+ while (!(UCB2IFG & UCTXIFG)); // Wait for TXIFG\r
UCB2TXBUF = 0x00; // Load data\r
- while (!(UCB2IFG & UCTXIFG)); // Wait for TXIFG \r
+ while (!(UCB2IFG & UCTXIFG)); // Wait for TXIFG\r
UCB2TXBUF = 0x00; // Load data\r
- } \r
+ }\r
while (UCB2STAT & UCBUSY); \r
LCD_CS_RST_OUT |= LCD_CS_PIN; //CS = 1 --> Stop Transfer\r
- \r
+\r
Current_Location += 0x20;\r
halLcdSetAddress(Current_Location );\r
}\r
}\r
\r
/**********************************************************************//**\r
- * @brief Writes Value to LCD CGRAM. Pointers internal to the LCD \r
- * are also updated. \r
- * \r
+ * @brief Writes Value to LCD CGRAM. Pointers internal to the LCD\r
+ * are also updated.\r
+ *\r
* @param Value The value to be written to the current LCD pointer\r
- * \r
+ *\r
* @return none\r
*************************************************************************/\r
void halLcdDrawTextBlock(unsigned int Value)\r
-{ \r
+{\r
int temp;\r
- \r
- Draw_Block_Value_Macro[4] = Value >> 8; \r
- Draw_Block_Value_Macro[5] = Value & 0xFF; \r
- LCD_MEM[ LcdTableAddress ] = Value; \r
- \r
+\r
+ Draw_Block_Value_Macro[4] = Value >> 8;\r
+ Draw_Block_Value_Macro[5] = Value & 0xFF;\r
+ LCD_MEM[ LcdTableAddress ] = Value;\r
+\r
halLcdSendCommand(Draw_Block_Value_Macro);\r
- \r
+\r
LcdAddress++;\r
temp = LcdAddress >> 5; // Divided by 0x20\r
- temp = temp + (temp << 4); \r
+ temp = temp + (temp << 4);\r
//Multiplied by (1+16) and added by the offset\r
- LcdTableAddress = temp + (LcdAddress & 0x1F); \r
- \r
- // If LcdAddress gets off the right edge, move to next line \r
+ LcdTableAddress = temp + (LcdAddress & 0x1F);\r
+\r
+ // If LcdAddress gets off the right edge, move to next line\r
if ((LcdAddress & 0x1F) > 0x10)\r
halLcdSetAddress( (LcdAddress & 0xFFE0) + 0x20 );\r
- \r
+\r
if (LcdAddress >= LCD_Size)\r
- halLcdSetAddress( 0 ); \r
+ halLcdSetAddress( 0 );\r
}\r
\r
/**********************************************************************//**\r
* @brief Displays the string to the LCD starting at current location.\r
- * \r
- * Writes all the data to LCD_MEM first, then updates all corresponding \r
+ *\r
+ * Writes all the data to LCD_MEM first, then updates all corresponding\r
* LCD CGRAM locations at once, in a continuous fashion.\r
- * \r
+ *\r
* @param String[] The string to be displayed on LCD.\r
- * \r
- * @param TextStyle Value that specifies whether the string is to be \r
- * inverted or overwritten. \r
- * - Invert = 0x01 \r
- * - Overwrite = 0x04 \r
- * \r
+ *\r
+ * @param TextStyle Value that specifies whether the string is to be\r
+ * inverted or overwritten.\r
+ * - Invert = 0x01\r
+ * - Overwrite = 0x04\r
+ *\r
* @return none\r
*************************************************************************/\r
-void halLcdPrint( char String[], unsigned char TextStyle) \r
+void halLcdPrint( char String[], unsigned char TextStyle)\r
{\r
int i, j, Counter=0, BlockValue;\r
int Address, LCD_MEM_Add, ActualAddress;\r
int temp;\r
char LookUpChar;\r
- \r
+\r
ActualAddress = LcdAddress;\r
- Counter = LcdAddress & 0x1F; \r
+ Counter = LcdAddress & 0x1F;\r
i=0;\r
- \r
+\r
while (String[i]!=0) // Stop on null character\r
- { \r
- LookUpChar = fonts_lookup[String[i]]; \r
- \r
- for (j=0;j < FONT_HEIGHT ;j++) \r
+ {\r
+ LookUpChar = fonts_lookup[String[i]];\r
+\r
+ for (j=0;j < FONT_HEIGHT ;j++)\r
{\r
Address = ActualAddress + j*0x20;\r
temp = Address >> 5;\r
temp += (temp <<4);\r
\r
- LCD_MEM_Add = temp + (Address & 0x1F); \r
- \r
+ LCD_MEM_Add = temp + (Address & 0x1F);\r
+\r
BlockValue = LCD_MEM[ LCD_MEM_Add ];\r
- \r
+\r
if(TextStyle & GRAYSCALE_TEXT)\r
{\r
if (TextStyle & INVERT_TEXT)\r
BlockValue |= 0xAAAA - GrayScale_fonts[LookUpChar*(FONT_HEIGHT+1) +j];\r
else\r
if (TextStyle & OVERWRITE_TEXT)\r
- BlockValue = GrayScale_fonts[LookUpChar*(FONT_HEIGHT+1) +j]; \r
+ BlockValue = GrayScale_fonts[LookUpChar*(FONT_HEIGHT+1) +j];\r
else\r
BlockValue |= GrayScale_fonts[LookUpChar*(FONT_HEIGHT+1) +j];\r
}\r
else\r
- { \r
- if (TextStyle & INVERT_TEXT) \r
+ {\r
+ if (TextStyle & INVERT_TEXT)\r
if (TextStyle & OVERWRITE_TEXT)\r
- BlockValue = 0xFFFF - fonts[LookUpChar*13+j]; \r
+ BlockValue = 0xFFFF - fonts[LookUpChar*13+j];\r
else\r
- BlockValue |= 0xFFFF - fonts[LookUpChar*13+j]; \r
- \r
- else \r
+ BlockValue |= 0xFFFF - fonts[LookUpChar*13+j];\r
+\r
+ else\r
if (TextStyle & OVERWRITE_TEXT)\r
- BlockValue = fonts[LookUpChar*(FONT_HEIGHT+1) +j]; \r
+ BlockValue = fonts[LookUpChar*(FONT_HEIGHT+1) +j];\r
else\r
- BlockValue |= fonts[LookUpChar*(FONT_HEIGHT+1) +j]; \r
+ BlockValue |= fonts[LookUpChar*(FONT_HEIGHT+1) +j];\r
}\r
- halLcdDrawBlock( Address, BlockValue); \r
+ halLcdDrawBlock( Address, BlockValue);\r
}\r
- \r
+\r
Counter++;\r
if (Counter == 17)\r
{\r
- Counter = 0; \r
+ Counter = 0;\r
ActualAddress += 0x20*FONT_HEIGHT - 16;\r
if (ActualAddress > LCD_Last_Pixel-0x20*FONT_HEIGHT )\r
ActualAddress = 0;\r
}\r
- else \r
+ else\r
ActualAddress++;\r
i++;\r
}\r
halLcdSetAddress(ActualAddress);\r
- \r
+\r
}\r
\r
/**********************************************************************//**\r
- * @brief Displays the string to the LCD starting at (x,y) location. \r
- * \r
- * Writes all the data to LCD_MEM first, then updates all corresponding \r
+ * @brief Displays the string to the LCD starting at (x,y) location.\r
+ *\r
+ * Writes all the data to LCD_MEM first, then updates all corresponding\r
* LCD CGRAM locations at once, in a continuous fashion.\r
- * \r
+ *\r
* @param String[] String to be displayed on LCD\r
- * \r
- * @param x x-coordinate of the write location on the LCD \r
- * \r
+ *\r
+ * @param x x-coordinate of the write location on the LCD\r
+ *\r
* @param y y-coordinate of the write location on the LCD\r
- * \r
- * @param TextStyle Value that specifies whether the string is to be \r
- * inverted or overwritten. \r
- * - Invert = 0x01 \r
- * - Overwrite = 0x04 \r
+ *\r
+ * @param TextStyle Value that specifies whether the string is to be\r
+ * inverted or overwritten.\r
+ * - Invert = 0x01\r
+ * - Overwrite = 0x04\r
*************************************************************************/\r
-void halLcdPrintXY( char String[], int x, int y, unsigned char TextStyle) \r
+void halLcdPrintXY( char String[], int x, int y, unsigned char TextStyle)\r
{\r
//Each line increments by 0x20\r
- halLcdSetAddress( (y << 5) + (x >> 3)) ; //Narrow down to 8 possible pixels \r
+ halLcdSetAddress( (y << 5) + (x >> 3)) ; //Narrow down to 8 possible pixels\r
halLcdPrint(String, TextStyle);\r
}\r
\r
/**********************************************************************//**\r
- * @brief Displays a string on the LCD on the specified line. \r
- * \r
+ * @brief Displays a string on the LCD on the specified line.\r
+ *\r
* @param String[] The string to be displayed on LCD.\r
- * \r
+ *\r
* @param Line The line on the LCD on which to print the string.\r
- * \r
- * @param TextStyle Value that specifies whether the string is to be \r
- * inverted or overwritten. \r
- * - Invert = 0x01 \r
- * - Overwrite = 0x04 \r
- * \r
+ *\r
+ * @param TextStyle Value that specifies whether the string is to be\r
+ * inverted or overwritten.\r
+ * - Invert = 0x01\r
+ * - Overwrite = 0x04\r
+ *\r
* @return none\r
*************************************************************************/\r
-void halLcdPrintLine(char String[], unsigned char Line, unsigned char TextStyle) \r
+void halLcdPrintLine(char String[], unsigned char Line, unsigned char TextStyle)\r
{\r
- int temp; \r
+ int temp;\r
temp = Line * FONT_HEIGHT ;\r
- halLcdSetAddress( temp << 5 ) ; // 0x20 = 2^5 \r
+ halLcdSetAddress( temp << 5 ) ; // 0x20 = 2^5\r
halLcdPrint(String, TextStyle);\r
}\r
\r
/**********************************************************************//**\r
- * @brief Prints a string beginning on a given line and column. \r
- * \r
+ * @brief Prints a string beginning on a given line and column.\r
+ *\r
* @param String[] The string to be displayed on LCD.\r
- * \r
+ *\r
* @param Line The line on which to print the string of text\r
- * \r
+ *\r
* @param Col The column on which to print the string of text\r
- * \r
- * @param TextStyle Value that specifies whether the string is to be \r
- * inverted or overwritten. \r
- * - Invert = 0x01 \r
- * - Overwrite = 0x04 \r
- * \r
+ *\r
+ * @param TextStyle Value that specifies whether the string is to be\r
+ * inverted or overwritten.\r
+ * - Invert = 0x01\r
+ * - Overwrite = 0x04\r
+ *\r
* @return none\r
*************************************************************************/\r
void halLcdPrintLineCol(char String[], unsigned char Line, unsigned char Col,\r
- unsigned char TextStyle) \r
+ unsigned char TextStyle)\r
{\r
- int temp; \r
- \r
+ int temp;\r
+\r
temp = Line * FONT_HEIGHT;\r
temp <<= 5;\r
temp += Col;\r
- \r
- halLcdSetAddress( temp ) ; // 0x20 = 2^5 \r
+\r
+ halLcdSetAddress( temp ) ; // 0x20 = 2^5\r
halLcdPrint(String, TextStyle);\r
}\r
\r
\r
/**********************************************************************//**\r
* @brief Draws a horizontral line from (x1,y) to (x2,y) of GrayScale level\r
- * \r
- * @param x1 x-coordinate of the first point \r
- * \r
+ *\r
+ * @param x1 x-coordinate of the first point\r
+ *\r
* @param x2 x-coordinate of the second point\r
- * \r
+ *\r
* @param y y-coordinate of both points\r
- * \r
+ *\r
* @param GrayScale Grayscale level of the horizontal line\r
- * \r
+ *\r
* @return none\r
*************************************************************************/\r
void halLcdHLine( int x1, int x2, int y, unsigned char GrayScale)\r
int x_dir, x;\r
if ( x1 < x2 )\r
x_dir = 1;\r
- else \r
+ else\r
x_dir = -1;\r
- x = x1; \r
+ x = x1;\r
while (x != x2)\r
{\r
- halLcdPixel( x,y, GrayScale); \r
+ halLcdPixel( x,y, GrayScale);\r
x += x_dir;\r
}\r
}\r
\r
/**********************************************************************//**\r
* @brief Draws a vertical line from (x,y1) to (x,y2) of GrayScale level\r
- * \r
+ *\r
* @param x x-coordinate of both points\r
- * \r
- * @param y1 y-coordinate of the first point \r
- * \r
+ *\r
+ * @param y1 y-coordinate of the first point\r
+ *\r
* @param y2 y-coordinate of the second point\r
- * \r
+ *\r
* @param GrayScale GrayScale level of the vertical line\r
- * \r
+ *\r
* @return none\r
*************************************************************************/\r
void halLcdVLine( int x, int y1, int y2, unsigned char GrayScale)\r
int y_dir, y;\r
if ( y1 < y2 )\r
y_dir = 1;\r
- else \r
+ else\r
y_dir = -1;\r
- y = y1; \r
+ y = y1;\r
while (y != y2)\r
{\r
- halLcdPixel( x,y, GrayScale); \r
+ halLcdPixel( x,y, GrayScale);\r
y += y_dir;\r
}\r
}\r
\r
/**********************************************************************//**\r
* @brief Draws a line from (x1,y1) to (x2,y2) of GrayScale level.\r
- * \r
+ *\r
* Uses Bresenham's line algorithm.\r
- * \r
- * @param x1 x-coordinate of the first point \r
- * \r
+ *\r
+ * @param x1 x-coordinate of the first point\r
+ *\r
* @param y1 y-coordinate of the first point\r
- * \r
+ *\r
* @param x2 x-coordinate of the second point\r
- * \r
+ *\r
* @param y2 y-coordinate of the second point\r
- * \r
- * @param GrayScale Grayscale level of the line \r
- * \r
+ *\r
+ * @param GrayScale Grayscale level of the line\r
+ *\r
* @return none\r
*************************************************************************/\r
-void halLcdLine( int x1, int y1, int x2, int y2, unsigned char GrayScale) \r
+void halLcdLine( int x1, int y1, int x2, int y2, unsigned char GrayScale)\r
{\r
- int x, y, deltay, deltax, d; \r
+ int x, y, deltay, deltax, d;\r
int x_dir, y_dir;\r
\r
if ( x1 == x2 )\r
if (y1 > y2)\r
y_dir = -1;\r
else y_dir = 1;\r
- \r
+\r
x = x1;\r
y = y1;\r
deltay = ABS(y2 - y1);\r
y += y_dir;\r
}\r
x += x_dir;\r
- } \r
+ }\r
}\r
else\r
{\r
x += x_dir;\r
}\r
y += y_dir;\r
- } \r
+ }\r
}\r
- } \r
+ }\r
}\r
}\r
\r
\r
/**********************************************************************//**\r
* @brief Draw a circle of Radius with center at (x,y) of GrayScale level.\r
- * \r
+ *\r
* Uses Bresenham's circle algorithm\r
- * \r
+ *\r
* @param x x-coordinate of the circle's center point\r
- * \r
+ *\r
* @param y y-coordinate of the circle's center point\r
- * \r
+ *\r
* @param Radius Radius of the circle\r
- * \r
- * @param GrayScale Grayscale level of the circle \r
+ *\r
+ * @param GrayScale Grayscale level of the circle\r
*************************************************************************/\r
void halLcdCircle(int x, int y, int Radius, int GrayScale)\r
{\r
int xx, yy, ddF_x, ddF_y, f;\r
- \r
+\r
ddF_x = 0;\r
ddF_y = -(2 * Radius);\r
f = 1 - Radius;\r
}\r
\r
/**********************************************************************//**\r
- * @brief Scrolls a single row of pixels one column to the left. \r
- * \r
- * The column that is scrolled out of the left side of the LCD will be \r
- * displayed the right side of the LCD. \r
- * \r
+ * @brief Scrolls a single row of pixels one column to the left.\r
+ *\r
+ * The column that is scrolled out of the left side of the LCD will be\r
+ * displayed the right side of the LCD.\r
+ *\r
* @param y The row of pixels to scroll. y = 0 is at the top-left\r
- * corner of the LCD. \r
- * \r
+ * corner of the LCD.\r
+ *\r
* @return none\r
*************************************************************************/\r
void halLcdScrollRow(int y)\r
{\r
int i, Address, LcdTableAddressTemp;\r
unsigned int temp;\r
- \r
+\r
Address = y << 5;\r
- \r
+\r
halLcdSetAddress( Address );\r
- \r
+\r
//Multiplied by (1+16) and added by the offset\r
- LcdTableAddressTemp = y + (y << 4); \r
+ LcdTableAddressTemp = y + (y << 4);\r
temp = ((LCD_MEM[LcdTableAddressTemp] & 0x0003) <<14);\r
- \r
- for (i = 0; i < 0x10; i++) \r
+\r
+ for (i = 0; i < 0x10; i++)\r
halLcdDrawCurrentBlock( ( (LCD_MEM[LcdTableAddressTemp+i] & 0xFFFC ) >> 2 ) \\r
+ ((LCD_MEM[LcdTableAddressTemp+i+1] & 0x0003) << 14 ));\r
- \r
- halLcdDrawCurrentBlock( (( LCD_MEM[LcdTableAddressTemp + 0x10] & 0xFFFC ) >> 2) + temp); \r
+\r
+ halLcdDrawCurrentBlock( (( LCD_MEM[LcdTableAddressTemp + 0x10] & 0xFFFC ) >> 2) + temp);\r
}\r
\r
/**********************************************************************//**\r
- * @brief Scrolls multiple rows of pixels, yStart to yEnd, \r
- * one column to the left. \r
- * \r
- * The column that is scrolled out of the left side of the LCD will be \r
- * displayed the right side of the LCD. y = 0 is at the top-left of the \r
+ * @brief Scrolls multiple rows of pixels, yStart to yEnd,\r
+ * one column to the left.\r
+ *\r
+ * The column that is scrolled out of the left side of the LCD will be\r
+ * displayed the right side of the LCD. y = 0 is at the top-left of the\r
* LCD screen.\r
- * \r
+ *\r
* @param yStart The beginning row to be scrolled\r
- * \r
- * @param yEnd The last row to be scrolled \r
- * \r
+ *\r
+ * @param yEnd The last row to be scrolled\r
+ *\r
* @return none\r
*************************************************************************/\r
void halLcdHScroll(int yStart, int yEnd)\r
{\r
- int i ; \r
- \r
+ int i ;\r
+\r
for (i = yStart; i < yEnd+1; i++)\r
halLcdScrollRow(i);\r
}\r
\r
/**********************************************************************//**\r
- * @brief Scrolls a line of text one column to the left. \r
- * \r
- * @param Line The line of text to be scrolled. \r
- * \r
+ * @brief Scrolls a line of text one column to the left.\r
+ *\r
+ * @param Line The line of text to be scrolled.\r
+ *\r
* @return none\r
*************************************************************************/\r
void halLcdScrollLine(int Line)\r
{\r
int i, Row ;\r
- \r
+\r
Row = Line * FONT_HEIGHT;\r
- \r
+\r
for (i = Row; i < Row + FONT_HEIGHT ; i++)\r
halLcdScrollRow(i);\r
}\r
licensing and training services.\r
*/\r
\r
+/*\r
+ * The documentation page for this demo available on http://www.FreeRTOS.org\r
+ * documents the hardware configuration required to run this demo. It also\r
+ * provides more information on the expected demo application behaviour.\r
+ *\r
+ * main() creates all the demo application tasks, then starts the scheduler.\r
+ * A lot of the created tasks are from the pool of "standard demo" tasks. The\r
+ * web documentation provides more details of the standard demo tasks, which\r
+ * provide no particular functionality but do provide good examples of how to\r
+ * use the FreeRTOS API.\r
+ *\r
+ * In addition to the standard demo tasks, the following tasks, interrupts and\r
+ * tests are defined and/or created within this file:\r
+ *\r
+ * "LCD" task - The LCD task is a 'gatekeeper' task. It is the only task that\r
+ * is permitted to access the LCD and therefore ensures access to the LCD is\r
+ * always serialised and there are no mutual exclusion issues. When a task or\r
+ * an interrupt wants to write to the LCD, it does not access the LCD directly\r
+ * but instead sends the message to the LCD task. The LCD task then performs\r
+ * the actual LCD output. This mechanism also allows interrupts to, in effect,\r
+ * write to the LCD by sending messages to the LCD task.\r
+ *\r
+ * The LCD task is also a demonstration of a 'controller' task design pattern.\r
+ * Some tasks do not actually send a string to the LCD task directly, but\r
+ * instead send a command that is interpreted by the LCD task. In a normal\r
+ * application these commands can be control values or set points, in this\r
+ * simple example the commands just result in messages being displayed on the\r
+ * LCD.\r
+ *\r
+ * "Button Poll" task - This task polls the state of the 'up' key on the\r
+ * joystick input device. It uses the vTaskDelay() API function to control\r
+ * the poll rate to ensure debouncing is not necessary and that the task does\r
+ * not use all the available CPU processing time.\r
+ *\r
+ * Button Interrupt and run time stats display - The select button on the\r
+ * joystick input device is configured to generate an external interrupt. The\r
+ * handler for this interrupt sends a message to LCD task, which interprets the\r
+ * message to mean, firstly write a message to the LCD, and secondly, generate\r
+ * a table of run time statistics. The run time statistics are displayed as a\r
+ * table that contains information on how much processing time each task has\r
+ * been allocated since the application started to execute. This information\r
+ * is provided both as an absolute time, and as a percentage of the total run\r
+ * time. The information is displayed in the terminal IO window of the IAR\r
+ * embedded workbench. The online documentation for this demo shows a screen\r
+ * shot demonstrating where the run time stats can be viewed.\r
+ *\r
+ * Idle Hook - The idle hook is a function that is called on each iteration of\r
+ * the idle task. In this case it is used to place the processor into a low\r
+ * power mode. Note however that this application is implemented using standard\r
+ * components, and is therefore not optimised for low power operation. Lower\r
+ * power consumption would be achieved by converting polling tasks into event\r
+ * driven tasks, and slowing the tick interrupt frequency.\r
+ *\r
+ * "Check" function called from the tick hook - The tick hook is called during\r
+ * each tick interrupt. It is called from an interrupt context so must execute\r
+ * quickly, not attempt to block, and not call any FreeRTOS API functions that\r
+ * do not end in "FromISR". In this case the tick hook executes a 'check'\r
+ * function. This only executes every five seconds. Its main function is to\r
+ * check that all the standard demo tasks are still operational. Each time it\r
+ * executes it sends a status code to the LCD task. The LCD task interprets the\r
+ * code and displays an appropriate message - which will be PASS if no tasks\r
+ * have reported any errors, or a message stating which task has reported an\r
+ * error.\r
+ *\r
+ * "Reg test" tasks - These fill the registers with known values, then check\r
+ * that each register still contains its expected value. Each task uses\r
+ * different values. The tasks run with very low priority so get preempted\r
+ * very frequently. A check variable is incremented on each iteration of the\r
+ * test loop. A register containing an unexpected value is indicative of an\r
+ * error in the context switching mechanism and will result in a branch to a\r
+ * null loop - which in turn will prevent the check variable from incrementing\r
+ * any further and allow the check task (described a above) to determine that an\r
+ * error has occurred. The nature of the reg test tasks necessitates that they\r
+ * are written in assembly code.\r
+ *\r
+ * *NOTE 2* vApplicationSetupTimerInterrupt() is called by the kernel to let\r
+ * the application set up a timer to generate the tick interrupt. In this\r
+ * example a timer A0 is used for this purpose.\r
+ *\r
+*/\r
+\r
/* Standard includes. */\r
#include <stdio.h>\r
\r
to send messages from tasks and interrupts the the LCD task. */\r
#define mainQUEUE_LENGTH ( 5 )\r
\r
+/* Priorities used by the test and demo tasks. */\r
#define mainLCD_TASK_PRIORITY ( tskIDLE_PRIORITY + 1 )\r
#define mainCOM_TEST_PRIORITY ( tskIDLE_PRIORITY + 2 )\r
#define mainGENERIC_QUEUE_TEST_PRIORITY ( tskIDLE_PRIORITY )\r
\r
/* The LED used by the comtest tasks. See the comtest.c file for more\r
-information. In this case it is deliberately out of range as there are only\r
-two LEDs, and they are both already in use. */\r
-#define mainCOM_TEST_LED ( 3 )\r
+information. */\r
+#define mainCOM_TEST_LED ( 1 )\r
\r
/* The baud rate used by the comtest tasks described at the top of this file. */\r
-#define mainCOM_TEST_BAUD_RATE ( 9600 )\r
+#define mainCOM_TEST_BAUD_RATE ( 115200 )\r
+\r
+/* The maximum number of lines of text that can be displayed on the LCD. */\r
+#define mainMAX_LCD_LINES ( 8 )\r
/*-----------------------------------------------------------*/\r
\r
+/*\r
+ * The reg test tasks as described at the top of this file.\r
+ */\r
extern void vRegTest1Task( void *pvParameters );\r
extern void vRegTest2Task( void *pvParameters );\r
+\r
+/*\r
+ * Configures clocks, LCD, port pints, etc. necessary to execute this demo.\r
+ */\r
static void prvSetupHardware( void );\r
-static void prvTerminalIOTask( void *pvParameters );\r
+\r
+/*\r
+ * Definition of the LCD/controller task described in the comments at the top\r
+ * of this file.\r
+ */\r
+static void prvLCDTask( void *pvParameters );\r
+\r
+/*\r
+ * Definition of the button poll task described in the comments at the top of\r
+ * this file.\r
+ */\r
static void prvButtonPollTask( void *pvParameters );\r
+\r
+/*\r
+ * Converts a status message value into an appropriate string for display on\r
+ * the LCD. The string is written to pcBuffer.\r
+ */\r
static void prvGenerateStatusMessage( char *pcBuffer, long lStatusValue );\r
\r
/*-----------------------------------------------------------*/\r
\r
+/* Variables that are incremented on each iteration of the reg test tasks -\r
+provided the tasks have not reported any errors. The check task inspects these\r
+variables to ensure they are still incrementing as expected. If a variable\r
+stops incrementing then it is likely that its associate task has stalled. */\r
volatile unsigned short usRegTest1Counter = 0, usRegTest2Counter = 0;\r
-volatile unsigned long ulStatsOverflowCount = 0;\r
\r
/* The handle of the queue used to send messages from tasks and interrupts to\r
the LCD task. */\r
task. */\r
typedef struct\r
{\r
- char cMessageID; /* << States what the message is. */\r
- unsigned long ulMessageValue; /* << States the message value (can be an integer, string pointer, etc. depending on the value of cMessageID. */\r
+ char cMessageID; /* << States what the message is. */\r
+ unsigned long ulMessageValue; /* << States the message value (can be an integer, string pointer, etc. depending on the value of cMessageID). */\r
} xQueueMessage;\r
+\r
/*-----------------------------------------------------------*/\r
\r
void main( void )\r
{\r
+ /* Configure the peripherals used by this demo application. This includes\r
+ configuring the joystick input select button to generate interrupts. */\r
prvSetupHardware();\r
\r
/* Create the queue used by tasks and interrupts to send strings to the LCD\r
task. */\r
xLCDQueue = xQueueCreate( mainQUEUE_LENGTH, sizeof( xQueueMessage ) );\r
\r
+ /* If the queue could not be created then don't create any tasks that might\r
+ attempt to use the queue. */\r
if( xLCDQueue != NULL )\r
{\r
/* Add the created queue to the queue registry so it can be viewed in\r
vStartDynamicPriorityTasks();\r
vStartGenericQueueTasks( mainGENERIC_QUEUE_TEST_PRIORITY );\r
\r
- /* Create the terminal IO and button poll tasks, as described at the top\r
- of this file. */\r
- xTaskCreate( prvTerminalIOTask, ( signed char * ) "IO", configMINIMAL_STACK_SIZE * 2, NULL, mainLCD_TASK_PRIORITY, NULL );\r
+ /* Create the LCD, button poll and register test tasks, as described at\r
+ the top of this file. */\r
+ xTaskCreate( prvLCDTask, ( signed char * ) "LCD", configMINIMAL_STACK_SIZE * 2, NULL, mainLCD_TASK_PRIORITY, NULL );\r
xTaskCreate( prvButtonPollTask, ( signed char * ) "BPoll", configMINIMAL_STACK_SIZE, NULL, tskIDLE_PRIORITY, NULL );\r
-\r
- /* Create the register test tasks as described at the top of this file. */\r
xTaskCreate( vRegTest1Task, "Reg1", configMINIMAL_STACK_SIZE, NULL, 0, NULL );\r
xTaskCreate( vRegTest2Task, "Reg2", configMINIMAL_STACK_SIZE, NULL, 0, NULL );\r
+\r
+ /* Start the scheduler. */\r
vTaskStartScheduler();\r
}\r
\r
+ /* If all is well then this line will never be reached. If it is reached\r
+ then it is likely that there was insufficient (FreeRTOS) heap memory space\r
+ to create the idle task. This may have been trapped by the malloc() failed\r
+ hook function, if one is configured. */ \r
for( ;; );\r
}\r
/*-----------------------------------------------------------*/\r
\r
-static void prvTerminalIOTask( void *pvParameters )\r
+static void prvLCDTask( void *pvParameters )\r
{\r
xQueueMessage xReceivedMessage;\r
\r
xQueueReceive( xLCDQueue, &xReceivedMessage, portMAX_DELAY );\r
\r
/* Clear the LCD if no room remains for any more text output. */\r
- if( ucLine > 8 )\r
+ if( ucLine > mainMAX_LCD_LINES )\r
{\r
halLcdClearScreen();\r
ucLine = 0;\r
the LCD - in this case the\r
pointer to the string to print\r
is sent directly in the\r
- lMessageValue member of the\r
+ ulMessageValue member of the\r
message. This just demonstrates\r
a different communication\r
technique. */\r
break;\r
}\r
\r
+ /* Output the message that was placed into the cBuffer array within the\r
+ switch statement above, then move onto the next line ready for the next\r
+ message to arrive on the queue. */\r
halLcdPrintLine( cBuffer, ucLine, OVERWRITE_TEXT );\r
ucLine++;\r
}\r
break;\r
case mainERROR_DYNAMIC_TASKS : sprintf( pcBuffer, "Err: Dynamic tsks" );\r
break;\r
- case mainERROR_COM_TEST : sprintf( pcBuffer, "Err: COM test" ); /* Error in COM test - is the Loopback connector connected? */ \r
+ case mainERROR_COM_TEST : sprintf( pcBuffer, "Err: COM test" );\r
break;\r
case mainERROR_GEN_QUEUE_TEST : sprintf( pcBuffer, "Error: Gen Q test" );\r
break;\r
\r
if( ucState != 0 )\r
{\r
+ /* The button was pressed. */\r
ucState = pdTRUE;\r
}\r
\r
\r
static void prvSetupHardware( void )\r
{\r
+/* Convert a Hz value to a KHz value, as required by the Init_FLL_Settle()\r
+function. */\r
unsigned long ulCPU_Clock_KHz = ( configCPU_CLOCK_HZ / 1000UL );\r
\r
halBoardInit();\r
\r
halButtonsInit( BUTTON_ALL );\r
halButtonsInterruptEnable( BUTTON_SELECT );\r
+\r
+ /* Initialise the LCD, but note that the backlight is not used as the\r
+ library function uses timer A0 to modulate the backlight, and this file\r
+ defines vApplicationSetupTimerInterrupt() to also use timer A0 to generate\r
+ the tick interrupt. If the backlight is required, then change either the\r
+ halLCD library or vApplicationSetupTimerInterrupt() to use a different\r
+ timer. Timer A1 is used for the run time stats time base6. */\r
halLcdInit();\r
- halLcdBackLightInit();\r
- halLcdSetBackLight( 0 );\r
halLcdSetContrast( 100 );\r
halLcdClearScreen();\r
\r
halLcdPrintLine( " www.FreeRTOS.org", 0, OVERWRITE_TEXT );\r
- \r
-while( ( halButtonsPressed() & BUTTON_UP ) == 0 );\r
-}\r
-/*-----------------------------------------------------------*/\r
-\r
-void vApplicationSetupTimerInterrupt( void )\r
-{\r
-const unsigned short usACLK_Frequency_Hz = 32768;\r
-\r
- /* Ensure the timer is stopped. */\r
- TA0CTL = 0;\r
-\r
- /* Run the timer from the ACLK. */\r
- TA0CTL = TASSEL_1;\r
-\r
- /* Clear everything to start with. */\r
- TA0CTL |= TACLR;\r
-\r
- /* Set the compare match value according to the tick rate we want. */\r
- TA0CCR0 = usACLK_Frequency_Hz / configTICK_RATE_HZ;\r
-\r
- /* Enable the interrupts. */\r
- TA0CCTL0 = CCIE;\r
-\r
- /* Start up clean. */\r
- TA0CTL |= TACLR;\r
-\r
- /* Up mode. */\r
- TA0CTL |= MC_1;\r
-}\r
-/*-----------------------------------------------------------*/\r
-\r
-void vApplicationMallocFailedHook( void )\r
-{\r
- for( ;; );\r
-}\r
-/*-----------------------------------------------------------*/\r
-\r
-void vApplicationStackOverflowHook( xTaskHandle *pxTask, signed char *pcTaskName )\r
-{\r
- ( void ) pxTask;\r
- ( void ) pcTaskName;\r
- \r
- for( ;; );\r
-}\r
-/*-----------------------------------------------------------*/\r
-\r
-void vApplicationIdleHook( void )\r
-{\r
- /* Want to leave the SMCLK running so the COMTest tasks don't fail. */\r
- __bis_SR_register( LPM1_bits + GIE );\r
}\r
/*-----------------------------------------------------------*/\r
\r
xStatusMessage.ulMessageValue = mainERROR_GEN_QUEUE_TEST;\r
} \r
\r
- /* Check the reg test tasks are still cycling. They will stop incrementing\r
- their loop counters if they encounter an error. */\r
+ /* Check the reg test tasks are still cycling. They will stop\r
+ incrementing their loop counters if they encounter an error. */\r
if( usRegTest1Counter == usLastRegTest1Counter )\r
{\r
xStatusMessage.ulMessageValue = mainERROR_REG_TEST;\r
ulCounter = 0;\r
}\r
\r
+ /* Just periodically toggle an LED to show that the tick interrupt is\r
+ running. Note that this access LED_PORT_OUT in a non-atomic way, so tasks\r
+ that access the same port must do so from a critical section. */\r
if( ( ulCounter & 0xff ) == 0 )\r
{\r
if( ( LED_PORT_OUT & LED_1 ) == 0 )\r
{\r
LED_PORT_OUT |= LED_1;\r
- LED_PORT_OUT &= ~LED_2;\r
}\r
else\r
{\r
LED_PORT_OUT &= ~LED_1;\r
- LED_PORT_OUT |= LED_2;\r
}\r
}\r
}\r
}\r
/*-----------------------------------------------------------*/\r
\r
-void vConfigureTimerForRunTimeStats( void )\r
+/* The MSP430X port uses this callback function to configure its tick interrupt.\r
+This allows the application to choose the tick interrupt source.\r
+configTICK_INTERRUPT_VECTOR must also be set in FreeRTOSConfig.h to the correct\r
+interrupt vector for the chosen tick interrupt source. This implementation of\r
+vApplicationSetupTimerInterrupt() generates the tick from timer A0, so in this\r
+case configTICK_INTERRUPT_VECTOR is set to TIMER0_A0_VECTOR. */\r
+void vApplicationSetupTimerInterrupt( void )\r
{\r
+const unsigned short usACLK_Frequency_Hz = 32768;\r
+\r
/* Ensure the timer is stopped. */\r
- TA1CTL = 0;\r
+ TA0CTL = 0;\r
\r
- /* Run the timer from the ACLK/4. */\r
- TA1CTL = TASSEL_1 | ID__4;\r
+ /* Run the timer from the ACLK. */\r
+ TA0CTL = TASSEL_1;\r
\r
/* Clear everything to start with. */\r
- TA1CTL |= TACLR;\r
+ TA0CTL |= TACLR;\r
+\r
+ /* Set the compare match value according to the tick rate we want. */\r
+ TA0CCR0 = usACLK_Frequency_Hz / configTICK_RATE_HZ;\r
\r
/* Enable the interrupts. */\r
- TA1CCTL0 = CCIE;\r
+ TA0CCTL0 = CCIE;\r
\r
/* Start up clean. */\r
- TA1CTL |= TACLR;\r
+ TA0CTL |= TACLR;\r
\r
- /* Continuous mode. */\r
- TA1CTL |= MC__CONTINOUS;\r
+ /* Up mode. */\r
+ TA0CTL |= MC_1;\r
}\r
/*-----------------------------------------------------------*/\r
\r
-#pragma vector=TIMER1_A0_VECTOR\r
-static __interrupt void prvRunTimeStatsOverflowISR( void )\r
+void vApplicationIdleHook( void )\r
{\r
- ulStatsOverflowCount++;\r
+ /* Called on each iteration of the idle task. In this case the idle task\r
+ just enters a low(ish) power mode. */\r
+ __bis_SR_register( LPM1_bits + GIE );\r
}\r
/*-----------------------------------------------------------*/\r
\r
-inline unsigned long ulGetRunTimeStatsTime( void )\r
+void vApplicationMallocFailedHook( void )\r
{\r
-unsigned long ulReturn;\r
+ /* Called if a call to pvPortMalloc() fails because there is insufficient\r
+ free memory available in the FreeRTOS heap. pvPortMalloc() is called\r
+ internally by FreeRTOS API functions that create tasks, queues or\r
+ semaphores. */\r
+ taskDISABLE_INTERRUPTS();\r
+ for( ;; );\r
+}\r
+/*-----------------------------------------------------------*/\r
\r
- TA1CTL &= ~MC__CONTINOUS;\r
- ulReturn = ( ( ulStatsOverflowCount << 16UL ) | ( unsigned long ) TA1R );\r
- TA1CTL |= MC__CONTINOUS;\r
+void vApplicationStackOverflowHook( xTaskHandle *pxTask, signed char *pcTaskName )\r
+{\r
+ ( void ) pxTask;\r
+ ( void ) pcTaskName;\r
\r
- return ulReturn;\r
+ /* Run time stack overflow checking is performed if\r
+ configconfigCHECK_FOR_STACK_OVERFLOW is defined to 1 or 2. This hook\r
+ function is called if a stack overflow is detected. */\r
+ taskDISABLE_INTERRUPTS();\r
+ for( ;; );\r
}\r
-\r
-\r
-\r
+/*-----------------------------------------------------------*/\r
\r