Nano102_112 Series BSP  V3.03.002
The Board Support Package for Nano102_112 Series
lcd.c
Go to the documentation of this file.
1 /**************************************************************************/
12 #include <stdio.h>
13 #include <string.h>
14 #include <stdlib.h>
15 //#include <stdbool.h>
16 #include "Nano1X2Series.h"
17 #include "lcd.h"
18 
19 
29 
34 /*---------------------------------------------------------------------------------------------------------*/
35 /* Global file scope (static) variables */
36 /*---------------------------------------------------------------------------------------------------------*/
37 
38 double g_LCDFreq;
39 static uint32_t g_LCDFrameRate; /* src:32768Hz, COM:4, FREQ Div:64, frame-rate 64Hz */
40 /* src:10240Hz, COM:4, FREQ Div:32, frame-rate 40Hz */
41 
42  /* end of group NANO1X2_LCD_EXPORTED_VARIABLES */
44 
46 
62 void LCD_SetPixel(uint32_t u32Com, uint32_t u32Seg, uint32_t u32OnFlag)
63 {
64  int32_t memnum = u32Seg / 4;
65  int32_t seg_shift = 8*(u32Seg-(4*memnum));
66 
67  if(u32OnFlag)
68  {
69  if(memnum==0)
70  {
71  LCD->MEM_0 |= (1<<u32Com)<<seg_shift;
72  }
73  else if(memnum==1)
74  {
75  LCD->MEM_1 |= (1<<u32Com)<<seg_shift;
76  }
77  else if(memnum==2)
78  {
79  LCD->MEM_2 |= (1<<u32Com)<<seg_shift;
80  }
81  else if(memnum==3)
82  {
83  LCD->MEM_3 |= (1<<u32Com)<<seg_shift;
84  }
85  else if(memnum==4)
86  {
87  LCD->MEM_4 |= (1<<u32Com)<<seg_shift;
88  }
89  else if(memnum==5)
90  {
91  LCD->MEM_5 |= (1<<u32Com)<<seg_shift;
92  }
93  else if(memnum==6)
94  {
95  LCD->MEM_6 |= (1<<u32Com)<<seg_shift;
96  }
97  else if(memnum==7)
98  {
99  LCD->MEM_7 |= (1<<u32Com)<<seg_shift;
100  }
101  else if(memnum==8)
102  {
103  LCD->MEM_8 |= (1<<u32Com)<<seg_shift;
104  }
105  }
106  else
107  {
108  if(memnum==0)
109  {
110  LCD->MEM_0 &= ~((1<<u32Com)<<seg_shift);
111  }
112  else if(memnum==1)
113  {
114  LCD->MEM_1 &= ~((1<<u32Com)<<seg_shift);
115  }
116  else if(memnum==2)
117  {
118  LCD->MEM_2 &= ~((1<<u32Com)<<seg_shift);
119  }
120  else if(memnum==3)
121  {
122  LCD->MEM_3 &= ~((1<<u32Com)<<seg_shift);
123  }
124  else if(memnum==4)
125  {
126  LCD->MEM_4 &= ~((1<<u32Com)<<seg_shift);
127  }
128  else if(memnum==5)
129  {
130  LCD->MEM_5 &= ~((1<<u32Com)<<seg_shift);
131  }
132  else if(memnum==6)
133  {
134  LCD->MEM_6 &= ~((1<<u32Com)<<seg_shift);
135  }
136  else if(memnum==7)
137  {
138  LCD->MEM_7 &= ~((1<<u32Com)<<seg_shift);
139  }
140  else if(memnum==8)
141  {
142  LCD->MEM_8 &= ~((1<<u32Com)<<seg_shift);
143  }
144  }
145 
146  if(CyclesPerUs > 0)
147  SysTick->LOAD = 300 * CyclesPerUs;
148  else
149  SysTick->LOAD = 15;
150  SysTick->VAL = (0x00);
151  SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | SysTick_CTRL_ENABLE_Msk;
152 
153  /* Waiting for down-count to zero */
154  while((SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk) == 0);
155 }
156 
166 void LCD_SetAllPixels(uint32_t u32OnOff)
167 {
168  uint32_t u32SetValue;
169 
170  if(u32OnOff)
171  {
172  u32SetValue = 0xFFFFFFFF;
173  }
174  else
175  {
176  u32SetValue = 0x00000000;
177  }
178 
179  LCD->MEM_0 = u32SetValue;
180  LCD->MEM_1 = u32SetValue;
181  LCD->MEM_2 = u32SetValue;
182  LCD->MEM_3 = u32SetValue;
183  LCD->MEM_4 = u32SetValue;
184  LCD->MEM_5 = u32SetValue;
185  LCD->MEM_6 = u32SetValue;
186  LCD->MEM_7 = u32SetValue;
187  LCD->MEM_8 = u32SetValue;
188 
189  if(CyclesPerUs > 0)
190  SysTick->LOAD = 300 * CyclesPerUs;
191  else
192  SysTick->LOAD = 15;
193  SysTick->VAL = (0x00);
194  SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | SysTick_CTRL_ENABLE_Msk;
195 
196  /* Waiting for down-count to zero */
197  while((SysTick->CTRL & SysTick_CTRL_COUNTFLAG_Msk) == 0);
198 }
199 
200 
210 uint32_t LCD_EnableFrameCounter(uint32_t u32Count)
211 {
212  uint32_t div = 1; // default prediv == LCD_FCPRESC_DIV1
213 
214  LCD->FCR = 0x00;
215  LCD->FCSTS |= LCD_FCSTS_FCSTS_Msk; // clear fcsts flag
216 
217  if(u32Count == 0) return 0;
218 
219  if(u32Count > 0x3F) // top value max. 63 = 0x3F
220  {
221  div = u32Count/64;
222 
223  if(div > 3)
224  {
225  div = 8;
226  LCD->FCR = LCD->FCR & ~LCD_FCR_PRESCL_Msk | LCD_FCPRESC_DIV8;
227  }
228  else if(div > 1)
229  {
230  div = 4;
231  LCD->FCR = LCD->FCR & ~LCD_FCR_PRESCL_Msk | LCD_FCPRESC_DIV4;
232  }
233  else
234  {
235  div = 2;
236  LCD->FCR = LCD->FCR & ~LCD_FCR_PRESCL_Msk | LCD_FCPRESC_DIV2;
237  }
238 
239  u32Count = (u32Count+(div/2))/div;
240  }
241  else
242  {
243  div = 1;
244  LCD->FCR = LCD->FCR & ~LCD_FCR_PRESCL_Msk | LCD_FCPRESC_DIV1;
245  }
246 
247  LCD->FCR = LCD->FCR & ~LCD_FCR_FCV_Msk | (u32Count << LCD_FCR_FCV_Pos);
248 
249  u32Count = u32Count*div;
250 
251  LCD->FCR |= LCD_FCR_FCEN_Msk; // enable LCD frame count
252 
253  return u32Count;
254 }
255 
265 {
266  LCD->FCR = 0x00; // disable LCD frame count
267 
268  if( LCD->FCSTS & LCD_FCSTS_FCSTS_Msk) // clear status flag
269  LCD->FCSTS = LCD_FCSTS_FCSTS_Msk;
270 }
271 
272 
287 uint32_t LCD_Open(uint32_t u32DrivingType, uint32_t u32ComNum, uint32_t u32BiasLevel, uint32_t u32FramerateDiv, uint32_t u32DrivingVol)
288 {
289  uint32_t clkdiv, muldiv;
290  uint32_t lcd_freq_div[] = {32, 64, 96, 128, 192, 256, 384, 512};
291  uint32_t multiplex_freq_div[] = {2, 4, 6, 8, 10, 12};
292  uint32_t u32clk_src;
293 
294  /* IP reset */
295  SYS->IPRST_CTL2 |= SYS_IPRST_CTL2_LCD_RST_Msk;
296  SYS->IPRST_CTL2 &= ~SYS_IPRST_CTL2_LCD_RST_Msk;
297 
299 
300  /* Turn all segments off */
301  LCD_SetAllPixels(0);
302 
303  LCD->DISPCTL &= ~LCD_DISPCTL_Ext_C_Msk;
304 
305  switch(u32DrivingType)
306  {
307  case LCD_C_TYPE:
308  case LCD_EXTERNAL_C_TYPE:
309 
310  LCD->DISPCTL &= ~LCD_DISPCTL_BV_SEL_Msk; // internal source for charge pump
311  LCD->DISPCTL = LCD->DISPCTL & ~LCD_DISPCTL_CPUMP_FREQ_Msk | (LCD_CPUMP_DIV1);
312  LCD->DISPCTL = LCD->DISPCTL & ~LCD_DISPCTL_CPUMP_VOL_SET_Msk | (u32DrivingVol);
313  LCD->DISPCTL &= ~LCD_DISPCTL_IBRL_EN_Msk;
314  LCD->DISPCTL |= LCD_DISPCTL_CPUMP_EN_Msk; // enable charge pump
315 
316  break;
317 
318  case LCD_EXTERNAL_R_TYPE:
319  case LCD_INTERNAL_R_TYPE:
320 
321  LCD->DISPCTL &= ~LCD_DISPCTL_CPUMP_EN_Msk;
322  LCD->DISPCTL |= LCD_DISPCTL_BV_SEL_Msk;
323  LCD->DISPCTL &= ~LCD_DISPCTL_IBRL_EN_Msk;
324  LCD->DISPCTL |= (u32DrivingType == LCD_INTERNAL_R_TYPE)?LCD_DISPCTL_IBRL_EN_Msk:0;
325  break;
326 
327  };
328 
329  if(u32DrivingType == LCD_EXTERNAL_C_TYPE)
330  LCD->DISPCTL |= LCD_DISPCTL_Ext_C_Msk;
331 
332  LCD->CTL &= ~LCD_CTL_FREQ_Msk;
333  LCD->CTL |= u32FramerateDiv;
334 
335  LCD->CTL = (LCD->CTL & ~LCD_CTL_MUX_Msk) | ((u32ComNum - 1) << LCD_CTL_MUX_Pos);
336  LCD->DISPCTL = LCD->DISPCTL & ~LCD_DISPCTL_BIAS_SEL_Msk | u32BiasLevel;
337 
338  if((CLK->CLKSEL1 & CLK_CLKSEL1_LCD_S_Msk) == 0)
339  u32clk_src = 32 * 1024;
340  else
341  u32clk_src = 10 * 1024;
342 
343  clkdiv = (LCD->CTL & LCD_CTL_FREQ_Msk) >> LCD_CTL_FREQ_Pos;
344  muldiv = (LCD->CTL & LCD_CTL_MUX_Msk) >> LCD_CTL_MUX_Pos;
345 
346  g_LCDFreq = (double)u32clk_src / lcd_freq_div[clkdiv];
347  g_LCDFrameRate = (uint32_t)g_LCDFreq / multiplex_freq_div[muldiv];
348 
349  return g_LCDFrameRate;
350 }
351 
352 
353 
362 void LCD_Close(void)
363 {
365 }
366 
367 
376 uint32_t LCD_EnableBlink(uint32_t u32ms)
377 {
378  uint32_t prescale=LCD_FCPRESC_DIV1, div=1;
379  uint32_t framecount;
380 
381  if((1000/u32ms) > g_LCDFrameRate) u32ms = (1000/g_LCDFrameRate);
382 
383  framecount = (uint32_t) (u32ms / (1000/g_LCDFrameRate)) ;
384 
385  if(framecount > 0x3F)
386  {
387  for(div=2; div<=8; div*=2)
388  {
389  framecount = (uint32_t) (u32ms / (1000/(g_LCDFrameRate/div)) );
390 
391  if( framecount <= 0x40 )
392  break;
393  }
394  if(div==2) prescale = LCD_FCPRESC_DIV2;
395  else if(div==4) prescale = LCD_FCPRESC_DIV4;
396  else if(div==8) prescale = LCD_FCPRESC_DIV8;
397  else return 0;
398  }
399  else if(framecount == 0)
400  {
401  framecount = 1;
402  }
403 
404  LCD->FCR = LCD->FCR & ~LCD_FCR_PRESCL_Msk | prescale;
405  LCD->FCR = LCD->FCR & ~LCD_FCR_FCV_Msk | ((framecount - 1) << LCD_FCR_FCV_Pos);
406  LCD->FCR |= LCD_FCR_FCEN_Msk;
407 
408  /* Enable Blink LCD */
409  LCD->CTL |= LCD_CTL_BLINK_Msk;
410 
411  return ( (framecount*1000)/(g_LCDFrameRate/div) );
412 }
413 
414 
424 {
425  /* Disable Blink LCD */
426  LCD->CTL &= ~LCD_CTL_BLINK_Msk;
427 
428  /* Disable frame count */
429  LCD->FCR = 0x00; // disable LCD frame count
430 
431  if( LCD->FCSTS & LCD_FCSTS_FCSTS_Msk) // clear status flag
432  LCD->FCSTS = LCD_FCSTS_FCSTS_Msk;
433 
434 }
435 
444 void LCD_EnableInt(uint32_t IntSrc)
445 {
446  if((IntSrc & LCD_FRAMECOUNT_INT) == LCD_FRAMECOUNT_INT )
447  {
448  LCD->FCR |= LCD_FCR_FCEN_Msk;
449  }
450 
451  if((IntSrc & LCD_POWERDOWN_INT) == LCD_POWERDOWN_INT )
452  {
453  LCD->CTL |= LCD_CTL_PDINT_EN_Msk;
454  }
455 
456 }
457 
466 void LCD_DisableInt(uint32_t IntSrc)
467 {
468  if((IntSrc & LCD_FRAMECOUNT_INT) == LCD_FRAMECOUNT_INT )
469  {
470  LCD->FCR &= ~LCD_FCR_FCEN_Msk;
471  LCD->FCSTS = LCD_FCSTS_FCSTS_Msk;
472  }
473 
474  if((IntSrc & LCD_POWERDOWN_INT) == LCD_POWERDOWN_INT )
475  {
476  LCD->CTL &= ~LCD_CTL_PDINT_EN_Msk;
477  LCD->FCSTS = LCD_FCSTS_PDSTS_Msk;
478  }
479 }
480  /* end of group NANO1X2_LCD_EXPORTED_FUNCTIONS */
482  /* end of group NANO1X2_LCD_Driver */
484  /* end of group NANO1X2_Device_Driver */
486 
487 /*** (C) COPYRIGHT 2014 Nuvoton Technology Corp. ***/
488 
#define LCD_DISPCTL_BIAS_SEL_Msk
#define LCD_FCSTS_FCSTS_Msk
#define CLK_CLKSEL1_LCD_S_Msk
#define LCD_FCSTS_PDSTS_Msk
#define LCD_DISPCTL_Ext_C_Msk
static __INLINE void LCD_DisableDisplay(void)
Disable LCD controller.
Definition: lcd.h:198
#define CLK
Pointer to CLK register structure.
#define LCD_FCR_FCV_Pos
#define LCD_FCR_FCEN_Msk
uint32_t LCD_EnableBlink(uint32_t u32ms)
Enable Blink function in LCD controller.
Definition: lcd.c:376
#define LCD_POWERDOWN_INT
Definition: lcd.h:88
#define SYS_IPRST_CTL2_LCD_RST_Msk
#define LCD_DISPCTL_CPUMP_VOL_SET_Msk
void LCD_DisableInt(uint32_t IntSrc)
This function is used to disable LCD specified interrupt.
Definition: lcd.c:466
uint32_t CyclesPerUs
#define LCD_CTL_PDINT_EN_Msk
#define LCD_CTL_MUX_Pos
void LCD_DisableBlink(void)
Disable Blink function in LCD controller.
Definition: lcd.c:423
Nano102/112 peripheral access layer header file. This file contains all the peripheral register's def...
Definition: lcd.h:98
#define LCD_FRAMECOUNT_INT
Definition: lcd.h:87
uint32_t LCD_EnableFrameCounter(uint32_t u32Count)
Set Frame Count and Enable frame count.
Definition: lcd.c:210
#define LCD_CPUMP_DIV1
Definition: lcd.h:64
Nano102/112 series LCD driver header file.
void LCD_SetPixel(uint32_t u32Com, uint32_t u32Seg, uint32_t u32OnFlag)
Enables a segment on the LCD display.
Definition: lcd.c:62
#define LCD
Pointer to LCD register structure.
#define LCD_FCR_FCV_Msk
uint32_t LCD_Open(uint32_t u32DrivingType, uint32_t u32ComNum, uint32_t u32BiasLevel, uint32_t u32FramerateDiv, uint32_t u32DrivingVol)
LCD Initialization routine.
Definition: lcd.c:287
#define LCD_FCPRESC_DIV8
Definition: lcd.h:85
#define LCD_FCPRESC_DIV1
Definition: lcd.h:82
#define LCD_CTL_FREQ_Pos
#define LCD_CTL_FREQ_Msk
void LCD_DisableFrameCounter(void)
Disable frame count function.
Definition: lcd.c:264
#define LCD_DISPCTL_BV_SEL_Msk
#define LCD_CTL_MUX_Msk
#define LCD_DISPCTL_IBRL_EN_Msk
#define LCD_FCPRESC_DIV2
Definition: lcd.h:83
#define LCD_DISPCTL_CPUMP_FREQ_Msk
#define LCD_DISPCTL_CPUMP_EN_Msk
#define LCD_FCR_PRESCL_Msk
void LCD_Close(void)
The function is used to disable LCD controller.
Definition: lcd.c:362
#define LCD_FCPRESC_DIV4
Definition: lcd.h:84
#define LCD_CTL_BLINK_Msk
#define SYS
Pointer to SYS register structure.
void LCD_EnableInt(uint32_t IntSrc)
This function is used to enable LCD interrupt.
Definition: lcd.c:444
void LCD_SetAllPixels(uint32_t u32OnOff)
LCD Enable/Disable all segments.
Definition: lcd.c:166