]> git.sur5r.net Git - freertos/blob - Demo/CORTEX_STM32L152_IAR/system_and_ST_code/STM32L152_EVAL/stm32l152_eval_lcd.c
Second phase of changing the directory that starts Cortex, with one that starts CORTEX.
[freertos] / Demo / CORTEX_STM32L152_IAR / system_and_ST_code / STM32L152_EVAL / stm32l152_eval_lcd.c
1 /**\r
2   ******************************************************************************\r
3   * @file    stm32l152_eval_lcd.c\r
4   * @author  MCD Application Team\r
5   * @version V4.4.0RC1\r
6   * @date    07/02/2010\r
7   * @brief   This file includes the LCD driver for AM-240320L8TNQW00H (LCD_ILI9320),\r
8   *          AM-240320LDTNQW00H (LCD_SPFD5408B) Liquid Crystal Display Module\r
9   *          of STM32L152-EVAL board.\r
10   ******************************************************************************\r
11   * @copy\r
12   *\r
13   * THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS\r
14   * WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE\r
15   * TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY\r
16   * DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING\r
17   * FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE\r
18   * CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.\r
19   *\r
20   * <h2><center>&copy; COPYRIGHT 2010 STMicroelectronics</center></h2>\r
21   */\r
22 \r
23 /* Includes ------------------------------------------------------------------*/\r
24 #include "stm32l152_eval_lcd.h"\r
25 #include "../Common/fonts.c"\r
26 \r
27 /** @addtogroup Utilities\r
28   * @{\r
29   */\r
30 \r
31 /** @addtogroup STM32_EVAL\r
32   * @{\r
33   */\r
34 \r
35 /** @addtogroup STM32L152_EVAL\r
36   * @{\r
37   */\r
38 \r
39 /** @defgroup STM32L152_EVAL_LCD\r
40   * @brief   This file includes the LCD driver for AM-240320L8TNQW00H (LCD_ILI9320),\r
41   *          AM-240320LDTNQW00H (LCD_SPFD5408B) Liquid Crystal Display Module\r
42   *          of STM32L152-EVAL board.\r
43   * @{\r
44   */\r
45 \r
46 /** @defgroup STM32L152_EVAL_LCD_Private_Types\r
47   * @{\r
48   */\r
49 /**\r
50   * @}\r
51   */\r
52 \r
53 /** @defgroup STM32L152_EVAL_LCD_Private_Defines\r
54   * @{\r
55   */\r
56 #define LCD_ILI9320        0x9320\r
57 #define LCD_SPFD5408       0x5408\r
58 #define START_BYTE         0x70\r
59 #define SET_INDEX          0x00\r
60 #define READ_STATUS        0x01\r
61 #define LCD_WRITE_REG      0x02\r
62 #define LCD_READ_REG       0x03\r
63 #define MAX_POLY_CORNERS   200\r
64 #define POLY_Y(Z)          ((int32_t)((Points + Z)->X))\r
65 #define POLY_X(Z)          ((int32_t)((Points + Z)->Y))\r
66 /**\r
67   * @}\r
68   */\r
69 \r
70 /** @defgroup STM32L152_EVAL_LCD_Private_Macros\r
71   * @{\r
72   */\r
73 #define ABS(X)  ((X) > 0 ? (X) : -(X))\r
74 /**\r
75   * @}\r
76   */\r
77 \r
78 /** @defgroup STM32L152_EVAL_LCD_Private_Variables\r
79   * @{\r
80   */\r
81 static sFONT *LCD_Currentfonts;\r
82 /* Global variables to set the written text color */\r
83 static __IO uint16_t TextColor = 0x0000, BackColor = 0xFFFF;\r
84 static __IO uint32_t LCDType = LCD_SPFD5408;\r
85 /**\r
86   * @}\r
87   */\r
88 \r
89 /** @defgroup STM32L152_EVAL_LCD_Private_Function_Prototypes\r
90   * @{\r
91   */\r
92 #ifndef USE_Delay\r
93 static void delay(__IO uint32_t nCount);\r
94 #endif /* USE_Delay*/\r
95 \r
96 static void PutPixel(int16_t x, int16_t y);\r
97 static void LCD_PolyLineRelativeClosed(pPoint Points, uint16_t PointCount, uint16_t Closed);\r
98 \r
99 /**\r
100   * @}\r
101   */\r
102 \r
103 /** @defgroup STM32L152_EVAL_LCD_Private_Functions\r
104   * @{\r
105   */\r
106 \r
107 /**\r
108   * @brief  DeInitializes the LCD.\r
109   * @param  None\r
110   * @retval None\r
111   */\r
112 void STM32L152_LCD_DeInit(void)\r
113 {\r
114   GPIO_InitTypeDef GPIO_InitStructure;\r
115 \r
116   /*!< LCD Display Off */\r
117   LCD_DisplayOff();\r
118 \r
119   /*!< LCD_SPI disable */\r
120   SPI_Cmd(LCD_SPI, DISABLE);\r
121 \r
122   /*!< LCD_SPI DeInit */\r
123   SPI_DeInit(LCD_SPI);\r
124 \r
125   /*!< Disable SPI clock  */\r
126   RCC_APB1PeriphClockCmd(LCD_SPI_CLK, DISABLE);\r
127 \r
128   /* Configure NCS in Output Push-Pull mode */\r
129   GPIO_InitStructure.GPIO_Pin = LCD_NCS_PIN;\r
130   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN;\r
131   GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;\r
132   GPIO_Init(LCD_NCS_GPIO_PORT, &GPIO_InitStructure);\r
133 \r
134   /* Configure SPI pins: SCK, MISO and MOSI */\r
135   GPIO_InitStructure.GPIO_Pin = LCD_SPI_SCK_PIN;\r
136   GPIO_Init(LCD_SPI_SCK_GPIO_PORT, &GPIO_InitStructure);\r
137 \r
138   GPIO_InitStructure.GPIO_Pin = LCD_SPI_MISO_PIN;\r
139   GPIO_Init(LCD_SPI_MISO_GPIO_PORT, &GPIO_InitStructure);\r
140 \r
141   GPIO_InitStructure.GPIO_Pin = LCD_SPI_MOSI_PIN;\r
142   GPIO_Init(LCD_SPI_MOSI_GPIO_PORT, &GPIO_InitStructure);\r
143 }\r
144 \r
145 /**\r
146   * @brief  Setups the LCD.\r
147   * @param  None\r
148   * @retval None\r
149   */\r
150 void LCD_Setup(void)\r
151 {\r
152 /* Configure the LCD Control pins --------------------------------------------*/\r
153   LCD_CtrlLinesConfig();\r
154 \r
155 /* Configure the LCD_SPI interface ----------------------------------------------*/\r
156   LCD_SPIConfig();\r
157 \r
158   if(LCDType == LCD_SPFD5408)\r
159   {\r
160     /* Start Initial Sequence --------------------------------------------------*/\r
161     LCD_WriteReg(LCD_REG_227, 0x3008); /* Set internal timing */\r
162     LCD_WriteReg(LCD_REG_231, 0x0012); /* Set internal timing */\r
163     LCD_WriteReg(LCD_REG_239, 0x1231); /* Set internal timing */\r
164     LCD_WriteReg(LCD_REG_1, 0x0100);   /* Set SS and SM bit */\r
165     LCD_WriteReg(LCD_REG_2, 0x0700);   /* Set 1 line inversion */\r
166     LCD_WriteReg(LCD_REG_3, 0x1030);   /* Set GRAM write direction and BGR=1. */\r
167     LCD_WriteReg(LCD_REG_4, 0x0000);   /* Resize register */\r
168     LCD_WriteReg(LCD_REG_8, 0x0202);   /* Set the back porch and front porch */\r
169     LCD_WriteReg(LCD_REG_9, 0x0000);   /* Set non-display area refresh cycle ISC[3:0] */\r
170     LCD_WriteReg(LCD_REG_10, 0x0000);  /* FMARK function */\r
171     LCD_WriteReg(LCD_REG_12, 0x0000);  /* RGB interface setting */\r
172     LCD_WriteReg(LCD_REG_13, 0x0000);  /* Frame marker Position */\r
173     LCD_WriteReg(LCD_REG_15, 0x0000);  /* RGB interface polarity */\r
174     /* Power On sequence -------------------------------------------------------*/\r
175     LCD_WriteReg(LCD_REG_16, 0x0000);  /* SAP, BT[3:0], AP, DSTB, SLP, STB */\r
176     LCD_WriteReg(LCD_REG_17, 0x0000);  /* DC1[2:0], DC0[2:0], VC[2:0] */\r
177     LCD_WriteReg(LCD_REG_18, 0x0000);  /* VREG1OUT voltage */\r
178     LCD_WriteReg(LCD_REG_19, 0x0000);  /* VDV[4:0] for VCOM amplitude */\r
179     _delay_(20);                /* Dis-charge capacitor power voltage (200ms) */\r
180     LCD_WriteReg(LCD_REG_17, 0x0007);  /* DC1[2:0], DC0[2:0], VC[2:0] */\r
181     _delay_(5);                 /* Delay 50 ms */\r
182     LCD_WriteReg(LCD_REG_16, 0x12B0);  /* SAP, BT[3:0], AP, DSTB, SLP, STB */\r
183     _delay_(5);                  /* Delay 50 ms */\r
184     LCD_WriteReg(LCD_REG_18, 0x01BD);  /* External reference voltage= Vci */\r
185     _delay_(5);                 /* Delay 50 ms */\r
186     LCD_WriteReg(LCD_REG_19, 0x1400);       /* VDV[4:0] for VCOM amplitude */\r
187     LCD_WriteReg(LCD_REG_41, 0x000E);  /* VCM[4:0] for VCOMH */\r
188     _delay_(5);                 /* Delay 50 ms */\r
189     LCD_WriteReg(LCD_REG_32, 0x0000);  /* GRAM horizontal Address */\r
190     LCD_WriteReg(LCD_REG_33, 0x013F);  /* GRAM Vertical Address */\r
191     /* Adjust the Gamma Curve --------------------------------------------------*/\r
192     LCD_WriteReg(LCD_REG_48, 0x0007);\r
193     LCD_WriteReg(LCD_REG_49, 0x0302);\r
194     LCD_WriteReg(LCD_REG_50, 0x0105);\r
195     LCD_WriteReg(LCD_REG_53, 0x0206);\r
196     LCD_WriteReg(LCD_REG_54, 0x0808);\r
197     LCD_WriteReg(LCD_REG_55, 0x0206);\r
198     LCD_WriteReg(LCD_REG_56, 0x0504);\r
199     LCD_WriteReg(LCD_REG_57, 0x0007);\r
200     LCD_WriteReg(LCD_REG_60, 0x0105);\r
201     LCD_WriteReg(LCD_REG_61, 0x0808);\r
202     /* Set GRAM area -----------------------------------------------------------*/\r
203     LCD_WriteReg(LCD_REG_80, 0x0000);  /* Horizontal GRAM Start Address */\r
204     LCD_WriteReg(LCD_REG_81, 0x00EF);  /* Horizontal GRAM End Address */\r
205     LCD_WriteReg(LCD_REG_82, 0x0000);  /* Vertical GRAM Start Address */\r
206     LCD_WriteReg(LCD_REG_83, 0x013F);  /* Vertical GRAM End Address */\r
207     LCD_WriteReg(LCD_REG_96,  0xA700); /* Gate Scan Line */\r
208     LCD_WriteReg(LCD_REG_97,  0x0001); /* NDL,VLE, REV */\r
209     LCD_WriteReg(LCD_REG_106, 0x0000); /* Set scrolling line */\r
210     /* Partial Display Control -------------------------------------------------*/\r
211     LCD_WriteReg(LCD_REG_128, 0x0000);\r
212     LCD_WriteReg(LCD_REG_129, 0x0000);\r
213     LCD_WriteReg(LCD_REG_130, 0x0000);\r
214     LCD_WriteReg(LCD_REG_131, 0x0000);\r
215     LCD_WriteReg(LCD_REG_132, 0x0000);\r
216     LCD_WriteReg(LCD_REG_133, 0x0000);\r
217     /* Panel Control -----------------------------------------------------------*/\r
218     LCD_WriteReg(LCD_REG_144, 0x0010);\r
219     LCD_WriteReg(LCD_REG_146, 0x0000);\r
220     LCD_WriteReg(LCD_REG_147, 0x0003);\r
221     LCD_WriteReg(LCD_REG_149, 0x0110);\r
222     LCD_WriteReg(LCD_REG_151, 0x0000);\r
223     LCD_WriteReg(LCD_REG_152, 0x0000);\r
224     /* Set GRAM write direction and BGR = 1\r
225        I/D=01 (Horizontal : increment, Vertical : decrement)\r
226        AM=1 (address is updated in vertical writing direction) */\r
227     LCD_WriteReg(LCD_REG_3, 0x1018);\r
228     LCD_WriteReg(LCD_REG_7, 0x0112);   /* 262K color and display ON */\r
229   }\r
230   else if(LCDType == LCD_ILI9320)\r
231   {\r
232     _delay_(5); /* Delay 50 ms */\r
233     /* Start Initial Sequence ------------------------------------------------*/\r
234     LCD_WriteReg(LCD_REG_229, 0x8000); /* Set the internal vcore voltage */\r
235     LCD_WriteReg(LCD_REG_0,  0x0001); /* Start internal OSC. */\r
236     LCD_WriteReg(LCD_REG_1,  0x0100); /* set SS and SM bit */\r
237     LCD_WriteReg(LCD_REG_2,  0x0700); /* set 1 line inversion */\r
238     LCD_WriteReg(LCD_REG_3,  0x1030); /* set GRAM write direction and BGR=1. */\r
239     LCD_WriteReg(LCD_REG_4,  0x0000); /* Resize register */\r
240     LCD_WriteReg(LCD_REG_8,  0x0202); /* set the back porch and front porch */\r
241     LCD_WriteReg(LCD_REG_9,  0x0000); /* set non-display area refresh cycle ISC[3:0] */\r
242     LCD_WriteReg(LCD_REG_10, 0x0000); /* FMARK function */\r
243     LCD_WriteReg(LCD_REG_12, 0x0000); /* RGB interface setting */\r
244     LCD_WriteReg(LCD_REG_13, 0x0000); /* Frame marker Position */\r
245     LCD_WriteReg(LCD_REG_15, 0x0000); /* RGB interface polarity */\r
246     /* Power On sequence -----------------------------------------------------*/\r
247     LCD_WriteReg(LCD_REG_16, 0x0000); /* SAP, BT[3:0], AP, DSTB, SLP, STB */\r
248     LCD_WriteReg(LCD_REG_17, 0x0000); /* DC1[2:0], DC0[2:0], VC[2:0] */\r
249     LCD_WriteReg(LCD_REG_18, 0x0000); /* VREG1OUT voltage */\r
250     LCD_WriteReg(LCD_REG_19, 0x0000); /* VDV[4:0] for VCOM amplitude */\r
251     _delay_(20);                      /* Dis-charge capacitor power voltage (200ms) */\r
252     LCD_WriteReg(LCD_REG_16, 0x17B0); /* SAP, BT[3:0], AP, DSTB, SLP, STB */\r
253     LCD_WriteReg(LCD_REG_17, 0x0137); /* DC1[2:0], DC0[2:0], VC[2:0] */\r
254     _delay_(5);                       /* Delay 50 ms */\r
255     LCD_WriteReg(LCD_REG_18, 0x0139); /* VREG1OUT voltage */\r
256     _delay_(5);                       /* Delay 50 ms */\r
257     LCD_WriteReg(LCD_REG_19, 0x1d00); /* VDV[4:0] for VCOM amplitude */\r
258     LCD_WriteReg(LCD_REG_41, 0x0013); /* VCM[4:0] for VCOMH */\r
259     _delay_(5);                       /* Delay 50 ms */\r
260     LCD_WriteReg(LCD_REG_32, 0x0000); /* GRAM horizontal Address */\r
261     LCD_WriteReg(LCD_REG_33, 0x0000); /* GRAM Vertical Address */\r
262     /* Adjust the Gamma Curve ------------------------------------------------*/\r
263     LCD_WriteReg(LCD_REG_48, 0x0006);\r
264     LCD_WriteReg(LCD_REG_49, 0x0101);\r
265     LCD_WriteReg(LCD_REG_50, 0x0003);\r
266     LCD_WriteReg(LCD_REG_53, 0x0106);\r
267     LCD_WriteReg(LCD_REG_54, 0x0b02);\r
268     LCD_WriteReg(LCD_REG_55, 0x0302);\r
269     LCD_WriteReg(LCD_REG_56, 0x0707);\r
270     LCD_WriteReg(LCD_REG_57, 0x0007);\r
271     LCD_WriteReg(LCD_REG_60, 0x0600);\r
272     LCD_WriteReg(LCD_REG_61, 0x020b);\r
273 \r
274     /* Set GRAM area ---------------------------------------------------------*/\r
275     LCD_WriteReg(LCD_REG_80, 0x0000); /* Horizontal GRAM Start Address */\r
276     LCD_WriteReg(LCD_REG_81, 0x00EF); /* Horizontal GRAM End Address */\r
277     LCD_WriteReg(LCD_REG_82, 0x0000); /* Vertical GRAM Start Address */\r
278     LCD_WriteReg(LCD_REG_83, 0x013F); /* Vertical GRAM End Address */\r
279     LCD_WriteReg(LCD_REG_96,  0x2700); /* Gate Scan Line */\r
280     LCD_WriteReg(LCD_REG_97,  0x0001); /* NDL,VLE, REV */\r
281     LCD_WriteReg(LCD_REG_106, 0x0000); /* set scrolling line */\r
282     /* Partial Display Control -----------------------------------------------*/\r
283     LCD_WriteReg(LCD_REG_128, 0x0000);\r
284     LCD_WriteReg(LCD_REG_129, 0x0000);\r
285     LCD_WriteReg(LCD_REG_130, 0x0000);\r
286     LCD_WriteReg(LCD_REG_131, 0x0000);\r
287     LCD_WriteReg(LCD_REG_132, 0x0000);\r
288     LCD_WriteReg(LCD_REG_133, 0x0000);\r
289     /* Panel Control ---------------------------------------------------------*/\r
290     LCD_WriteReg(LCD_REG_144, 0x0010);\r
291     LCD_WriteReg(LCD_REG_146, 0x0000);\r
292     LCD_WriteReg(LCD_REG_147, 0x0003);\r
293     LCD_WriteReg(LCD_REG_149, 0x0110);\r
294     LCD_WriteReg(LCD_REG_151, 0x0000);\r
295     LCD_WriteReg(LCD_REG_152, 0x0000);\r
296     /* Set GRAM write direction and BGR = 1 */\r
297     /* I/D=01 (Horizontal : increment, Vertical : decrement) */\r
298     /* AM=1 (address is updated in vertical writing direction) */\r
299     LCD_WriteReg(LCD_REG_3, 0x1018);\r
300     LCD_WriteReg(LCD_REG_7, 0x0173); /* 262K color and display ON */\r
301   }\r
302 }\r
303 \r
304 \r
305 /**\r
306   * @brief  Initializes the LCD.\r
307   * @param  None\r
308   * @retval None\r
309   */\r
310 void STM32L152_LCD_Init(void)\r
311 {\r
312   /* Setups the LCD */\r
313   LCD_Setup();\r
314 \r
315   /* Try to read new LCD controller ID 0x5408 */\r
316   if (LCD_ReadReg(LCD_REG_0) == LCD_SPFD5408)\r
317   {\r
318     LCDType = LCD_SPFD5408;\r
319   }\r
320   else\r
321   {\r
322     LCDType = LCD_ILI9320;\r
323     /* Setups the LCD */\r
324     LCD_Setup();\r
325   }\r
326 \r
327   LCD_SetFont(&LCD_DEFAULT_FONT);\r
328 }\r
329 \r
330 /**\r
331   * @brief  Sets the LCD Text and Background colors.\r
332   * @param  _TextColor: specifies the Text Color.\r
333   * @param  _BackColor: specifies the Background Color.\r
334   * @retval None\r
335   */\r
336 void LCD_SetColors(__IO uint16_t _TextColor, __IO uint16_t _BackColor)\r
337 {\r
338   TextColor = _TextColor;\r
339   BackColor = _BackColor;\r
340 }\r
341 \r
342 /**\r
343   * @brief  Gets the LCD Text and Background colors.\r
344   * @param  _TextColor: pointer to the variable that will contain the Text\r
345             Color.\r
346   * @param  _BackColor: pointer to the variable that will contain the Background\r
347             Color.\r
348   * @retval None\r
349   */\r
350 void LCD_GetColors(__IO uint16_t *_TextColor, __IO uint16_t *_BackColor)\r
351 {\r
352   *_TextColor = TextColor; *_BackColor = BackColor;\r
353 }\r
354 \r
355 /**\r
356   * @brief  Sets the Text color.\r
357   * @param  Color: specifies the Text color code RGB(5-6-5).\r
358   * @retval None\r
359   */\r
360 void LCD_SetTextColor(__IO uint16_t Color)\r
361 {\r
362   TextColor = Color;\r
363 }\r
364 \r
365 \r
366 /**\r
367   * @brief  Sets the Background color.\r
368   * @param  Color: specifies the Background color code RGB(5-6-5).\r
369   * @retval None\r
370   */\r
371 void LCD_SetBackColor(__IO uint16_t Color)\r
372 {\r
373   BackColor = Color;\r
374 }\r
375 \r
376 /**\r
377   * @brief  Sets the Text Font.\r
378   * @param  fonts: specifies the font to be used.\r
379   * @retval None\r
380   */\r
381 void LCD_SetFont(sFONT *fonts)\r
382 {\r
383   LCD_Currentfonts = fonts;\r
384 }\r
385 \r
386 /**\r
387   * @brief  Gets the Text Font.\r
388   * @param  None.\r
389   * @retval the used font.\r
390   */\r
391 sFONT *LCD_GetFont(void)\r
392 {\r
393   return LCD_Currentfonts;\r
394 }\r
395 \r
396 /**\r
397   * @brief  Clears the selected line.\r
398   * @param  Line: the Line to be cleared.\r
399   *   This parameter can be one of the following values:\r
400   *     @arg Linex: where x can be 0..n\r
401   * @retval None\r
402   */\r
403 void LCD_ClearLine(uint8_t Line)\r
404 {\r
405   uint16_t refcolumn = LCD_PIXEL_WIDTH - 1;\r
406 \r
407   /* Send the string character by character on lCD */\r
408   while (((refcolumn + 1) & 0xFFFF) >= LCD_Currentfonts->Width)\r
409   {\r
410     /* Display one character on LCD */\r
411     LCD_DisplayChar(Line, refcolumn, ' ');\r
412     /* Decrement the column position by 16 */\r
413     refcolumn -= LCD_Currentfonts->Width;\r
414   }\r
415 }\r
416 \r
417 \r
418 /**\r
419   * @brief  Clears the hole LCD.\r
420   * @param  Color: the color of the background.\r
421   * @retval None\r
422   */\r
423 void LCD_Clear(uint16_t Color)\r
424 {\r
425   uint32_t index = 0;\r
426 \r
427   LCD_SetCursor(0x00, 0x013F);\r
428 \r
429   LCD_WriteRAM_Prepare(); /* Prepare to write GRAM */\r
430 \r
431   for(index = 0; index < 76800; index++)\r
432   {\r
433     LCD_WriteRAM(Color);\r
434   }\r
435 \r
436   LCD_CtrlLinesWrite(LCD_NCS_GPIO_PORT, LCD_NCS_PIN, Bit_SET);\r
437 \r
438 }\r
439 \r
440 \r
441 /**\r
442   * @brief  Sets the cursor position.\r
443   * @param  Xpos: specifies the X position.\r
444   * @param  Ypos: specifies the Y position.\r
445   * @retval None\r
446   */\r
447 void LCD_SetCursor(uint8_t Xpos, uint16_t Ypos)\r
448 {\r
449   LCD_WriteReg(LCD_REG_32, Xpos);\r
450   LCD_WriteReg(LCD_REG_33, Ypos);\r
451 }\r
452 \r
453 \r
454 /**\r
455   * @brief  Draws a character on LCD.\r
456   * @param  Xpos: the Line where to display the character shape.\r
457   * @param  Ypos: start column address.\r
458   * @param  c: pointer to the character data.\r
459   * @retval None\r
460   */\r
461 void LCD_DrawChar(uint8_t Xpos, uint16_t Ypos, const uint16_t *c)\r
462 {\r
463   uint32_t index = 0, i = 0;\r
464   uint8_t Xaddress = 0;\r
465 \r
466   Xaddress = Xpos;\r
467 \r
468   LCD_SetCursor(Xaddress, Ypos);\r
469 \r
470   for(index = 0; index < LCD_Currentfonts->Height; index++)\r
471   {\r
472     LCD_WriteRAM_Prepare(); /* Prepare to write GRAM */\r
473 \r
474     for(i = 0; i < LCD_Currentfonts->Width; i++)\r
475     {\r
476       if((((c[index] & ((0x80 << ((LCD_Currentfonts->Width / 12 ) * 8 ) ) >> i)) == 0x00) &&(LCD_Currentfonts->Width <= 12))||\r
477         (((c[index] & (0x1 << i)) == 0x00)&&(LCD_Currentfonts->Width > 12 )))\r
478 \r
479       {\r
480         LCD_WriteRAM(BackColor);\r
481       }\r
482       else\r
483       {\r
484         LCD_WriteRAM(TextColor);\r
485       }\r
486     }\r
487 \r
488     LCD_CtrlLinesWrite(LCD_NCS_GPIO_PORT, LCD_NCS_PIN, Bit_SET);\r
489     Xaddress++;\r
490     LCD_SetCursor(Xaddress, Ypos);\r
491   }\r
492 }\r
493 \r
494 \r
495 /**\r
496   * @brief  Displays one character (16dots width, 24dots height).\r
497   * @param  Line: the Line where to display the character shape .\r
498   *   This parameter can be one of the following values:\r
499   *     @arg Linex: where x can be 0..9\r
500   * @param  Column: start column address.\r
501   * @param  Ascii: character ascii code, must be between 0x20 and 0x7E.\r
502   * @retval None\r
503   */\r
504 void LCD_DisplayChar(uint8_t Line, uint16_t Column, uint8_t Ascii)\r
505 {\r
506   Ascii -= 32;\r
507   LCD_DrawChar(Line, Column, &LCD_Currentfonts->table[Ascii * LCD_Currentfonts->Height]);\r
508 }\r
509 \r
510 \r
511 /**\r
512   * @brief  Displays a maximum of 20 char on the LCD.\r
513   * @param  Line: the Line where to display the character shape .\r
514   *   This parameter can be one of the following values:\r
515   *     @arg Linex: where x can be 0..9\r
516   * @param  *ptr: pointer to string to display on LCD.\r
517   * @retval None\r
518   */\r
519 void LCD_DisplayStringLine(uint8_t Line, uint8_t *ptr)\r
520 {\r
521   uint16_t refcolumn = LCD_PIXEL_WIDTH - 1;\r
522 \r
523   /* Send the string character by character on lCD */\r
524   while ((*ptr != 0) & (((refcolumn + 1) & 0xFFFF) >= LCD_Currentfonts->Width))\r
525   {\r
526     /* Display one character on LCD */\r
527     LCD_DisplayChar(Line, refcolumn, *ptr);\r
528     /* Decrement the column position by 16 */\r
529     refcolumn -= LCD_Currentfonts->Width;\r
530     /* Point on the next character */\r
531     ptr++;\r
532   }\r
533 }\r
534 \r
535 \r
536 /**\r
537   * @brief  Sets a display window\r
538   * @param  Xpos: specifies the X buttom left position.\r
539   * @param  Ypos: specifies the Y buttom left position.\r
540   * @param  Height: display window height.\r
541   * @param  Width: display window width.\r
542   * @retval None\r
543   */\r
544 void LCD_SetDisplayWindow(uint8_t Xpos, uint16_t Ypos, uint8_t Height, uint16_t Width)\r
545 {\r
546   /* Horizontal GRAM Start Address */\r
547   if(Xpos >= Height)\r
548   {\r
549     LCD_WriteReg(LCD_REG_80, (Xpos - Height + 1));\r
550   }\r
551   else\r
552   {\r
553     LCD_WriteReg(LCD_REG_80, 0);\r
554   }\r
555   /* Horizontal GRAM End Address */\r
556   LCD_WriteReg(LCD_REG_81, Xpos);\r
557   /* Vertical GRAM Start Address */\r
558   if(Ypos >= Width)\r
559   {\r
560     LCD_WriteReg(LCD_REG_82, (Ypos - Width + 1));\r
561   }\r
562   else\r
563   {\r
564     LCD_WriteReg(LCD_REG_82, 0);\r
565   }\r
566   /* Vertical GRAM End Address */\r
567   LCD_WriteReg(LCD_REG_83, Ypos);\r
568 \r
569   LCD_SetCursor(Xpos, Ypos);\r
570 }\r
571 \r
572 \r
573 /**\r
574   * @brief  Disables LCD Window mode.\r
575   * @param  None\r
576   * @retval None\r
577   */\r
578 void LCD_WindowModeDisable(void)\r
579 {\r
580   LCD_SetDisplayWindow(239, 0x13F, 240, 320);\r
581   LCD_WriteReg(LCD_REG_3, 0x1018);\r
582 }\r
583 \r
584 /**\r
585   * @brief  Displays a line.\r
586   * @param  Xpos: specifies the X position.\r
587   * @param  Ypos: specifies the Y position.\r
588   * @param  Length: line length.\r
589   * @param  Direction: line direction.\r
590   *   This parameter can be one of the following values: Vertical or Horizontal.\r
591   * @retval None\r
592   */\r
593 void LCD_DrawLine(uint8_t Xpos, uint16_t Ypos, uint16_t Length, uint8_t Direction)\r
594 {\r
595   uint32_t i = 0;\r
596 \r
597   LCD_SetCursor(Xpos, Ypos);\r
598 \r
599   if(Direction == LCD_DIR_HORIZONTAL)\r
600   {\r
601     LCD_WriteRAM_Prepare(); /* Prepare to write GRAM */\r
602 \r
603     for(i = 0; i < Length; i++)\r
604     {\r
605       LCD_WriteRAM(TextColor);\r
606     }\r
607     LCD_CtrlLinesWrite(LCD_NCS_GPIO_PORT, LCD_NCS_PIN, Bit_SET);\r
608   }\r
609   else\r
610   {\r
611     for(i = 0; i < Length; i++)\r
612     {\r
613       LCD_WriteRAMWord(TextColor);\r
614       Xpos++;\r
615       LCD_SetCursor(Xpos, Ypos);\r
616     }\r
617   }\r
618 }\r
619 \r
620 \r
621 /**\r
622   * @brief  Displays a rectangle.\r
623   * @param  Xpos: specifies the X position.\r
624   * @param  Ypos: specifies the Y position.\r
625   * @param  Height: display rectangle height.\r
626   * @param  Width: display rectangle width.\r
627   * @retval None\r
628   */\r
629 void LCD_DrawRect(uint8_t Xpos, uint16_t Ypos, uint8_t Height, uint16_t Width)\r
630 {\r
631   LCD_DrawLine(Xpos, Ypos, Width, LCD_DIR_HORIZONTAL);\r
632   LCD_DrawLine((Xpos + Height), Ypos, Width, LCD_DIR_HORIZONTAL);\r
633 \r
634   LCD_DrawLine(Xpos, Ypos, Height, LCD_DIR_VERTICAL);\r
635   LCD_DrawLine(Xpos, (Ypos - Width + 1), Height, LCD_DIR_VERTICAL);\r
636 }\r
637 \r
638 \r
639 /**\r
640   * @brief  Displays a circle.\r
641   * @param  Xpos: specifies the X position.\r
642   * @param  Ypos: specifies the Y position.\r
643   * @param  Radius\r
644   * @retval None\r
645   */\r
646 void LCD_DrawCircle(uint8_t Xpos, uint16_t Ypos, uint16_t Radius)\r
647 {\r
648   int32_t  D;/* Decision Variable */\r
649   uint32_t  CurX;/* Current X Value */\r
650   uint32_t  CurY;/* Current Y Value */\r
651 \r
652   D = 3 - (Radius << 1);\r
653   CurX = 0;\r
654   CurY = Radius;\r
655 \r
656   while (CurX <= CurY)\r
657   {\r
658     LCD_SetCursor(Xpos + CurX, Ypos + CurY);\r
659     LCD_WriteRAMWord(TextColor);\r
660     LCD_SetCursor(Xpos + CurX, Ypos - CurY);\r
661     LCD_WriteRAMWord(TextColor);\r
662 \r
663     LCD_SetCursor(Xpos - CurX, Ypos + CurY);\r
664     LCD_WriteRAMWord(TextColor);\r
665 \r
666     LCD_SetCursor(Xpos - CurX, Ypos - CurY);\r
667     LCD_WriteRAMWord(TextColor);\r
668 \r
669     LCD_SetCursor(Xpos + CurY, Ypos + CurX);\r
670     LCD_WriteRAMWord(TextColor);\r
671 \r
672     LCD_SetCursor(Xpos + CurY, Ypos - CurX);\r
673     LCD_WriteRAMWord(TextColor);\r
674 \r
675     LCD_SetCursor(Xpos - CurY, Ypos + CurX);\r
676     LCD_WriteRAMWord(TextColor);\r
677 \r
678     LCD_SetCursor(Xpos - CurY, Ypos - CurX);\r
679     LCD_WriteRAMWord(TextColor);\r
680 \r
681     if (D < 0)\r
682     {\r
683       D += (CurX << 2) + 6;\r
684     }\r
685     else\r
686     {\r
687       D += ((CurX - CurY) << 2) + 10;\r
688       CurY--;\r
689     }\r
690     CurX++;\r
691   }\r
692 }\r
693 \r
694 \r
695 /**\r
696   * @brief  Displays a monocolor picture.\r
697   * @param  Pict: pointer to the picture array.\r
698   * @retval None\r
699   */\r
700 void LCD_DrawMonoPict(const uint32_t *Pict)\r
701 {\r
702   uint32_t index = 0, i = 0;\r
703   LCD_SetCursor(0, (LCD_PIXEL_WIDTH - 1));\r
704 \r
705   LCD_WriteRAM_Prepare(); /* Prepare to write GRAM */\r
706 \r
707   for(index = 0; index < 2400; index++)\r
708   {\r
709     for(i = 0; i < 32; i++)\r
710     {\r
711       if((Pict[index] & (1 << i)) == 0x00)\r
712       {\r
713         LCD_WriteRAM(BackColor);\r
714       }\r
715       else\r
716       {\r
717         LCD_WriteRAM(TextColor);\r
718       }\r
719     }\r
720   }\r
721 \r
722   LCD_CtrlLinesWrite(LCD_NCS_GPIO_PORT, LCD_NCS_PIN, Bit_SET);\r
723 }\r
724 \r
725 #ifdef USE_LCD_DrawBMP\r
726 /**\r
727   * @brief  Displays a bitmap picture loaded in the SPI Flash.\r
728   * @param  BmpAddress: Bmp picture address in the SPI Flash.\r
729   * @retval None\r
730   */\r
731 void LCD_DrawBMP(uint32_t BmpAddress)\r
732 {\r
733   uint32_t i = 0, size = 0;\r
734   /* Read bitmap size */\r
735   SPI_FLASH_BufferRead((uint8_t*)&size, BmpAddress + 2, 4);\r
736   /* get bitmap data address offset */\r
737   SPI_FLASH_BufferRead((uint8_t*)&i, BmpAddress + 10, 4);\r
738 \r
739   size = (size - i)/2;\r
740   SPI_FLASH_StartReadSequence(BmpAddress + i);\r
741   /* Disable SPI1  */\r
742   SPI_Cmd(SPI1, DISABLE);\r
743   /* SPI in 16-bit mode */\r
744   SPI_DataSizeConfig(SPI1, SPI_DataSize_16b);\r
745   /* Enable SPI1  */\r
746   SPI_Cmd(SPI1, ENABLE);\r
747 \r
748   if((LCDType == LCD_ILI9320) || (LCDType == LCD_SPFD5408))\r
749   {\r
750     /* Set GRAM write direction and BGR = 1 */\r
751     /* I/D=00 (Horizontal : decrement, Vertical : decrement) */\r
752     /* AM=1 (address is updated in vertical writing direction) */\r
753     LCD_WriteReg(LCD_REG_3, 0x1008);\r
754     LCD_WriteRAM_Prepare(); /* Prepare to write GRAM */\r
755   }\r
756 \r
757   /* Read bitmap data from SPI Flash and send them to LCD */\r
758   for(i = 0; i < size; i++)\r
759   {\r
760     LCD_WriteRAM(__REV16(SPI_FLASH_SendHalfWord(0xA5A5)));\r
761   }\r
762   if((LCDType == LCD_ILI9320) || (LCDType == LCD_SPFD5408))\r
763   {\r
764     LCD_CtrlLinesWrite(LCD_NCS_GPIO_PORT, LCD_NCS_PIN, Bit_SET);\r
765   }\r
766 \r
767   /* Deselect the FLASH: Chip Select high */\r
768   SPI_FLASH_CS_HIGH();\r
769   /* Disable SPI1  */\r
770   SPI_Cmd(SPI1, DISABLE);\r
771   /* SPI in 8-bit mode */\r
772   SPI_DataSizeConfig(SPI1, SPI_DataSize_8b);\r
773   /* Enable SPI1  */\r
774   SPI_Cmd(SPI1, ENABLE);\r
775 \r
776   if((LCDType == LCD_ILI9320) || (LCDType == LCD_SPFD5408))\r
777   {\r
778     /* Set GRAM write direction and BGR = 1 */\r
779     /* I/D = 01 (Horizontal : increment, Vertical : decrement) */\r
780     /* AM = 1 (address is updated in vertical writing direction) */\r
781     LCD_WriteReg(LCD_REG_3, 0x1018);\r
782   }\r
783 }\r
784 #endif /* USE_LCD_DrawBMP */\r
785 \r
786 /**\r
787   * @brief  Displays a full rectangle.\r
788   * @param  Xpos: specifies the X position.\r
789   * @param  Ypos: specifies the Y position.\r
790   * @param  Height: rectangle height.\r
791   * @param  Width: rectangle width.\r
792   * @retval None\r
793   */\r
794 void LCD_DrawFullRect(uint16_t Xpos, uint16_t Ypos, uint16_t Width, uint16_t Height)\r
795 {\r
796   LCD_SetTextColor(TextColor);\r
797 \r
798   LCD_DrawLine(Xpos, Ypos, Width, LCD_DIR_HORIZONTAL);\r
799   LCD_DrawLine((Xpos + Height), Ypos, Width, LCD_DIR_HORIZONTAL);\r
800 \r
801   LCD_DrawLine(Xpos, Ypos, Height, LCD_DIR_VERTICAL);\r
802   LCD_DrawLine(Xpos, (Ypos - Width + 1), Height, LCD_DIR_VERTICAL);\r
803 \r
804   Width -= 2;\r
805   Height--;\r
806   Ypos--;\r
807 \r
808   LCD_SetTextColor(BackColor);\r
809 \r
810   while(Height--)\r
811   {\r
812     LCD_DrawLine(++Xpos, Ypos, Width, LCD_DIR_HORIZONTAL);\r
813   }\r
814 \r
815   LCD_SetTextColor(TextColor);\r
816 }\r
817 \r
818 /**\r
819   * @brief  Displays a full circle.\r
820   * @param  Xpos: specifies the X position.\r
821   * @param  Ypos: specifies the Y position.\r
822   * @param  Radius\r
823   * @retval None\r
824   */\r
825 void LCD_DrawFullCircle(uint16_t Xpos, uint16_t Ypos, uint16_t Radius)\r
826 {\r
827   int32_t  D;    /* Decision Variable */\r
828   uint32_t  CurX;/* Current X Value */\r
829   uint32_t  CurY;/* Current Y Value */\r
830 \r
831   D = 3 - (Radius << 1);\r
832 \r
833   CurX = 0;\r
834   CurY = Radius;\r
835 \r
836   LCD_SetTextColor(BackColor);\r
837 \r
838   while (CurX <= CurY)\r
839   {\r
840     if(CurY > 0)\r
841     {\r
842       LCD_DrawLine(Xpos - CurX, Ypos + CurY, 2*CurY, LCD_DIR_HORIZONTAL);\r
843       LCD_DrawLine(Xpos + CurX, Ypos + CurY, 2*CurY, LCD_DIR_HORIZONTAL);\r
844     }\r
845 \r
846     if(CurX > 0)\r
847     {\r
848       LCD_DrawLine(Xpos - CurY, Ypos + CurX, 2*CurX, LCD_DIR_HORIZONTAL);\r
849       LCD_DrawLine(Xpos + CurY, Ypos + CurX, 2*CurX, LCD_DIR_HORIZONTAL);\r
850     }\r
851     if (D < 0)\r
852     {\r
853       D += (CurX << 2) + 6;\r
854     }\r
855     else\r
856     {\r
857       D += ((CurX - CurY) << 2) + 10;\r
858       CurY--;\r
859     }\r
860     CurX++;\r
861   }\r
862 \r
863   LCD_SetTextColor(TextColor);\r
864   LCD_DrawCircle(Xpos, Ypos, Radius);\r
865 }\r
866 \r
867 /**\r
868   * @brief  Displays an uni line (between two points).\r
869   * @param  x1: specifies the point 1 x position.\r
870   * @param  y1: specifies the point 1 y position.\r
871   * @param  x2: specifies the point 2 x position.\r
872   * @param  y2: specifies the point 2 y position.\r
873   * @retval None\r
874   */\r
875 void LCD_DrawUniLine(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2)\r
876 {\r
877   int16_t deltax = 0, deltay = 0, x = 0, y = 0, xinc1 = 0, xinc2 = 0,\r
878   yinc1 = 0, yinc2 = 0, den = 0, num = 0, numadd = 0, numpixels = 0,\r
879   curpixel = 0;\r
880 \r
881   deltax = ABS(x2 - x1);        /* The difference between the x's */\r
882   deltay = ABS(y2 - y1);        /* The difference between the y's */\r
883   x = x1;                       /* Start x off at the first pixel */\r
884   y = y1;                       /* Start y off at the first pixel */\r
885 \r
886   if (x2 >= x1)                 /* The x-values are increasing */\r
887   {\r
888     xinc1 = 1;\r
889     xinc2 = 1;\r
890   }\r
891   else                          /* The x-values are decreasing */\r
892   {\r
893     xinc1 = -1;\r
894     xinc2 = -1;\r
895   }\r
896 \r
897   if (y2 >= y1)                 /* The y-values are increasing */\r
898   {\r
899     yinc1 = 1;\r
900     yinc2 = 1;\r
901   }\r
902   else                          /* The y-values are decreasing */\r
903   {\r
904     yinc1 = -1;\r
905     yinc2 = -1;\r
906   }\r
907 \r
908   if (deltax >= deltay)         /* There is at least one x-value for every y-value */\r
909   {\r
910     xinc1 = 0;                  /* Don't change the x when numerator >= denominator */\r
911     yinc2 = 0;                  /* Don't change the y for every iteration */\r
912     den = deltax;\r
913     num = deltax / 2;\r
914     numadd = deltay;\r
915     numpixels = deltax;         /* There are more x-values than y-values */\r
916   }\r
917   else                          /* There is at least one y-value for every x-value */\r
918   {\r
919     xinc2 = 0;                  /* Don't change the x for every iteration */\r
920     yinc1 = 0;                  /* Don't change the y when numerator >= denominator */\r
921     den = deltay;\r
922     num = deltay / 2;\r
923     numadd = deltax;\r
924     numpixels = deltay;         /* There are more y-values than x-values */\r
925   }\r
926 \r
927   for (curpixel = 0; curpixel <= numpixels; curpixel++)\r
928   {\r
929     PutPixel(x, y);             /* Draw the current pixel */\r
930     num += numadd;              /* Increase the numerator by the top of the fraction */\r
931     if (num >= den)             /* Check if numerator >= denominator */\r
932     {\r
933       num -= den;               /* Calculate the new numerator value */\r
934       x += xinc1;               /* Change the x as appropriate */\r
935       y += yinc1;               /* Change the y as appropriate */\r
936     }\r
937     x += xinc2;                 /* Change the x as appropriate */\r
938     y += yinc2;                 /* Change the y as appropriate */\r
939   }\r
940 }\r
941 \r
942 /**\r
943   * @brief  Displays an polyline (between many points).\r
944   * @param  Points: pointer to the points array.\r
945   * @param  PointCount: Number of points.\r
946   * @retval None\r
947   */\r
948 void LCD_PolyLine(pPoint Points, uint16_t PointCount)\r
949 {\r
950   int16_t X = 0, Y = 0;\r
951 \r
952   if(PointCount < 2)\r
953   {\r
954     return;\r
955   }\r
956 \r
957   while(--PointCount)\r
958   {\r
959     X = Points->X;\r
960     Y = Points->Y;\r
961     Points++;\r
962     LCD_DrawUniLine(X, Y, Points->X, Points->Y);\r
963   }\r
964 }\r
965 \r
966 /**\r
967   * @brief  Displays an relative polyline (between many points).\r
968   * @param  Points: pointer to the points array.\r
969   * @param  PointCount: Number of points.\r
970   * @param  Closed: specifies if the draw is closed or not.\r
971   *           1: closed, 0 : not closed.\r
972   * @retval None\r
973   */\r
974 static void LCD_PolyLineRelativeClosed(pPoint Points, uint16_t PointCount, uint16_t Closed)\r
975 {\r
976   int16_t X = 0, Y = 0;\r
977   pPoint First = Points;\r
978 \r
979   if(PointCount < 2)\r
980   {\r
981     return;\r
982   }\r
983   X = Points->X;\r
984   Y = Points->Y;\r
985   while(--PointCount)\r
986   {\r
987     Points++;\r
988     LCD_DrawUniLine(X, Y, X + Points->X, Y + Points->Y);\r
989     X = X + Points->X;\r
990     Y = Y + Points->Y;\r
991   }\r
992   if(Closed)\r
993   {\r
994     LCD_DrawUniLine(First->X, First->Y, X, Y);\r
995   }\r
996 }\r
997 \r
998 /**\r
999   * @brief  Displays a closed polyline (between many points).\r
1000   * @param  Points: pointer to the points array.\r
1001   * @param  PointCount: Number of points.\r
1002   * @retval None\r
1003   */\r
1004 void LCD_ClosedPolyLine(pPoint Points, uint16_t PointCount)\r
1005 {\r
1006   LCD_PolyLine(Points, PointCount);\r
1007   LCD_DrawUniLine(Points->X, Points->Y, (Points+PointCount-1)->X, (Points+PointCount-1)->Y);\r
1008 }\r
1009 \r
1010 /**\r
1011   * @brief  Displays a relative polyline (between many points).\r
1012   * @param  Points: pointer to the points array.\r
1013   * @param  PointCount: Number of points.\r
1014   * @retval None\r
1015   */\r
1016 void LCD_PolyLineRelative(pPoint Points, uint16_t PointCount)\r
1017 {\r
1018   LCD_PolyLineRelativeClosed(Points, PointCount, 0);\r
1019 }\r
1020 \r
1021 /**\r
1022   * @brief  Displays a closed relative polyline (between many points).\r
1023   * @param  Points: pointer to the points array.\r
1024   * @param  PointCount: Number of points.\r
1025   * @retval None\r
1026   */\r
1027 void LCD_ClosedPolyLineRelative(pPoint Points, uint16_t PointCount)\r
1028 {\r
1029   LCD_PolyLineRelativeClosed(Points, PointCount, 1);\r
1030 }\r
1031 \r
1032 \r
1033 /**\r
1034   * @brief  Displays a  full polyline (between many points).\r
1035   * @param  Points: pointer to the points array.\r
1036   * @param  PointCount: Number of points.\r
1037   * @retval None\r
1038   */\r
1039 void LCD_FillPolyLine(pPoint Points, uint16_t PointCount)\r
1040 {\r
1041   /*  public-domain code by Darel Rex Finley, 2007 */\r
1042   uint16_t  nodes = 0, nodeX[MAX_POLY_CORNERS], pixelX = 0, pixelY = 0, i = 0,\r
1043   j = 0, swap = 0;\r
1044   uint16_t  IMAGE_LEFT = 0, IMAGE_RIGHT = 0, IMAGE_TOP = 0, IMAGE_BOTTOM = 0;\r
1045 \r
1046   IMAGE_LEFT = IMAGE_RIGHT = Points->X;\r
1047   IMAGE_TOP= IMAGE_BOTTOM = Points->Y;\r
1048 \r
1049   for(i = 1; i < PointCount; i++)\r
1050   {\r
1051     pixelX = POLY_X(i);\r
1052     if(pixelX < IMAGE_LEFT)\r
1053     {\r
1054       IMAGE_LEFT = pixelX;\r
1055     }\r
1056     if(pixelX > IMAGE_RIGHT)\r
1057     {\r
1058       IMAGE_RIGHT = pixelX;\r
1059     }\r
1060 \r
1061     pixelY = POLY_Y(i);\r
1062     if(pixelY < IMAGE_TOP)\r
1063     {\r
1064       IMAGE_TOP = pixelY;\r
1065     }\r
1066     if(pixelY > IMAGE_BOTTOM)\r
1067     {\r
1068       IMAGE_BOTTOM = pixelY;\r
1069     }\r
1070   }\r
1071 \r
1072   LCD_SetTextColor(BackColor);\r
1073 \r
1074   /*  Loop through the rows of the image. */\r
1075   for (pixelY = IMAGE_TOP; pixelY < IMAGE_BOTTOM; pixelY++)\r
1076   {\r
1077     /* Build a list of nodes. */\r
1078     nodes = 0; j = PointCount-1;\r
1079 \r
1080     for (i = 0; i < PointCount; i++)\r
1081     {\r
1082       if (POLY_Y(i)<(double) pixelY && POLY_Y(j)>=(double) pixelY || POLY_Y(j)<(double) pixelY && POLY_Y(i)>=(double) pixelY)\r
1083       {\r
1084         nodeX[nodes++]=(int) (POLY_X(i)+((pixelY-POLY_Y(i))*(POLY_X(j)-POLY_X(i)))/(POLY_Y(j)-POLY_Y(i)));\r
1085       }\r
1086       j = i;\r
1087     }\r
1088 \r
1089     /* Sort the nodes, via a simple \93Bubble\94 sort. */\r
1090     i = 0;\r
1091     while (i < nodes-1)\r
1092     {\r
1093       if (nodeX[i]>nodeX[i+1])\r
1094       {\r
1095         swap = nodeX[i];\r
1096         nodeX[i] = nodeX[i+1];\r
1097         nodeX[i+1] = swap;\r
1098         if(i)\r
1099         {\r
1100           i--;\r
1101         }\r
1102       }\r
1103       else\r
1104       {\r
1105         i++;\r
1106       }\r
1107     }\r
1108 \r
1109     /*  Fill the pixels between node pairs. */\r
1110     for (i = 0; i < nodes; i+=2)\r
1111     {\r
1112       if(nodeX[i] >= IMAGE_RIGHT)\r
1113       {\r
1114         break;\r
1115       }\r
1116       if(nodeX[i+1] > IMAGE_LEFT)\r
1117       {\r
1118         if (nodeX[i] < IMAGE_LEFT)\r
1119         {\r
1120           nodeX[i]=IMAGE_LEFT;\r
1121         }\r
1122         if(nodeX[i+1] > IMAGE_RIGHT)\r
1123         {\r
1124           nodeX[i+1] = IMAGE_RIGHT;\r
1125         }\r
1126         LCD_SetTextColor(BackColor);\r
1127         LCD_DrawLine(pixelY, nodeX[i+1], nodeX[i+1] - nodeX[i], LCD_DIR_HORIZONTAL);\r
1128         LCD_SetTextColor(TextColor);\r
1129         PutPixel(pixelY, nodeX[i+1]);\r
1130         PutPixel(pixelY, nodeX[i]);\r
1131         /* for (j=nodeX[i]; j<nodeX[i+1]; j++) PutPixel(j,pixelY); */\r
1132       }\r
1133     }\r
1134   }\r
1135 \r
1136   /* draw the edges */\r
1137   LCD_SetTextColor(TextColor);\r
1138 }\r
1139 \r
1140 /**\r
1141   * @brief  Reset LCD control line(/CS) and Send Start-Byte\r
1142   * @param  Start_Byte: the Start-Byte to be sent\r
1143   * @retval None\r
1144   */\r
1145 void LCD_nCS_StartByte(uint8_t Start_Byte)\r
1146 {\r
1147   LCD_CtrlLinesWrite(LCD_NCS_GPIO_PORT, LCD_NCS_PIN, Bit_RESET);\r
1148 \r
1149   SPI_SendData(LCD_SPI, Start_Byte);\r
1150 \r
1151   while(SPI_GetFlagStatus(LCD_SPI, SPI_FLAG_BSY) != RESET)\r
1152   {\r
1153   }\r
1154 }\r
1155 \r
1156 \r
1157 /**\r
1158   * @brief  Writes index to select the LCD register.\r
1159   * @param  LCD_Reg: address of the selected register.\r
1160   * @retval None\r
1161   */\r
1162 void LCD_WriteRegIndex(uint8_t LCD_Reg)\r
1163 {\r
1164   /* Reset LCD control line(/CS) and Send Start-Byte */\r
1165   LCD_nCS_StartByte(START_BYTE | SET_INDEX);\r
1166 \r
1167   /* Write 16-bit Reg Index (High Byte is 0) */\r
1168   SPI_SendData(LCD_SPI, 0x00);\r
1169 \r
1170   while(SPI_GetFlagStatus(LCD_SPI, SPI_FLAG_BSY) != RESET)\r
1171   {\r
1172   }\r
1173 \r
1174   SPI_SendData(LCD_SPI, LCD_Reg);\r
1175 \r
1176   while(SPI_GetFlagStatus(LCD_SPI, SPI_FLAG_BSY) != RESET)\r
1177   {\r
1178   }\r
1179 \r
1180   LCD_CtrlLinesWrite(LCD_NCS_GPIO_PORT, LCD_NCS_PIN, Bit_SET);\r
1181 }\r
1182 \r
1183 \r
1184 /**\r
1185   * @brief  Writes to the selected LCD ILI9320 register.\r
1186   * @param  LCD_Reg: address of the selected register.\r
1187   * @param  LCD_RegValue: value to write to the selected register.\r
1188   * @retval None\r
1189   */\r
1190 void LCD_WriteReg(uint8_t LCD_Reg, uint16_t LCD_RegValue)\r
1191 {\r
1192   /* Write 16-bit Index (then Write Reg) */\r
1193   LCD_WriteRegIndex(LCD_Reg);\r
1194 \r
1195   /* Write 16-bit Reg */\r
1196   /* Reset LCD control line(/CS) and Send Start-Byte */\r
1197   LCD_nCS_StartByte(START_BYTE | LCD_WRITE_REG);\r
1198 \r
1199   SPI_SendData(LCD_SPI, LCD_RegValue >> 8);\r
1200 \r
1201   while(SPI_GetFlagStatus(LCD_SPI, SPI_FLAG_BSY) != RESET)\r
1202   {\r
1203   }\r
1204 \r
1205   SPI_SendData(LCD_SPI, (LCD_RegValue & 0xFF));\r
1206 \r
1207   while(SPI_GetFlagStatus(LCD_SPI, SPI_FLAG_BSY) != RESET)\r
1208   {\r
1209   }\r
1210 \r
1211   LCD_CtrlLinesWrite(LCD_NCS_GPIO_PORT, LCD_NCS_PIN, Bit_SET);\r
1212 }\r
1213 \r
1214 \r
1215 /**\r
1216   * @brief  Reads the selected LCD Register.\r
1217   * @param  LCD_Reg: address of the selected register.\r
1218   * @retval LCD Register Value.\r
1219   */\r
1220 uint16_t LCD_ReadReg(uint8_t LCD_Reg)\r
1221 {\r
1222   uint16_t tmp = 0;\r
1223   uint8_t i = 0;\r
1224 \r
1225   /* LCD_SPI prescaler: 4 */\r
1226   LCD_SPI->CR1 &= 0xFFC7;\r
1227   LCD_SPI->CR1 |= 0x0008;\r
1228   /* Write 16-bit Index (then Read Reg) */\r
1229   LCD_WriteRegIndex(LCD_Reg);\r
1230   /* Read 16-bit Reg */\r
1231   /* Reset LCD control line(/CS) and Send Start-Byte */\r
1232   LCD_nCS_StartByte(START_BYTE | LCD_READ_REG);\r
1233 \r
1234   for(i = 0; i < 5; i++)\r
1235   {\r
1236     SPI_SendData(LCD_SPI, 0xFF);\r
1237     while(SPI_GetFlagStatus(LCD_SPI, SPI_FLAG_BSY) != RESET)\r
1238     {\r
1239     }\r
1240     /* One byte of invalid dummy data read after the start byte */\r
1241     while(SPI_GetFlagStatus(LCD_SPI, SPI_FLAG_RXNE) == RESET)\r
1242     {\r
1243     }\r
1244     SPI_ReceiveData(LCD_SPI);\r
1245   }\r
1246 \r
1247   SPI_SendData(LCD_SPI, 0xFF);\r
1248 \r
1249   /* Read upper byte */\r
1250   while(SPI_GetFlagStatus(LCD_SPI, SPI_FLAG_BSY) != RESET)\r
1251   {\r
1252   }\r
1253 \r
1254   /* Read lower byte */\r
1255   while(SPI_GetFlagStatus(LCD_SPI, SPI_FLAG_RXNE) == RESET)\r
1256   {\r
1257   }\r
1258   tmp = SPI_ReceiveData(LCD_SPI);\r
1259 \r
1260 \r
1261   SPI_SendData(LCD_SPI, 0xFF);\r
1262   while(SPI_GetFlagStatus(LCD_SPI, SPI_FLAG_BSY) != RESET)\r
1263   {\r
1264   }\r
1265 \r
1266   /* Read lower byte */\r
1267   while(SPI_GetFlagStatus(LCD_SPI, SPI_FLAG_RXNE) == RESET)\r
1268   {\r
1269   }\r
1270 \r
1271   tmp = ((tmp & 0xFF) << 8) | SPI_ReceiveData(LCD_SPI);\r
1272   LCD_CtrlLinesWrite(LCD_NCS_GPIO_PORT, LCD_NCS_PIN, Bit_SET);\r
1273 \r
1274   /* LCD_SPI prescaler: 2 */\r
1275   LCD_SPI->CR1 &= 0xFFC7;\r
1276 \r
1277   return tmp;\r
1278 }\r
1279 \r
1280 \r
1281 /**\r
1282   * @brief  Prepare to write to the LCD RAM.\r
1283   * @param  None\r
1284   * @retval None\r
1285   */\r
1286 void LCD_WriteRAM_Prepare(void)\r
1287 {\r
1288   LCD_WriteRegIndex(LCD_REG_34); /* Select GRAM Reg */\r
1289 \r
1290   /* Reset LCD control line(/CS) and Send Start-Byte */\r
1291   LCD_nCS_StartByte(START_BYTE | LCD_WRITE_REG);\r
1292 }\r
1293 \r
1294 \r
1295 /**\r
1296   * @brief  Writes 1 word to the LCD RAM.\r
1297   * @param  RGB_Code: the pixel color in RGB mode (5-6-5).\r
1298   * @retval None\r
1299   */\r
1300 void LCD_WriteRAMWord(uint16_t RGB_Code)\r
1301 {\r
1302   LCD_WriteRAM_Prepare();\r
1303 \r
1304   LCD_WriteRAM(RGB_Code);\r
1305 \r
1306   LCD_CtrlLinesWrite(LCD_NCS_GPIO_PORT, LCD_NCS_PIN, Bit_SET);\r
1307 }\r
1308 \r
1309 /**\r
1310   * @brief  Writes to the LCD RAM.\r
1311   * @param  RGB_Code: the pixel color in RGB mode (5-6-5).\r
1312   * @retval None\r
1313   */\r
1314 void LCD_WriteRAM(uint16_t RGB_Code)\r
1315 {\r
1316   SPI_SendData(LCD_SPI, RGB_Code >> 8);\r
1317   while(SPI_GetFlagStatus(LCD_SPI, SPI_FLAG_BSY) != RESET)\r
1318   {\r
1319   }\r
1320   SPI_SendData(LCD_SPI, RGB_Code & 0xFF);\r
1321   while(SPI_GetFlagStatus(LCD_SPI, SPI_FLAG_BSY) != RESET)\r
1322   {\r
1323   }\r
1324 }\r
1325 \r
1326 \r
1327 /**\r
1328   * @brief  Power on the LCD.\r
1329   * @param  None\r
1330   * @retval None\r
1331   */\r
1332 void LCD_PowerOn(void)\r
1333 {\r
1334   /* Power On sequence ---------------------------------------------------------*/\r
1335   LCD_WriteReg(LCD_REG_16, 0x0000); /* SAP, BT[3:0], AP, DSTB, SLP, STB */\r
1336   LCD_WriteReg(LCD_REG_17, 0x0000); /* DC1[2:0], DC0[2:0], VC[2:0] */\r
1337   LCD_WriteReg(LCD_REG_18, 0x0000); /* VREG1OUT voltage */\r
1338   LCD_WriteReg(LCD_REG_19, 0x0000); /* VDV[4:0] for VCOM amplitude */\r
1339   _delay_(20);                 /* Dis-charge capacitor power voltage (200ms) */\r
1340   LCD_WriteReg(LCD_REG_16, 0x17B0); /* SAP, BT[3:0], AP, DSTB, SLP, STB */\r
1341   LCD_WriteReg(LCD_REG_17, 0x0137); /* DC1[2:0], DC0[2:0], VC[2:0] */\r
1342   _delay_(5);                /* Delay 50 ms */\r
1343   LCD_WriteReg(LCD_REG_18, 0x0139); /* VREG1OUT voltage */\r
1344   _delay_(5);                /* delay 50 ms */\r
1345   LCD_WriteReg(LCD_REG_19, 0x1d00); /* VDV[4:0] for VCOM amplitude */\r
1346   LCD_WriteReg(LCD_REG_41, 0x0013); /* VCM[4:0] for VCOMH */\r
1347   _delay_(5);                /* delay 50 ms */\r
1348   LCD_WriteReg(LCD_REG_7, 0x0173);  /* 262K color and display ON */\r
1349 }\r
1350 \r
1351 \r
1352 /**\r
1353   * @brief  Enables the Display.\r
1354   * @param  None\r
1355   * @retval None\r
1356   */\r
1357 void LCD_DisplayOn(void)\r
1358 {\r
1359   /* Display On */\r
1360   LCD_WriteReg(LCD_REG_7, 0x0173); /* 262K color and display ON */\r
1361 }\r
1362 \r
1363 \r
1364 /**\r
1365   * @brief  Disables the Display.\r
1366   * @param  None\r
1367   * @retval None\r
1368   */\r
1369 void LCD_DisplayOff(void)\r
1370 {\r
1371   /* Display Off */\r
1372   LCD_WriteReg(LCD_REG_7, 0x0);\r
1373 }\r
1374 \r
1375 \r
1376 /**\r
1377   * @brief  Configures LCD control lines in Output Push-Pull mode.\r
1378   * @param  None\r
1379   * @retval None\r
1380   */\r
1381 void LCD_CtrlLinesConfig(void)\r
1382 {\r
1383   GPIO_InitTypeDef GPIO_InitStructure;\r
1384 \r
1385   RCC_AHBPeriphClockCmd(LCD_NCS_GPIO_CLK, ENABLE);\r
1386 \r
1387   /* Configure NCS (PF.02) in Output Push-Pull mode */\r
1388   GPIO_InitStructure.GPIO_Pin = LCD_NCS_PIN;\r
1389   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;\r
1390   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_OUT;\r
1391   GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;\r
1392   GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;\r
1393   GPIO_Init(LCD_NCS_GPIO_PORT, &GPIO_InitStructure);\r
1394 \r
1395   LCD_CtrlLinesWrite(LCD_NCS_GPIO_PORT, LCD_NCS_PIN, Bit_SET);\r
1396 }\r
1397 \r
1398 \r
1399 /**\r
1400   * @brief  Sets or reset LCD control lines.\r
1401   * @param  GPIOx: where x can be B or D to select the GPIO peripheral.\r
1402   * @param  CtrlPins: the Control line.\r
1403   *   This parameter can be:\r
1404   *     @arg LCD_NCS_PIN: Chip Select pin\r
1405   *     @arg LCD_NWR_PIN: Read/Write Selection pin\r
1406   *     @arg LCD_RS_PIN: Register/RAM Selection pin\r
1407   * @param  BitVal: specifies the value to be written to the selected bit.\r
1408   *   This parameter can be:\r
1409   *     @arg Bit_RESET: to clear the port pin\r
1410   *     @arg Bit_SET: to set the port pin\r
1411   * @retval None\r
1412   */\r
1413 void LCD_CtrlLinesWrite(GPIO_TypeDef* GPIOx, uint16_t CtrlPins, BitAction BitVal)\r
1414 {\r
1415   /* Set or Reset the control line */\r
1416   GPIO_WriteBit(GPIOx, CtrlPins, BitVal);\r
1417 }\r
1418 \r
1419 \r
1420 /**\r
1421   * @brief  Configures the LCD_SPI interface.\r
1422   * @param  None\r
1423   * @retval None\r
1424   */\r
1425 void LCD_SPIConfig(void)\r
1426 {\r
1427   SPI_InitTypeDef    SPI_InitStructure;\r
1428   GPIO_InitTypeDef   GPIO_InitStructure;\r
1429 \r
1430   /* Enable LCD_SPI_SCK_GPIO_CLK, LCD_SPI_MISO_GPIO_CLK and LCD_SPI_MOSI_GPIO_CLK clock */\r
1431   RCC_AHBPeriphClockCmd(LCD_SPI_SCK_GPIO_CLK | LCD_SPI_MISO_GPIO_CLK | LCD_SPI_MOSI_GPIO_CLK, ENABLE);\r
1432 \r
1433   /* Enable LCD_SPI and SYSCFG clock  */\r
1434   RCC_APB2PeriphClockCmd(LCD_SPI_CLK | RCC_APB2Periph_SYSCFG, ENABLE);\r
1435 \r
1436   /* Configure LCD_SPI SCK pin */\r
1437   GPIO_InitStructure.GPIO_Pin = LCD_SPI_SCK_PIN;\r
1438   GPIO_InitStructure.GPIO_Speed = GPIO_Speed_40MHz;\r
1439   GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF;\r
1440   GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;\r
1441   GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;\r
1442   GPIO_Init(LCD_SPI_SCK_GPIO_PORT, &GPIO_InitStructure);\r
1443 \r
1444   /* Configure LCD_SPI MISO pin */\r
1445   GPIO_InitStructure.GPIO_Pin = LCD_SPI_MISO_PIN;\r
1446   GPIO_Init(LCD_SPI_MISO_GPIO_PORT, &GPIO_InitStructure);\r
1447 \r
1448   /* Configure LCD_SPI MOSI pin */\r
1449   GPIO_InitStructure.GPIO_Pin = LCD_SPI_MOSI_PIN;\r
1450   GPIO_Init(LCD_SPI_MOSI_GPIO_PORT, &GPIO_InitStructure);\r
1451 \r
1452   /* Connect PE.13 to SPI SCK */\r
1453   GPIO_PinAFConfig(LCD_SPI_SCK_GPIO_PORT, LCD_SPI_SCK_SOURCE, LCD_SPI_SCK_AF);\r
1454 \r
1455   /* Connect PE.14 to SPI MISO */\r
1456   GPIO_PinAFConfig(LCD_SPI_MISO_GPIO_PORT, LCD_SPI_MISO_SOURCE, LCD_SPI_MISO_AF);\r
1457 \r
1458   /* Connect PE.15 to SPI MOSI */\r
1459   GPIO_PinAFConfig(LCD_SPI_MOSI_GPIO_PORT, LCD_SPI_MOSI_SOURCE, LCD_SPI_MOSI_AF);\r
1460 \r
1461   SPI_DeInit(LCD_SPI);\r
1462 \r
1463   /* SPI Config */\r
1464   SPI_InitStructure.SPI_Direction = SPI_Direction_2Lines_FullDuplex;\r
1465   SPI_InitStructure.SPI_Mode = SPI_Mode_Master;\r
1466   SPI_InitStructure.SPI_DataSize = SPI_DataSize_8b;\r
1467   SPI_InitStructure.SPI_CPOL = SPI_CPOL_High;\r
1468   SPI_InitStructure.SPI_CPHA = SPI_CPHA_2Edge;\r
1469   SPI_InitStructure.SPI_NSS = SPI_NSS_Soft;\r
1470   SPI_InitStructure.SPI_BaudRatePrescaler = SPI_BaudRatePrescaler_2;\r
1471   SPI_InitStructure.SPI_FirstBit = SPI_FirstBit_MSB;\r
1472   SPI_InitStructure.SPI_CRCPolynomial = 7;\r
1473   SPI_Init(LCD_SPI, &SPI_InitStructure);\r
1474 \r
1475   /* SPI enable */\r
1476   SPI_Cmd(LCD_SPI, ENABLE);\r
1477 }\r
1478 \r
1479 /**\r
1480   * @brief  Displays a pixel.\r
1481   * @param  x: pixel x.\r
1482   * @param  y: pixel y.\r
1483   * @retval None\r
1484   */\r
1485 static void PutPixel(int16_t x, int16_t y)\r
1486 {\r
1487   if(x < 0 || x > 239 || y < 0 || y > 319)\r
1488   {\r
1489     return;\r
1490   }\r
1491   LCD_DrawLine(x, y, 1, LCD_DIR_HORIZONTAL);\r
1492 }\r
1493 \r
1494 #ifndef USE_Delay\r
1495 /**\r
1496   * @brief  Inserts a delay time.\r
1497   * @param  nCount: specifies the delay time length.\r
1498   * @retval None\r
1499   */\r
1500 static void delay(__IO uint32_t nCount)\r
1501 {\r
1502   __IO uint32_t index = 0;\r
1503   for(index = (34000 * nCount); index != 0; index--)\r
1504   {\r
1505   }\r
1506 }\r
1507 #endif /* USE_Delay*/\r
1508 /**\r
1509   * @}\r
1510   */\r
1511 \r
1512 /**\r
1513   * @}\r
1514   */\r
1515 \r
1516 /**\r
1517   * @}\r
1518   */\r
1519 \r
1520 /**\r
1521   * @}\r
1522   */\r
1523 \r
1524 /**\r
1525   * @}\r
1526   */\r
1527 \r
1528 /******************* (C) COPYRIGHT 2010 STMicroelectronics *****END OF FILE****/\r