Salem TANG / SLCD

Dependents:   FRDM-KL46Z_Debug

Fork of SLCD by Erik -

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers SLCD.cpp Source File

SLCD.cpp

Go to the documentation of this file.
00001 /**
00002  * @file   SLCD.cpp
00003  * @brief  Abstract
00004  * @copyright (c) 
00005  */
00006 // -----------------------------------------------------------------------------
00007 //  note
00008 // -----------------------------------------------------------------------------
00009 
00010 // -----------------------------------------------------------------------------
00011 //  include files
00012 // -----------------------------------------------------------------------------
00013 #include "SLCD.h"
00014 #include "LCDconfig.h"
00015 
00016 // -----------------------------------------------------------------------------
00017 //  general define
00018 // -----------------------------------------------------------------------------
00019 
00020 // -----------------------------------------------------------------------------
00021 //  struct define
00022 // -----------------------------------------------------------------------------
00023 const uint8_t WF_ORDERING_TABLE[ ] = {
00024     CHAR1a,   // LCD81 --- Pin:5  LCDnAddress=51
00025     CHAR1b,   // LCD82 --- Pin:6  LCDnAddress=52
00026     CHAR2a,   // LCD83 --- Pin:7  LCDnAddress=53
00027     CHAR2b,   // LCD84 --- Pin:8  LCDnAddress=54
00028     CHAR3a,   // LCD85 --- Pin:9  LCDnAddress=55
00029     CHAR3b,   // LCD86 --- Pin:10 LCDnAddress=56
00030     CHAR4a,   // LCD87 --- Pin:11 LCDnAddress=57
00031     CHAR4b,   // LCD88 --- Pin:12 LCDnAddress=58
00032     CHARCOM0, // LCD77 --- Pin:1  LCDnAddress=4D
00033     CHARCOM1, // LCD78 --- Pin:2  LCDnAddress=4E
00034     CHARCOM2, // LCD79 --- Pin:3  LCDnAddress=4F
00035     CHARCOM3, // LCD80 --- Pin:4  LCDnAddress=50
00036 };
00037 
00038 const char ASCII_TO_WF_CODIFICATION_TABLE [ ] = {
00039 
00040     /*
00041                    segA
00042                  ________
00043                 |        |
00044            segF |        | segB
00045                 |        |
00046                  -segG--
00047                 |        |
00048            segE |        | segC
00049                 |________|
00050                    segD
00051     */
00052 
00053     ( SEGD+ SEGE+ SEGF+!SEGG) , ( SEGC+ SEGB+ SEGA) ,//Char = 0,   offset=0
00054     (!SEGD+!SEGE+!SEGF+!SEGG) , ( SEGC+ SEGB+!SEGA) ,//Char = 1,   offset=4
00055     ( SEGD+ SEGE+!SEGF+ SEGG) , (!SEGC+ SEGB+ SEGA) ,//Char = 2,   offset=8
00056     ( SEGD+!SEGE+!SEGF+ SEGG) , ( SEGC+ SEGB+ SEGA) ,//Char = 3,   offset=12
00057     (!SEGD+!SEGE+ SEGF+ SEGG) , ( SEGC+ SEGB+!SEGA) ,//Char = 4,   offset=16
00058     ( SEGD+!SEGE+ SEGF+ SEGG) , ( SEGC+!SEGB+ SEGA) ,//Char = 5,   offset=20
00059     ( SEGD+ SEGE+ SEGF+ SEGG) , ( SEGC+!SEGB+ SEGA) ,//Char = 6,   offset=24
00060     (!SEGD+!SEGE+!SEGF+!SEGG) , ( SEGC+ SEGB+ SEGA) ,//Char = 7,   offset=28
00061     ( SEGD+ SEGE+ SEGF+ SEGG) , ( SEGC+ SEGB+ SEGA) ,//Char = 8,   offset=32
00062     ( SEGD+!SEGE+ SEGF+ SEGG) , ( SEGC+ SEGB+ SEGA) ,//Char = 9,   offset=36
00063     (!SEGD+!SEGE+!SEGF+!SEGG) , (!SEGC+!SEGB+!SEGA) ,//Char = :,   offset=40
00064     (!SEGD+!SEGE+!SEGF+!SEGG) , (!SEGC+!SEGB+!SEGA) ,//Char = ;,   offset=44
00065     (!SEGD+!SEGE+!SEGF+!SEGG) , (!SEGC+!SEGB+!SEGA) ,//Char = <,   offset=48
00066     ( SEGD+!SEGE+!SEGF+ SEGG) , (!SEGC+!SEGB+!SEGA) ,//Char = =,   offset=52
00067     (!SEGD+!SEGE+!SEGF+!SEGG) , (!SEGC+!SEGB+!SEGA) ,//Char = >,   offset=56
00068     (!SEGD+!SEGE+!SEGF+!SEGG) , (!SEGC+!SEGB+ SEGA) ,//Char = ?,   offset=60
00069     ( SEGD+ SEGE+ SEGF+ SEGG) , ( SEGC+ SEGB+ SEGA) ,//Char = @,   offset=64
00070     (!SEGD+ SEGE+ SEGF+ SEGG) , ( SEGC+ SEGB+ SEGA) ,//Char = A,   offset=68
00071     ( SEGD+ SEGE+ SEGF+ SEGG) , ( SEGC+!SEGB+!SEGA) ,//Char = B,   offset=72
00072     ( SEGD+ SEGE+ SEGF+!SEGG) , (!SEGC+!SEGB+ SEGA) ,//Char = C,   offset=76
00073     ( SEGD+ SEGE+!SEGF+ SEGG) , ( SEGC+ SEGB+!SEGA) ,//Char = D,   offset=80
00074     ( SEGD+ SEGE+ SEGF+ SEGG) , (!SEGC+!SEGB+ SEGA) ,//Char = E,   offset=84
00075     (!SEGD+ SEGE+ SEGF+ SEGG) , (!SEGC+!SEGB+ SEGA) ,//Char = F,   offset=88
00076     ( SEGD+ SEGE+ SEGF+ SEGG) , ( SEGC+!SEGB+ SEGA) ,//Char = G,   offset=92
00077     (!SEGD+ SEGE+ SEGF+ SEGG) , ( SEGC+ SEGB+!SEGA) ,//Char = H,   offset=96
00078     (!SEGD+!SEGE+!SEGF+!SEGG) , ( SEGC+!SEGB+!SEGA) ,//Char = I,   offset=100
00079     ( SEGD+ SEGE+!SEGF+!SEGG) , ( SEGC+ SEGB+!SEGA) ,//Char = J,   offset=104
00080     (!SEGD+ SEGE+ SEGF+ SEGG) , ( SEGC+!SEGB+ SEGA) ,//Char = K,   offset=108
00081     ( SEGD+ SEGE+ SEGF+!SEGG) , (!SEGC+!SEGB+!SEGA) ,//Char = L,   offset=112
00082     (!SEGD+ SEGE+ SEGF+!SEGG) , ( SEGC+ SEGB+ SEGA) ,//Char = M,   offset=116
00083     (!SEGD+ SEGE+!SEGF+ SEGG) , ( SEGC+!SEGB+!SEGA) ,//Char = N,   offset=120
00084     ( SEGD+ SEGE+!SEGF+ SEGG) , ( SEGC+!SEGB+!SEGA) ,//Char = O,   offset=124
00085     (!SEGD+ SEGE+ SEGF+ SEGG) , (!SEGC+ SEGB+ SEGA) ,//Char = P,   offset=128
00086     ( SEGD+!SEGE+ SEGF+ SEGG) , ( SEGC+ SEGB+ SEGA) ,//Char = Q,   offset=132
00087     (!SEGD+ SEGE+!SEGF+ SEGG) , (!SEGC+!SEGB+!SEGA) ,//Char = R,   offset=136
00088     ( SEGD+!SEGE+ SEGF+ SEGG) , ( SEGC+!SEGB+ SEGA) ,//Char = S,   offset=140
00089     ( SEGD+ SEGE+ SEGF+ SEGG) , (!SEGC+!SEGB+!SEGA) ,//Char = T,   offset=144
00090     ( SEGD+ SEGE+ SEGF+!SEGG) , ( SEGC+ SEGB+!SEGA) ,//Char = U,   offset=148
00091     ( SEGD+ SEGE+!SEGF+!SEGG) , ( SEGC+!SEGB+!SEGA) ,//Char = V,   offset=152
00092     ( SEGD+ SEGE+ SEGF+!SEGG) , ( SEGC+ SEGB+!SEGA) ,//Char = W,   offset=156
00093     (!SEGD+ SEGE+ SEGF+ SEGG) , ( SEGC+ SEGB+!SEGA) ,//Char = X,   offset=160
00094     ( SEGD+!SEGE+ SEGF+ SEGG) , ( SEGC+ SEGB+!SEGA) ,//Char = Y,   offset=164
00095     ( SEGD+!SEGE+!SEGF+ SEGG) , (!SEGC+!SEGB+!SEGA) ,//Char = Z,   offset=168
00096     ( SEGD+!SEGE+!SEGF+!SEGG) , (!SEGC+!SEGB+ SEGA) ,//Char = [,   offset=172
00097     ( SEGD+!SEGE+!SEGF+!SEGG) , (!SEGC+!SEGB+ SEGA) ,//Char = \,   offset=176
00098     ( SEGD+!SEGE+!SEGF+!SEGG) , (!SEGC+!SEGB+ SEGA) ,//Char = ],   offset=180
00099     ( SEGD+!SEGE+!SEGF+!SEGG) , (!SEGC+!SEGB+ SEGA) ,//Char = ^,   offset=184
00100     ( SEGD+!SEGE+!SEGF+!SEGG) , (!SEGC+!SEGB+ SEGA) ,//Char = _,   offset=188
00101     ( SEGD+!SEGE+!SEGF+!SEGG) , (!SEGC+!SEGB+ SEGA) ,//Char = `,   offset=192
00102 };
00103 
00104 // -----------------------------------------------------------------------------
00105 //  external function
00106 // -----------------------------------------------------------------------------
00107 
00108 // -----------------------------------------------------------------------------
00109 //  function prototype
00110 // -----------------------------------------------------------------------------
00111 
00112 // -----------------------------------------------------------------------------
00113 //  external variable
00114 // -----------------------------------------------------------------------------
00115 
00116 // -----------------------------------------------------------------------------
00117 //  global variable
00118 // -----------------------------------------------------------------------------
00119 
00120 // -----------------------------------------------------------------------------
00121 //  function
00122 // -----------------------------------------------------------------------------
00123 // -----------------------------------------------------------------------------
00124 //! @brief  SLCD Main Function
00125 //! @param  [in] nil
00126 //! @retval nil
00127 // -----------------------------------------------------------------------------
00128 SLCD::SLCD()
00129 {
00130     init();
00131     CharPosition = 0;
00132 }
00133 
00134 // -----------------------------------------------------------------------------
00135 //! @brief  Initialize Setting
00136 //! @param  [in] nil
00137 //! @retval nil
00138 // -----------------------------------------------------------------------------
00139 void SLCD::init()
00140 {
00141     SIM->SCGC5 |= SIM_SCGC5_SLCD_MASK | SIM_SCGC5_PORTB_MASK | SIM_SCGC5_PORTC_MASK | SIM_SCGC5_PORTD_MASK | SIM_SCGC5_PORTE_MASK;
00142 
00143     // configure pins for LCD operation
00144     PORTC->PCR[20] = 0x00000000;     //VLL2
00145     PORTC->PCR[21] = 0x00000000;     //VLL1
00146     PORTC->PCR[22] = 0x00000000;     //VCAP2
00147     PORTC->PCR[23] = 0x00000000;     //VCAP1
00148     // Enable IRCLK
00149     MCG->C1  |= MCG_C1_IRCLKEN_MASK | MCG_C1_IREFSTEN_MASK;
00150     MCG->C2  |= MCG_C2_IRCS_MASK ;  //0 32KHZ internal reference clock; 1= 4MHz irc
00151 
00152     //Check if the Fast reference has its divide by 2 enabled (default):
00153     if ((MCG->SC & MCG_SC_FCRDIV_MASK) != 1<<1)
00154         error("Invalid clock configuration for SLCD\n");
00155     LCD->GCR = 0x0;
00156     LCD->AR  = 0x0;
00157 
00158     // LCD configurartion
00159     LCD->GCR =   ( LCD_GCR_RVEN_MASK*_LCDRVEN
00160                    | LCD_GCR_RVTRIM(_LCDRVTRIM)         //0-15
00161                    | LCD_GCR_CPSEL_MASK*_LCDCPSEL
00162                    | LCD_GCR_LADJ(_LCDLOADADJUST)       //0-3
00163                    | LCD_GCR_VSUPPLY_MASK*_LCDSUPPLY    //0-1
00164                    |!LCD_GCR_FDCIEN_MASK
00165                    | LCD_GCR_ALTDIV(1)         //divide by something
00166                    |!LCD_GCR_LCDDOZE_MASK
00167                    |!LCD_GCR_LCDSTP_MASK
00168                    |!LCD_GCR_LCDEN_MASK                 //WILL BE ENABLE ON SUBSEQUENT STEP
00169                    | LCD_GCR_SOURCE_MASK*1
00170                    | LCD_GCR_ALTSOURCE_MASK*0
00171                    | LCD_GCR_LCLK(0)    //0-7
00172                    | LCD_GCR_DUTY(_LCDDUTY)   //0-7
00173                  );
00174     uint8_t i;
00175     uint32_t *p_pen;
00176     uint8_t pen_offset;   // 0 or 1
00177     uint8_t pen_bit;      // 0 to 31
00178     LCD->PEN[0] = 0x0;
00179     LCD->PEN[1] = 0x0;
00180     LCD->BPEN[0] = 0x0;
00181     LCD->BPEN[1] = 0x0;
00182     p_pen = (uint32_t *)&LCD->PEN[0];
00183     for (i=0; i<_LCDUSEDPINS; i++) {
00184         pen_offset = WF_ORDERING_TABLE[i]/32;
00185         pen_bit    = WF_ORDERING_TABLE[i]%32;
00186         p_pen[pen_offset] |= 1 << pen_bit;
00187         if (i>= _LCDFRONTPLANES) {  // Pin is a backplane
00188             p_pen[pen_offset+2] |= 1 << pen_bit;  // Enable  BPEN
00189             LCD->WF8B[(uint8_t)WF_ORDERING_TABLE[i]] = 1 << (i - _LCDFRONTPLANES);   // fill with 0x01, 0x02, etc
00190         }
00191     }
00192     LCD->GCR |= LCD_GCR_LCDEN_MASK;
00193 }
00194 
00195 // -----------------------------------------------------------------------------
00196 //! @brief  Put Characters
00197 //! @param  [in] c integer 
00198 //! @retval int
00199 // -----------------------------------------------------------------------------
00200 int SLCD::_putc(int c)
00201 {
00202     Write_Char(c);
00203     return 0;
00204 }
00205 
00206 // -----------------------------------------------------------------------------
00207 //! @brief  Write Characters
00208 //! @param  [in] lbValue characters 
00209 //! @retval nil
00210 // -----------------------------------------------------------------------------
00211 void SLCD::Write_Char (char lbValue)
00212 {
00213     if (CharPosition >= _CHARNUM)
00214         CharPosition = 0;
00215 
00216     if (lbValue == '.') {
00217         // Use built-in dot
00218         DP(CharPosition-1, true);
00219         return;
00220     }
00221 
00222     uint8_t char_val;
00223     uint8_t temp;
00224     uint8_t *lbpLCDWF;
00225     uint8_t lbCounter;
00226     uint16_t arrayOffset;
00227     uint8_t position;
00228 
00229     lbpLCDWF = (uint8_t *)&LCD->WF8B[0];
00230     /* only ascii character if value not writeable write as @ */
00231     if (lbValue>='a' && lbValue<='z') {
00232         lbValue -= 32; // UpperCase
00233     }
00234     if (lbValue<ASCCI_TABLE_START || lbValue >ASCCI_TABLE_END) {
00235         lbValue = BLANK_CHARACTER;  // default value as space
00236     }
00237     lbValue -=ASCCI_TABLE_START;        // Remove the offset to search in the ascci table
00238     arrayOffset = (lbValue * _CHAR_SIZE); // Compensate matrix offset
00239     // ensure bLCD position is in valid limit
00240     lbCounter = 0;  //number of writings to complete one char
00241     while (lbCounter<_CHAR_SIZE) {
00242         position = (CharPosition) *_LCDTYPE + lbCounter;
00243         temp=0;
00244         if (lbCounter==1) {
00245             temp = lbpLCDWF[WF_ORDERING_TABLE[position]] & 0x01;//bit 0 has the special symbol information
00246         }
00247         char_val = ASCII_TO_WF_CODIFICATION_TABLE[arrayOffset + lbCounter];
00248         lbpLCDWF[WF_ORDERING_TABLE[position]] = char_val | temp;
00249         //  if (char_val==0) lbCounter = _CHAR_SIZE; //end of this character
00250         lbCounter++;
00251     }
00252     CharPosition++;
00253 }
00254 
00255 // -----------------------------------------------------------------------------
00256 //! @brief  Set Home Position
00257 //! @param  [in] nil 
00258 //! @retval nil
00259 // -----------------------------------------------------------------------------
00260 void SLCD::Home()
00261 {
00262     CharPosition =  0;
00263 }
00264 
00265 // -----------------------------------------------------------------------------
00266 //! @brief  Set Contrast
00267 //! @param  [in] lbContrast contrast 
00268 //! @retval nil
00269 // -----------------------------------------------------------------------------
00270 void SLCD::Contrast (uint8_t lbContrast)
00271 {
00272     lbContrast &= 0x0F;              //Forced to the only values accepted
00273     LCD->GCR |= LCD_GCR_RVTRIM(lbContrast);
00274 }
00275 
00276 // -----------------------------------------------------------------------------
00277 //! @brief  Clear Segments
00278 //! @param  [in] nil 
00279 //! @retval nil
00280 // -----------------------------------------------------------------------------
00281 void SLCD::clear()
00282 {
00283     All_Segments(0);
00284 }
00285 
00286 // -----------------------------------------------------------------------------
00287 //! @brief  Set Segments
00288 //! @param  [in] mode mode 
00289 //! @retval nil
00290 // -----------------------------------------------------------------------------
00291 void SLCD::All_Segments (int mode)
00292 {
00293     uint8_t lbTotalBytes = _CHARNUM * _LCDTYPE;
00294     uint8_t lbCounter=0;
00295     uint8_t *lbpLCDWF;
00296 
00297     lbpLCDWF = (uint8_t *)&LCD->WF8B[0];
00298     while (lbCounter < lbTotalBytes) {
00299         if (mode==1) {
00300             lbpLCDWF[(uint8_t)WF_ORDERING_TABLE[lbCounter++]]=_ALLON;
00301         } else {
00302             lbpLCDWF[WF_ORDERING_TABLE[lbCounter++]]=0;
00303         }
00304     }
00305 }
00306 
00307 // -----------------------------------------------------------------------------
00308 //! @brief  Set DP
00309 //! @param  [in] pos position 
00310 //! @param  [in] on on
00311 //! @retval nil
00312 // -----------------------------------------------------------------------------
00313 void SLCD::DP(int pos, bool on)
00314 {
00315     uint8_t *lbpLCDWF;
00316     int tableLoc;
00317     switch (pos) {
00318         case 0:
00319             tableLoc = 1;
00320             break;
00321         case 1:
00322             tableLoc = 3;
00323             break;
00324         case 2:
00325             tableLoc = 5;
00326             break;
00327         default:
00328             return; // Bad position
00329     }
00330     lbpLCDWF = (uint8_t *)&LCD->WF8B[0];
00331     if (on) {
00332         lbpLCDWF[(uint8_t)WF_ORDERING_TABLE[tableLoc]]|=1;
00333     } else {
00334         lbpLCDWF[(uint8_t)WF_ORDERING_TABLE[tableLoc]]&=~1;
00335     }
00336 }
00337 
00338 // -----------------------------------------------------------------------------
00339 //! @brief  Set DP1
00340 //! @param  [in] mode mode
00341 //! @retval nil
00342 // -----------------------------------------------------------------------------
00343 void SLCD::DP1 (int mode)
00344 {
00345     DP(0, mode==1);
00346 }
00347 
00348 // -----------------------------------------------------------------------------
00349 //! @brief  Set DP2
00350 //! @param  [in] mode mode
00351 //! @retval nil
00352 // -----------------------------------------------------------------------------
00353 void SLCD::DP2 (int mode)
00354 {
00355     DP(1, mode==1);
00356 }
00357 
00358 // -----------------------------------------------------------------------------
00359 //! @brief  Set DP3
00360 //! @param  [in] mode mode
00361 //! @retval nil
00362 // -----------------------------------------------------------------------------
00363 void SLCD::DP3 (int mode)
00364 {
00365     DP(2, mode==1);
00366 }
00367 
00368 // -----------------------------------------------------------------------------
00369 //! @brief  Set Colon
00370 //! @param  [in] on on
00371 //! @retval nil
00372 // -----------------------------------------------------------------------------
00373 void SLCD::Colon (bool on)
00374 {
00375     uint8_t *lbpLCDWF;
00376     lbpLCDWF = (uint8_t *)&LCD->WF8B[0];
00377     if (on) {
00378         lbpLCDWF[(uint8_t)WF_ORDERING_TABLE[7]]|=1;
00379     } else {
00380         lbpLCDWF[(uint8_t)WF_ORDERING_TABLE[7]]&=~1;
00381     }
00382 }
00383 
00384 // -----------------------------------------------------------------------------
00385 //! @brief  Set Blink
00386 //! @param  [in] blink blink
00387 //! @retval nil
00388 // -----------------------------------------------------------------------------
00389 void SLCD::blink(int blink)
00390 {
00391     if (( blink > 7) || (blink < 0))
00392         LCD->AR &= ~LCD_AR_BLINK_MASK;
00393     else
00394         LCD->AR |= LCD_AR_BLINK_MASK | blink;
00395 }
00396 
00397 // -----------------------------------------------------------------------------
00398 //! @brief  Deep Sleep Enable
00399 //! @param  [in] enable enable
00400 //! @retval nil
00401 // -----------------------------------------------------------------------------
00402 void SLCD::deepsleepEnable(bool enable)
00403 {
00404     MCG->C1 &= ~MCG_C1_IREFSTEN_MASK;
00405     MCG->C1 |= enable << MCG_C1_IREFSTEN_SHIFT;
00406     LCD->GCR &= ~LCD_GCR_LCDSTP_MASK;
00407     LCD->GCR |= (!enable) << LCD_GCR_LCDSTP_SHIFT;
00408 }