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