]> git.sur5r.net Git - freertos/blob - FreeRTOS/Demo/CORTEX_EFM32_Gecko_Starter_Kit_Simplicity_Studio/Source/SilLabs_Code/emlib/em_lcd.c
Add Pearl Gecko demo.
[freertos] / FreeRTOS / Demo / CORTEX_EFM32_Gecko_Starter_Kit_Simplicity_Studio / Source / SilLabs_Code / emlib / em_lcd.c
1 /***************************************************************************//**\r
2  * @file em_lcd.c\r
3  * @brief Liquid Crystal Display (LCD) Peripheral API\r
4  * @version 4.2.1\r
5  *******************************************************************************\r
6  * @section License\r
7  * <b>(C) Copyright 2015 Silicon Labs, http://www.silabs.com</b>\r
8  *******************************************************************************\r
9  *\r
10  * Permission is granted to anyone to use this software for any purpose,\r
11  * including commercial applications, and to alter it and redistribute it\r
12  * freely, subject to the following restrictions:\r
13  *\r
14  * 1. The origin of this software must not be misrepresented; you must not\r
15  *    claim that you wrote the original software.\r
16  * 2. Altered source versions must be plainly marked as such, and must not be\r
17  *    misrepresented as being the original software.\r
18  * 3. This notice may not be removed or altered from any source distribution.\r
19  *\r
20  * DISCLAIMER OF WARRANTY/LIMITATION OF REMEDIES: Silicon Labs has no\r
21  * obligation to support this Software. Silicon Labs is providing the\r
22  * Software "AS IS", with no express or implied warranties of any kind,\r
23  * including, but not limited to, any implied warranties of merchantability\r
24  * or fitness for any particular purpose or warranties against infringement\r
25  * of any proprietary rights of a third party.\r
26  *\r
27  * Silicon Labs will not be liable for any consequential, incidental, or\r
28  * special damages, or any other relief, or for any claim by any third party,\r
29  * arising from your use of this Software.\r
30  *\r
31  ******************************************************************************/\r
32 \r
33 #include "em_lcd.h"\r
34 #if defined(LCD_COUNT) && (LCD_COUNT > 0)\r
35 #include "em_assert.h"\r
36 #include "em_bus.h"\r
37 \r
38 /***************************************************************************//**\r
39  * @addtogroup EM_Library\r
40  * @{\r
41  ******************************************************************************/\r
42 \r
43 /***************************************************************************//**\r
44  * @addtogroup LCD\r
45  * @brief Liquid Crystal Display (LCD) Peripheral API\r
46  * @{\r
47  ******************************************************************************/\r
48 \r
49 /***************************************************************************//**\r
50  * @brief\r
51  *   Initalize Liquid Crystal Display (LCD) controller\r
52  *\r
53  * @details\r
54  *   This function call will only configure the LCD controller. You must enable\r
55  *   it afterwards, potentially configuring Frame Control and interrupts first\r
56  *   according to requirements.\r
57  *\r
58  * @param[in] lcdInit\r
59  *   Pointer to initialization structure which configures LCD controller.\r
60  *\r
61  ******************************************************************************/\r
62 void LCD_Init(const LCD_Init_TypeDef *lcdInit)\r
63 {\r
64   uint32_t dispCtrl = LCD->DISPCTRL;\r
65 \r
66   EFM_ASSERT(lcdInit != (void *) 0);\r
67 \r
68   /* Disable controller before reconfiguration */\r
69   LCD_Enable(false);\r
70 \r
71   /* Make sure we don't touch other bit fields (i.e. voltage boost) */\r
72   dispCtrl &= ~(0\r
73 #if defined(LCD_DISPCTRL_MUXE)\r
74                 | _LCD_DISPCTRL_MUXE_MASK\r
75 #endif\r
76                 | _LCD_DISPCTRL_MUX_MASK\r
77                 | _LCD_DISPCTRL_BIAS_MASK\r
78                 | _LCD_DISPCTRL_WAVE_MASK\r
79                 | _LCD_DISPCTRL_VLCDSEL_MASK\r
80                 | _LCD_DISPCTRL_CONCONF_MASK);\r
81 \r
82   /* Configure controller according to initialization structure */\r
83   dispCtrl |= lcdInit->mux; /* also configures MUXE */\r
84   dispCtrl |= lcdInit->bias;\r
85   dispCtrl |= lcdInit->wave;\r
86   dispCtrl |= lcdInit->vlcd;\r
87   dispCtrl |= lcdInit->contrast;\r
88 \r
89   /* Update display controller */\r
90   LCD->DISPCTRL = dispCtrl;\r
91 \r
92   /* Enable controller if wanted */\r
93   if (lcdInit->enable)\r
94   {\r
95     LCD_Enable(true);\r
96   }\r
97 }\r
98 \r
99 \r
100 /***************************************************************************//**\r
101  * @brief\r
102  *   Select source for VLCD\r
103  *\r
104  * @param[in] vlcd\r
105  *   Select source for VLD voltage\r
106  ******************************************************************************/\r
107 void LCD_VLCDSelect(LCD_VLCDSel_TypeDef vlcd)\r
108 {\r
109   uint32_t dispctrl = LCD->DISPCTRL;\r
110 \r
111   /* Select VEXT or VDD */\r
112   dispctrl &= ~_LCD_DISPCTRL_VLCDSEL_MASK;\r
113   switch (vlcd)\r
114   {\r
115     case lcdVLCDSelVExtBoost:\r
116       dispctrl |= LCD_DISPCTRL_VLCDSEL_VEXTBOOST;\r
117       break;\r
118     case lcdVLCDSelVDD:\r
119       dispctrl |= LCD_DISPCTRL_VLCDSEL_VDD;\r
120       break;\r
121     default:\r
122       break;\r
123   }\r
124 \r
125   LCD->DISPCTRL = dispctrl;\r
126 }\r
127 \r
128 \r
129 /***************************************************************************//**\r
130  * @brief\r
131  *   Configure Update Control\r
132  *\r
133  * @param[in] ud\r
134  *   Configures LCD update method\r
135  ******************************************************************************/\r
136 void LCD_UpdateCtrl(LCD_UpdateCtrl_TypeDef ud)\r
137 {\r
138   LCD->CTRL = (LCD->CTRL & ~_LCD_CTRL_UDCTRL_MASK) | ud;\r
139 }\r
140 \r
141 \r
142 /***************************************************************************//**\r
143  * @brief\r
144  *   Initialize LCD Frame Counter\r
145  *\r
146  * @param[in] fcInit\r
147  *   Pointer to Frame Counter initialization structure\r
148  ******************************************************************************/\r
149 void LCD_FrameCountInit(const LCD_FrameCountInit_TypeDef *fcInit)\r
150 {\r
151   uint32_t bactrl = LCD->BACTRL;\r
152 \r
153   EFM_ASSERT(fcInit != (void *) 0);\r
154 \r
155   /* Verify FC Top Counter to be within limits */\r
156   EFM_ASSERT(fcInit->top < 64);\r
157 \r
158   /* Reconfigure frame count configuration */\r
159   bactrl &= ~(_LCD_BACTRL_FCTOP_MASK\r
160               | _LCD_BACTRL_FCPRESC_MASK);\r
161   bactrl |= (fcInit->top << _LCD_BACTRL_FCTOP_SHIFT);\r
162   bactrl |= fcInit->prescale;\r
163 \r
164   /* Set Blink and Animation Control Register */\r
165   LCD->BACTRL = bactrl;\r
166 \r
167   LCD_FrameCountEnable(fcInit->enable);\r
168 }\r
169 \r
170 \r
171 /***************************************************************************//**\r
172  * @brief\r
173  *   Configures LCD controller Animation feature\r
174  *\r
175  * @param[in] animInit\r
176  *   Pointer to LCD Animation initialization structure\r
177  ******************************************************************************/\r
178 void LCD_AnimInit(const LCD_AnimInit_TypeDef *animInit)\r
179 {\r
180   uint32_t bactrl = LCD->BACTRL;\r
181 \r
182   EFM_ASSERT(animInit != (void *) 0);\r
183 \r
184   /* Set Animation Register Values */\r
185   LCD->AREGA = animInit->AReg;\r
186   LCD->AREGB = animInit->BReg;\r
187 \r
188   /* Configure Animation Shift and Logic */\r
189   bactrl &= ~(_LCD_BACTRL_AREGASC_MASK\r
190               | _LCD_BACTRL_AREGBSC_MASK\r
191               | _LCD_BACTRL_ALOGSEL_MASK);\r
192 \r
193   bactrl |= (animInit->AShift << _LCD_BACTRL_AREGASC_SHIFT);\r
194   bactrl |= (animInit->BShift << _LCD_BACTRL_AREGBSC_SHIFT);\r
195   bactrl |= animInit->animLogic;\r
196 \r
197 #if defined(LCD_BACTRL_ALOC)\r
198   bactrl &= ~(_LCD_BACTRL_ALOC_MASK);\r
199 \r
200   if(animInit->startSeg == 0)\r
201   {\r
202     bactrl |= LCD_BACTRL_ALOC_SEG0TO7;\r
203   }\r
204   else if(animInit->startSeg == 8)\r
205   {\r
206     bactrl |= LCD_BACTRL_ALOC_SEG8TO15;\r
207   }\r
208 #endif\r
209 \r
210   /* Reconfigure */\r
211   LCD->BACTRL = bactrl;\r
212 \r
213   /* Enable */\r
214   LCD_AnimEnable(animInit->enable);\r
215 }\r
216 \r
217 \r
218 /***************************************************************************//**\r
219  * @brief\r
220  *   Enables update of this range of LCD segment lines\r
221  *\r
222  * @param[in] segmentRange\r
223  *   Range of 4 LCD segments lines to enable or disable, for all enabled COM\r
224  *   lines\r
225  *\r
226  * @param[in] enable\r
227  *   Bool true to enable segment updates, false to disable updates\r
228  ******************************************************************************/\r
229 void LCD_SegmentRangeEnable(LCD_SegmentRange_TypeDef segmentRange, bool enable)\r
230 {\r
231   if (enable)\r
232   {\r
233     LCD->SEGEN |= segmentRange;\r
234   }\r
235   else\r
236   {\r
237     LCD->SEGEN &= ~((uint32_t)segmentRange);\r
238   }\r
239 }\r
240 \r
241 \r
242 /***************************************************************************//**\r
243  * @brief\r
244  *   Turn on or clear a segment\r
245  *\r
246  * @note\r
247  *    On Gecko Family, max configuration is (COM-lines x Segment-Lines) 4x40\r
248  *    On Tiny Family, max configuration is 8x20 or 4x24\r
249  *    On Giant Family, max configuration is 8x36 or 4x40\r
250  *\r
251  * @param[in] com\r
252  *   COM line to change\r
253  *\r
254  * @param[in] bit\r
255  *   Bit index of which field to change\r
256  *\r
257  * @param[in] enable\r
258  *   When true will set segment, when false will clear segment\r
259  ******************************************************************************/\r
260 void LCD_SegmentSet(int com, int bit, bool enable)\r
261 {\r
262 #if defined(_LCD_SEGD7L_MASK)\r
263   /* Tiny and Giant Family supports up to 8 COM lines */\r
264   EFM_ASSERT(com < 8);\r
265 #else\r
266   /* Gecko Family supports up to 4 COM lines */\r
267   EFM_ASSERT(com < 4);\r
268 #endif\r
269 \r
270 #if defined(_LCD_SEGD0H_MASK)\r
271   EFM_ASSERT(bit < 40);\r
272 #else\r
273   /* Tiny Gecko Family supports only "low" segment registers */\r
274   EFM_ASSERT(bit < 32);\r
275 #endif\r
276 \r
277   /* Use bitband access for atomic bit set/clear of segment */\r
278   switch (com)\r
279   {\r
280     case 0:\r
281       if (bit < 32)\r
282       {\r
283         BUS_RegBitWrite(&(LCD->SEGD0L), bit, enable);\r
284       }\r
285 #if defined(_LCD_SEGD0H_MASK)\r
286       else\r
287       {\r
288         bit -= 32;\r
289         BUS_RegBitWrite(&(LCD->SEGD0H), bit, enable);\r
290       }\r
291 #endif\r
292       break;\r
293     case 1:\r
294       if (bit < 32)\r
295       {\r
296         BUS_RegBitWrite(&(LCD->SEGD1L), bit, enable);\r
297       }\r
298 #if defined(_LCD_SEGD1H_MASK)\r
299       else\r
300       {\r
301         bit -= 32;\r
302         BUS_RegBitWrite(&(LCD->SEGD1H), bit, enable);\r
303       }\r
304 #endif\r
305       break;\r
306     case 2:\r
307       if (bit < 32)\r
308       {\r
309         BUS_RegBitWrite(&(LCD->SEGD2L), bit, enable);\r
310       }\r
311 #if defined(_LCD_SEGD2H_MASK)\r
312       else\r
313       {\r
314         bit -= 32;\r
315         BUS_RegBitWrite(&(LCD->SEGD2H), bit, enable);\r
316       }\r
317 #endif\r
318       break;\r
319     case 3:\r
320       if (bit < 32)\r
321       {\r
322         BUS_RegBitWrite(&(LCD->SEGD3L), bit, enable);\r
323       }\r
324 #if defined(_LCD_SEGD3H_MASK)\r
325       else\r
326       {\r
327         bit -= 32;\r
328         BUS_RegBitWrite(&(LCD->SEGD3H), bit, enable);\r
329       }\r
330 #endif\r
331       break;\r
332 #if defined(_LCD_SEGD4L_MASK)\r
333     case 4:\r
334       if (bit < 32)\r
335       {\r
336         BUS_RegBitWrite(&(LCD->SEGD4L), bit, enable);\r
337       }\r
338 #if defined(_LCD_SEGD4H_MASK)\r
339       else\r
340       {\r
341         bit -= 32;\r
342         BUS_RegBitWrite(&(LCD->SEGD4H), bit, enable);\r
343       }\r
344 #endif\r
345       break;\r
346 #endif\r
347 #if defined(_LCD_SEGD5L_MASK)\r
348     case 5:\r
349       if (bit < 32)\r
350       {\r
351         BUS_RegBitWrite(&(LCD->SEGD5L), bit, enable);\r
352       }\r
353 #if defined(_LCD_SEGD5H_MASK)\r
354       else\r
355       {\r
356         bit -= 32;\r
357         BUS_RegBitWrite(&(LCD->SEGD5H), bit, enable);\r
358       }\r
359 #endif\r
360       break;\r
361 #endif\r
362     case 6:\r
363 #if defined(_LCD_SEGD6L_MASK)\r
364       if (bit < 32)\r
365       {\r
366         BUS_RegBitWrite(&(LCD->SEGD6L), bit, enable);\r
367       }\r
368 #if defined(_LCD_SEGD6H_MASK)\r
369       else\r
370       {\r
371         bit -= 32;\r
372         BUS_RegBitWrite(&(LCD->SEGD6H), bit, enable);\r
373       }\r
374 #endif\r
375       break;\r
376 #endif\r
377 #if defined(_LCD_SEGD7L_MASK)\r
378     case 7:\r
379       if (bit < 32)\r
380       {\r
381         BUS_RegBitWrite(&(LCD->SEGD7L), bit, enable);\r
382       }\r
383 #if defined(_LCD_SEGD7H_MASK)\r
384       else\r
385       {\r
386         bit -= 32;\r
387         BUS_RegBitWrite(&(LCD->SEGD7H), bit, enable);\r
388       }\r
389 #endif\r
390       break;\r
391 #endif\r
392 \r
393     default:\r
394       EFM_ASSERT(0);\r
395       break;\r
396   }\r
397 }\r
398 \r
399 \r
400 /***************************************************************************//**\r
401  * @brief\r
402  *   Updates the 0-31 lowest segments on a given COM-line in one operation,\r
403  *   according to bit mask\r
404  *\r
405  * @param[in] com\r
406  *   Which COM line to update\r
407  *\r
408  * @param[in] mask\r
409  *   Bit mask for segments 0-31\r
410  *\r
411  * @param[in] bits\r
412  *   Bit pattern for segments 0-31\r
413  ******************************************************************************/\r
414 void LCD_SegmentSetLow(int com, uint32_t mask, uint32_t bits)\r
415 {\r
416   uint32_t segData;\r
417 \r
418   /* Maximum number of com lines */\r
419 #if defined(_LCD_SEGD7L_MASK)\r
420   EFM_ASSERT(com < 8);\r
421 #else\r
422   /* Gecko Family supports up to 4 COM lines */\r
423   EFM_ASSERT(com < 4);\r
424 #endif\r
425 \r
426   switch (com)\r
427   {\r
428     case 0:\r
429       segData     = LCD->SEGD0L;\r
430       segData    &= ~(mask);\r
431       segData    |= (mask & bits);\r
432       LCD->SEGD0L = segData;\r
433       break;\r
434     case 1:\r
435       segData     = LCD->SEGD1L;\r
436       segData    &= ~(mask);\r
437       segData    |= (mask & bits);\r
438       LCD->SEGD1L = segData;\r
439       break;\r
440     case 2:\r
441       segData     = LCD->SEGD2L;\r
442       segData    &= ~(mask);\r
443       segData    |= (mask & bits);\r
444       LCD->SEGD2L = segData;\r
445       break;\r
446     case 3:\r
447       segData     = LCD->SEGD3L;\r
448       segData    &= ~(mask);\r
449       segData    |= (mask & bits);\r
450       LCD->SEGD3L = segData;\r
451       break;\r
452 #if defined(_LCD_SEGD4L_MASK)\r
453     case 4:\r
454       segData     = LCD->SEGD4L;\r
455       segData    &= ~(mask);\r
456       segData    |= (mask & bits);\r
457       LCD->SEGD4L = segData;\r
458       break;\r
459 #endif\r
460 #if defined(_LCD_SEGD5L_MASK)\r
461     case 5:\r
462       segData     = LCD->SEGD5L;\r
463       segData    &= ~(mask);\r
464       segData    |= (mask & bits);\r
465       LCD->SEGD5L = segData;\r
466       break;\r
467 #endif\r
468 #if defined(_LCD_SEGD6L_MASK)\r
469     case 6:\r
470       segData     = LCD->SEGD6L;\r
471       segData    &= ~(mask);\r
472       segData    |= (mask & bits);\r
473       LCD->SEGD6L = segData;\r
474       break;\r
475 #endif\r
476 #if defined(_LCD_SEGD7L_MASK)\r
477     case 7:\r
478       segData     = LCD->SEGD7L;\r
479       segData    &= ~(mask);\r
480       segData    |= (mask & bits);\r
481       LCD->SEGD7L = segData;\r
482       break;\r
483 #endif\r
484     default:\r
485       EFM_ASSERT(0);\r
486       break;\r
487   }\r
488 }\r
489 \r
490 \r
491 #if defined(_LCD_SEGD0H_MASK)\r
492 /***************************************************************************//**\r
493  * @brief\r
494  *   Updated the high (32-39) segments on a given COM-line in one operation\r
495  *\r
496  * @param[in] com\r
497  *   Which COM line to update\r
498  *\r
499  * @param[in] mask\r
500  *   Bit mask for segments 32-39\r
501  *\r
502  * @param[in] bits\r
503  *   Bit pattern for segments 32-39\r
504  ******************************************************************************/\r
505 void LCD_SegmentSetHigh(int com, uint32_t mask, uint32_t bits)\r
506 {\r
507   uint32_t segData;\r
508 \r
509 #if defined(_LCD_SEGD7H_MASK)\r
510   EFM_ASSERT(com < 8);\r
511 #else\r
512   EFM_ASSERT(com < 4);\r
513 #endif\r
514 \r
515   /* Maximum number of com lines */\r
516   switch (com)\r
517   {\r
518     case 0:\r
519       segData     = LCD->SEGD0H;\r
520       segData    &= ~(mask);\r
521       segData    |= (mask & bits);\r
522       LCD->SEGD0H = segData;\r
523       break;\r
524     case 1:\r
525       segData     = LCD->SEGD1H;\r
526       segData    &= ~(mask);\r
527       segData    |= (mask & bits);\r
528       LCD->SEGD1H = segData;\r
529       break;\r
530     case 2:\r
531       segData     = LCD->SEGD2H;\r
532       segData    &= ~(mask);\r
533       segData    |= (mask & bits);\r
534       LCD->SEGD2H = segData;\r
535       break;\r
536     case 3:\r
537       segData     = LCD->SEGD3H;\r
538       segData    &= ~(mask);\r
539       segData    |= (mask & bits);\r
540       LCD->SEGD3H = segData;\r
541       break;\r
542 #if defined(_LCD_SEGD4H_MASK)\r
543     case 4:\r
544       segData     = LCD->SEGD4H;\r
545       segData    &= ~(mask);\r
546       segData    |= (mask & bits);\r
547       LCD->SEGD4H = segData;\r
548       break;\r
549 #endif\r
550 #if defined(_LCD_SEGD5H_MASK)\r
551     case 5:\r
552       segData     = LCD->SEGD5H;\r
553       segData    &= ~(mask);\r
554       segData    |= (mask & bits);\r
555       LCD->SEGD5H = segData;\r
556       break;\r
557 #endif\r
558 #if defined(_LCD_SEGD6H_MASK)\r
559     case 6:\r
560       segData     = LCD->SEGD6H;\r
561       segData    &= ~(mask);\r
562       segData    |= (mask & bits);\r
563       LCD->SEGD6H = segData;\r
564       break;\r
565 #endif\r
566 #if defined(_LCD_SEGD7H_MASK)\r
567     case 7:\r
568       segData     = LCD->SEGD7H;\r
569       segData    &= ~(mask);\r
570       segData    |= (mask & bits);\r
571       LCD->SEGD7H = segData;\r
572       break;\r
573 #endif\r
574     default:\r
575       break;\r
576   }\r
577 }\r
578 #endif\r
579 \r
580 /***************************************************************************//**\r
581  * @brief\r
582  *   Configure contrast level on LCD panel\r
583  *\r
584  * @param[in] level\r
585  *   Contrast level in the range 0-31\r
586  ******************************************************************************/\r
587 void LCD_ContrastSet(int level)\r
588 {\r
589   EFM_ASSERT(level < 32);\r
590 \r
591   LCD->DISPCTRL = (LCD->DISPCTRL & ~_LCD_DISPCTRL_CONLEV_MASK)\r
592                   | (level << _LCD_DISPCTRL_CONLEV_SHIFT);\r
593 }\r
594 \r
595 \r
596 /***************************************************************************//**\r
597  * @brief\r
598  *   Configure voltage booster\r
599  *\r
600  * The resulting voltage level is described in each part number's data sheet\r
601  *\r
602  * @param[in] vboost\r
603  *   Voltage boost level\r
604  ******************************************************************************/\r
605 void LCD_VBoostSet(LCD_VBoostLevel_TypeDef vboost)\r
606 {\r
607   /* Reconfigure Voltage Boost */\r
608   LCD->DISPCTRL = (LCD->DISPCTRL & ~_LCD_DISPCTRL_VBLEV_MASK) | vboost;\r
609 }\r
610 \r
611 \r
612 #if defined(LCD_CTRL_DSC)\r
613 /***************************************************************************//**\r
614  * @brief\r
615  *   Configure bias level for a specific segment line for Direct Segment Control\r
616  *\r
617  * @note\r
618  *   When DSC is active, each configuration takes up 4 bits in the Segment\r
619  *   Registers (SEGD0L/SEGD1H) which defines bias level.\r
620  *   For optimal use of this feature, the entire SEGD-registers should be set\r
621  *   at once in a optimized routine, so this function is mainly here to\r
622  *   demonstrate how to correctly configure the bias levels, and should be used\r
623  *   with care.\r
624  *\r
625  * @param[in] segmentLine\r
626  *   Segment line number\r
627  *\r
628  * @param[in] biasLevel\r
629  *   Bias configuration level, 0-4. This value must be within the constraint\r
630  *   defined by the LCD_DISPCTRL bias setting, see Reference Manual/Datasheet\r
631  ******************************************************************************/\r
632 void LCD_BiasSegmentSet(int segmentLine, int biasLevel)\r
633 {\r
634   int               biasRegister;\r
635   int               bitShift;\r
636   volatile uint32_t *segmentRegister;\r
637 \r
638 #if !defined(_LCD_SEGD0H_MASK)\r
639   EFM_ASSERT(segmentLine < 20);\r
640 \r
641   /* Bias config for 8 segment lines per SEGDnL register */\r
642   biasRegister = segmentLine / 8;\r
643   bitShift     = (segmentLine % 8) * 4;\r
644 \r
645   switch (biasRegister)\r
646   {\r
647     case 0:\r
648       segmentRegister = &LCD->SEGD0L;\r
649       break;\r
650     case 1:\r
651       segmentRegister = &LCD->SEGD1L;\r
652       break;\r
653     case 2:\r
654       segmentRegister = &LCD->SEGD2L;\r
655       break;\r
656     case 3:\r
657       segmentRegister = &LCD->SEGD3L;\r
658       break;\r
659     default:\r
660       segmentRegister = (uint32_t *)0x00000000;\r
661       EFM_ASSERT(0);\r
662       break;\r
663   }\r
664 #else\r
665   EFM_ASSERT(segmentLine < 40);\r
666 \r
667   /* Bias config for 10 segment lines per SEGDn L+H registers */\r
668   biasRegister = segmentLine / 10;\r
669   bitShift     = (segmentLine % 10) * 4;\r
670 \r
671   switch (biasRegister)\r
672   {\r
673     case 0:\r
674       if (bitShift < 32)\r
675       {\r
676         segmentRegister = &LCD->SEGD0L;\r
677       }\r
678       else\r
679       {\r
680         segmentRegister = &LCD->SEGD0H;\r
681         bitShift       -= 32;\r
682       }\r
683       break;\r
684     case 1:\r
685       if (bitShift < 32)\r
686       {\r
687         segmentRegister = &LCD->SEGD1L;\r
688       }\r
689       else\r
690       {\r
691         segmentRegister = &LCD->SEGD1H;\r
692         bitShift       -= 32;\r
693       }\r
694       break;\r
695     case 2:\r
696       if (bitShift < 32)\r
697       {\r
698         segmentRegister = &LCD->SEGD2L;\r
699       }\r
700       else\r
701       {\r
702         segmentRegister = &LCD->SEGD1H;\r
703         bitShift       -= 32;\r
704       }\r
705       break;\r
706     case 3:\r
707       if (bitShift < 32)\r
708       {\r
709         segmentRegister = &LCD->SEGD3L;\r
710       }\r
711       else\r
712       {\r
713         segmentRegister = &LCD->SEGD3H;\r
714         bitShift       -= 32;\r
715       }\r
716       break;\r
717     default:\r
718       segmentRegister = (uint32_t *)0x00000000;\r
719       EFM_ASSERT(0);\r
720       break;\r
721   }\r
722 #endif\r
723 \r
724   /* Configure new bias setting */\r
725   *segmentRegister = (*segmentRegister & ~(0xF << bitShift)) | (biasLevel << bitShift);\r
726 }\r
727 #endif\r
728 \r
729 \r
730 #if defined(LCD_CTRL_DSC)\r
731 /***************************************************************************//**\r
732  * @brief\r
733  *   Configure bias level for a specific segment line\r
734  *\r
735  * @note\r
736  *   When DSC is active, each configuration takes up 4 bits in the Segment\r
737  *   Registers (SEGD4L/SEGD4H) which defines bias level.\r
738  *   For optimal use of this feature, the entire SEGD-registers should be set\r
739  *   at once in a optimized routine, so this function is mainly here to\r
740  *   demonstrate how to correctly configure the bias levels, and should be used\r
741  *   with care.\r
742  *\r
743  * @param[in] comLine\r
744  *   COM line number, 0-7\r
745  *\r
746  * @param[in] biasLevel\r
747  *   Bias configuration level, 0-4. This value must be within the constraint\r
748  *   defined by the LCD_DISPCTRL bias setting, see Reference Manual/Datasheet\r
749  ******************************************************************************/\r
750 void LCD_BiasComSet(int comLine, int biasLevel)\r
751 {\r
752   int bitShift;\r
753   EFM_ASSERT(comLine < 8);\r
754 \r
755   bitShift    = comLine * 4;\r
756   LCD->SEGD4L = (LCD->SEGD4L & ~(0xF << bitShift)) | (biasLevel << bitShift);\r
757 }\r
758 #endif\r
759 \r
760 /** @} (end addtogroup LCD) */\r
761 /** @} (end addtogroup EM_Library) */\r
762 \r
763 #endif /* defined(LCD_COUNT) && (LCD_COUNT > 0) */\r