A library with drivers for different peripherals on the LPC4088 QuickStart Board or related add-on boards.
Fork of EALib by
Diff: EaLcdBoard.cpp
- Revision:
- 4:b32cf4ef45c5
- Parent:
- 0:0fdadbc3d852
- Child:
- 12:15597e45eea0
--- a/EaLcdBoard.cpp Wed Oct 09 07:51:52 2013 +0000 +++ b/EaLcdBoard.cpp Fri Oct 18 12:48:58 2013 +0200 @@ -1,7 +1,17 @@ + +/****************************************************************************** + * Includes + *****************************************************************************/ #include "mbed.h" #include "EaLcdBoard.h" +/****************************************************************************** + * Defines and typedefs + *****************************************************************************/ + +#define PORT_PIN_BUG_IN_MBED_SDK + #define LCDB_MAGIC 0xEA01CDAE @@ -38,7 +48,7 @@ /* * Set which sequence string version that is supported */ -#define LCDB_SEQ_VER 1 +#define LCDB_SEQ_VER 2 #ifndef MIN #define MIN(x, y) (((x)<(y))?(x):(y)) @@ -163,6 +173,10 @@ nxp_lcd_param_t lcdParam; + if (cfg == NULL) { + return InvalidArgument; + } + getStore(&h); if (h.magic != LCDB_MAGIC) { @@ -196,6 +210,10 @@ EaLcdBoard::Result EaLcdBoard::getDisplayName(char* buf, int len) { store_t h; + if (buf == NULL) { + return InvalidArgument; + } + getStore(&h); if (h.magic != LCDB_MAGIC) { @@ -214,6 +232,10 @@ EaLcdBoard::Result EaLcdBoard::getDisplayMfg(char* buf, int len) { store_t h; + if (buf == NULL) { + return InvalidArgument; + } + getStore(&h); if (h.magic != LCDB_MAGIC) { @@ -232,6 +254,10 @@ EaLcdBoard::Result EaLcdBoard::getInitSeq(char* buf, int len) { store_t h; + if (buf == NULL) { + return InvalidArgument; + } + getStore(&h); if (h.magic != LCDB_MAGIC) { @@ -251,6 +277,10 @@ EaLcdBoard::Result EaLcdBoard::getPowerDownSeq(char* buf, int len) { store_t h; + if (buf == NULL) { + return InvalidArgument; + } + getStore(&h); if (h.magic != LCDB_MAGIC) { @@ -267,6 +297,93 @@ return Ok; } +EaLcdBoard::Result EaLcdBoard::getTouchParameters(TouchParams_t* params) { + store_t h; + + if (params == NULL) { + return InvalidArgument; + } + + getStore(&h); + + if (h.magic != LCDB_MAGIC) { + return InvalidStorage; + } + + + if (eepromRead((uint8_t*)params, h.tsOff, + (h.end-h.tsOff)) == -1) { + return InvalidStorage; + } + + + if (params->panelId <= TouchPanelInvalidFirst + || params->panelId >= TouchPanelInvalidLast) { + params->panelId = TouchPanelUnknown; + } + + + return Ok; +} + +EaLcdBoard::Result EaLcdBoard::storeParameters( + const char* lcdName, + const char* lcdMfg, + LcdController::Config* cfg, + const char* initSeqStr, + const char* pdSeqStr, + TouchParams_t* touch, + bool controlWp) +{ + store_t h; + nxp_lcd_param_t lcdParam; + + if (lcdName == NULL || lcdMfg == NULL || cfg == NULL + || initSeqStr == NULL || pdSeqStr == NULL) { + return InvalidArgument; + + } + + + lcdParam.h_back_porch = cfg->horizontalBackPorch; + lcdParam.h_front_porch = cfg->horizontalFrontPorch; + lcdParam.h_sync_pulse_width = cfg->hsync; + lcdParam.pixels_per_line = cfg->width; + lcdParam.v_back_porch = cfg->verticalBackPorch; + lcdParam.v_front_porch = cfg->verticalFrontPorch; + lcdParam.v_sync_pulse_width = cfg->vsync; + lcdParam.lines_per_panel = cfg->height; + lcdParam.invert_output_enable = (cfg->invertOutputEnable ? 1 : 0); + lcdParam.invert_panel_clock = (cfg->invertPanelClock ? 1 : 0); + lcdParam.invert_hsync = (cfg->invertHsync ? 1 : 0); + lcdParam.invert_vsync = (cfg->invertVsync ? 1 : 0); + lcdParam.ac_bias_frequency = cfg->acBias; + lcdParam.optimal_clock = cfg->optimalClock; + lcdParam.lcd_panel_type = (nxp_lcd_panel_t)cfg->panelType; + lcdParam.dual_panel = (cfg->dualPanel ? 1 : 0); + + + h.magic = LCDB_MAGIC; + strncpy((char*)h.lcd_name, lcdName, 30); + strncpy((char*)h.lcd_mfg, lcdMfg, 30); + + h.lcdParamOff = sizeof(store_t); + h.initOff = h.lcdParamOff + sizeof(nxp_lcd_param_t); + h.pdOff = h.initOff + strlen(initSeqStr)+1; + h.tsOff = h.pdOff + strlen(pdSeqStr)+1; + h.end = h.tsOff + sizeof(TouchParams_t); + + if (controlWp) setWriteProtect(false); + eepromWrite((uint8_t*)&h, 0, h.lcdParamOff); + eepromWrite((uint8_t*)&lcdParam, h.lcdParamOff, (h.initOff-h.lcdParamOff)); + eepromWrite((uint8_t*)initSeqStr, h.initOff, (h.pdOff-h.initOff)); + eepromWrite((uint8_t*)pdSeqStr, h.pdOff, (h.tsOff-h.pdOff)); + eepromWrite((uint8_t*)touch, h.tsOff, (h.end-h.tsOff)); + if (controlWp) setWriteProtect(true); + + return Ok; +} + EaLcdBoard::Result EaLcdBoard::getStore(store_t* store) { int num = 0; @@ -287,19 +404,26 @@ int EaLcdBoard::eepromRead(uint8_t* buf, uint16_t offset, uint16_t len) { int i = 0; char off[2]; + uint16_t retLen = 0; if (len > LCDB_EEPROM_TOTAL_SIZE || offset+len > LCDB_EEPROM_TOTAL_SIZE) { return -1; } + wait_ms(10); + off[0] = ((offset >> 8) & 0xff); off[1] = (offset & 0xff); - _i2c.write(LCDB_EEPROM_I2C_ADDR, (char*)off, 2); - for ( i = 0; i < 0x2000; i++); - _i2c.read(LCDB_EEPROM_I2C_ADDR, (char*)buf, len); + do { + if (_i2c.write(LCDB_EEPROM_I2C_ADDR, (char*)off, 2) != 0) break; + for ( i = 0; i < 0x2000; i++); + if (_i2c.read(LCDB_EEPROM_I2C_ADDR, (char*)buf, len) != 0) break; - return len; + retLen = len; + } while(0); + + return retLen; } int EaLcdBoard::eepromWrite(uint8_t* buf, uint16_t offset, uint16_t len) { @@ -312,6 +436,8 @@ return -1; } + wait_ms(1); + wLen = LCDB_EEPROM_PAGE_SIZE - (off % LCDB_EEPROM_PAGE_SIZE); wLen = MIN(wLen, len); @@ -319,11 +445,11 @@ tmp[0] = ((off >> 8) & 0xff); tmp[1] = (off & 0xff); memcpy(&tmp[2], (void*)&buf[written], wLen); - _i2c.write(LCDB_EEPROM_I2C_ADDR, (char*)tmp, wLen+2); + if (_i2c.write(LCDB_EEPROM_I2C_ADDR, (char*)tmp, wLen+2) != 0) break; // delay to wait for a write cycle //eepromDelay(); - wait_ms(1); + wait_ms(10); len -= wLen; written += wLen; @@ -400,6 +526,11 @@ break; + // exec pin set + case 'p': + execPinSet(c, len-1); + break; + } if (result != Ok) { @@ -457,6 +588,54 @@ return Ok; } +#ifdef PORT_PIN_BUG_IN_MBED_SDK +static PinName port_pin2(PortName port, int pin_n) { + return (PinName)(((port << 5) | pin_n)); +} +#endif + + +EaLcdBoard::Result EaLcdBoard::execPinSet(char* cmd, uint32_t len) { + + PortName port; + + do { + // cmd: 0_02=1 means p0.2 = 1 + if (len < 6) break; + if (cmd[1] != '_' || cmd[4] != '=') break; + + // port + int portnum = cmd[0] - '0'; + if (portnum < 0 || portnum > 5) break; + port = (PortName)portnum; + + // pin + int pinnum = (10*(cmd[2]-'0'))+ cmd[3]-'0'; + if (pinnum < 0 || pinnum > 31) break; + + // value + int value = cmd[5]-'0'; + if (!(value == 0 || value == 1)) break; + +#ifdef PORT_PIN_BUG_IN_MBED_SDK + PinName pin = port_pin2(port, pinnum); +#else + PinName pin = port_pin(port, pinnum); +#endif + + gpio_t gp; + gpio_init(&gp, pin, PIN_OUTPUT); + gpio_write(&gp, value); + + return Ok; + + } while (false); + + + return InvalidCommandString; +} + + // ########################### // PCA9532 is used as a control inteface to the display. // voltages can be turned on/off and backlight can be controlled. @@ -549,6 +728,15 @@ setLeds(); } +void EaLcdBoard::setWriteProtect(bool enable) +{ + if (enable) { + pca9532_setLeds(0, LCDB_EEPROM_WP); + } else { + pca9532_setLeds(LCDB_EEPROM_WP, 0); + } +} + void EaLcdBoard::set3V3Signal(bool enabled) { if (enabled) { pca9532_setLeds(LCDB_CTRL_3V3, 0); @@ -598,5 +786,3 @@ } - -