This is a driver for the segment LCD found on the Silicon Labs EF32 Giant, Leopard and Wonder Gecko platforms. NOTE: This driver will not work with other platforms, because it contains EFM32-specific code.
Dependents: EFM32 RDA5807M RDS Radio EMF32-Segment-Touch-Demo EMF32_ShowKey blinky_EFM32_Giant ... more
segmentlcd.c
00001 /**************************************************************************//** 00002 * @file 00003 * @brief EFM32 Segment LCD Display driver 00004 * @version 3.20.9 00005 ****************************************************************************** 00006 * @section License 00007 * <b>(C) Copyright 2014 Silicon Labs, http://www.silabs.com</b> 00008 ******************************************************************************* 00009 * 00010 * This file is licensensed under the Silabs License Agreement. See the file 00011 * "Silabs_License_Agreement.txt" for details. Before using this software for 00012 * any purpose, you must agree to the terms of that agreement. 00013 * 00014 ******************************************************************************/ 00015 00016 #include <stdio.h> 00017 #include <string.h> 00018 #include <stdlib.h> 00019 #include <stdbool.h> 00020 #include "em_device.h" 00021 #include "em_cmu.h" 00022 #include "em_gpio.h" 00023 00024 #include "device_peripherals.h" 00025 00026 #include "segmentlcd.h" 00027 00028 /**************************************************************************//** 00029 * @brief 00030 * Defines each text symbol's segment in terms of COM and BIT numbers, 00031 * in a way that we can enumerate each bit for each text segment in the 00032 * following bit pattern: 00033 * @verbatim 00034 * -------0------ 00035 * 00036 * | \7 |8 /9 | 00037 * |5 \ | / |1 00038 * 00039 * --6--- ---10-- 00040 * 00041 * | / | \11 | 00042 * |4 /13 |12 \ |2 00043 * 00044 * -------3------ 00045 * @endverbatim 00046 * E.g.: First text character bit pattern #3 (above) is 00047 * Segment 1D for Display 00048 * Location COM 3, BIT 0 00049 *****************************************************************************/ 00050 typedef struct 00051 { 00052 uint8_t com[14]; /**< LCD COM line (for multiplexing) */ 00053 uint8_t bit[14]; /**< LCD bit number */ 00054 } CHAR_TypeDef; 00055 00056 00057 /**************************************************************************//** 00058 * @brief Defines segment COM and BIT fields numeric display 00059 *****************************************************************************/ 00060 typedef struct 00061 { 00062 uint8_t com[7]; /**< LCD COM line (for multiplexing) */ 00063 uint8_t bit[7]; /**< LCD bit number */ 00064 } NUMBER_TypeDef; 00065 00066 /**************************************************************************//** 00067 * @brief Defines segment COM and BIT fields for Energy Modes on display 00068 *****************************************************************************/ 00069 typedef struct 00070 { 00071 uint8_t com[5]; /**< LCD COM line (for multiplexing) */ 00072 uint8_t bit[5]; /**< LCD bit number */ 00073 } EM_TypeDef; 00074 00075 /**************************************************************************//** 00076 * @brief Defines segment COM and BIT fields for A-wheel (suited for Anim) 00077 *****************************************************************************/ 00078 typedef struct 00079 { 00080 uint8_t com[8]; /**< LCD COM line (for multiplexing) */ 00081 uint8_t bit[8]; /**< LCD bit number */ 00082 } ARING_TypeDef; 00083 00084 /**************************************************************************//** 00085 * @brief Defines segment COM and BIT fields for A-wheel (suited for Anim) 00086 *****************************************************************************/ 00087 typedef struct 00088 { 00089 uint8_t com[4]; /**< LCD COM line (for multiplexing) */ 00090 uint8_t bit[4]; /**< LCD bit number */ 00091 } BATTERY_TypeDef; 00092 00093 /**************************************************************************//** 00094 * @brief Defines prototype for all segments in display 00095 *****************************************************************************/ 00096 typedef struct 00097 { 00098 CHAR_TypeDef Text[7]; /**< Text on display */ 00099 NUMBER_TypeDef Number[4]; /**< Numbers on display */ 00100 EM_TypeDef EMode; /**< Display energy mode */ 00101 ARING_TypeDef ARing; /**< Display ring */ 00102 BATTERY_TypeDef Battery; /**< Display battery */ 00103 } MCU_DISPLAY; 00104 00105 /**************************************************************************//** 00106 * @brief Working instance of LCD display 00107 *****************************************************************************/ 00108 static const MCU_DISPLAY EFM_Display = EFM_DISPLAY_DEF; 00109 00110 00111 /**************************************************************************//** 00112 * @brief 00113 * Defines higlighted segments for the alphabet, starting from "blank" (SPACE) 00114 * Uses bit pattern as defined for text segments above. 00115 * E.g. a capital O, would have bits 0 1 2 3 4 5 => 0x003f defined 00116 *****************************************************************************/ 00117 static const uint16_t EFM_Alphabet[] = { 00118 0x0000, /* space */ 00119 0x1100, /* ! */ 00120 0x0280, /* " */ 00121 0x0000, /* # */ 00122 0x0000, /* $ */ 00123 0x0602, /* % */ 00124 0x0000, /* & */ 00125 0x0020, /* ' */ 00126 0x0039, /* ( */ 00127 0x000f, /* ) */ 00128 0x0000, /* * */ 00129 0x1540, /* + */ 00130 0x2000, /* , */ 00131 0x0440, /* - */ 00132 0x1000, /* . */ 00133 0x2200, /* / */ 00134 00135 0x003f, /* 0 */ 00136 0x0006, /* 1 */ 00137 0x045b, /* 2 */ 00138 0x044f, /* 3 */ 00139 0x0466, /* 4 */ 00140 0x046d, /* 5 */ 00141 0x047d, /* 6 */ 00142 0x0007, /* 7 */ 00143 0x047f, /* 8 */ 00144 0x046f, /* 9 */ 00145 00146 0x0000, /* : */ 00147 0x0000, /* ; */ 00148 0x0a00, /* < */ 00149 0x0000, /* = */ 00150 0x2080, /* > */ 00151 0x0000, /* ? */ 00152 0xffff, /* @ */ 00153 00154 0x0477, /* A */ 00155 0x0a79, /* B */ 00156 0x0039, /* C */ 00157 0x20b0, /* D */ 00158 0x0079, /* E */ 00159 0x0071, /* F */ 00160 0x047d, /* G */ 00161 0x0476, /* H */ 00162 0x0006, /* I */ 00163 0x000e, /* J */ 00164 0x0a70, /* K */ 00165 0x0038, /* L */ 00166 0x02b6, /* M */ 00167 0x08b6, /* N */ 00168 0x003f, /* O */ 00169 0x0473, /* P */ 00170 0x083f, /* Q */ 00171 0x0c73, /* R */ 00172 0x046d, /* S */ 00173 0x1101, /* T */ 00174 0x003e, /* U */ 00175 0x2230, /* V */ 00176 0x2836, /* W */ 00177 0x2a80, /* X */ 00178 0x046e, /* Y */ 00179 0x2209, /* Z */ 00180 00181 0x0039, /* [ */ 00182 0x0880, /* backslash */ 00183 0x000f, /* ] */ 00184 0x0001, /* ^ */ 00185 0x0008, /* _ */ 00186 0x0100, /* ` */ 00187 00188 0x1058, /* a */ 00189 0x047c, /* b */ 00190 0x0058, /* c */ 00191 0x045e, /* d */ 00192 0x2058, /* e */ 00193 0x0471, /* f */ 00194 0x0c0c, /* g */ 00195 0x0474, /* h */ 00196 0x0004, /* i */ 00197 0x000e, /* j */ 00198 0x0c70, /* k */ 00199 0x0038, /* l */ 00200 0x1454, /* m */ 00201 0x0454, /* n */ 00202 0x045c, /* o */ 00203 0x0473, /* p */ 00204 0x0467, /* q */ 00205 0x0450, /* r */ 00206 0x0c08, /* s */ 00207 0x0078, /* t */ 00208 0x001c, /* u */ 00209 0x2010, /* v */ 00210 0x2814, /* w */ 00211 0x2a80, /* x */ 00212 0x080c, /* y */ 00213 0x2048, /* z */ 00214 00215 0x0000, 00216 }; 00217 00218 /**************************************************************************//** 00219 * @brief 00220 * Defines higlighted segments for the numeric display 00221 *****************************************************************************/ 00222 00223 static const uint16_t EFM_Numbers[] = { 00224 0x003f, /* 0 */ 00225 0x0006, /* 1 */ 00226 0x005b, /* 2 */ 00227 0x004f, /* 3 */ 00228 0x0066, /* 4 */ 00229 0x006d, /* 5 */ 00230 0x007d, /* 6 */ 00231 0x0007, /* 7 */ 00232 0x007f, /* 8 */ 00233 0x006f, /* 9 */ 00234 0x0077, /* A */ 00235 0x007c, /* b */ 00236 0x0039, /* C */ 00237 0x005e, /* d */ 00238 0x0079, /* E */ 00239 0x0071, /* F */ 00240 0x0040 /* - */ 00241 }; 00242 00243 /** @cond DO_NOT_INCLUDE_WITH_DOXYGEN */ 00244 /* sign is last element of the table */ 00245 static const uint16_t signIndex = sizeof(EFM_Numbers)/sizeof(uint16_t) - 1 ; 00246 00247 static const LCD_Init_TypeDef lcdInit = LCD_INIT_DEF; 00248 /** @endcond */ 00249 00250 00251 /**************************************************************************//** 00252 * @brief Disable all segments 00253 *****************************************************************************/ 00254 void SegmentLCD_AllOff(void) 00255 { 00256 /* Turn on low segments */ 00257 LCD_ALL_SEGMENTS_OFF(); 00258 } 00259 00260 00261 /**************************************************************************//** 00262 * @brief Enable all segments 00263 *****************************************************************************/ 00264 void SegmentLCD_AllOn(void) 00265 { 00266 LCD_ALL_SEGMENTS_ON(); 00267 } 00268 00269 00270 /**************************************************************************//** 00271 * @brief Turn all segments on alpha characters in display off 00272 *****************************************************************************/ 00273 void SegmentLCD_AlphaNumberOff(void) 00274 { 00275 LCD_ALPHA_NUMBER_OFF(); 00276 return; 00277 } 00278 00279 00280 /**************************************************************************//** 00281 * @brief Light up or shut off Ring of Indicators 00282 * @param anum "Segment number" on "Ring", range 0 - 7 00283 * @param on Zero is off, non-zero is on 00284 *****************************************************************************/ 00285 void SegmentLCD_ARing(int anum, int on) 00286 { 00287 uint32_t com, bit; 00288 00289 com = EFM_Display.ARing.com[anum]; 00290 bit = EFM_Display.ARing.bit[anum]; 00291 00292 if (on) 00293 { 00294 LCD_SegmentSet(com, bit, true); 00295 } 00296 else 00297 { 00298 LCD_SegmentSet(com, bit, false); 00299 } 00300 } 00301 00302 00303 /**************************************************************************//** 00304 * @brief Light up or shut off Battery Indicator 00305 * @param batteryLevel Battery Level, 0 to 4 (0 turns all off) 00306 *****************************************************************************/ 00307 void SegmentLCD_Battery(int batteryLevel) 00308 { 00309 uint32_t com, bit; 00310 int i, on; 00311 00312 for (i = 0; i < 4; i++) 00313 { 00314 if (i < batteryLevel) 00315 { 00316 on = 1; 00317 } 00318 else 00319 { 00320 on = 0; 00321 } 00322 com = EFM_Display.Battery.com[i]; 00323 bit = EFM_Display.Battery.bit[i]; 00324 00325 if (on) 00326 { 00327 LCD_SegmentSet(com, bit, true); 00328 } 00329 else 00330 { 00331 LCD_SegmentSet(com, bit, false); 00332 } 00333 } 00334 } 00335 00336 00337 /**************************************************************************//** 00338 * @brief Disables LCD controller 00339 *****************************************************************************/ 00340 void SegmentLCD_Disable(void) 00341 { 00342 /* Disable LCD */ 00343 LCD_Enable(false); 00344 00345 /* Make sure CTRL register has been updated */ 00346 LCD_SyncBusyDelay(LCD_SYNCBUSY_CTRL); 00347 00348 /* Turn off LCD clock */ 00349 CMU_ClockEnable(cmuClock_LCD, false); 00350 00351 /* Turn off voltage boost if enabled */ 00352 CMU->LCDCTRL = 0; 00353 } 00354 00355 00356 /**************************************************************************//** 00357 * @brief Light up or shut off Energy Mode indicator 00358 * @param em Energy Mode numer 0 to 4 00359 * @param on Zero is off, non-zero is on 00360 *****************************************************************************/ 00361 void SegmentLCD_EnergyMode(int em, int on) 00362 { 00363 uint32_t com, bit; 00364 00365 com = EFM_Display.EMode.com[em]; 00366 bit = EFM_Display.EMode.bit[em]; 00367 00368 if (on) 00369 { 00370 LCD_SegmentSet(com, bit, true); 00371 } 00372 else 00373 { 00374 LCD_SegmentSet(com, bit, false); 00375 } 00376 } 00377 00378 /**************************************************************************//** 00379 * @brief Get frame rate division value corresponding to mux selection 00380 * @param mux enum 00381 *****************************************************************************/ 00382 uint8_t SegmentLCD_GetFrameRateDiv(LCD_Mux_TypeDef muxSetting) { 00383 switch(muxSetting) { 00384 /** Static (segments can be multiplexed with LCD_COM[0]) */ 00385 case lcdMuxStatic: return 2; 00386 /** Duplex / 1/2 Duty cycle (segments can be multiplexed with LCD_COM[0:1]) */ 00387 case lcdMuxDuplex: return 4; 00388 /** Triplex / 1/3 Duty cycle (segments can be multiplexed with LCD_COM[0:2]) */ 00389 case lcdMuxTriplex: return 6; 00390 /** Quadruplex / 1/4 Duty cycle (segments can be multiplexed with LCD_COM[0:3]) */ 00391 case lcdMuxQuadruplex: return 8; 00392 #if defined(_EFM32_TINY_FAMILY) || defined(_EFM32_GIANT_FAMILY) || defined(_EFM32_WONDER_FAMILY) 00393 /** Sextaplex / 1/6 Duty cycle (segments can be multiplexed with LCD_COM[0:5]) */ 00394 case lcdMuxSextaplex: return 12; 00395 /** Octaplex / 1/6 Duty cycle (segments can be multiplexed with LCD_COM[0:5]) */ 00396 case lcdMuxOctaplex: return 16; 00397 #endif 00398 default: return 1; 00399 } 00400 } 00401 00402 /**************************************************************************//** 00403 * @brief Segment LCD Initialization routine for EFM32 STK display 00404 * @param useBoost Set to use voltage boost 00405 *****************************************************************************/ 00406 void SegmentLCD_Init(bool useBoost) 00407 { 00408 00409 /* Ensure LE modules are accessible */ 00410 CMU_ClockEnable(cmuClock_CORELE, true); 00411 00412 /* Enable LFRCO as LFACLK in CMU (will also enable oscillator if not enabled) */ 00413 CMU_ClockSelectSet(cmuClock_LFA, cmuSelect_LFRCO); 00414 00415 /* LCD Controller Prescaler */ 00416 00417 /* Calculate value. Approach 50Hz for framerate. */ 00418 uint32_t prescaler = (LOW_ENERGY_CLOCK_FREQUENCY / 32) / SegmentLCD_GetFrameRateDiv(lcdInit.mux); 00419 00420 CMU_ClockDivSet(cmuClock_LCDpre, prescaler); 00421 00422 /* Frame Rate */ 00423 CMU_LCDClkFDIVSet(0); 00424 00425 /* Enable clock to LCD module */ 00426 CMU_ClockEnable(cmuClock_LCD, true); 00427 00428 LCD_DISPLAY_ENABLE(); 00429 00430 /* Disable interrupts */ 00431 LCD_IntDisable(0xFFFFFFFF); 00432 00433 /* Initialize and enable LCD controller */ 00434 LCD_Init(&lcdInit); 00435 00436 /* Enable all display segments */ 00437 LCD_SEGMENTS_ENABLE(); 00438 00439 /* Enable boost if necessary */ 00440 if (useBoost) 00441 { 00442 LCD_VBoostSet(LCD_BOOST_LEVEL); 00443 LCD_VLCDSelect(lcdVLCDSelVExtBoost); 00444 CMU->LCDCTRL |= CMU_LCDCTRL_VBOOSTEN; 00445 } 00446 00447 /* Turn all segments off */ 00448 SegmentLCD_AllOff(); 00449 00450 LCD_SyncBusyDelay(0xFFFFFFFF); 00451 } 00452 00453 00454 /**************************************************************************//** 00455 * @brief Write a hexadecimal number on lower alphanumeric part of 00456 * Segment LCD display 00457 * @param num Hexadecimal number value to put on display, in range 0 00458 * to 0x0FFFFFFF 00459 *****************************************************************************/ 00460 void SegmentLCD_LowerHex( uint32_t num ) 00461 { 00462 int i; 00463 char str[7]; 00464 uint32_t nibble; 00465 00466 SegmentLCD_Symbol(LCD_SYMBOL_MINUS, 0); 00467 00468 for ( i=6; i>=0; i-- ) 00469 { 00470 nibble = num & 0xF; 00471 00472 if ( nibble < 10 ) 00473 str[i] = nibble + '0'; 00474 else if ( nibble == 11 ) 00475 str[i] = 'b'; 00476 else if ( nibble == 13 ) 00477 str[i] = 'd'; 00478 else 00479 str[i] = (nibble - 10) + 'A'; 00480 00481 num >>= 4; 00482 } 00483 00484 SegmentLCD_Write(str); 00485 } 00486 00487 /**************************************************************************//** 00488 * @brief Write number on lower alphanumeric part of Segment LCD display 00489 * @param num Numeric value to put on display, in range -9999999 to +9999999 00490 *****************************************************************************/ 00491 void SegmentLCD_LowerNumber( int num ) 00492 { 00493 int i; 00494 char str[7]; 00495 00496 SegmentLCD_Symbol(LCD_SYMBOL_MINUS, 0); 00497 00498 if ( ( num > 9999999 ) || ( num < -9999999 ) ) 00499 { 00500 SegmentLCD_Write("Ovrflow"); 00501 return; 00502 } 00503 00504 if ( num < 0 ) 00505 { 00506 SegmentLCD_Symbol(LCD_SYMBOL_MINUS, 1); 00507 num = -num; 00508 } 00509 00510 for ( i=6; i>=0; i-- ) 00511 { 00512 if ( ( i < 6 ) && ( num == 0 ) ) 00513 { 00514 str[i] = ' '; 00515 } 00516 else 00517 { 00518 str[i] = (num % 10) + '0'; 00519 num /= 10; 00520 } 00521 } 00522 00523 SegmentLCD_Write(str); 00524 } 00525 00526 00527 /**************************************************************************//** 00528 * @brief Write number on numeric part on Segment LCD display 00529 * @param value Numeric value to put on display, in range -999 to +9999 00530 *****************************************************************************/ 00531 void SegmentLCD_Number(int value) 00532 { 00533 int i, com, bit, digit, div, neg; 00534 uint16_t bitpattern; 00535 uint16_t num; 00536 00537 /* Parameter consistancy check */ 00538 if (value >= 9999) 00539 { 00540 value = 9999; 00541 } 00542 if (value <= -1000) 00543 { 00544 value = -999; 00545 } 00546 if (value < 0) 00547 { 00548 value = abs(value); 00549 neg = 1; 00550 } 00551 else 00552 { 00553 neg = 0; 00554 } 00555 00556 /* If an update is in progress we must block, or there might be tearing */ 00557 LCD_SyncBusyDelay(0xFFFFFFFF); 00558 00559 /* Freeze updates to avoid partial refresh of display */ 00560 LCD_FreezeEnable(true); 00561 00562 /* Turn off all number LCD segments */ 00563 SegmentLCD_NumberOff(); 00564 00565 /* Extract useful digits */ 00566 div = 1; 00567 for (digit = 0; digit < 4; digit++) 00568 { 00569 num = (value / div) % 10; 00570 if ((neg == 1) && (digit == 3)) num = signIndex; 00571 /* Get number layout of display */ 00572 bitpattern = EFM_Numbers[num]; 00573 for (i = 0; i < 7; i++) 00574 { 00575 bit = EFM_Display.Number[digit].bit[i]; 00576 com = EFM_Display.Number[digit].com[i]; 00577 if (bitpattern & (1 << i)) 00578 { 00579 LCD_SegmentSet(com, bit, true); 00580 } 00581 } 00582 div = div * 10; 00583 } 00584 /* Sync LCD registers to LE domain */ 00585 LCD_FreezeEnable(false); 00586 } 00587 00588 00589 /**************************************************************************//** 00590 * @brief Turn all segments on numeric digits in display off 00591 *****************************************************************************/ 00592 void SegmentLCD_NumberOff(void) 00593 { 00594 /* Turn off all number segments */ 00595 LCD_NUMBER_OFF(); 00596 return; 00597 } 00598 00599 00600 /**************************************************************************//** 00601 * @brief Light up or shut off various symbols on Segment LCD 00602 * @param s Which symbol to turn on or off 00603 * @param on Zero is off, non-zero is on 00604 *****************************************************************************/ 00605 void SegmentLCD_Symbol(lcdSymbol s, int on) 00606 { 00607 int com = 0; 00608 int bit = 0; 00609 00610 switch (s) 00611 { 00612 case LCD_SYMBOL_GECKO: 00613 com = LCD_SYMBOL_GECKO_COM; 00614 bit = LCD_SYMBOL_GECKO_SEG; 00615 break; 00616 case LCD_SYMBOL_ANT: 00617 com = LCD_SYMBOL_ANT_COM; 00618 bit = LCD_SYMBOL_ANT_SEG; 00619 break; 00620 case LCD_SYMBOL_PAD0: 00621 com = LCD_SYMBOL_PAD0_COM; 00622 bit = LCD_SYMBOL_PAD0_SEG; 00623 break; 00624 case LCD_SYMBOL_PAD1: 00625 com = LCD_SYMBOL_PAD1_COM; 00626 bit = LCD_SYMBOL_PAD1_SEG; 00627 break; 00628 case LCD_SYMBOL_EFM32: 00629 com = LCD_SYMBOL_EFM32_COM; 00630 bit = LCD_SYMBOL_EFM32_SEG; 00631 break; 00632 case LCD_SYMBOL_MINUS: 00633 com = LCD_SYMBOL_MINUS_COM; 00634 bit = LCD_SYMBOL_MINUS_SEG; 00635 break; 00636 case LCD_SYMBOL_COL3: 00637 com = LCD_SYMBOL_COL3_COM; 00638 bit = LCD_SYMBOL_COL3_SEG; 00639 break; 00640 case LCD_SYMBOL_COL5: 00641 com = LCD_SYMBOL_COL5_COM; 00642 bit = LCD_SYMBOL_COL5_SEG; 00643 break; 00644 case LCD_SYMBOL_COL10: 00645 com = LCD_SYMBOL_COL10_COM; 00646 bit = LCD_SYMBOL_COL10_SEG; 00647 break; 00648 #ifdef LCD_SYMBOL_DEGC_SEG 00649 case LCD_SYMBOL_DEGC: 00650 com = LCD_SYMBOL_DEGC_COM; 00651 bit = LCD_SYMBOL_DEGC_SEG; 00652 break; 00653 #endif 00654 #ifdef LCD_SYMBOL_DEGF_SEG 00655 case LCD_SYMBOL_DEGF: 00656 com = LCD_SYMBOL_DEGF_COM; 00657 bit = LCD_SYMBOL_DEGF_SEG; 00658 break; 00659 #endif 00660 #ifdef LCD_SYMBOL_DP2_SEG 00661 case LCD_SYMBOL_DP2: 00662 com = LCD_SYMBOL_DP2_COM; 00663 bit = LCD_SYMBOL_DP2_SEG; 00664 break; 00665 #endif 00666 #ifdef LCD_SYMBOL_DP3_SEG 00667 case LCD_SYMBOL_DP3: 00668 com = LCD_SYMBOL_DP3_COM; 00669 bit = LCD_SYMBOL_DP3_SEG; 00670 break; 00671 #endif 00672 #ifdef LCD_SYMBOL_DP4_SEG 00673 case LCD_SYMBOL_DP4: 00674 com = LCD_SYMBOL_DP4_COM; 00675 bit = LCD_SYMBOL_DP4_SEG; 00676 break; 00677 #endif 00678 #ifdef LCD_SYMBOL_DP5_SEG 00679 case LCD_SYMBOL_DP5: 00680 com = LCD_SYMBOL_DP5_COM; 00681 bit = LCD_SYMBOL_DP5_SEG; 00682 break; 00683 #endif 00684 case LCD_SYMBOL_DP6: 00685 com = LCD_SYMBOL_DP6_COM; 00686 bit = LCD_SYMBOL_DP6_SEG; 00687 break; 00688 case LCD_SYMBOL_DP10: 00689 com = LCD_SYMBOL_DP10_COM; 00690 bit = LCD_SYMBOL_DP10_SEG; 00691 break; 00692 #ifdef LCD_SYMBOL_AM_SEG 00693 case LCD_SYMBOL_AM: 00694 com = LCD_SYMBOL_AM_COM; 00695 bit = LCD_SYMBOL_AM_SEG; 00696 break; 00697 #endif 00698 #ifdef LCD_SYMBOL_PM_SEG 00699 case LCD_SYMBOL_PM: 00700 com = LCD_SYMBOL_PM_COM; 00701 bit = LCD_SYMBOL_PM_SEG; 00702 break; 00703 #endif 00704 #ifdef LCD_SYMBOL_MICROAMP_SEG 00705 case LCD_SYMBOL_MICROAMP: 00706 com = LCD_SYMBOL_MICROAMP_COM; 00707 bit = LCD_SYMBOL_MICROAMP_SEG; 00708 break; 00709 #endif 00710 #ifdef LCD_SYMBOL_MILLIAMP_SEG 00711 case LCD_SYMBOL_MILLIAMP: 00712 com = LCD_SYMBOL_MILLIAMP_COM; 00713 bit = LCD_SYMBOL_MILLIAMP_SEG; 00714 break; 00715 #endif 00716 00717 } 00718 if (on) 00719 { 00720 LCD_SegmentSet(com, bit, true); 00721 } 00722 else 00723 { 00724 LCD_SegmentSet(com, bit, false); 00725 } 00726 } 00727 00728 00729 /**************************************************************************//** 00730 * @brief Write hexadecimal number on numeric part on Segment LCD display 00731 * @param value Numeric value to put on display, in range 0x0000-0xFFFF 00732 *****************************************************************************/ 00733 void SegmentLCD_UnsignedHex(uint16_t value) 00734 { 00735 int num, i, com, bit, digit; 00736 uint16_t bitpattern; 00737 00738 /* Parameter consistancy check */ 00739 if (value >= 0xffff) 00740 { 00741 value = 0xffff; 00742 } 00743 00744 /* If an update is in progress we must block, or there might be tearing */ 00745 LCD_SyncBusyDelay(0xFFFFFFFF); 00746 00747 /* Freeze updates to avoid partial refresh of display */ 00748 LCD_FreezeEnable(true); 00749 00750 /* Turn off all number LCD segments */ 00751 SegmentLCD_NumberOff(); 00752 00753 for (digit = 0; digit < 4; digit++) 00754 { 00755 num = (value >> (4 * digit)) & 0x0f; 00756 bitpattern = EFM_Numbers[num]; 00757 for (i = 0; i < 7; i++) 00758 { 00759 bit = EFM_Display.Number[digit].bit[i]; 00760 com = EFM_Display.Number[digit].com[i]; 00761 if (bitpattern & (1 << i)) 00762 { 00763 LCD_SegmentSet(com, bit, true); 00764 } 00765 } 00766 } 00767 00768 /* Sync LCD registers to LE domain */ 00769 LCD_FreezeEnable(false); 00770 } 00771 00772 00773 /**************************************************************************//** 00774 * @brief Write text on LCD display 00775 * @param string Text string to show on display 00776 *****************************************************************************/ 00777 void SegmentLCD_Write(char *string) 00778 { 00779 int data, length, index; 00780 uint16_t bitfield; 00781 uint32_t com, bit; 00782 int i; 00783 00784 length = strlen(string); 00785 index = 0; 00786 00787 /* If an update is in progress we must block, or there might be tearing */ 00788 LCD_SyncBusyDelay(0xFFFFFFFF); 00789 00790 /* Freeze LCD to avoid partial updates */ 00791 LCD_FreezeEnable(true); 00792 00793 /* Turn all segments off */ 00794 SegmentLCD_AlphaNumberOff(); 00795 00796 /* Fill out all characters on display */ 00797 for (index = 0; index < 7; index++) 00798 { 00799 if (index < length) 00800 { 00801 data = (int) *string; 00802 } 00803 else /* Padding with space */ 00804 { 00805 data = 0x20; /* SPACE */ 00806 } 00807 /* Defined letters currently starts at "SPACE" - ASCII 0x20; */ 00808 data = data - 0x20; 00809 /* Get font for this letter */ 00810 bitfield = EFM_Alphabet[data]; 00811 00812 for (i = 0; i < 14; i++) 00813 { 00814 bit = EFM_Display.Text[index].bit[i]; 00815 com = EFM_Display.Text[index].com[i]; 00816 00817 if (bitfield & (1 << i)) 00818 { 00819 /* Turn on segment */ 00820 LCD_SegmentSet(com, bit, true); 00821 } 00822 } 00823 string++; 00824 } 00825 /* Enable update */ 00826 LCD_FreezeEnable(false); 00827 }
Generated on Thu Jul 14 2022 05:15:53 by 1.7.2