LPCOpen Platform for LPC112X microcontrollers  112X
LPCOpen Platform for the NXP LPC112X family of Microcontrollers
lcd_st7565s.c
Go to the documentation of this file.
1 /*
2  * @brief LPCXpresso Shield LCD functions
3  *
4  * @note
5  * Copyright(C) NXP Semiconductors, 2013
6  * All rights reserved.
7  *
8  * @par
9  * Software that is described herein is for illustrative purposes only
10  * which provides customers with programming information regarding the
11  * LPC products. This software is supplied "AS IS" without any warranties of
12  * any kind, and NXP Semiconductors and its licensor disclaim any and
13  * all warranties, express or implied, including all implied warranties of
14  * merchantability, fitness for a particular purpose and non-infringement of
15  * intellectual property rights. NXP Semiconductors assumes no responsibility
16  * or liability for the use of the software, conveys no license or rights under any
17  * patent, copyright, mask work right, or any other intellectual property rights in
18  * or to any products. NXP Semiconductors reserves the right to make changes
19  * in the software without notification. NXP Semiconductors also makes no
20  * representation or warranty that such application will be suitable for the
21  * specified use without further testing or modification.
22  *
23  * @par
24  * Permission to use, copy, modify, and distribute this software and its
25  * documentation is hereby granted, under NXP Semiconductors' and its
26  * licensor's relevant copyrights in the software, without fee, provided that it
27  * is used in conjunction with NXP Semiconductors microcontrollers. This
28  * copyright, permission, and disclaimer notice must appear in all copies of
29  * this code.
30  */
31 
32 #include <stdlib.h>
33 #include "board.h"
34 #include "lcd_st7565s.h"
35 
36 /*****************************************************************************
37  * Private types/enumerations/variables
38  ****************************************************************************/
39 
40 #ifndef LCD_FLIP_Y
41 #define LCD_FLIP_Y 1 /* If 0 Mirrors Y direction */
42 #endif
43 
44 /* Font data structure */
45 static struct {
46  int fcolor;
47  int bgcolor;
48  int spacing;
49  int fwidth;
50  const FONT_T *font;
51 } cfont, *cf = &cfont;
52 
53 static const uint8_t lcd_init_cmd[] = {
54  0xA2, /* Set LCD Bias to 1/9 */
55  0xA0, /* Set ADC Mode [NORMAL] */
56  0xC0 | (LCD_FLIP_Y << 3), /* Set SHL mode */
57  0x40, /* Set Start line address as 0 */
58  0x2C,
59  0x2E,
60  0x2F,
61  0x25,
62  0x81,
63  0x20,
64  0xAF, /* Turn LCD ON */
65  0xB0,
66  0x10,
67  0x04,
68 };
69 
70 #ifdef LCD_ORIENT_PORTRAIT
71 static uint8_t fbuffer[LCD_X_RES >> 3][LCD_Y_RES];
72 #else
73 static uint8_t fbuffer[LCD_Y_RES >> 3][LCD_X_RES];
74 #endif
75 
76 /*****************************************************************************
77  * Public types/enumerations/variables
78  ****************************************************************************/
79 
80 /*****************************************************************************
81  * Private functions
82  ****************************************************************************/
83 
84 /* Write a command to LCD Module */
85 static void LCD_WriteCmd(const uint8_t *cmd, uint16_t size)
86 {
87  Chip_GPIO_SetPinOutLow(LPC_GPIO_PORT, LCD_CMD_GPIO_PORT, LCD_CMD_GPIO_PIN);
88  Board_LCD_WriteData(cmd, size);
89  Chip_GPIO_SetPinOutHigh(LPC_GPIO_PORT, LCD_CMD_GPIO_PORT, LCD_CMD_GPIO_PIN);
90 }
91 
92 /* Set column address */
93 static void LCD_SetRAMAddr(uint8_t pgAddr, uint8_t colAddr)
94 {
95  uint8_t cmd[3];
96  cmd[0] = 0xB0 | pgAddr;
97  cmd[1] = colAddr & 0x0F; /* Lower addr */
98  cmd[2] = 0x10 | (colAddr >> 4); /* Upper addr */
99  LCD_WriteCmd(cmd, sizeof(cmd));
100 }
101 
102 /* Get the width of a given char index (in pixels) */
103 static int LCD_GetCharWidth(int index)
104 {
105  if (cf->font->font_width_table) {
106  return cf->font->font_width_table[index];
107  }
108  else {
109  return cf->fwidth;
110  }
111 }
112 
113 /*****************************************************************************
114  * Public functions
115  ****************************************************************************/
116 
117 /* Initialize and turn on the LCD */
118 void LCD_Init(void)
119 {
120  int i;
121 
122  /* Initialize LCD and turn it On */
123  for (i = 0; i < sizeof(lcd_init_cmd); i++) {
124  LCD_WriteCmd(&lcd_init_cmd[i], 1);
125  if ((lcd_init_cmd[i] >> 3) == 5) {
126  volatile uint32_t dly = SystemCoreClock / 100;
127  while (dly --);
128  }
129  }
130  LCD_Refresh(0, 0, LCD_X_RES - 1, LCD_Y_RES - 1);
131 }
132 
133 /* Refresh the LCD frame buffer content to device */
134 void LCD_Refresh(int left, int top, int right, int bottom)
135 {
136  int pg;
137 
138  /* Sanity check boundaries */
139  if (right >= LCD_X_RES) {
140  right = LCD_X_RES - 1;
141  }
142 
143  if (bottom >= LCD_Y_RES) {
144  bottom = LCD_Y_RES - 1;
145  }
146 
147 #ifdef LCD_ORIENT_PORTRAIT
148  pg = left;
149  left = top;
150  top = LCD_X_RES - right - 1;
151  right = bottom;
152  bottom = LCD_X_RES - pg - 1;
153 #endif
154  for (pg = top / 8; pg <= bottom / 8; pg ++) {
155  LCD_SetRAMAddr(pg, left);
156  Board_LCD_WriteData(&fbuffer[pg][left], right - left + 1);
157  }
158 }
159 
160 /* Sets a pixel in display RAM */
161 void LCD_SetPixel(int x, int y, int col)
162 {
163  if (x > LCD_X_RES || y > LCD_Y_RES)
164  return;
165 #ifdef LCD_ORIENT_PORTRAIT
166  if (1) {
167  int t = x;
168  x = y;
169  y = LCD_X_RES - t - 1;
170  }
171 #endif
172  if (col)
173  fbuffer[y/8][x] |= 1 << (y & 7);
174  else
175  fbuffer[y/8][x] &= ~(1 << (y & 7));
176 }
177 
178 /* Sets a pixel in the Display device */
179 void LCD_PutPixel(int x, int y, int col)
180 {
181  LCD_SetPixel(x, y, col);
182  LCD_Refresh(x, y, x, y);
183 }
184 
185 /* Draw a rectangle with given coordinates and color */
186 void LCD_DrawRect(int left, int top, int right, int bottom, int col)
187 {
188  int i;
189 
190  for (i = left; i <= right; i++) {
191  LCD_SetPixel(i, top, col);
192  LCD_SetPixel(i, bottom, col);
193  }
194  for (i = top + 1; i < bottom; i++) {
195  LCD_SetPixel(left, i, col);
196  LCD_SetPixel(right, i, col);
197  }
198  LCD_Refresh(left, top, right, bottom);
199 }
200 
201 /* Draw a rectangle filled with given color */
202 void LCD_FillRect(int left, int top, int right, int bottom, int col)
203 {
204  int i, j;
205  /* TODO: improve this algorithm */
206  for (i = top; i <= bottom; i++) {
207  for (j = left; j <= right; j ++) {
208  LCD_SetPixel(j, i, col);
209  }
210  }
211  LCD_Refresh(left, top, right, bottom);
212 }
213 
214 /* Draws a line using given cordinates */
215 void LCD_DrawLine(int x0, int y0, int x1, int y1, int col)
216 {
217  int dx = abs(x1-x0), sx = x0<x1 ? 1 : -1;
218  int dy = abs(y1-y0), sy = y0<y1 ? 1 : -1;
219  int err = (dx>dy ? dx : -dy)/2, e2;
220 
221  LCD_PutPixel(x0, y0, col);
222  while(x0 != x1 || y0 != y1){
223  e2 = err;
224  if (e2 >-dx) { err -= dy; x0 += sx; }
225  if (e2 < dy) { err += dx; y0 += sy; }
226  LCD_PutPixel(x0, y0, col);
227  }
228 }
229 
230 
231 /* Sets the foreground color of the font */
232 void LCD_SetFontColor(int color)
233 {
234  cf->fcolor = color;
235 }
236 
237 /* Set the background color of the font */
238 void LCD_SetFontBgColor(int color)
239 {
240  cf->bgcolor = color;
241 }
242 
243 /* Set width of the font for fixed width fonts */
244 void LCD_SetFontWidth(int width)
245 {
246  cf->fwidth = width;
247 }
248 
249 /* Sets the current font */
250 void LCD_SetFont(const FONT_T *font)
251 {
252  cf->font = font;
253 }
254 
255 /* Sets the space between two characters */
256 void LCD_SetFontCharSpace(int space)
257 {
258  cf->spacing = space;
259 }
260 
261 /* Prints an ASCII character at a given position */
262 uint32_t LCD_PutCharXY(int xPos, int yPos, int ch)
263 {
264  int w, h, r, c;
265  uint16_t *fp;
266 
267  if (!cf->font) {
268  return xPos | (yPos << 16);
269  }
270  if ((ch < cf->font->first_char) || (ch > cf->font->last_char)) {
271  return xPos | (yPos << 16);
272  }
273  ch -= cf->font->first_char;
274  w = LCD_GetCharWidth(ch) + cf->spacing;
275  h = cf->font->font_height;
276  fp = cf->font->font_table + (ch * h);
277  for (r = 0; r < h; r++, fp++) {
278  uint16_t t = 0x8000;
279  for (c = 0; c < w; c ++, t >>= 1) {
280  LCD_SetPixel(xPos + c, yPos + r, (*fp & t) ? cf->fcolor : cf->bgcolor);
281  }
282  }
283  LCD_Refresh(xPos, yPos, xPos + w - 1, yPos + h - 1);
284  return (xPos + w) | ((yPos + h) << 16);
285 }
286 
287 /* Prints and ASCII string at a given position */
288 void LCD_PutStrXY(int xPos, int yPos, const char *str)
289 {
290  uint32_t xp = xPos;
291  while (str && *str) {
292  xp = LCD_PutCharXY(xp & 0xFFFF, yPos, *str++);
293  }
294 }