1*1664436fSMatthias Ringwald /**
2*1664436fSMatthias Ringwald * @file hal_lcd.c
3*1664436fSMatthias Ringwald *
4*1664436fSMatthias Ringwald * Copyright 2008 Texas Instruments, Inc.
5*1664436fSMatthias Ringwald ***************************************************************************/
6*1664436fSMatthias Ringwald
7*1664436fSMatthias Ringwald #include "hal_lcd.h"
8*1664436fSMatthias Ringwald
9*1664436fSMatthias Ringwald #include <msp430x54x.h>
10*1664436fSMatthias Ringwald
11*1664436fSMatthias Ringwald #include "hal_compat.h"
12*1664436fSMatthias Ringwald #include "hal_lcd_fonts.h"
13*1664436fSMatthias Ringwald #include "hal_board.h"
14*1664436fSMatthias Ringwald
15*1664436fSMatthias Ringwald static unsigned char LcdInitMacro[]={
16*1664436fSMatthias Ringwald 0x74,0x00,0x00,0x76,0x00,0x01, // R00 start oscillation
17*1664436fSMatthias Ringwald 0x74,0x00,0x01,0x76,0x00,0x0D, // R01 driver output control
18*1664436fSMatthias Ringwald 0x74,0x00,0x02,0x76,0x00,0x4C, // R02 LCD - driving waveform control
19*1664436fSMatthias Ringwald 0x74,0x00,0x03,0x76,0x12,0x14, // R03 Power control
20*1664436fSMatthias Ringwald 0x74,0x00,0x04,0x76,0x04,0x66, // R04 Contrast control
21*1664436fSMatthias Ringwald 0x74,0x00,0x05,0x76,0x00,0x10, // R05 Entry mode
22*1664436fSMatthias Ringwald 0x74,0x00,0x06,0x76,0x00,0x00, // R06 RAM data write mask
23*1664436fSMatthias Ringwald 0x74,0x00,0x07,0x76,0x00,0x15, // R07 Display control
24*1664436fSMatthias Ringwald 0x74,0x00,0x08,0x76,0x00,0x03, // R08 Cursor Control
25*1664436fSMatthias Ringwald 0x74,0x00,0x09,0x76,0x00,0x00, // R09 RAM data write mask
26*1664436fSMatthias Ringwald 0x74,0x00,0x0A,0x76,0x00,0x15, // R0A
27*1664436fSMatthias Ringwald 0x74,0x00,0x0B,0x76,0x00,0x03, // R0B Horizontal Cursor Position
28*1664436fSMatthias Ringwald 0x74,0x00,0x0C,0x76,0x00,0x03, // R0C Vertical Cursor Position
29*1664436fSMatthias Ringwald 0x74,0x00,0x0D,0x76,0x00,0x00, // R0D
30*1664436fSMatthias Ringwald 0x74,0x00,0x0E,0x76,0x00,0x15, // R0E
31*1664436fSMatthias Ringwald 0x74,0x00,0x0F,0x76,0x00,0x03, // R0F
32*1664436fSMatthias Ringwald 0x74,0x00,0x10,0x76,0x00,0x15, // R0E
33*1664436fSMatthias Ringwald 0x74,0x00,0x11,0x76,0x00,0x03, // R0F
34*1664436fSMatthias Ringwald };
35*1664436fSMatthias Ringwald
36*1664436fSMatthias Ringwald static unsigned char Read_Block_Address_Macro[]= {0x74,0x00,0x12,0x77,0x00,0x00};
37*1664436fSMatthias Ringwald static unsigned char Draw_Block_Value_Macro[]={0x74,0x00,0x12,0x76,0xFF,0xFF};
38*1664436fSMatthias Ringwald static unsigned char Draw_Block_Address_Macro[]={0x74,0x00,0x11,0x76,0x00,0x00};
39*1664436fSMatthias Ringwald
40*1664436fSMatthias Ringwald static unsigned int LcdAddress = 0, LcdTableAddress = 0;
41*1664436fSMatthias Ringwald static unsigned char backlight = 8;
42*1664436fSMatthias Ringwald static int LCD_MEM[110*17];
43*1664436fSMatthias Ringwald
44*1664436fSMatthias Ringwald /************************************************************************
45*1664436fSMatthias Ringwald * @brief Sends 3+3 bytes of data to the LCD using the format specified
46*1664436fSMatthias Ringwald * by the LCD Guide.
47*1664436fSMatthias Ringwald *
48*1664436fSMatthias Ringwald * @param Data[] Data array for transmission
49*1664436fSMatthias Ringwald *
50*1664436fSMatthias Ringwald * @return none
51*1664436fSMatthias Ringwald *************************************************************************/
halLcdSendCommand(unsigned char Data[])52*1664436fSMatthias Ringwald void halLcdSendCommand(unsigned char Data[])
53*1664436fSMatthias Ringwald {
54*1664436fSMatthias Ringwald unsigned char i;
55*1664436fSMatthias Ringwald
56*1664436fSMatthias Ringwald LCD_CS_RST_OUT &= ~LCD_CS_PIN; //CS = 0 --> Start Transfer
57*1664436fSMatthias Ringwald for ( i = 0; i < 6; i++ )
58*1664436fSMatthias Ringwald {
59*1664436fSMatthias Ringwald while (!(UCB2IFG & UCTXIFG)); // Wait for TXIFG
60*1664436fSMatthias Ringwald UCB2TXBUF = Data[i]; // Load data
61*1664436fSMatthias Ringwald
62*1664436fSMatthias Ringwald while (UCB2STAT & UCBUSY);
63*1664436fSMatthias Ringwald
64*1664436fSMatthias Ringwald if (i == 2) //Pull CS up after 3 bytes
65*1664436fSMatthias Ringwald {
66*1664436fSMatthias Ringwald LCD_CS_RST_OUT |= LCD_CS_PIN; //CS = 1 --> Stop Transfer
67*1664436fSMatthias Ringwald LCD_CS_RST_OUT &= ~LCD_CS_PIN; //CS = 0 --> Start Transfer
68*1664436fSMatthias Ringwald }
69*1664436fSMatthias Ringwald }
70*1664436fSMatthias Ringwald LCD_CS_RST_OUT |= LCD_CS_PIN; //CS = 1 --> Stop Transfer
71*1664436fSMatthias Ringwald }
72*1664436fSMatthias Ringwald
73*1664436fSMatthias Ringwald /************************************************************************
74*1664436fSMatthias Ringwald * @brief Initializes the USCI module, LCD device for communication.
75*1664436fSMatthias Ringwald *
76*1664436fSMatthias Ringwald * - Sets up the SPI2C Communication Module
77*1664436fSMatthias Ringwald * - Performs Hitachi LCD Initialization Procedure
78*1664436fSMatthias Ringwald *
79*1664436fSMatthias Ringwald * @param none
80*1664436fSMatthias Ringwald *
81*1664436fSMatthias Ringwald * @return none
82*1664436fSMatthias Ringwald *************************************************************************/
halLcdInit(void)83*1664436fSMatthias Ringwald void halLcdInit(void)
84*1664436fSMatthias Ringwald {
85*1664436fSMatthias Ringwald volatile unsigned int i=0;
86*1664436fSMatthias Ringwald
87*1664436fSMatthias Ringwald LCD_CS_RST_OUT |= LCD_CS_PIN | LCD_RESET_PIN ;
88*1664436fSMatthias Ringwald LCD_CS_RST_DIR |= LCD_CS_PIN | LCD_RESET_PIN ;
89*1664436fSMatthias Ringwald
90*1664436fSMatthias Ringwald LCD_COMM_SEL |= LCD_BACKLIGHT_PIN;
91*1664436fSMatthias Ringwald
92*1664436fSMatthias Ringwald LCD_CS_RST_OUT &= ~LCD_RESET_PIN; // Reset LCD
93*1664436fSMatthias Ringwald __delay_cycles(0x47FF); //Reset Pulse
94*1664436fSMatthias Ringwald LCD_CS_RST_OUT |= LCD_RESET_PIN;
95*1664436fSMatthias Ringwald
96*1664436fSMatthias Ringwald // UCLK,MOSI setup, SOMI cleared
97*1664436fSMatthias Ringwald P9SEL |= BIT1 + BIT3;
98*1664436fSMatthias Ringwald P9SEL &= ~BIT2;
99*1664436fSMatthias Ringwald P9DIR |= BIT1 + BIT3;
100*1664436fSMatthias Ringwald P9DIR &= ~BIT2;
101*1664436fSMatthias Ringwald
102*1664436fSMatthias Ringwald /* Initialize USCI state machine */
103*1664436fSMatthias Ringwald UCB2CTL0 |= UCMST+UCSYNC+UCCKPL+UCMSB; // 3-pin, 8-bit SPI master
104*1664436fSMatthias Ringwald UCB2CTL1 |= UCSSEL_2; // SMCLK
105*1664436fSMatthias Ringwald UCB2BR0 = 3;
106*1664436fSMatthias Ringwald UCB2BR1 = 0;
107*1664436fSMatthias Ringwald UCB2CTL1 &= ~UCSWRST;
108*1664436fSMatthias Ringwald UCB2IFG &= ~UCRXIFG;
109*1664436fSMatthias Ringwald
110*1664436fSMatthias Ringwald // LCD Initialization Routine Using Predefined Macros
111*1664436fSMatthias Ringwald while (i < 8*6)
112*1664436fSMatthias Ringwald {
113*1664436fSMatthias Ringwald halLcdSendCommand(&LcdInitMacro[i]);
114*1664436fSMatthias Ringwald i += 6;
115*1664436fSMatthias Ringwald }
116*1664436fSMatthias Ringwald halLcdActive();
117*1664436fSMatthias Ringwald }
118*1664436fSMatthias Ringwald
119*1664436fSMatthias Ringwald /************************************************************************
120*1664436fSMatthias Ringwald * @brief Shuts down the LCD display and hdisables the USCI communication.
121*1664436fSMatthias Ringwald *
122*1664436fSMatthias Ringwald * @param none
123*1664436fSMatthias Ringwald *
124*1664436fSMatthias Ringwald * @return none
125*1664436fSMatthias Ringwald *************************************************************************/
halLcdShutDown(void)126*1664436fSMatthias Ringwald void halLcdShutDown(void)
127*1664436fSMatthias Ringwald {
128*1664436fSMatthias Ringwald halLcdStandby();
129*1664436fSMatthias Ringwald
130*1664436fSMatthias Ringwald LCD_CS_RST_DIR |= LCD_CS_PIN | LCD_RESET_PIN ;
131*1664436fSMatthias Ringwald LCD_CS_RST_OUT &= ~(LCD_CS_PIN | LCD_RESET_PIN );
132*1664436fSMatthias Ringwald LCD_CS_RST_OUT &= ~LCD_RESET_PIN;
133*1664436fSMatthias Ringwald
134*1664436fSMatthias Ringwald P9SEL &= ~(BIT1 + BIT3 + BIT2);
135*1664436fSMatthias Ringwald P9DIR |= BIT1 + BIT3 + BIT2;
136*1664436fSMatthias Ringwald P9OUT &= ~(BIT1 + BIT3 + BIT2);
137*1664436fSMatthias Ringwald
138*1664436fSMatthias Ringwald UCB2CTL0 = UCSWRST;
139*1664436fSMatthias Ringwald }
140*1664436fSMatthias Ringwald
141*1664436fSMatthias Ringwald /************************************************************************
142*1664436fSMatthias Ringwald * @brief Initializes the LCD backlight PWM signal.
143*1664436fSMatthias Ringwald *
144*1664436fSMatthias Ringwald * @param none
145*1664436fSMatthias Ringwald *
146*1664436fSMatthias Ringwald * @return none
147*1664436fSMatthias Ringwald *
148*1664436fSMatthias Ringwald *************************************************************************/
halLcdBackLightInit(void)149*1664436fSMatthias Ringwald void halLcdBackLightInit(void)
150*1664436fSMatthias Ringwald {
151*1664436fSMatthias Ringwald LCD_COMM_DIR |= LCD_BACKLIGHT_PIN;
152*1664436fSMatthias Ringwald LCD_COMM_OUT |= LCD_BACKLIGHT_PIN;
153*1664436fSMatthias Ringwald
154*1664436fSMatthias Ringwald LCD_COMM_SEL |= LCD_BACKLIGHT_PIN;
155*1664436fSMatthias Ringwald TA0CCTL3 = OUTMOD_7;
156*1664436fSMatthias Ringwald TA0CCR3 = TA0CCR0 >> 1 ;
157*1664436fSMatthias Ringwald backlight = 8;
158*1664436fSMatthias Ringwald
159*1664436fSMatthias Ringwald TA0CCR0 = 400;
160*1664436fSMatthias Ringwald TA0CTL = TASSEL_2+MC_1;
161*1664436fSMatthias Ringwald }
162*1664436fSMatthias Ringwald
163*1664436fSMatthias Ringwald /************************************************************************
164*1664436fSMatthias Ringwald * @brief Get function for the backlight PWM's duty cycle.
165*1664436fSMatthias Ringwald *
166*1664436fSMatthias Ringwald * @param none
167*1664436fSMatthias Ringwald *
168*1664436fSMatthias Ringwald * @return backlight One of the the 17 possible settings - valued 0 to 16.
169*1664436fSMatthias Ringwald *
170*1664436fSMatthias Ringwald *************************************************************************/
halLcdGetBackLight(void)171*1664436fSMatthias Ringwald unsigned int halLcdGetBackLight(void)
172*1664436fSMatthias Ringwald {
173*1664436fSMatthias Ringwald return backlight;
174*1664436fSMatthias Ringwald }
175*1664436fSMatthias Ringwald
176*1664436fSMatthias Ringwald /************************************************************************
177*1664436fSMatthias Ringwald * @brief Set function for the backlight PWM's duty cycle
178*1664436fSMatthias Ringwald *
179*1664436fSMatthias Ringwald * @param BackLightLevel The target backlight duty cycle - valued 0 to 16.
180*1664436fSMatthias Ringwald *
181*1664436fSMatthias Ringwald * @return none
182*1664436fSMatthias Ringwald *************************************************************************/
halLcdSetBackLight(unsigned char BackLightLevel)183*1664436fSMatthias Ringwald void halLcdSetBackLight(unsigned char BackLightLevel)
184*1664436fSMatthias Ringwald {
185*1664436fSMatthias Ringwald unsigned int dutyCycle = 0, i, dummy;
186*1664436fSMatthias Ringwald
187*1664436fSMatthias Ringwald if (BackLightLevel > 0)
188*1664436fSMatthias Ringwald {
189*1664436fSMatthias Ringwald TA0CCTL3 = OUTMOD_7;
190*1664436fSMatthias Ringwald dummy = (TA0CCR0 >> 4);
191*1664436fSMatthias Ringwald
192*1664436fSMatthias Ringwald for (i = 0; i < BackLightLevel; i++)
193*1664436fSMatthias Ringwald dutyCycle += dummy;
194*1664436fSMatthias Ringwald
195*1664436fSMatthias Ringwald TA0CCR3 = dutyCycle;
196*1664436fSMatthias Ringwald
197*1664436fSMatthias Ringwald // If the backlight was previously turned off, turn it on.
198*1664436fSMatthias Ringwald if (!backlight)
199*1664436fSMatthias Ringwald TA0CTL |= MC0;
200*1664436fSMatthias Ringwald }
201*1664436fSMatthias Ringwald else
202*1664436fSMatthias Ringwald {
203*1664436fSMatthias Ringwald TA0CCTL3 = 0;
204*1664436fSMatthias Ringwald TA0CTL &= ~MC0;
205*1664436fSMatthias Ringwald }
206*1664436fSMatthias Ringwald backlight = BackLightLevel;
207*1664436fSMatthias Ringwald }
208*1664436fSMatthias Ringwald
209*1664436fSMatthias Ringwald /************************************************************************
210*1664436fSMatthias Ringwald * @brief Turns off the backlight.
211*1664436fSMatthias Ringwald *
212*1664436fSMatthias Ringwald * Clears the respective GPIO and timer settings.
213*1664436fSMatthias Ringwald *
214*1664436fSMatthias Ringwald * @param none
215*1664436fSMatthias Ringwald *
216*1664436fSMatthias Ringwald * @return none
217*1664436fSMatthias Ringwald *************************************************************************/
halLcdShutDownBackLight(void)218*1664436fSMatthias Ringwald void halLcdShutDownBackLight(void)
219*1664436fSMatthias Ringwald {
220*1664436fSMatthias Ringwald LCD_COMM_DIR |= LCD_BACKLIGHT_PIN;
221*1664436fSMatthias Ringwald LCD_COMM_OUT &= ~(LCD_BACKLIGHT_PIN);
222*1664436fSMatthias Ringwald LCD_COMM_SEL &= ~LCD_BACKLIGHT_PIN;
223*1664436fSMatthias Ringwald
224*1664436fSMatthias Ringwald TA0CCTL3 = 0;
225*1664436fSMatthias Ringwald TA0CTL = 0;
226*1664436fSMatthias Ringwald
227*1664436fSMatthias Ringwald backlight = 0;
228*1664436fSMatthias Ringwald }
229*1664436fSMatthias Ringwald
230*1664436fSMatthias Ringwald /************************************************************************
231*1664436fSMatthias Ringwald * @brief Set function for the contrast level of the LCD.
232*1664436fSMatthias Ringwald *
233*1664436fSMatthias Ringwald * @param ContrastLevel The target contrast level
234*1664436fSMatthias Ringwald *
235*1664436fSMatthias Ringwald * @return none
236*1664436fSMatthias Ringwald *************************************************************************/
halLcdSetContrast(unsigned char ContrastLevel)237*1664436fSMatthias Ringwald void halLcdSetContrast(unsigned char ContrastLevel)
238*1664436fSMatthias Ringwald {
239*1664436fSMatthias Ringwald if (ContrastLevel > 127) ContrastLevel = 127;
240*1664436fSMatthias Ringwald if (ContrastLevel < 70) ContrastLevel = 70;
241*1664436fSMatthias Ringwald LcdInitMacro[ 0x04 * 6 + 5 ] = ContrastLevel;
242*1664436fSMatthias Ringwald halLcdSendCommand(&LcdInitMacro[ 0x04 * 6 ]);
243*1664436fSMatthias Ringwald }
244*1664436fSMatthias Ringwald
245*1664436fSMatthias Ringwald /************************************************************************
246*1664436fSMatthias Ringwald * @brief Get function for the contrast level of the LCD.
247*1664436fSMatthias Ringwald *
248*1664436fSMatthias Ringwald * @param none
249*1664436fSMatthias Ringwald *
250*1664436fSMatthias Ringwald * @return ContrastLevel The LCD constrast level
251*1664436fSMatthias Ringwald *************************************************************************/
halLcdGetContrast(void)252*1664436fSMatthias Ringwald unsigned char halLcdGetContrast(void)
253*1664436fSMatthias Ringwald {
254*1664436fSMatthias Ringwald return LcdInitMacro[ 0x04 * 6 + 5 ] ;
255*1664436fSMatthias Ringwald }
256*1664436fSMatthias Ringwald
257*1664436fSMatthias Ringwald /************************************************************************
258*1664436fSMatthias Ringwald * @brief Turns the LCD cursor on at the current text position.
259*1664436fSMatthias Ringwald *
260*1664436fSMatthias Ringwald * @param none
261*1664436fSMatthias Ringwald *
262*1664436fSMatthias Ringwald * @return none
263*1664436fSMatthias Ringwald *************************************************************************/
halLcdCursor(void)264*1664436fSMatthias Ringwald void halLcdCursor(void)
265*1664436fSMatthias Ringwald {
266*1664436fSMatthias Ringwald LcdInitMacro[ 8 * 6 + 5 ] ^= BIT2;
267*1664436fSMatthias Ringwald halLcdSendCommand(&LcdInitMacro[ 8 * 6 ]);
268*1664436fSMatthias Ringwald
269*1664436fSMatthias Ringwald LcdInitMacro[ 0x0B * 6 + 5 ] = ((LcdAddress & 0x1F) << 3) ;
270*1664436fSMatthias Ringwald LcdInitMacro[ 0x0B * 6 + 4 ] = ( (LcdAddress & 0x1F) << 3 ) + 3;
271*1664436fSMatthias Ringwald LcdInitMacro[ 0x0C * 6 + 5 ] = (LcdAddress >> 5);
272*1664436fSMatthias Ringwald LcdInitMacro[ 0x0C * 6 + 4 ] = (LcdAddress >> 5) + 7;
273*1664436fSMatthias Ringwald halLcdSendCommand(&LcdInitMacro[ 0x0B * 6 ]);
274*1664436fSMatthias Ringwald halLcdSendCommand(&LcdInitMacro[ 0x0C * 6 ]);
275*1664436fSMatthias Ringwald
276*1664436fSMatthias Ringwald halLcdSetAddress(LcdAddress);
277*1664436fSMatthias Ringwald }
278*1664436fSMatthias Ringwald
279*1664436fSMatthias Ringwald /************************************************************************
280*1664436fSMatthias Ringwald * @brief Turns off the LCD cursor.
281*1664436fSMatthias Ringwald *
282*1664436fSMatthias Ringwald * @param none
283*1664436fSMatthias Ringwald *
284*1664436fSMatthias Ringwald * @return none
285*1664436fSMatthias Ringwald *************************************************************************/
halLcdCursorOff(void)286*1664436fSMatthias Ringwald void halLcdCursorOff(void)
287*1664436fSMatthias Ringwald {
288*1664436fSMatthias Ringwald LcdInitMacro[ 8 * 6 + 5 ] &= ~BIT2;
289*1664436fSMatthias Ringwald halLcdSendCommand(&LcdInitMacro[ 8 * 6 ]);
290*1664436fSMatthias Ringwald }
291*1664436fSMatthias Ringwald
292*1664436fSMatthias Ringwald /************************************************************************
293*1664436fSMatthias Ringwald * @brief Inverts the grayscale values of the LCD display (Black <> white).
294*1664436fSMatthias Ringwald *
295*1664436fSMatthias Ringwald * @param none
296*1664436fSMatthias Ringwald *
297*1664436fSMatthias Ringwald * @return none
298*1664436fSMatthias Ringwald *************************************************************************/
halLcdReverse(void)299*1664436fSMatthias Ringwald void halLcdReverse(void)
300*1664436fSMatthias Ringwald {
301*1664436fSMatthias Ringwald LcdInitMacro[ 7 * 6 + 5 ] ^= BIT1;
302*1664436fSMatthias Ringwald halLcdSendCommand(&LcdInitMacro[ 7 * 6 ]);
303*1664436fSMatthias Ringwald }
304*1664436fSMatthias Ringwald
305*1664436fSMatthias Ringwald /************************************************************************
306*1664436fSMatthias Ringwald * @brief Sets the LCD in standby mode to reduce power consumption.
307*1664436fSMatthias Ringwald *
308*1664436fSMatthias Ringwald * @param none
309*1664436fSMatthias Ringwald *
310*1664436fSMatthias Ringwald * @return none
311*1664436fSMatthias Ringwald *************************************************************************/
halLcdStandby(void)312*1664436fSMatthias Ringwald void halLcdStandby(void)
313*1664436fSMatthias Ringwald {
314*1664436fSMatthias Ringwald LcdInitMacro[ 3 * 6 + 5 ] &= (~BIT3) & (~BIT2);
315*1664436fSMatthias Ringwald LcdInitMacro[ 3 * 6 + 5 ] |= BIT0;
316*1664436fSMatthias Ringwald halLcdSendCommand(&LcdInitMacro[ 3 * 6 ]);
317*1664436fSMatthias Ringwald }
318*1664436fSMatthias Ringwald
319*1664436fSMatthias Ringwald /************************************************************************
320*1664436fSMatthias Ringwald * @brief Puts the LCD into active mode.
321*1664436fSMatthias Ringwald *
322*1664436fSMatthias Ringwald * @param none
323*1664436fSMatthias Ringwald *
324*1664436fSMatthias Ringwald * @return none
325*1664436fSMatthias Ringwald *************************************************************************/
halLcdActive(void)326*1664436fSMatthias Ringwald void halLcdActive(void)
327*1664436fSMatthias Ringwald {
328*1664436fSMatthias Ringwald halLcdSendCommand(LcdInitMacro);
329*1664436fSMatthias Ringwald LcdInitMacro[ 3 * 6 + 5 ] |= BIT3 ;
330*1664436fSMatthias Ringwald LcdInitMacro[ 3 * 6 + 5 ] &= ~BIT0;
331*1664436fSMatthias Ringwald halLcdSendCommand(&LcdInitMacro[ 3 * 6 ]);
332*1664436fSMatthias Ringwald }
333*1664436fSMatthias Ringwald
334*1664436fSMatthias Ringwald /************************************************************************
335*1664436fSMatthias Ringwald * @brief Sets the pointer location in the LCD.
336*1664436fSMatthias Ringwald *
337*1664436fSMatthias Ringwald * - LcdAddress = Address
338*1664436fSMatthias Ringwald * - LcdTableAddress = Correct Address Row + Column
339*1664436fSMatthias Ringwald * = (Address / 0x20)* 17 + Column
340*1664436fSMatthias Ringwald *
341*1664436fSMatthias Ringwald * @param Address The target pointer location in the LCD.
342*1664436fSMatthias Ringwald *
343*1664436fSMatthias Ringwald * @return none
344*1664436fSMatthias Ringwald *************************************************************************/
halLcdSetAddress(int Address)345*1664436fSMatthias Ringwald void halLcdSetAddress(int Address)
346*1664436fSMatthias Ringwald {
347*1664436fSMatthias Ringwald int temp;
348*1664436fSMatthias Ringwald
349*1664436fSMatthias Ringwald Draw_Block_Address_Macro[4] = Address >> 8;
350*1664436fSMatthias Ringwald Draw_Block_Address_Macro[5] = Address & 0xFF;
351*1664436fSMatthias Ringwald halLcdSendCommand(Draw_Block_Address_Macro);
352*1664436fSMatthias Ringwald LcdAddress = Address;
353*1664436fSMatthias Ringwald temp = Address >> 5; // Divided by 0x20
354*1664436fSMatthias Ringwald temp = temp + (temp << 4);
355*1664436fSMatthias Ringwald //Multiplied by (1+16) and added by the offset
356*1664436fSMatthias Ringwald LcdTableAddress = temp + (Address & 0x1F);
357*1664436fSMatthias Ringwald }
358*1664436fSMatthias Ringwald
359*1664436fSMatthias Ringwald /************************************************************************
360*1664436fSMatthias Ringwald * @brief Draws a block at the specified LCD address.
361*1664436fSMatthias Ringwald *
362*1664436fSMatthias Ringwald * A block is the smallest addressable memory on the LCD and is
363*1664436fSMatthias Ringwald * equivalent to 8 pixels, each of which is represented by 2 bits
364*1664436fSMatthias Ringwald * that represent a grayscale value between 00b and 11b.
365*1664436fSMatthias Ringwald *
366*1664436fSMatthias Ringwald * @param Address The address at which to draw the block.
367*1664436fSMatthias Ringwald *
368*1664436fSMatthias Ringwald * @param Value The value of the block
369*1664436fSMatthias Ringwald *
370*1664436fSMatthias Ringwald * @return none
371*1664436fSMatthias Ringwald *************************************************************************/
halLcdDrawBlock(unsigned int Address,unsigned int Value)372*1664436fSMatthias Ringwald void halLcdDrawBlock(unsigned int Address, unsigned int Value)
373*1664436fSMatthias Ringwald {
374*1664436fSMatthias Ringwald halLcdSetAddress(Address);
375*1664436fSMatthias Ringwald halLcdDrawCurrentBlock(Value);
376*1664436fSMatthias Ringwald }
377*1664436fSMatthias Ringwald
378*1664436fSMatthias Ringwald /************************************************************************
379*1664436fSMatthias Ringwald * @brief Writes Value to LCD CGram and MSP430 internal LCD table.
380*1664436fSMatthias Ringwald *
381*1664436fSMatthias Ringwald * Also updates the LcdAddress and LcdTableAddress to the correct values.
382*1664436fSMatthias Ringwald *
383*1664436fSMatthias Ringwald * @param Value The value of the block to be written to the LCD.
384*1664436fSMatthias Ringwald *
385*1664436fSMatthias Ringwald * @return none
386*1664436fSMatthias Ringwald *************************************************************************/
halLcdDrawCurrentBlock(unsigned int Value)387*1664436fSMatthias Ringwald void halLcdDrawCurrentBlock(unsigned int Value)
388*1664436fSMatthias Ringwald {
389*1664436fSMatthias Ringwald int temp;
390*1664436fSMatthias Ringwald
391*1664436fSMatthias Ringwald Draw_Block_Value_Macro[4] = Value >> 8;
392*1664436fSMatthias Ringwald Draw_Block_Value_Macro[5] = Value & 0xFF;
393*1664436fSMatthias Ringwald LCD_MEM[ LcdTableAddress ] = Value;
394*1664436fSMatthias Ringwald
395*1664436fSMatthias Ringwald halLcdSendCommand(Draw_Block_Value_Macro);
396*1664436fSMatthias Ringwald
397*1664436fSMatthias Ringwald LcdAddress++;
398*1664436fSMatthias Ringwald temp = LcdAddress >> 5; // Divided by 0x20
399*1664436fSMatthias Ringwald temp = temp + (temp << 4);
400*1664436fSMatthias Ringwald // Multiplied by (1+16) and added by the offset
401*1664436fSMatthias Ringwald LcdTableAddress = temp + (LcdAddress & 0x1F);
402*1664436fSMatthias Ringwald
403*1664436fSMatthias Ringwald // If LcdAddress gets off the right edge, move to next line
404*1664436fSMatthias Ringwald if ((LcdAddress & 0x1F) > 0x11)
405*1664436fSMatthias Ringwald halLcdSetAddress( (LcdAddress & 0xFFE0) + 0x20 );
406*1664436fSMatthias Ringwald if (LcdAddress == LCD_Size)
407*1664436fSMatthias Ringwald halLcdSetAddress( 0 );
408*1664436fSMatthias Ringwald }
409*1664436fSMatthias Ringwald
410*1664436fSMatthias Ringwald
411*1664436fSMatthias Ringwald /************************************************************************
412*1664436fSMatthias Ringwald * @brief Returns the LCD CGRAM value at location Address.
413*1664436fSMatthias Ringwald *
414*1664436fSMatthias Ringwald * @param Address The address of the block to be read from the LCD.
415*1664436fSMatthias Ringwald *
416*1664436fSMatthias Ringwald * @return Value The value held at the specified address.
417*1664436fSMatthias Ringwald *************************************************************************/
halLcdReadBlock(unsigned int Address)418*1664436fSMatthias Ringwald int halLcdReadBlock(unsigned int Address)
419*1664436fSMatthias Ringwald {
420*1664436fSMatthias Ringwald int i = 0, Value = 0, ReadData[7];
421*1664436fSMatthias Ringwald
422*1664436fSMatthias Ringwald halLcdSetAddress( Address );
423*1664436fSMatthias Ringwald halLcdSendCommand(Read_Block_Address_Macro);
424*1664436fSMatthias Ringwald
425*1664436fSMatthias Ringwald LCD_COMM_OUT &= ~LCD_CS_PIN; // start transfer CS=0
426*1664436fSMatthias Ringwald UCB2TXBUF = 0x77; // Transmit first character 0x75
427*1664436fSMatthias Ringwald
428*1664436fSMatthias Ringwald while (!(UCB2IFG & UCTXIFG));
429*1664436fSMatthias Ringwald while (UCB2STAT & UCBUSY);
430*1664436fSMatthias Ringwald
431*1664436fSMatthias Ringwald //Read 5 dummies values and 2 valid address data
432*1664436fSMatthias Ringwald P9SEL &= ~BIT1; //Change SPI2C Dir
433*1664436fSMatthias Ringwald P9SEL |= BIT2;
434*1664436fSMatthias Ringwald
435*1664436fSMatthias Ringwald for (i = 0; i < 7; i ++ )
436*1664436fSMatthias Ringwald {
437*1664436fSMatthias Ringwald P4OUT |= BIT2;
438*1664436fSMatthias Ringwald P4OUT &= ~BIT2;
439*1664436fSMatthias Ringwald UCA0IFG &= ~UCRXIFG;
440*1664436fSMatthias Ringwald UCA0TXBUF = 1; // load dummy byte 1 for clk
441*1664436fSMatthias Ringwald while (!(UCA0IFG & UCRXIFG));
442*1664436fSMatthias Ringwald ReadData[i] = UCA0RXBUF;
443*1664436fSMatthias Ringwald }
444*1664436fSMatthias Ringwald LCD_COMM_OUT |= LCD_CS_PIN; // Stop Transfer CS = 1
445*1664436fSMatthias Ringwald
446*1664436fSMatthias Ringwald P9SEL |= BIT1; //Change SPI2C Dir
447*1664436fSMatthias Ringwald P9SEL &= ~BIT2;
448*1664436fSMatthias Ringwald
449*1664436fSMatthias Ringwald Value = (ReadData[5] << 8) + ReadData[6];
450*1664436fSMatthias Ringwald return Value;
451*1664436fSMatthias Ringwald }
452*1664436fSMatthias Ringwald
453*1664436fSMatthias Ringwald /************************************************************************
454*1664436fSMatthias Ringwald * @brief Draw a Pixel of grayscale at coordinate (x,y) to LCD
455*1664436fSMatthias Ringwald *
456*1664436fSMatthias Ringwald * @param x x-coordinate for grayscale value
457*1664436fSMatthias Ringwald *
458*1664436fSMatthias Ringwald * @param y y-coordinate for grayscale value
459*1664436fSMatthias Ringwald *
460*1664436fSMatthias Ringwald * @param GrayScale The intended grayscale value of the pixel - one of
461*1664436fSMatthias Ringwald * four possible settings.
462*1664436fSMatthias Ringwald *
463*1664436fSMatthias Ringwald * @return none
464*1664436fSMatthias Ringwald *************************************************************************/
halLcdPixel(int x,int y,unsigned char GrayScale)465*1664436fSMatthias Ringwald void halLcdPixel( int x, int y, unsigned char GrayScale)
466*1664436fSMatthias Ringwald {
467*1664436fSMatthias Ringwald int Address, Value;
468*1664436fSMatthias Ringwald unsigned char offset;
469*1664436fSMatthias Ringwald //Each line increments by 0x20
470*1664436fSMatthias Ringwald if ( (x>=0 ) && (x<LCD_COL) && (y>=0) && (y<LCD_ROW))
471*1664436fSMatthias Ringwald {
472*1664436fSMatthias Ringwald Address = (y << 5) + (x >> 3) ; //Narrow down to 8 possible pixels
473*1664436fSMatthias Ringwald offset = x & 0x07; //3 LSBs = pos. within the 8 columns
474*1664436fSMatthias Ringwald
475*1664436fSMatthias Ringwald Value = LCD_MEM[(y << 4)+ y + (x>>3)]; //y * 17 --> row. x>>3 --> column
476*1664436fSMatthias Ringwald switch(GrayScale)
477*1664436fSMatthias Ringwald {
478*1664436fSMatthias Ringwald case PIXEL_OFF:
479*1664436fSMatthias Ringwald Value &= ~ ( 3 << (offset * 2 )); //Both corresponding bits are off
480*1664436fSMatthias Ringwald break;
481*1664436fSMatthias Ringwald case PIXEL_LIGHT:
482*1664436fSMatthias Ringwald Value &= ~ ( 1 << ((offset * 2) + 1));
483*1664436fSMatthias Ringwald Value |= 1<< ( offset * 2 ); //Lower bit is on
484*1664436fSMatthias Ringwald
485*1664436fSMatthias Ringwald break;
486*1664436fSMatthias Ringwald case PIXEL_DARK:
487*1664436fSMatthias Ringwald Value &= ~ ( 1 << (offset * 2) ); //Lower bit is on
488*1664436fSMatthias Ringwald Value |= ( 1 << ( (offset * 2) + 1));
489*1664436fSMatthias Ringwald
490*1664436fSMatthias Ringwald break;
491*1664436fSMatthias Ringwald case PIXEL_ON:
492*1664436fSMatthias Ringwald Value |= ( 3 << (offset * 2 )); //Both on
493*1664436fSMatthias Ringwald break;
494*1664436fSMatthias Ringwald }
495*1664436fSMatthias Ringwald halLcdDrawBlock( Address, Value );
496*1664436fSMatthias Ringwald }
497*1664436fSMatthias Ringwald }
498*1664436fSMatthias Ringwald
499*1664436fSMatthias Ringwald /************************************************************************
500*1664436fSMatthias Ringwald * @brief Clears entire LCD CGRAM as well as LCD_MEM.
501*1664436fSMatthias Ringwald *
502*1664436fSMatthias Ringwald * @param none
503*1664436fSMatthias Ringwald *
504*1664436fSMatthias Ringwald * @return none
505*1664436fSMatthias Ringwald *************************************************************************/
halLcdClearScreen(void)506*1664436fSMatthias Ringwald void halLcdClearScreen(void)
507*1664436fSMatthias Ringwald {
508*1664436fSMatthias Ringwald int i;
509*1664436fSMatthias Ringwald
510*1664436fSMatthias Ringwald halLcdSetAddress(0);
511*1664436fSMatthias Ringwald
512*1664436fSMatthias Ringwald // Clear the entire LCD CGRAM
513*1664436fSMatthias Ringwald for ( i = 0; i < LCD_Size; i++)
514*1664436fSMatthias Ringwald halLcdDrawCurrentBlock(0x00);
515*1664436fSMatthias Ringwald
516*1664436fSMatthias Ringwald halLcdSetAddress(0); // Reset LCD address
517*1664436fSMatthias Ringwald }
518*1664436fSMatthias Ringwald
519*1664436fSMatthias Ringwald /************************************************************************
520*1664436fSMatthias Ringwald * @brief Loads an image of size = rows * columns, starting at the
521*1664436fSMatthias Ringwald * coordinate (x,y).
522*1664436fSMatthias Ringwald *
523*1664436fSMatthias Ringwald * @param Image[] The image to be loaded
524*1664436fSMatthias Ringwald *
525*1664436fSMatthias Ringwald * @param Rows The number of rows in the image. Size = Rows * Columns.
526*1664436fSMatthias Ringwald *
527*1664436fSMatthias Ringwald * @param Columns The number of columns in the image. Size = Rows * Columns.
528*1664436fSMatthias Ringwald *
529*1664436fSMatthias Ringwald * @param x x-coordinate of the image's starting location
530*1664436fSMatthias Ringwald *
531*1664436fSMatthias Ringwald * @param y y-coordinate of the image's starting location
532*1664436fSMatthias Ringwald *
533*1664436fSMatthias Ringwald * @return none
534*1664436fSMatthias Ringwald *************************************************************************/
halLcdImage(const unsigned int Image[],int Columns,int Rows,int x,int y)535*1664436fSMatthias Ringwald void halLcdImage(const unsigned int Image[], int Columns, int Rows, int x, int y)
536*1664436fSMatthias Ringwald {
537*1664436fSMatthias Ringwald int i,j, CurrentLocation, index=0 ;
538*1664436fSMatthias Ringwald
539*1664436fSMatthias Ringwald CurrentLocation = (y << 5) + (x >> 3);
540*1664436fSMatthias Ringwald halLcdSetAddress( CurrentLocation );
541*1664436fSMatthias Ringwald for (i=0; i < Rows; i++)
542*1664436fSMatthias Ringwald {
543*1664436fSMatthias Ringwald for (j=0; j < Columns; j++)
544*1664436fSMatthias Ringwald halLcdDrawCurrentBlock(Image[index++]);
545*1664436fSMatthias Ringwald CurrentLocation += 0x20;
546*1664436fSMatthias Ringwald halLcdSetAddress(CurrentLocation );
547*1664436fSMatthias Ringwald }
548*1664436fSMatthias Ringwald }
549*1664436fSMatthias Ringwald
550*1664436fSMatthias Ringwald /************************************************************************
551*1664436fSMatthias Ringwald * @brief Clears an image of size rows x columns starting at (x, y).
552*1664436fSMatthias Ringwald *
553*1664436fSMatthias Ringwald * @param Columns The size, in columns, of the image to be cleared.
554*1664436fSMatthias Ringwald *
555*1664436fSMatthias Ringwald * @param Rows The size, in rows, of the image to be cleared.
556*1664436fSMatthias Ringwald *
557*1664436fSMatthias Ringwald * @param x x-coordinate of the image to be cleared
558*1664436fSMatthias Ringwald *
559*1664436fSMatthias Ringwald * @param y y-coordinate of the image to be cleared
560*1664436fSMatthias Ringwald *
561*1664436fSMatthias Ringwald * @return none
562*1664436fSMatthias Ringwald *************************************************************************/
halLcdClearImage(int Columns,int Rows,int x,int y)563*1664436fSMatthias Ringwald void halLcdClearImage(int Columns, int Rows, int x, int y)
564*1664436fSMatthias Ringwald {
565*1664436fSMatthias Ringwald int i,j, Current_Location;
566*1664436fSMatthias Ringwald Current_Location = (y << 5) + (x >> 3);
567*1664436fSMatthias Ringwald halLcdSetAddress( Current_Location );
568*1664436fSMatthias Ringwald for (i=0; i < Rows; i++)
569*1664436fSMatthias Ringwald {
570*1664436fSMatthias Ringwald for (j=0; j < Columns; j++)
571*1664436fSMatthias Ringwald halLcdDrawCurrentBlock(0);
572*1664436fSMatthias Ringwald Current_Location += 0x20;
573*1664436fSMatthias Ringwald halLcdSetAddress(Current_Location );
574*1664436fSMatthias Ringwald }
575*1664436fSMatthias Ringwald }
576*1664436fSMatthias Ringwald
577*1664436fSMatthias Ringwald /************************************************************************
578*1664436fSMatthias Ringwald * @brief Writes Value to LCD CGRAM. Pointers internal to the LCD
579*1664436fSMatthias Ringwald * are also updated.
580*1664436fSMatthias Ringwald *
581*1664436fSMatthias Ringwald * @param Value The value to be written to the current LCD pointer
582*1664436fSMatthias Ringwald *
583*1664436fSMatthias Ringwald * @return none
584*1664436fSMatthias Ringwald *************************************************************************/
halLcdDrawTextBlock(unsigned int Value)585*1664436fSMatthias Ringwald void halLcdDrawTextBlock(unsigned int Value)
586*1664436fSMatthias Ringwald {
587*1664436fSMatthias Ringwald int temp;
588*1664436fSMatthias Ringwald
589*1664436fSMatthias Ringwald Draw_Block_Value_Macro[4] = Value >> 8;
590*1664436fSMatthias Ringwald Draw_Block_Value_Macro[5] = Value & 0xFF;
591*1664436fSMatthias Ringwald LCD_MEM[ LcdTableAddress ] = Value;
592*1664436fSMatthias Ringwald
593*1664436fSMatthias Ringwald halLcdSendCommand(Draw_Block_Value_Macro);
594*1664436fSMatthias Ringwald
595*1664436fSMatthias Ringwald LcdAddress++;
596*1664436fSMatthias Ringwald temp = LcdAddress >> 5; // Divided by 0x20
597*1664436fSMatthias Ringwald temp = temp + (temp << 4);
598*1664436fSMatthias Ringwald //Multiplied by (1+16) and added by the offset
599*1664436fSMatthias Ringwald LcdTableAddress = temp + (LcdAddress & 0x1F);
600*1664436fSMatthias Ringwald
601*1664436fSMatthias Ringwald // If LcdAddress gets off the right edge, move to next line
602*1664436fSMatthias Ringwald if ((LcdAddress & 0x1F) > 0x10)
603*1664436fSMatthias Ringwald halLcdSetAddress( (LcdAddress & 0xFFE0) + 0x20 );
604*1664436fSMatthias Ringwald
605*1664436fSMatthias Ringwald if (LcdAddress >= LCD_Size)
606*1664436fSMatthias Ringwald halLcdSetAddress( 0 );
607*1664436fSMatthias Ringwald }
608*1664436fSMatthias Ringwald
609*1664436fSMatthias Ringwald /************************************************************************
610*1664436fSMatthias Ringwald * @brief Displays the string to the LCD starting at current location.
611*1664436fSMatthias Ringwald *
612*1664436fSMatthias Ringwald * Writes all the data to LCD_MEM first, then updates all corresponding
613*1664436fSMatthias Ringwald * LCD CGRAM locations at once, in a continuous fashion.
614*1664436fSMatthias Ringwald *
615*1664436fSMatthias Ringwald * @param String[] The string to be displayed on LCD.
616*1664436fSMatthias Ringwald *
617*1664436fSMatthias Ringwald * @param TextStyle Value that specifies whether the string is to be
618*1664436fSMatthias Ringwald * inverted or overwritten.
619*1664436fSMatthias Ringwald * - Invert = 0x01
620*1664436fSMatthias Ringwald * - Overwrite = 0x04
621*1664436fSMatthias Ringwald *
622*1664436fSMatthias Ringwald * @return none
623*1664436fSMatthias Ringwald *************************************************************************/
halLcdPrint(char String[],unsigned char TextStyle)624*1664436fSMatthias Ringwald void halLcdPrint( char String[], unsigned char TextStyle)
625*1664436fSMatthias Ringwald {
626*1664436fSMatthias Ringwald int Address;
627*1664436fSMatthias Ringwald int LCD_MEM_Add;
628*1664436fSMatthias Ringwald int ActualAddress;
629*1664436fSMatthias Ringwald int i, j, Counter=0, BlockValue;
630*1664436fSMatthias Ringwald int temp;
631*1664436fSMatthias Ringwald char LookUpChar;
632*1664436fSMatthias Ringwald
633*1664436fSMatthias Ringwald ActualAddress = LcdAddress;
634*1664436fSMatthias Ringwald Counter = LcdAddress & 0x1F;
635*1664436fSMatthias Ringwald i=0;
636*1664436fSMatthias Ringwald
637*1664436fSMatthias Ringwald while (String[i]!=0) // Stop on null character
638*1664436fSMatthias Ringwald {
639*1664436fSMatthias Ringwald LookUpChar = fonts_lookup[(uint8_t)String[i]];
640*1664436fSMatthias Ringwald
641*1664436fSMatthias Ringwald for (j=0;j < FONT_HEIGHT ;j++)
642*1664436fSMatthias Ringwald {
643*1664436fSMatthias Ringwald Address = ActualAddress + j*0x20;
644*1664436fSMatthias Ringwald temp = Address >> 5;
645*1664436fSMatthias Ringwald temp += (temp <<4);
646*1664436fSMatthias Ringwald
647*1664436fSMatthias Ringwald LCD_MEM_Add = temp + (Address & 0x1F);
648*1664436fSMatthias Ringwald
649*1664436fSMatthias Ringwald BlockValue = LCD_MEM[ LCD_MEM_Add ];
650*1664436fSMatthias Ringwald
651*1664436fSMatthias Ringwald #if 0
652*1664436fSMatthias Ringwald // work around a mspgcc bug - fixed in LTS but not in 11.10 yet
653*1664436fSMatthias Ringwald if (TextStyle & INVERT_TEXT)
654*1664436fSMatthias Ringwald if (TextStyle & OVERWRITE_TEXT)
655*1664436fSMatthias Ringwald BlockValue = 0xFFFF - fonts[LookUpChar*13+j];
656*1664436fSMatthias Ringwald else
657*1664436fSMatthias Ringwald BlockValue |= 0xFFFF - fonts[LookUpChar*13+j];
658*1664436fSMatthias Ringwald
659*1664436fSMatthias Ringwald else
660*1664436fSMatthias Ringwald if (TextStyle & OVERWRITE_TEXT)
661*1664436fSMatthias Ringwald BlockValue = fonts[LookUpChar*(FONT_HEIGHT+1) +j];
662*1664436fSMatthias Ringwald else
663*1664436fSMatthias Ringwald BlockValue |= fonts[LookUpChar*(FONT_HEIGHT+1) +j];
664*1664436fSMatthias Ringwald #else
665*1664436fSMatthias Ringwald int offset = j;
666*1664436fSMatthias Ringwald int counter;
667*1664436fSMatthias Ringwald for (counter = 0 ; counter < LookUpChar ; counter++){
668*1664436fSMatthias Ringwald offset = offset + FONT_HEIGHT + 1;
669*1664436fSMatthias Ringwald }
670*1664436fSMatthias Ringwald BlockValue |= fonts[offset];
671*1664436fSMatthias Ringwald #endif
672*1664436fSMatthias Ringwald halLcdDrawBlock( Address, BlockValue);
673*1664436fSMatthias Ringwald }
674*1664436fSMatthias Ringwald
675*1664436fSMatthias Ringwald Counter++;
676*1664436fSMatthias Ringwald if (Counter == 17)
677*1664436fSMatthias Ringwald {
678*1664436fSMatthias Ringwald Counter = 0;
679*1664436fSMatthias Ringwald ActualAddress += 0x20*FONT_HEIGHT - 16;
680*1664436fSMatthias Ringwald if (ActualAddress > LCD_Last_Pixel-0x20*FONT_HEIGHT )
681*1664436fSMatthias Ringwald ActualAddress = 0;
682*1664436fSMatthias Ringwald }
683*1664436fSMatthias Ringwald else
684*1664436fSMatthias Ringwald ActualAddress++;
685*1664436fSMatthias Ringwald i++;
686*1664436fSMatthias Ringwald }
687*1664436fSMatthias Ringwald halLcdSetAddress(ActualAddress);
688*1664436fSMatthias Ringwald
689*1664436fSMatthias Ringwald }
690*1664436fSMatthias Ringwald
691*1664436fSMatthias Ringwald
692*1664436fSMatthias Ringwald /************************************************************************
693*1664436fSMatthias Ringwald * @brief Displays the string to the LCD starting at (x,y) location.
694*1664436fSMatthias Ringwald *
695*1664436fSMatthias Ringwald * Writes all the data to LCD_MEM first, then updates all corresponding
696*1664436fSMatthias Ringwald * LCD CGRAM locations at once, in a continuous fashion.
697*1664436fSMatthias Ringwald *
698*1664436fSMatthias Ringwald * @param String[] String to be displayed on LCD
699*1664436fSMatthias Ringwald *
700*1664436fSMatthias Ringwald * @param x x-coordinate of the write location on the LCD
701*1664436fSMatthias Ringwald *
702*1664436fSMatthias Ringwald * @param y y-coordinate of the write location on the LCD
703*1664436fSMatthias Ringwald *
704*1664436fSMatthias Ringwald * @param TextStyle Value that specifies whether the string is to be
705*1664436fSMatthias Ringwald * inverted or overwritten.
706*1664436fSMatthias Ringwald * - Invert = 0x01
707*1664436fSMatthias Ringwald * - Overwrite = 0x04
708*1664436fSMatthias Ringwald *************************************************************************/
halLcdPrintXY(char String[],int x,int y,unsigned char TextStyle)709*1664436fSMatthias Ringwald void halLcdPrintXY( char String[], int x, int y, unsigned char TextStyle)
710*1664436fSMatthias Ringwald {
711*1664436fSMatthias Ringwald //Each line increments by 0x20
712*1664436fSMatthias Ringwald halLcdSetAddress( (y << 5) + (x >> 3)) ; //Narrow down to 8 possible pixels
713*1664436fSMatthias Ringwald halLcdPrint(String, TextStyle);
714*1664436fSMatthias Ringwald }
715*1664436fSMatthias Ringwald
716*1664436fSMatthias Ringwald /************************************************************************
717*1664436fSMatthias Ringwald * @brief Displays a string on the LCD on the specified line.
718*1664436fSMatthias Ringwald *
719*1664436fSMatthias Ringwald * @param String[] The string to be displayed on LCD.
720*1664436fSMatthias Ringwald *
721*1664436fSMatthias Ringwald * @param Line The line on the LCD on which to print the string.
722*1664436fSMatthias Ringwald *
723*1664436fSMatthias Ringwald * @param TextStyle Value that specifies whether the string is to be
724*1664436fSMatthias Ringwald * inverted or overwritten.
725*1664436fSMatthias Ringwald * - Invert = 0x01
726*1664436fSMatthias Ringwald * - Overwrite = 0x04
727*1664436fSMatthias Ringwald *
728*1664436fSMatthias Ringwald * @return none
729*1664436fSMatthias Ringwald *************************************************************************/
halLcdPrintLine(char String[],unsigned char Line,unsigned char TextStyle)730*1664436fSMatthias Ringwald void halLcdPrintLine(char String[], unsigned char Line, unsigned char TextStyle)
731*1664436fSMatthias Ringwald {
732*1664436fSMatthias Ringwald int temp;
733*1664436fSMatthias Ringwald temp = Line * FONT_HEIGHT ;
734*1664436fSMatthias Ringwald halLcdSetAddress( temp << 5 ) ; // 0x20 = 2^5
735*1664436fSMatthias Ringwald halLcdPrint(String, TextStyle);
736*1664436fSMatthias Ringwald }
737*1664436fSMatthias Ringwald
738*1664436fSMatthias Ringwald /************************************************************************
739*1664436fSMatthias Ringwald * @brief Prints a string beginning on a given line and column.
740*1664436fSMatthias Ringwald *
741*1664436fSMatthias Ringwald * @param String[] The string to be displayed on LCD.
742*1664436fSMatthias Ringwald *
743*1664436fSMatthias Ringwald * @param Line The line on which to print the string of text
744*1664436fSMatthias Ringwald *
745*1664436fSMatthias Ringwald * @param Col The column on which to print the string of text
746*1664436fSMatthias Ringwald *
747*1664436fSMatthias Ringwald * @param TextStyle Value that specifies whether the string is to be
748*1664436fSMatthias Ringwald * inverted or overwritten.
749*1664436fSMatthias Ringwald * - Invert = 0x01
750*1664436fSMatthias Ringwald * - Overwrite = 0x04
751*1664436fSMatthias Ringwald *
752*1664436fSMatthias Ringwald * @return none
753*1664436fSMatthias Ringwald *************************************************************************/
halLcdPrintLineCol(char String[],unsigned char Line,unsigned char Col,unsigned char TextStyle)754*1664436fSMatthias Ringwald void halLcdPrintLineCol(char String[], unsigned char Line, unsigned char Col,
755*1664436fSMatthias Ringwald unsigned char TextStyle)
756*1664436fSMatthias Ringwald {
757*1664436fSMatthias Ringwald int temp;
758*1664436fSMatthias Ringwald
759*1664436fSMatthias Ringwald temp = Line * FONT_HEIGHT;
760*1664436fSMatthias Ringwald temp <<= 5;
761*1664436fSMatthias Ringwald temp += Col;
762*1664436fSMatthias Ringwald
763*1664436fSMatthias Ringwald halLcdSetAddress( temp ) ; // 0x20 = 2^5
764*1664436fSMatthias Ringwald halLcdPrint(String, TextStyle);
765*1664436fSMatthias Ringwald }
766*1664436fSMatthias Ringwald
767*1664436fSMatthias Ringwald
768*1664436fSMatthias Ringwald /************************************************************************
769*1664436fSMatthias Ringwald * @brief Draws a horizontral line from (x1,y) to (x2,y) of GrayScale level
770*1664436fSMatthias Ringwald *
771*1664436fSMatthias Ringwald * @param x1 x-coordinate of the first point
772*1664436fSMatthias Ringwald *
773*1664436fSMatthias Ringwald * @param x2 x-coordinate of the second point
774*1664436fSMatthias Ringwald *
775*1664436fSMatthias Ringwald * @param y y-coordinate of both points
776*1664436fSMatthias Ringwald *
777*1664436fSMatthias Ringwald * @param GrayScale Grayscale level of the horizontal line
778*1664436fSMatthias Ringwald *
779*1664436fSMatthias Ringwald * @return none
780*1664436fSMatthias Ringwald *************************************************************************/
halLcdHLine(int x1,int x2,int y,unsigned char GrayScale)781*1664436fSMatthias Ringwald void halLcdHLine( int x1, int x2, int y, unsigned char GrayScale)
782*1664436fSMatthias Ringwald {
783*1664436fSMatthias Ringwald int x_dir, x;
784*1664436fSMatthias Ringwald if ( x1 < x2 )
785*1664436fSMatthias Ringwald x_dir = 1;
786*1664436fSMatthias Ringwald else
787*1664436fSMatthias Ringwald x_dir = -1;
788*1664436fSMatthias Ringwald x = x1;
789*1664436fSMatthias Ringwald while (x != x2)
790*1664436fSMatthias Ringwald {
791*1664436fSMatthias Ringwald halLcdPixel( x,y, GrayScale);
792*1664436fSMatthias Ringwald x += x_dir;
793*1664436fSMatthias Ringwald }
794*1664436fSMatthias Ringwald }
795*1664436fSMatthias Ringwald
796*1664436fSMatthias Ringwald /************************************************************************
797*1664436fSMatthias Ringwald * @brief Draws a vertical line from (x,y1) to (x,y2) of GrayScale level
798*1664436fSMatthias Ringwald *
799*1664436fSMatthias Ringwald * @param x x-coordinate of both points
800*1664436fSMatthias Ringwald *
801*1664436fSMatthias Ringwald * @param y1 y-coordinate of the first point
802*1664436fSMatthias Ringwald *
803*1664436fSMatthias Ringwald * @param y2 y-coordinate of the second point
804*1664436fSMatthias Ringwald *
805*1664436fSMatthias Ringwald * @param GrayScale GrayScale level of the vertical line
806*1664436fSMatthias Ringwald *
807*1664436fSMatthias Ringwald * @return none
808*1664436fSMatthias Ringwald *************************************************************************/
halLcdVLine(int x,int y1,int y2,unsigned char GrayScale)809*1664436fSMatthias Ringwald void halLcdVLine( int x, int y1, int y2, unsigned char GrayScale)
810*1664436fSMatthias Ringwald {
811*1664436fSMatthias Ringwald int y_dir, y;
812*1664436fSMatthias Ringwald if ( y1 < y2 )
813*1664436fSMatthias Ringwald y_dir = 1;
814*1664436fSMatthias Ringwald else
815*1664436fSMatthias Ringwald y_dir = -1;
816*1664436fSMatthias Ringwald y = y1;
817*1664436fSMatthias Ringwald while (y != y2)
818*1664436fSMatthias Ringwald {
819*1664436fSMatthias Ringwald halLcdPixel( x,y, GrayScale);
820*1664436fSMatthias Ringwald y += y_dir;
821*1664436fSMatthias Ringwald }
822*1664436fSMatthias Ringwald }
823*1664436fSMatthias Ringwald
824*1664436fSMatthias Ringwald /************************************************************************
825*1664436fSMatthias Ringwald * @brief Draws a line from (x1,y1) to (x2,y2) of GrayScale level.
826*1664436fSMatthias Ringwald *
827*1664436fSMatthias Ringwald * Uses Bresenham's line algorithm.
828*1664436fSMatthias Ringwald *
829*1664436fSMatthias Ringwald * @param x1 x-coordinate of the first point
830*1664436fSMatthias Ringwald *
831*1664436fSMatthias Ringwald * @param y1 y-coordinate of the first point
832*1664436fSMatthias Ringwald *
833*1664436fSMatthias Ringwald * @param x2 x-coordinate of the second point
834*1664436fSMatthias Ringwald *
835*1664436fSMatthias Ringwald * @param y2 y-coordinate of the second point
836*1664436fSMatthias Ringwald *
837*1664436fSMatthias Ringwald * @param GrayScale Grayscale level of the line
838*1664436fSMatthias Ringwald *
839*1664436fSMatthias Ringwald * @return none
840*1664436fSMatthias Ringwald *************************************************************************/
halLcdLine(int x1,int y1,int x2,int y2,unsigned char GrayScale)841*1664436fSMatthias Ringwald void halLcdLine( int x1, int y1, int x2, int y2, unsigned char GrayScale)
842*1664436fSMatthias Ringwald {
843*1664436fSMatthias Ringwald int x, y, deltay, deltax, d;
844*1664436fSMatthias Ringwald int x_dir, y_dir;
845*1664436fSMatthias Ringwald
846*1664436fSMatthias Ringwald if ( x1 == x2 )
847*1664436fSMatthias Ringwald halLcdVLine( x1, y1, y2, GrayScale );
848*1664436fSMatthias Ringwald else
849*1664436fSMatthias Ringwald {
850*1664436fSMatthias Ringwald if ( y1 == y2 )
851*1664436fSMatthias Ringwald halLcdHLine( x1, x2, y1, GrayScale );
852*1664436fSMatthias Ringwald else // a diagonal line
853*1664436fSMatthias Ringwald {
854*1664436fSMatthias Ringwald if (x1 > x2)
855*1664436fSMatthias Ringwald x_dir = -1;
856*1664436fSMatthias Ringwald else x_dir = 1;
857*1664436fSMatthias Ringwald if (y1 > y2)
858*1664436fSMatthias Ringwald y_dir = -1;
859*1664436fSMatthias Ringwald else y_dir = 1;
860*1664436fSMatthias Ringwald
861*1664436fSMatthias Ringwald x = x1;
862*1664436fSMatthias Ringwald y = y1;
863*1664436fSMatthias Ringwald deltay = ABS(y2 - y1);
864*1664436fSMatthias Ringwald deltax = ABS(x2 - x1);
865*1664436fSMatthias Ringwald
866*1664436fSMatthias Ringwald if (deltax >= deltay)
867*1664436fSMatthias Ringwald {
868*1664436fSMatthias Ringwald d = (deltay << 1) - deltax;
869*1664436fSMatthias Ringwald while (x != x2)
870*1664436fSMatthias Ringwald {
871*1664436fSMatthias Ringwald halLcdPixel(x, y, GrayScale);
872*1664436fSMatthias Ringwald if ( d < 0 )
873*1664436fSMatthias Ringwald d += (deltay << 1);
874*1664436fSMatthias Ringwald else
875*1664436fSMatthias Ringwald {
876*1664436fSMatthias Ringwald d += ((deltay - deltax) << 1);
877*1664436fSMatthias Ringwald y += y_dir;
878*1664436fSMatthias Ringwald }
879*1664436fSMatthias Ringwald x += x_dir;
880*1664436fSMatthias Ringwald }
881*1664436fSMatthias Ringwald }
882*1664436fSMatthias Ringwald else
883*1664436fSMatthias Ringwald {
884*1664436fSMatthias Ringwald d = (deltax << 1) - deltay;
885*1664436fSMatthias Ringwald while (y != y2)
886*1664436fSMatthias Ringwald {
887*1664436fSMatthias Ringwald halLcdPixel(x, y, GrayScale);
888*1664436fSMatthias Ringwald if ( d < 0 )
889*1664436fSMatthias Ringwald d += (deltax << 1);
890*1664436fSMatthias Ringwald else
891*1664436fSMatthias Ringwald {
892*1664436fSMatthias Ringwald d += ((deltax - deltay) << 1);
893*1664436fSMatthias Ringwald x += x_dir;
894*1664436fSMatthias Ringwald }
895*1664436fSMatthias Ringwald y += y_dir;
896*1664436fSMatthias Ringwald }
897*1664436fSMatthias Ringwald }
898*1664436fSMatthias Ringwald }
899*1664436fSMatthias Ringwald }
900*1664436fSMatthias Ringwald }
901*1664436fSMatthias Ringwald
902*1664436fSMatthias Ringwald
903*1664436fSMatthias Ringwald /************************************************************************
904*1664436fSMatthias Ringwald * @brief Draw a circle of Radius with center at (x,y) of GrayScale level.
905*1664436fSMatthias Ringwald *
906*1664436fSMatthias Ringwald * Uses Bresenham's circle algorithm
907*1664436fSMatthias Ringwald *
908*1664436fSMatthias Ringwald * @param x x-coordinate of the circle's center point
909*1664436fSMatthias Ringwald *
910*1664436fSMatthias Ringwald * @param y y-coordinate of the circle's center point
911*1664436fSMatthias Ringwald *
912*1664436fSMatthias Ringwald * @param Radius Radius of the circle
913*1664436fSMatthias Ringwald *
914*1664436fSMatthias Ringwald * @param GrayScale Grayscale level of the circle
915*1664436fSMatthias Ringwald *************************************************************************/
halLcdCircle(int x,int y,int Radius,int GrayScale)916*1664436fSMatthias Ringwald void halLcdCircle(int x, int y, int Radius, int GrayScale)
917*1664436fSMatthias Ringwald {
918*1664436fSMatthias Ringwald int xx, yy, ddF_x, ddF_y, f;
919*1664436fSMatthias Ringwald
920*1664436fSMatthias Ringwald ddF_x = 0;
921*1664436fSMatthias Ringwald ddF_y = -(2 * Radius);
922*1664436fSMatthias Ringwald f = 1 - Radius;
923*1664436fSMatthias Ringwald
924*1664436fSMatthias Ringwald xx = 0;
925*1664436fSMatthias Ringwald yy = Radius;
926*1664436fSMatthias Ringwald halLcdPixel(x + xx, y + yy, GrayScale);
927*1664436fSMatthias Ringwald halLcdPixel(x + xx, y - yy, GrayScale);
928*1664436fSMatthias Ringwald halLcdPixel(x - xx, y + yy, GrayScale);
929*1664436fSMatthias Ringwald halLcdPixel(x - xx, y - yy, GrayScale);
930*1664436fSMatthias Ringwald halLcdPixel(x + yy, y + xx, GrayScale);
931*1664436fSMatthias Ringwald halLcdPixel(x + yy, y - xx, GrayScale);
932*1664436fSMatthias Ringwald halLcdPixel(x - yy, y + xx, GrayScale);
933*1664436fSMatthias Ringwald halLcdPixel(x - yy, y - xx, GrayScale);
934*1664436fSMatthias Ringwald while (xx < yy)
935*1664436fSMatthias Ringwald {
936*1664436fSMatthias Ringwald if (f >= 0)
937*1664436fSMatthias Ringwald {
938*1664436fSMatthias Ringwald yy--;
939*1664436fSMatthias Ringwald ddF_y += 2;
940*1664436fSMatthias Ringwald f += ddF_y;
941*1664436fSMatthias Ringwald }
942*1664436fSMatthias Ringwald xx++;
943*1664436fSMatthias Ringwald ddF_x += 2;
944*1664436fSMatthias Ringwald f += ddF_x + 1;
945*1664436fSMatthias Ringwald halLcdPixel(x + xx, y + yy, GrayScale);
946*1664436fSMatthias Ringwald halLcdPixel(x + xx, y - yy, GrayScale);
947*1664436fSMatthias Ringwald halLcdPixel(x - xx, y + yy, GrayScale);
948*1664436fSMatthias Ringwald halLcdPixel(x - xx, y - yy, GrayScale);
949*1664436fSMatthias Ringwald halLcdPixel(x + yy, y + xx, GrayScale);
950*1664436fSMatthias Ringwald halLcdPixel(x + yy, y - xx, GrayScale);
951*1664436fSMatthias Ringwald halLcdPixel(x - yy, y + xx, GrayScale);
952*1664436fSMatthias Ringwald halLcdPixel(x - yy, y - xx, GrayScale);
953*1664436fSMatthias Ringwald }
954*1664436fSMatthias Ringwald }
955*1664436fSMatthias Ringwald
956*1664436fSMatthias Ringwald /************************************************************************
957*1664436fSMatthias Ringwald * @brief Scrolls a single row of pixels one column to the left.
958*1664436fSMatthias Ringwald *
959*1664436fSMatthias Ringwald * The column that is scrolled out of the left side of the LCD will be
960*1664436fSMatthias Ringwald * displayed the right side of the LCD.
961*1664436fSMatthias Ringwald *
962*1664436fSMatthias Ringwald * @param y The row of pixels to scroll. y = 0 is at the top-left
963*1664436fSMatthias Ringwald * corner of the LCD.
964*1664436fSMatthias Ringwald *
965*1664436fSMatthias Ringwald * @return none
966*1664436fSMatthias Ringwald *************************************************************************/
halLcdScrollRow(int y)967*1664436fSMatthias Ringwald void halLcdScrollRow(int y)
968*1664436fSMatthias Ringwald {
969*1664436fSMatthias Ringwald int i, Address, LcdTableAddressTemp;
970*1664436fSMatthias Ringwald unsigned int temp;
971*1664436fSMatthias Ringwald
972*1664436fSMatthias Ringwald Address = y << 5;
973*1664436fSMatthias Ringwald
974*1664436fSMatthias Ringwald halLcdSetAddress( Address );
975*1664436fSMatthias Ringwald
976*1664436fSMatthias Ringwald //Multiplied by (1+16) and added by the offset
977*1664436fSMatthias Ringwald LcdTableAddressTemp = y + (y << 4);
978*1664436fSMatthias Ringwald temp = ((LCD_MEM[LcdTableAddressTemp] & 0x0003) <<14);
979*1664436fSMatthias Ringwald
980*1664436fSMatthias Ringwald for (i = 0; i < 0x10; i++)
981*1664436fSMatthias Ringwald halLcdDrawCurrentBlock( ( (LCD_MEM[LcdTableAddressTemp+i] & 0xFFFC ) >> 2 ) \
982*1664436fSMatthias Ringwald + ((LCD_MEM[LcdTableAddressTemp+i+1] & 0x0003) << 14 ));
983*1664436fSMatthias Ringwald
984*1664436fSMatthias Ringwald halLcdDrawCurrentBlock( (( LCD_MEM[LcdTableAddressTemp + 0x10] & 0xFFFC ) >> 2) + temp);
985*1664436fSMatthias Ringwald }
986*1664436fSMatthias Ringwald
987*1664436fSMatthias Ringwald /************************************************************************
988*1664436fSMatthias Ringwald * @brief Scrolls multiple rows of pixels, yStart to yEnd,
989*1664436fSMatthias Ringwald * one column to the left.
990*1664436fSMatthias Ringwald *
991*1664436fSMatthias Ringwald * The column that is scrolled out of the left side of the LCD will be
992*1664436fSMatthias Ringwald * displayed the right side of the LCD. y = 0 is at the top-left of the
993*1664436fSMatthias Ringwald * LCD screen.
994*1664436fSMatthias Ringwald *
995*1664436fSMatthias Ringwald * @param yStart The beginning row to be scrolled
996*1664436fSMatthias Ringwald *
997*1664436fSMatthias Ringwald * @param yEnd The last row to be scrolled
998*1664436fSMatthias Ringwald *
999*1664436fSMatthias Ringwald * @return none
1000*1664436fSMatthias Ringwald *************************************************************************/
halLcdHScroll(int yStart,int yEnd)1001*1664436fSMatthias Ringwald void halLcdHScroll(int yStart, int yEnd)
1002*1664436fSMatthias Ringwald {
1003*1664436fSMatthias Ringwald int i ;
1004*1664436fSMatthias Ringwald
1005*1664436fSMatthias Ringwald for (i = yStart; i < yEnd+1; i++)
1006*1664436fSMatthias Ringwald halLcdScrollRow(i);
1007*1664436fSMatthias Ringwald }
1008*1664436fSMatthias Ringwald
1009*1664436fSMatthias Ringwald /************************************************************************
1010*1664436fSMatthias Ringwald * @brief Scrolls a line of text one column to the left.
1011*1664436fSMatthias Ringwald *
1012*1664436fSMatthias Ringwald * @param Line The line of text to be scrolled.
1013*1664436fSMatthias Ringwald *
1014*1664436fSMatthias Ringwald * @return none
1015*1664436fSMatthias Ringwald *************************************************************************/
halLcdScrollLine(int Line)1016*1664436fSMatthias Ringwald void halLcdScrollLine(int Line)
1017*1664436fSMatthias Ringwald {
1018*1664436fSMatthias Ringwald int i, Row ;
1019*1664436fSMatthias Ringwald
1020*1664436fSMatthias Ringwald Row = Line * FONT_HEIGHT;
1021*1664436fSMatthias Ringwald
1022*1664436fSMatthias Ringwald for (i = Row; i < Row + FONT_HEIGHT ; i++)
1023*1664436fSMatthias Ringwald halLcdScrollRow(i);
1024*1664436fSMatthias Ringwald }
1025