The wait in mci_WaitForEvent will delay all card transactions.

Dependencies:   FATFileSystem

Fork of EALib by EmbeddedArtists AB

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers EaLcdBoard.cpp Source File

EaLcdBoard.cpp

00001 
00002 /******************************************************************************
00003  * Includes
00004  *****************************************************************************/
00005 
00006 #include "mbed.h"
00007 #include "EaLcdBoard.h"
00008 
00009 /******************************************************************************
00010  * Defines and typedefs
00011  *****************************************************************************/
00012 
00013 #define PORT_PIN_BUG_IN_MBED_SDK
00014 
00015 #define LCDB_MAGIC 0xEA01CDAE
00016 
00017 
00018 #define LCDB_PCA9532_I2C_ADDR    (0x64 << 1)
00019 
00020 /* PCA9532 registers*/
00021 #define LCDB_PCA9532_INPUT0   0x00
00022 #define LCDB_PCA9532_INPUT1   0x01
00023 #define LCDB_PCA9532_PSC0     0x02
00024 #define LCDB_PCA9532_PWM0     0x03
00025 #define LCDB_PCA9532_PSC1     0x04
00026 #define LCDB_PCA9532_PWM1     0x05
00027 #define LCDB_PCA9532_LS0      0x06
00028 #define LCDB_PCA9532_LS1      0x07
00029 #define LCDB_PCA9532_LS2      0x08
00030 #define LCDB_PCA9532_LS3      0x09
00031 #define LCDB_PCA9532_AUTO_INC 0x10
00032 
00033 #define LCDB_LS_MODE_ON     0x01
00034 #define LCDB_LS_MODE_BLINK0 0x02
00035 #define LCDB_LS_MODE_BLINK1 0x03
00036 
00037 #define LCDB_CTRL_3V3     0x0001
00038 #define LCDB_CTRL_5V      0x0002
00039 #define LCDB_CTRL_DISP_EN 0x0010
00040 #define LCDB_CTRL_BL_EN   0x0080
00041 #define LCDB_CTRL_BL_C    0x0100
00042 #define LCDB_EEPROM_WP    0x8000
00043 
00044 #define LCDB_EEPROM_I2C_ADDR  (0x56 << 1)
00045 #define LCDB_EEPROM_PAGE_SIZE     32
00046 #define LCDB_EEPROM_TOTAL_SIZE  8192
00047 
00048 /*
00049  * Set which sequence string version that is supported
00050  */
00051 #define LCDB_SEQ_VER 2
00052 
00053 #ifndef MIN
00054 #define MIN(x, y) (((x)<(y))?(x):(y))
00055 #endif
00056 
00057 #define EA_LCD_TMP_BUFFER_SZ 256
00058 static char* eaLcdTmpBuffer[EA_LCD_TMP_BUFFER_SZ];
00059 
00060 
00061 /* Structure containing the parameters for the LCD panel as stored on LCD Board */
00062 
00063 /* LCD display types */
00064 typedef enum {
00065     TFT = 0,   /* standard TFT */
00066     ADTFT,     /* advanced TFT */
00067     HRTFT,     /* highly reflective TFT */
00068     MONO_4BIT, /* 4-bit mono */
00069     MONO_8BIT, /* 8-bit mono */
00070     CSTN       /* color STN */
00071 } nxp_lcd_panel_t;
00072 
00073 typedef struct {
00074     uint8_t         h_back_porch;         /* Horizontal back porch in clocks */
00075     uint8_t         h_front_porch;        /* Horizontal front porch in clocks */
00076     uint8_t         h_sync_pulse_width;   /* HSYNC pulse width in clocks */
00077     uint16_t        pixels_per_line;      /* Pixels per line (horizontal resolution) */
00078     uint8_t         v_back_porch;         /* Vertical back porch in clocks */
00079     uint8_t         v_front_porch;        /* Vertical front porch in clocks */
00080     uint8_t         v_sync_pulse_width;   /* VSYNC pulse width in clocks */
00081     uint16_t        lines_per_panel;      /* Lines per panel (vertical resolution) */
00082     uint8_t         invert_output_enable; /* Invert output enable, 1 = invert*/
00083     uint8_t         invert_panel_clock;   /* Invert panel clock, 1 = invert*/
00084     uint8_t         invert_hsync;         /* Invert HSYNC, 1 = invert */
00085     uint8_t         invert_vsync;         /* Invert VSYNC, 1 = invert */
00086     uint8_t         ac_bias_frequency;    /* AC bias frequency in clocks */
00087     uint8_t         bits_per_pixel;       /* Maximum bits per pixel the display supports */
00088     uint32_t        optimal_clock;        /* Optimal clock rate (Hz) */
00089     nxp_lcd_panel_t lcd_panel_type;       /* LCD panel type */
00090     uint8_t         dual_panel;           /* Dual panel, 1 = dual panel display */
00091 } nxp_lcd_param_t;
00092 
00093 static uint32_t str_to_uint(char* str, uint32_t len);
00094 
00095 EaLcdBoard::EaLcdBoard(PinName sda, PinName scl) : _i2c(sda, scl) {
00096     _blink0Shadow = 0;
00097     _blink1Shadow = 0;
00098     _ledStateShadow = 0;
00099     _lcdPwrOn = false;
00100 }
00101 
00102 EaLcdBoard::Result EaLcdBoard::open(LcdController::Config* cfg, char* initSeq) {
00103 
00104     EaLcdBoard::Result result = Ok;
00105 
00106     // load LCD configuration from storage
00107     if (cfg == NULL) {
00108         result = getLcdConfig(&_cfg);
00109         cfg = &_cfg;
00110     }
00111 
00112     // load init sequence from storage
00113     if (result == Ok && initSeq == NULL) {
00114         result = getInitSeq((char*)eaLcdTmpBuffer, EA_LCD_TMP_BUFFER_SZ);
00115         initSeq = (char*)eaLcdTmpBuffer;
00116     }
00117 
00118     if (result != Ok) {
00119         return result;
00120     }
00121 
00122     return parseInitString(initSeq, cfg);
00123 }
00124 
00125 EaLcdBoard::Result EaLcdBoard::close() {
00126     int r = 0;
00127 
00128     do {
00129         r = lcdCtrl.setPower(false);
00130         if (r != 0) break;
00131 
00132         _lcdPwrOn = false;
00133 
00134         r = lcdCtrl.close();
00135     } while(0);
00136 
00137     if (r != 0) {
00138         return LcdAccessError;
00139     }
00140 
00141     return Ok;
00142 }
00143 
00144 EaLcdBoard::Result EaLcdBoard::setFrameBuffer(uint32_t address) {
00145     int r = 0;
00146 
00147     do {
00148 
00149         // begin by powering on the display
00150         if (!_lcdPwrOn) {
00151             r = lcdCtrl.setPower(true);
00152             if (r != 0) break;
00153 
00154             _lcdPwrOn = true;
00155         }
00156 
00157         // activate specified frame buffer
00158         r = lcdCtrl.setFrameBuffer(address);
00159         if (r != 0) break;
00160 
00161     } while(0);
00162 
00163     if (r != 0) {
00164         return LcdAccessError;
00165     }
00166 
00167 
00168     return Ok;
00169 }
00170 
00171 EaLcdBoard::Result EaLcdBoard::getLcdConfig(LcdController::Config* cfg) {
00172     store_t h;
00173 
00174     nxp_lcd_param_t lcdParam;
00175 
00176     if (cfg == NULL) {
00177         return InvalidArgument;
00178     }
00179 
00180     getStore(&h);
00181 
00182     if (h.magic != LCDB_MAGIC) {
00183         return InvalidStorage;
00184     }
00185 
00186     eepromRead((uint8_t*)&lcdParam, h.lcdParamOff,
00187             (h.initOff-h.lcdParamOff));
00188 
00189     cfg->horizontalBackPorch  = lcdParam.h_back_porch;
00190     cfg->horizontalFrontPorch = lcdParam.h_front_porch;
00191     cfg->hsync                = lcdParam.h_sync_pulse_width;
00192     cfg->width                = lcdParam.pixels_per_line;
00193     cfg->verticalBackPorch    = lcdParam.v_back_porch;
00194     cfg->verticalFrontPorch   = lcdParam.v_front_porch;
00195     cfg->vsync                = lcdParam.v_sync_pulse_width;
00196     cfg->height               = lcdParam.lines_per_panel;
00197     cfg->invertOutputEnable   = (lcdParam.invert_output_enable == 1);
00198     cfg->invertPanelClock     = (lcdParam.invert_panel_clock == 1);
00199     cfg->invertHsync          = (lcdParam.invert_hsync == 1);
00200     cfg->invertVsync          = (lcdParam.invert_vsync == 1);
00201     cfg->acBias               = lcdParam.ac_bias_frequency;
00202     cfg->bpp = LcdController::Bpp_16_565;
00203     cfg->optimalClock         = lcdParam.optimal_clock;
00204     cfg->panelType            = (LcdController::LcdPanel)lcdParam.lcd_panel_type;
00205     cfg->dualPanel            = (lcdParam.dual_panel == 1);
00206 
00207     return Ok;
00208 }
00209 
00210 EaLcdBoard::Result EaLcdBoard::getDisplayName(char* buf, int len) {
00211     store_t h;
00212 
00213     if (buf == NULL) {
00214         return InvalidArgument;
00215     }
00216 
00217     getStore(&h);
00218 
00219     if (h.magic != LCDB_MAGIC) {
00220         return InvalidStorage;
00221     }
00222 
00223     if (len < NameBufferSize) {
00224         return BufferTooSmall;
00225     }
00226 
00227     strncpy(buf, (char*)h.lcd_name, NameBufferSize);
00228 
00229     return Ok;
00230 }
00231 
00232 EaLcdBoard::Result EaLcdBoard::getDisplayMfg(char* buf, int len) {
00233     store_t h;
00234 
00235     if (buf == NULL) {
00236         return InvalidArgument;
00237     }
00238 
00239     getStore(&h);
00240 
00241     if (h.magic != LCDB_MAGIC) {
00242         return InvalidStorage;
00243     }
00244 
00245     if (len < NameBufferSize) {
00246         return BufferTooSmall;
00247     }
00248 
00249     strncpy(buf, (char*)h.lcd_mfg, NameBufferSize);
00250 
00251     return Ok;
00252 }
00253 
00254 EaLcdBoard::Result EaLcdBoard::getInitSeq(char* buf, int len) {
00255     store_t h;
00256 
00257     if (buf == NULL) {
00258         return InvalidArgument;
00259     }
00260 
00261     getStore(&h);
00262 
00263     if (h.magic != LCDB_MAGIC) {
00264         return InvalidStorage;
00265     }
00266 
00267     if ((h.pdOff-h.initOff) > len) {
00268         return BufferTooSmall;
00269     }
00270 
00271     eepromRead((uint8_t*)buf, h.initOff,
00272             (h.pdOff-h.initOff));
00273 
00274     return Ok;
00275 }
00276 
00277 EaLcdBoard::Result EaLcdBoard::getPowerDownSeq(char* buf, int len) {
00278     store_t h;
00279 
00280     if (buf == NULL) {
00281         return InvalidArgument;
00282     }
00283 
00284     getStore(&h);
00285 
00286     if (h.magic != LCDB_MAGIC) {
00287         return InvalidStorage;
00288     }
00289 
00290     if ((h.tsOff-h.pdOff) > len) {
00291         return BufferTooSmall;
00292     }
00293 
00294     eepromRead((uint8_t*)buf, h.pdOff,
00295             (h.tsOff-h.pdOff));
00296 
00297     return Ok;
00298 }
00299 
00300 EaLcdBoard::Result EaLcdBoard::getTouchParameters(TouchParams_t* params) {
00301     store_t h;
00302 
00303     if (params == NULL) {
00304         return InvalidArgument;
00305     }
00306 
00307     getStore(&h);
00308 
00309     if (h.magic != LCDB_MAGIC) {
00310         return InvalidStorage;
00311     }
00312 
00313 
00314     if (eepromRead((uint8_t*)params, h.tsOff,
00315             (h.end-h.tsOff)) == -1) {
00316         return InvalidStorage;
00317     }
00318 
00319 
00320     if (params->panelId <= TouchPanelInvalidFirst
00321             || params->panelId >= TouchPanelInvalidLast) {
00322         params->panelId = TouchPanelUnknown;
00323     }
00324 
00325 
00326     return Ok;
00327 }
00328 
00329 EaLcdBoard::Result EaLcdBoard::storeParameters(
00330   const char* lcdName,
00331   const char* lcdMfg,
00332   LcdController::Config* cfg,
00333   const char* initSeqStr,
00334   const char* pdSeqStr,
00335   TouchParams_t* touch,
00336   bool controlWp)
00337 {
00338     store_t h;
00339     nxp_lcd_param_t lcdParam;
00340 
00341     if (lcdName == NULL || lcdMfg == NULL || cfg == NULL
00342             || initSeqStr == NULL || pdSeqStr == NULL) {
00343         return InvalidArgument;
00344 
00345     }
00346 
00347 
00348     lcdParam.h_back_porch         = cfg->horizontalBackPorch;
00349     lcdParam.h_front_porch        = cfg->horizontalFrontPorch;
00350     lcdParam.h_sync_pulse_width   = cfg->hsync;
00351     lcdParam.pixels_per_line      = cfg->width;
00352     lcdParam.v_back_porch         = cfg->verticalBackPorch;
00353     lcdParam.v_front_porch        = cfg->verticalFrontPorch;
00354     lcdParam.v_sync_pulse_width   = cfg->vsync;
00355     lcdParam.lines_per_panel      = cfg->height;
00356     lcdParam.invert_output_enable = (cfg->invertOutputEnable ? 1 : 0);
00357     lcdParam.invert_panel_clock   = (cfg->invertPanelClock ? 1 : 0);
00358     lcdParam.invert_hsync         = (cfg->invertHsync ? 1 : 0);
00359     lcdParam.invert_vsync         = (cfg->invertVsync ? 1 : 0);
00360     lcdParam.ac_bias_frequency    = cfg->acBias;
00361     lcdParam.optimal_clock        = cfg->optimalClock;
00362     lcdParam.lcd_panel_type       = (nxp_lcd_panel_t)cfg->panelType;
00363     lcdParam.dual_panel           = (cfg->dualPanel ? 1 : 0);
00364 
00365 
00366     h.magic = LCDB_MAGIC;
00367     strncpy((char*)h.lcd_name, lcdName, 30);
00368     strncpy((char*)h.lcd_mfg, lcdMfg, 30);
00369 
00370     h.lcdParamOff = sizeof(store_t);
00371     h.initOff     = h.lcdParamOff + sizeof(nxp_lcd_param_t);
00372     h.pdOff       = h.initOff + strlen(initSeqStr)+1;
00373     h.tsOff       = h.pdOff + strlen(pdSeqStr)+1;
00374     h.end         = h.tsOff + sizeof(TouchParams_t);
00375 
00376     if (controlWp) setWriteProtect(false);
00377     eepromWrite((uint8_t*)&h,         0,             h.lcdParamOff);
00378     eepromWrite((uint8_t*)&lcdParam,  h.lcdParamOff, (h.initOff-h.lcdParamOff));
00379     eepromWrite((uint8_t*)initSeqStr, h.initOff,     (h.pdOff-h.initOff));
00380     eepromWrite((uint8_t*)pdSeqStr,   h.pdOff,       (h.tsOff-h.pdOff));
00381     eepromWrite((uint8_t*)touch,      h.tsOff,       (h.end-h.tsOff));
00382     if (controlWp) setWriteProtect(true);
00383 
00384     return Ok;
00385 }
00386 
00387 EaLcdBoard::Result EaLcdBoard::getStore(store_t* store) {
00388     int num = 0;
00389 
00390     if (store == NULL) return InvalidArgument;
00391 
00392     num = eepromRead((uint8_t*)store, 0, sizeof(store_t));
00393     if (num < (int)sizeof(store_t)) {
00394         return InvalidStorage;
00395     }
00396 
00397     return Ok;
00398 }
00399 
00400 // ###########################
00401 // An EEPROM is used for persistent storage
00402 // ###########################
00403 
00404 int EaLcdBoard::eepromRead(uint8_t* buf, uint16_t offset, uint16_t len) {
00405     int i = 0;
00406     char off[2];
00407     uint16_t retLen = 0;
00408 
00409     if (len > LCDB_EEPROM_TOTAL_SIZE || offset+len > LCDB_EEPROM_TOTAL_SIZE) {
00410         return -1;
00411     }
00412 
00413     wait_ms(10);
00414 
00415     off[0] = ((offset >> 8) & 0xff);
00416     off[1] = (offset & 0xff);
00417 
00418     do {
00419         if (_i2c.write(LCDB_EEPROM_I2C_ADDR, (char*)off, 2) != 0) break;
00420         for ( i = 0; i < 0x2000; i++);
00421         if (_i2c.read(LCDB_EEPROM_I2C_ADDR, (char*)buf, len) != 0) break;
00422 
00423         retLen = len;
00424     } while(0);
00425 
00426     return retLen;
00427 }
00428 
00429 int EaLcdBoard::eepromWrite(uint8_t* buf, uint16_t offset, uint16_t len) {
00430     int16_t written = 0;
00431     uint16_t wLen = 0;
00432     uint16_t off = offset;
00433     uint8_t tmp[LCDB_EEPROM_PAGE_SIZE+2];
00434 
00435     if (len > LCDB_EEPROM_TOTAL_SIZE || offset+len > LCDB_EEPROM_TOTAL_SIZE) {
00436         return -1;
00437     }
00438 
00439     wait_ms(1);
00440 
00441     wLen = LCDB_EEPROM_PAGE_SIZE - (off % LCDB_EEPROM_PAGE_SIZE);
00442     wLen = MIN(wLen, len);
00443 
00444     while (len) {
00445         tmp[0] = ((off >> 8) & 0xff);
00446         tmp[1] = (off & 0xff);
00447         memcpy(&tmp[2], (void*)&buf[written], wLen);
00448         if (_i2c.write(LCDB_EEPROM_I2C_ADDR, (char*)tmp, wLen+2) != 0) break;
00449 
00450         // delay to wait for a write cycle
00451         //eepromDelay();
00452         wait_ms(10);
00453 
00454         len     -= wLen;
00455         written += wLen;
00456         off     += wLen;
00457 
00458         wLen = MIN(LCDB_EEPROM_PAGE_SIZE, len);
00459     }
00460 
00461     return written;
00462 }
00463 
00464 // ###########################
00465 // string parsing (initialization and power down strings)
00466 // ###########################
00467 
00468 EaLcdBoard::Result EaLcdBoard::parseInitString(char* str, LcdController::Config* cfg) {
00469     char* c = NULL;
00470     uint32_t len = 0;
00471     Result result = Ok;
00472 
00473     if (str == NULL) {
00474         return InvalidCommandString;
00475     }
00476 
00477     while(*str != '\0') {
00478 
00479         // skip whitespaces
00480         while(*str == ' ') {
00481             str++;
00482         }
00483 
00484         c = str;
00485 
00486         // find end of command
00487         while(*str != ',' && *str != '\0') {
00488             str++;
00489         }
00490 
00491         len = (str-c);
00492 
00493         if (*str == ',') {
00494             str++;
00495         }
00496 
00497         switch (*c++) {
00498 
00499         case 'v':
00500             result = checkVersion(c, len-1);
00501             break;
00502 
00503             // sequence control command (pca9532)
00504         case 'c':
00505             execSeqCtrl(c, len-1);
00506             break;
00507 
00508             // delay
00509         case 'd':
00510             execDelay(c, len-1);
00511             break;
00512 
00513             // open lcd (init LCD controller)
00514         case 'o':
00515 
00516             if (cfg != NULL) {
00517 
00518                 if (lcdCtrl.open(cfg) != 0) {
00519                     result = LcdAccessError;
00520                 }
00521             }
00522 
00523             else {
00524                 result = InvalidArgument;
00525             }
00526 
00527             break;
00528 
00529             // exec pin set
00530         case 'p':
00531             execPinSet(c, len-1);
00532             break;
00533 
00534         }
00535 
00536         if (result != Ok) {
00537             break;
00538         }
00539 
00540 
00541     }
00542 
00543 
00544     return result;
00545 }
00546 
00547 EaLcdBoard::Result EaLcdBoard::checkVersion(char* v, uint32_t len) {
00548     uint32_t ver = str_to_uint(v, len);
00549 
00550     if (ver > LCDB_SEQ_VER) {
00551         return VersionNotSupported;
00552     }
00553 
00554     return Ok;
00555 }
00556 
00557 EaLcdBoard::Result EaLcdBoard::execDelay(char* del, uint32_t len) {
00558     wait_ms(str_to_uint(del, len));
00559 
00560     return Ok;
00561 }
00562 
00563 EaLcdBoard::Result EaLcdBoard::execSeqCtrl(char* cmd, uint32_t len) {
00564 
00565     switch (*cmd++) {
00566 
00567     // display enable
00568     case 'd':
00569         setDisplayEnableSignal(*cmd == '1');
00570         break;
00571 
00572         // backlight contrast
00573     case 'c':
00574         setBacklightContrast(str_to_uint(cmd, len));
00575         break;
00576 
00577         // 3v3 enable
00578     case '3':
00579         set3V3Signal(*cmd == '1');
00580         break;
00581 
00582         // 5v enable
00583     case '5':
00584         set5VSignal(*cmd == '1');
00585         break;
00586     }
00587 
00588     return Ok;
00589 }
00590 
00591 #ifdef PORT_PIN_BUG_IN_MBED_SDK
00592 static PinName port_pin2(PortName port, int pin_n) {
00593     return (PinName)(((port << 5) | pin_n));
00594 }
00595 #endif
00596 
00597 
00598 EaLcdBoard::Result EaLcdBoard::execPinSet(char* cmd, uint32_t len) {
00599 
00600     PortName port;
00601 
00602     do {
00603         // cmd: 0_02=1 means p0.2 = 1
00604         if (len < 6) break;
00605         if (cmd[1] != '_' || cmd[4] != '=') break;
00606 
00607         // port
00608         int portnum  = cmd[0] - '0';
00609         if (portnum < 0 || portnum > 5) break;
00610         port = (PortName)portnum;
00611 
00612         // pin
00613         int pinnum = (10*(cmd[2]-'0'))+ cmd[3]-'0';
00614         if (pinnum < 0 || pinnum > 31) break;
00615 
00616         // value
00617         int value = cmd[5]-'0';
00618         if (!(value == 0 || value == 1)) break;
00619 
00620 #ifdef PORT_PIN_BUG_IN_MBED_SDK
00621         PinName pin = port_pin2(port, pinnum);
00622 #else
00623         PinName pin = port_pin(port, pinnum);
00624 #endif
00625 
00626         gpio_t gp;
00627         gpio_init(&gp, pin, PIN_OUTPUT);
00628         gpio_write(&gp, value);
00629 
00630         return Ok;
00631 
00632     } while (false);
00633 
00634 
00635     return InvalidCommandString;
00636 }
00637 
00638 
00639 // ###########################
00640 // PCA9532 is used as a control inteface to the display.
00641 // voltages can be turned on/off and backlight can be controlled.
00642 // ###########################
00643 
00644 // Helper function to set LED states
00645 void EaLcdBoard::setLsStates(uint16_t states, uint8_t* ls, uint8_t mode)
00646 {
00647 #define IS_LED_SET(bit, x) ( ( ((x) & (bit)) != 0 ) ? 1 : 0 )
00648 
00649     int i = 0;
00650 
00651     for (i = 0; i < 4; i++) {
00652 
00653         ls[i] |= ( (IS_LED_SET(0x0001, states)*mode << 0)
00654                 | (IS_LED_SET(0x0002, states)*mode << 2)
00655                 | (IS_LED_SET(0x0004, states)*mode << 4)
00656                 | (IS_LED_SET(0x0008, states)*mode << 6) );
00657 
00658         states >>= 4;
00659     }
00660 }
00661 
00662 void EaLcdBoard::setLeds(void)
00663 {
00664     uint8_t buf[5];
00665     uint8_t ls[4] = {0,0,0,0};
00666     uint16_t states = _ledStateShadow;
00667 
00668     // LEDs in On/Off state
00669     setLsStates(states, ls, LCDB_LS_MODE_ON);
00670 
00671     // set the LEDs that should blink
00672     setLsStates(_blink0Shadow, ls, LCDB_LS_MODE_BLINK0);
00673     setLsStates(_blink1Shadow, ls, LCDB_LS_MODE_BLINK1);
00674 
00675     buf[0] = LCDB_PCA9532_LS0 | LCDB_PCA9532_AUTO_INC;
00676     buf[1] = ls[0];
00677     buf[2] = ls[1];
00678     buf[3] = ls[2];
00679     buf[4] = ls[3];
00680 
00681     _i2c.write(LCDB_PCA9532_I2C_ADDR, (char*)buf, 5);
00682 }
00683 
00684 void EaLcdBoard::pca9532_setLeds (uint16_t ledOnMask, uint16_t ledOffMask)
00685 {
00686     // turn off leds
00687     _ledStateShadow &= (~(ledOffMask) & 0xffff);
00688 
00689     // ledOnMask has priority over ledOffMask
00690     _ledStateShadow |= ledOnMask;
00691 
00692     // turn off blinking
00693     _blink0Shadow &= (~(ledOffMask) & 0xffff);
00694     _blink1Shadow &= (~(ledOffMask) & 0xffff);
00695 
00696     setLeds();
00697 }
00698 
00699 void EaLcdBoard::pca9532_setBlink0Period(uint8_t period)
00700 {
00701     uint8_t buf[2];
00702 
00703     buf[0] = LCDB_PCA9532_PSC0;
00704     buf[1] = period;
00705 
00706     _i2c.write(LCDB_PCA9532_I2C_ADDR, (char*)buf, 2);
00707 }
00708 
00709 void EaLcdBoard::pca9532_setBlink0Duty(uint8_t duty)
00710 {
00711     uint8_t buf[2];
00712     uint32_t tmp = duty;
00713     if (tmp > 100) {
00714         tmp = 100;
00715     }
00716 
00717     tmp = (255 * tmp)/100;
00718 
00719     buf[0] = LCDB_PCA9532_PWM0;
00720     buf[1] = tmp;
00721 
00722     _i2c.write(LCDB_PCA9532_I2C_ADDR, (char*)buf, 2);
00723 }
00724 
00725 void EaLcdBoard::pca9532_setBlink0Leds(uint16_t ledMask)
00726 {
00727     _blink0Shadow |= ledMask;
00728     setLeds();
00729 }
00730 
00731 void EaLcdBoard::setWriteProtect(bool enable)
00732 {
00733     if (enable) {
00734         pca9532_setLeds(0, LCDB_EEPROM_WP);
00735     } else {
00736         pca9532_setLeds(LCDB_EEPROM_WP, 0);
00737     }
00738 }
00739 
00740 void EaLcdBoard::set3V3Signal(bool enabled) {
00741     if (enabled) {
00742         pca9532_setLeds(LCDB_CTRL_3V3, 0);
00743     } else {
00744         pca9532_setLeds(0, LCDB_CTRL_3V3);
00745     }
00746 }
00747 
00748 void EaLcdBoard::set5VSignal(bool enabled) {
00749     if (enabled) {
00750         pca9532_setLeds(LCDB_CTRL_5V, 0);
00751     } else {
00752         pca9532_setLeds(0, LCDB_CTRL_5V);
00753     }
00754 }
00755 
00756 void EaLcdBoard::setDisplayEnableSignal(bool enabled) {
00757     if (!enabled) {
00758         pca9532_setLeds(LCDB_CTRL_DISP_EN, 0);
00759     } else {
00760         pca9532_setLeds(0, LCDB_CTRL_DISP_EN);
00761     }
00762 }
00763 
00764 void EaLcdBoard::setBacklightContrast(uint32_t value) {
00765 
00766     if (value > 100) return;
00767 
00768     pca9532_setBlink0Duty(100-value);
00769     pca9532_setBlink0Period(0);
00770     pca9532_setBlink0Leds(LCDB_CTRL_BL_C);
00771 }
00772 
00773 
00774 // convert string to integer
00775 static uint32_t str_to_uint(char* str, uint32_t len)
00776 {
00777     uint32_t val = 0;
00778 
00779     while(len > 0 && *str <= '9' && *str >= '0') {
00780         val = (val * 10) + (*str - '0');
00781         str++;
00782         len--;
00783     }
00784 
00785     return val;
00786 }
00787 
00788