A library with drivers for different peripherals on the LPC4088 QuickStart Board or related add-on boards.
Dependencies: FATFileSystem
Fork of EALib by
EaLcdBoard.cpp@10:f2409dc07e49, 2014-01-10 (annotated)
- Committer:
- embeddedartists
- Date:
- Fri Jan 10 08:24:42 2014 +0000
- Revision:
- 10:f2409dc07e49
- Parent:
- 4:b32cf4ef45c5
- Child:
- 12:15597e45eea0
Fixed example in QSPIFileSystem documentation
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
embeddedartists | 4:b32cf4ef45c5 | 1 | |
embeddedartists | 4:b32cf4ef45c5 | 2 | /****************************************************************************** |
embeddedartists | 4:b32cf4ef45c5 | 3 | * Includes |
embeddedartists | 4:b32cf4ef45c5 | 4 | *****************************************************************************/ |
embeddedartists | 0:0fdadbc3d852 | 5 | |
embeddedartists | 0:0fdadbc3d852 | 6 | #include "mbed.h" |
embeddedartists | 0:0fdadbc3d852 | 7 | #include "EaLcdBoard.h" |
embeddedartists | 0:0fdadbc3d852 | 8 | |
embeddedartists | 4:b32cf4ef45c5 | 9 | /****************************************************************************** |
embeddedartists | 4:b32cf4ef45c5 | 10 | * Defines and typedefs |
embeddedartists | 4:b32cf4ef45c5 | 11 | *****************************************************************************/ |
embeddedartists | 4:b32cf4ef45c5 | 12 | |
embeddedartists | 4:b32cf4ef45c5 | 13 | #define PORT_PIN_BUG_IN_MBED_SDK |
embeddedartists | 4:b32cf4ef45c5 | 14 | |
embeddedartists | 0:0fdadbc3d852 | 15 | #define LCDB_MAGIC 0xEA01CDAE |
embeddedartists | 0:0fdadbc3d852 | 16 | |
embeddedartists | 0:0fdadbc3d852 | 17 | |
embeddedartists | 0:0fdadbc3d852 | 18 | #define LCDB_PCA9532_I2C_ADDR (0x64 << 1) |
embeddedartists | 0:0fdadbc3d852 | 19 | |
embeddedartists | 0:0fdadbc3d852 | 20 | /* PCA9532 registers*/ |
embeddedartists | 0:0fdadbc3d852 | 21 | #define LCDB_PCA9532_INPUT0 0x00 |
embeddedartists | 0:0fdadbc3d852 | 22 | #define LCDB_PCA9532_INPUT1 0x01 |
embeddedartists | 0:0fdadbc3d852 | 23 | #define LCDB_PCA9532_PSC0 0x02 |
embeddedartists | 0:0fdadbc3d852 | 24 | #define LCDB_PCA9532_PWM0 0x03 |
embeddedartists | 0:0fdadbc3d852 | 25 | #define LCDB_PCA9532_PSC1 0x04 |
embeddedartists | 0:0fdadbc3d852 | 26 | #define LCDB_PCA9532_PWM1 0x05 |
embeddedartists | 0:0fdadbc3d852 | 27 | #define LCDB_PCA9532_LS0 0x06 |
embeddedartists | 0:0fdadbc3d852 | 28 | #define LCDB_PCA9532_LS1 0x07 |
embeddedartists | 0:0fdadbc3d852 | 29 | #define LCDB_PCA9532_LS2 0x08 |
embeddedartists | 0:0fdadbc3d852 | 30 | #define LCDB_PCA9532_LS3 0x09 |
embeddedartists | 0:0fdadbc3d852 | 31 | #define LCDB_PCA9532_AUTO_INC 0x10 |
embeddedartists | 0:0fdadbc3d852 | 32 | |
embeddedartists | 0:0fdadbc3d852 | 33 | #define LCDB_LS_MODE_ON 0x01 |
embeddedartists | 0:0fdadbc3d852 | 34 | #define LCDB_LS_MODE_BLINK0 0x02 |
embeddedartists | 0:0fdadbc3d852 | 35 | #define LCDB_LS_MODE_BLINK1 0x03 |
embeddedartists | 0:0fdadbc3d852 | 36 | |
embeddedartists | 0:0fdadbc3d852 | 37 | #define LCDB_CTRL_3V3 0x0001 |
embeddedartists | 0:0fdadbc3d852 | 38 | #define LCDB_CTRL_5V 0x0002 |
embeddedartists | 0:0fdadbc3d852 | 39 | #define LCDB_CTRL_DISP_EN 0x0010 |
embeddedartists | 0:0fdadbc3d852 | 40 | #define LCDB_CTRL_BL_EN 0x0080 |
embeddedartists | 0:0fdadbc3d852 | 41 | #define LCDB_CTRL_BL_C 0x0100 |
embeddedartists | 0:0fdadbc3d852 | 42 | #define LCDB_EEPROM_WP 0x8000 |
embeddedartists | 0:0fdadbc3d852 | 43 | |
embeddedartists | 0:0fdadbc3d852 | 44 | #define LCDB_EEPROM_I2C_ADDR (0x56 << 1) |
embeddedartists | 0:0fdadbc3d852 | 45 | #define LCDB_EEPROM_PAGE_SIZE 32 |
embeddedartists | 0:0fdadbc3d852 | 46 | #define LCDB_EEPROM_TOTAL_SIZE 8192 |
embeddedartists | 0:0fdadbc3d852 | 47 | |
embeddedartists | 0:0fdadbc3d852 | 48 | /* |
embeddedartists | 0:0fdadbc3d852 | 49 | * Set which sequence string version that is supported |
embeddedartists | 0:0fdadbc3d852 | 50 | */ |
embeddedartists | 4:b32cf4ef45c5 | 51 | #define LCDB_SEQ_VER 2 |
embeddedartists | 0:0fdadbc3d852 | 52 | |
embeddedartists | 0:0fdadbc3d852 | 53 | #ifndef MIN |
embeddedartists | 0:0fdadbc3d852 | 54 | #define MIN(x, y) (((x)<(y))?(x):(y)) |
embeddedartists | 0:0fdadbc3d852 | 55 | #endif |
embeddedartists | 0:0fdadbc3d852 | 56 | |
embeddedartists | 0:0fdadbc3d852 | 57 | #define EA_LCD_TMP_BUFFER_SZ 256 |
embeddedartists | 0:0fdadbc3d852 | 58 | static char* eaLcdTmpBuffer[EA_LCD_TMP_BUFFER_SZ]; |
embeddedartists | 0:0fdadbc3d852 | 59 | |
embeddedartists | 0:0fdadbc3d852 | 60 | |
embeddedartists | 0:0fdadbc3d852 | 61 | /* Structure containing the parameters for the LCD panel as stored on LCD Board */ |
embeddedartists | 0:0fdadbc3d852 | 62 | |
embeddedartists | 0:0fdadbc3d852 | 63 | /* LCD display types */ |
embeddedartists | 0:0fdadbc3d852 | 64 | typedef enum { |
embeddedartists | 0:0fdadbc3d852 | 65 | TFT = 0, /* standard TFT */ |
embeddedartists | 0:0fdadbc3d852 | 66 | ADTFT, /* advanced TFT */ |
embeddedartists | 0:0fdadbc3d852 | 67 | HRTFT, /* highly reflective TFT */ |
embeddedartists | 0:0fdadbc3d852 | 68 | MONO_4BIT, /* 4-bit mono */ |
embeddedartists | 0:0fdadbc3d852 | 69 | MONO_8BIT, /* 8-bit mono */ |
embeddedartists | 0:0fdadbc3d852 | 70 | CSTN /* color STN */ |
embeddedartists | 0:0fdadbc3d852 | 71 | } nxp_lcd_panel_t; |
embeddedartists | 0:0fdadbc3d852 | 72 | |
embeddedartists | 0:0fdadbc3d852 | 73 | typedef struct { |
embeddedartists | 0:0fdadbc3d852 | 74 | uint8_t h_back_porch; /* Horizontal back porch in clocks */ |
embeddedartists | 0:0fdadbc3d852 | 75 | uint8_t h_front_porch; /* Horizontal front porch in clocks */ |
embeddedartists | 0:0fdadbc3d852 | 76 | uint8_t h_sync_pulse_width; /* HSYNC pulse width in clocks */ |
embeddedartists | 0:0fdadbc3d852 | 77 | uint16_t pixels_per_line; /* Pixels per line (horizontal resolution) */ |
embeddedartists | 0:0fdadbc3d852 | 78 | uint8_t v_back_porch; /* Vertical back porch in clocks */ |
embeddedartists | 0:0fdadbc3d852 | 79 | uint8_t v_front_porch; /* Vertical front porch in clocks */ |
embeddedartists | 0:0fdadbc3d852 | 80 | uint8_t v_sync_pulse_width; /* VSYNC pulse width in clocks */ |
embeddedartists | 0:0fdadbc3d852 | 81 | uint16_t lines_per_panel; /* Lines per panel (vertical resolution) */ |
embeddedartists | 0:0fdadbc3d852 | 82 | uint8_t invert_output_enable; /* Invert output enable, 1 = invert*/ |
embeddedartists | 0:0fdadbc3d852 | 83 | uint8_t invert_panel_clock; /* Invert panel clock, 1 = invert*/ |
embeddedartists | 0:0fdadbc3d852 | 84 | uint8_t invert_hsync; /* Invert HSYNC, 1 = invert */ |
embeddedartists | 0:0fdadbc3d852 | 85 | uint8_t invert_vsync; /* Invert VSYNC, 1 = invert */ |
embeddedartists | 0:0fdadbc3d852 | 86 | uint8_t ac_bias_frequency; /* AC bias frequency in clocks */ |
embeddedartists | 0:0fdadbc3d852 | 87 | uint8_t bits_per_pixel; /* Maximum bits per pixel the display supports */ |
embeddedartists | 0:0fdadbc3d852 | 88 | uint32_t optimal_clock; /* Optimal clock rate (Hz) */ |
embeddedartists | 0:0fdadbc3d852 | 89 | nxp_lcd_panel_t lcd_panel_type; /* LCD panel type */ |
embeddedartists | 0:0fdadbc3d852 | 90 | uint8_t dual_panel; /* Dual panel, 1 = dual panel display */ |
embeddedartists | 0:0fdadbc3d852 | 91 | } nxp_lcd_param_t; |
embeddedartists | 0:0fdadbc3d852 | 92 | |
embeddedartists | 0:0fdadbc3d852 | 93 | static uint32_t str_to_uint(char* str, uint32_t len); |
embeddedartists | 0:0fdadbc3d852 | 94 | |
embeddedartists | 0:0fdadbc3d852 | 95 | EaLcdBoard::EaLcdBoard(PinName sda, PinName scl) : _i2c(sda, scl) { |
embeddedartists | 0:0fdadbc3d852 | 96 | _blink0Shadow = 0; |
embeddedartists | 0:0fdadbc3d852 | 97 | _blink1Shadow = 0; |
embeddedartists | 0:0fdadbc3d852 | 98 | _ledStateShadow = 0; |
embeddedartists | 0:0fdadbc3d852 | 99 | _lcdPwrOn = false; |
embeddedartists | 0:0fdadbc3d852 | 100 | } |
embeddedartists | 0:0fdadbc3d852 | 101 | |
embeddedartists | 0:0fdadbc3d852 | 102 | EaLcdBoard::Result EaLcdBoard::open(LcdController::Config* cfg, char* initSeq) { |
embeddedartists | 0:0fdadbc3d852 | 103 | |
embeddedartists | 0:0fdadbc3d852 | 104 | EaLcdBoard::Result result = Ok; |
embeddedartists | 0:0fdadbc3d852 | 105 | |
embeddedartists | 0:0fdadbc3d852 | 106 | // load LCD configuration from storage |
embeddedartists | 0:0fdadbc3d852 | 107 | if (cfg == NULL) { |
embeddedartists | 0:0fdadbc3d852 | 108 | result = getLcdConfig(&_cfg); |
embeddedartists | 0:0fdadbc3d852 | 109 | cfg = &_cfg; |
embeddedartists | 0:0fdadbc3d852 | 110 | } |
embeddedartists | 0:0fdadbc3d852 | 111 | |
embeddedartists | 0:0fdadbc3d852 | 112 | // load init sequence from storage |
embeddedartists | 0:0fdadbc3d852 | 113 | if (result == Ok && initSeq == NULL) { |
embeddedartists | 0:0fdadbc3d852 | 114 | result = getInitSeq((char*)eaLcdTmpBuffer, EA_LCD_TMP_BUFFER_SZ); |
embeddedartists | 0:0fdadbc3d852 | 115 | initSeq = (char*)eaLcdTmpBuffer; |
embeddedartists | 0:0fdadbc3d852 | 116 | } |
embeddedartists | 0:0fdadbc3d852 | 117 | |
embeddedartists | 0:0fdadbc3d852 | 118 | if (result != Ok) { |
embeddedartists | 0:0fdadbc3d852 | 119 | return result; |
embeddedartists | 0:0fdadbc3d852 | 120 | } |
embeddedartists | 0:0fdadbc3d852 | 121 | |
embeddedartists | 0:0fdadbc3d852 | 122 | return parseInitString(initSeq, cfg); |
embeddedartists | 0:0fdadbc3d852 | 123 | } |
embeddedartists | 0:0fdadbc3d852 | 124 | |
embeddedartists | 0:0fdadbc3d852 | 125 | EaLcdBoard::Result EaLcdBoard::close() { |
embeddedartists | 0:0fdadbc3d852 | 126 | int r = 0; |
embeddedartists | 0:0fdadbc3d852 | 127 | |
embeddedartists | 0:0fdadbc3d852 | 128 | do { |
embeddedartists | 0:0fdadbc3d852 | 129 | r = lcdCtrl.setPower(false); |
embeddedartists | 0:0fdadbc3d852 | 130 | if (r != 0) break; |
embeddedartists | 0:0fdadbc3d852 | 131 | |
embeddedartists | 0:0fdadbc3d852 | 132 | _lcdPwrOn = false; |
embeddedartists | 0:0fdadbc3d852 | 133 | |
embeddedartists | 0:0fdadbc3d852 | 134 | r = lcdCtrl.close(); |
embeddedartists | 0:0fdadbc3d852 | 135 | } while(0); |
embeddedartists | 0:0fdadbc3d852 | 136 | |
embeddedartists | 0:0fdadbc3d852 | 137 | if (r != 0) { |
embeddedartists | 0:0fdadbc3d852 | 138 | return LcdAccessError; |
embeddedartists | 0:0fdadbc3d852 | 139 | } |
embeddedartists | 0:0fdadbc3d852 | 140 | |
embeddedartists | 0:0fdadbc3d852 | 141 | return Ok; |
embeddedartists | 0:0fdadbc3d852 | 142 | } |
embeddedartists | 0:0fdadbc3d852 | 143 | |
embeddedartists | 0:0fdadbc3d852 | 144 | EaLcdBoard::Result EaLcdBoard::setFrameBuffer(uint32_t address) { |
embeddedartists | 0:0fdadbc3d852 | 145 | int r = 0; |
embeddedartists | 0:0fdadbc3d852 | 146 | |
embeddedartists | 0:0fdadbc3d852 | 147 | do { |
embeddedartists | 0:0fdadbc3d852 | 148 | |
embeddedartists | 0:0fdadbc3d852 | 149 | // begin by powering on the display |
embeddedartists | 0:0fdadbc3d852 | 150 | if (!_lcdPwrOn) { |
embeddedartists | 0:0fdadbc3d852 | 151 | r = lcdCtrl.setPower(true); |
embeddedartists | 0:0fdadbc3d852 | 152 | if (r != 0) break; |
embeddedartists | 0:0fdadbc3d852 | 153 | |
embeddedartists | 0:0fdadbc3d852 | 154 | _lcdPwrOn = true; |
embeddedartists | 0:0fdadbc3d852 | 155 | } |
embeddedartists | 0:0fdadbc3d852 | 156 | |
embeddedartists | 0:0fdadbc3d852 | 157 | // activate specified frame buffer |
embeddedartists | 0:0fdadbc3d852 | 158 | r = lcdCtrl.setFrameBuffer(address); |
embeddedartists | 0:0fdadbc3d852 | 159 | if (r != 0) break; |
embeddedartists | 0:0fdadbc3d852 | 160 | |
embeddedartists | 0:0fdadbc3d852 | 161 | } while(0); |
embeddedartists | 0:0fdadbc3d852 | 162 | |
embeddedartists | 0:0fdadbc3d852 | 163 | if (r != 0) { |
embeddedartists | 0:0fdadbc3d852 | 164 | return LcdAccessError; |
embeddedartists | 0:0fdadbc3d852 | 165 | } |
embeddedartists | 0:0fdadbc3d852 | 166 | |
embeddedartists | 0:0fdadbc3d852 | 167 | |
embeddedartists | 0:0fdadbc3d852 | 168 | return Ok; |
embeddedartists | 0:0fdadbc3d852 | 169 | } |
embeddedartists | 0:0fdadbc3d852 | 170 | |
embeddedartists | 0:0fdadbc3d852 | 171 | EaLcdBoard::Result EaLcdBoard::getLcdConfig(LcdController::Config* cfg) { |
embeddedartists | 0:0fdadbc3d852 | 172 | store_t h; |
embeddedartists | 0:0fdadbc3d852 | 173 | |
embeddedartists | 0:0fdadbc3d852 | 174 | nxp_lcd_param_t lcdParam; |
embeddedartists | 0:0fdadbc3d852 | 175 | |
embeddedartists | 4:b32cf4ef45c5 | 176 | if (cfg == NULL) { |
embeddedartists | 4:b32cf4ef45c5 | 177 | return InvalidArgument; |
embeddedartists | 4:b32cf4ef45c5 | 178 | } |
embeddedartists | 4:b32cf4ef45c5 | 179 | |
embeddedartists | 0:0fdadbc3d852 | 180 | getStore(&h); |
embeddedartists | 0:0fdadbc3d852 | 181 | |
embeddedartists | 0:0fdadbc3d852 | 182 | if (h.magic != LCDB_MAGIC) { |
embeddedartists | 0:0fdadbc3d852 | 183 | return InvalidStorage; |
embeddedartists | 0:0fdadbc3d852 | 184 | } |
embeddedartists | 0:0fdadbc3d852 | 185 | |
embeddedartists | 0:0fdadbc3d852 | 186 | eepromRead((uint8_t*)&lcdParam, h.lcdParamOff, |
embeddedartists | 0:0fdadbc3d852 | 187 | (h.initOff-h.lcdParamOff)); |
embeddedartists | 0:0fdadbc3d852 | 188 | |
embeddedartists | 0:0fdadbc3d852 | 189 | cfg->horizontalBackPorch = lcdParam.h_back_porch; |
embeddedartists | 0:0fdadbc3d852 | 190 | cfg->horizontalFrontPorch = lcdParam.h_front_porch; |
embeddedartists | 0:0fdadbc3d852 | 191 | cfg->hsync = lcdParam.h_sync_pulse_width; |
embeddedartists | 0:0fdadbc3d852 | 192 | cfg->width = lcdParam.pixels_per_line; |
embeddedartists | 0:0fdadbc3d852 | 193 | cfg->verticalBackPorch = lcdParam.v_back_porch; |
embeddedartists | 0:0fdadbc3d852 | 194 | cfg->verticalFrontPorch = lcdParam.v_front_porch; |
embeddedartists | 0:0fdadbc3d852 | 195 | cfg->vsync = lcdParam.v_sync_pulse_width; |
embeddedartists | 0:0fdadbc3d852 | 196 | cfg->height = lcdParam.lines_per_panel; |
embeddedartists | 0:0fdadbc3d852 | 197 | cfg->invertOutputEnable = (lcdParam.invert_output_enable == 1); |
embeddedartists | 0:0fdadbc3d852 | 198 | cfg->invertPanelClock = (lcdParam.invert_panel_clock == 1); |
embeddedartists | 0:0fdadbc3d852 | 199 | cfg->invertHsync = (lcdParam.invert_hsync == 1); |
embeddedartists | 0:0fdadbc3d852 | 200 | cfg->invertVsync = (lcdParam.invert_vsync == 1); |
embeddedartists | 0:0fdadbc3d852 | 201 | cfg->acBias = lcdParam.ac_bias_frequency; |
embeddedartists | 0:0fdadbc3d852 | 202 | cfg->bpp = LcdController::Bpp_16_565; |
embeddedartists | 0:0fdadbc3d852 | 203 | cfg->optimalClock = lcdParam.optimal_clock; |
embeddedartists | 0:0fdadbc3d852 | 204 | cfg->panelType = (LcdController::LcdPanel)lcdParam.lcd_panel_type; |
embeddedartists | 0:0fdadbc3d852 | 205 | cfg->dualPanel = (lcdParam.dual_panel == 1); |
embeddedartists | 0:0fdadbc3d852 | 206 | |
embeddedartists | 0:0fdadbc3d852 | 207 | return Ok; |
embeddedartists | 0:0fdadbc3d852 | 208 | } |
embeddedartists | 0:0fdadbc3d852 | 209 | |
embeddedartists | 0:0fdadbc3d852 | 210 | EaLcdBoard::Result EaLcdBoard::getDisplayName(char* buf, int len) { |
embeddedartists | 0:0fdadbc3d852 | 211 | store_t h; |
embeddedartists | 0:0fdadbc3d852 | 212 | |
embeddedartists | 4:b32cf4ef45c5 | 213 | if (buf == NULL) { |
embeddedartists | 4:b32cf4ef45c5 | 214 | return InvalidArgument; |
embeddedartists | 4:b32cf4ef45c5 | 215 | } |
embeddedartists | 4:b32cf4ef45c5 | 216 | |
embeddedartists | 0:0fdadbc3d852 | 217 | getStore(&h); |
embeddedartists | 0:0fdadbc3d852 | 218 | |
embeddedartists | 0:0fdadbc3d852 | 219 | if (h.magic != LCDB_MAGIC) { |
embeddedartists | 0:0fdadbc3d852 | 220 | return InvalidStorage; |
embeddedartists | 0:0fdadbc3d852 | 221 | } |
embeddedartists | 0:0fdadbc3d852 | 222 | |
embeddedartists | 0:0fdadbc3d852 | 223 | if (len < NameBufferSize) { |
embeddedartists | 0:0fdadbc3d852 | 224 | return BufferTooSmall; |
embeddedartists | 0:0fdadbc3d852 | 225 | } |
embeddedartists | 0:0fdadbc3d852 | 226 | |
embeddedartists | 0:0fdadbc3d852 | 227 | strncpy(buf, (char*)h.lcd_name, NameBufferSize); |
embeddedartists | 0:0fdadbc3d852 | 228 | |
embeddedartists | 0:0fdadbc3d852 | 229 | return Ok; |
embeddedartists | 0:0fdadbc3d852 | 230 | } |
embeddedartists | 0:0fdadbc3d852 | 231 | |
embeddedartists | 0:0fdadbc3d852 | 232 | EaLcdBoard::Result EaLcdBoard::getDisplayMfg(char* buf, int len) { |
embeddedartists | 0:0fdadbc3d852 | 233 | store_t h; |
embeddedartists | 0:0fdadbc3d852 | 234 | |
embeddedartists | 4:b32cf4ef45c5 | 235 | if (buf == NULL) { |
embeddedartists | 4:b32cf4ef45c5 | 236 | return InvalidArgument; |
embeddedartists | 4:b32cf4ef45c5 | 237 | } |
embeddedartists | 4:b32cf4ef45c5 | 238 | |
embeddedartists | 0:0fdadbc3d852 | 239 | getStore(&h); |
embeddedartists | 0:0fdadbc3d852 | 240 | |
embeddedartists | 0:0fdadbc3d852 | 241 | if (h.magic != LCDB_MAGIC) { |
embeddedartists | 0:0fdadbc3d852 | 242 | return InvalidStorage; |
embeddedartists | 0:0fdadbc3d852 | 243 | } |
embeddedartists | 0:0fdadbc3d852 | 244 | |
embeddedartists | 0:0fdadbc3d852 | 245 | if (len < NameBufferSize) { |
embeddedartists | 0:0fdadbc3d852 | 246 | return BufferTooSmall; |
embeddedartists | 0:0fdadbc3d852 | 247 | } |
embeddedartists | 0:0fdadbc3d852 | 248 | |
embeddedartists | 0:0fdadbc3d852 | 249 | strncpy(buf, (char*)h.lcd_mfg, NameBufferSize); |
embeddedartists | 0:0fdadbc3d852 | 250 | |
embeddedartists | 0:0fdadbc3d852 | 251 | return Ok; |
embeddedartists | 0:0fdadbc3d852 | 252 | } |
embeddedartists | 0:0fdadbc3d852 | 253 | |
embeddedartists | 0:0fdadbc3d852 | 254 | EaLcdBoard::Result EaLcdBoard::getInitSeq(char* buf, int len) { |
embeddedartists | 0:0fdadbc3d852 | 255 | store_t h; |
embeddedartists | 0:0fdadbc3d852 | 256 | |
embeddedartists | 4:b32cf4ef45c5 | 257 | if (buf == NULL) { |
embeddedartists | 4:b32cf4ef45c5 | 258 | return InvalidArgument; |
embeddedartists | 4:b32cf4ef45c5 | 259 | } |
embeddedartists | 4:b32cf4ef45c5 | 260 | |
embeddedartists | 0:0fdadbc3d852 | 261 | getStore(&h); |
embeddedartists | 0:0fdadbc3d852 | 262 | |
embeddedartists | 0:0fdadbc3d852 | 263 | if (h.magic != LCDB_MAGIC) { |
embeddedartists | 0:0fdadbc3d852 | 264 | return InvalidStorage; |
embeddedartists | 0:0fdadbc3d852 | 265 | } |
embeddedartists | 0:0fdadbc3d852 | 266 | |
embeddedartists | 0:0fdadbc3d852 | 267 | if ((h.pdOff-h.initOff) > len) { |
embeddedartists | 0:0fdadbc3d852 | 268 | return BufferTooSmall; |
embeddedartists | 0:0fdadbc3d852 | 269 | } |
embeddedartists | 0:0fdadbc3d852 | 270 | |
embeddedartists | 0:0fdadbc3d852 | 271 | eepromRead((uint8_t*)buf, h.initOff, |
embeddedartists | 0:0fdadbc3d852 | 272 | (h.pdOff-h.initOff)); |
embeddedartists | 0:0fdadbc3d852 | 273 | |
embeddedartists | 0:0fdadbc3d852 | 274 | return Ok; |
embeddedartists | 0:0fdadbc3d852 | 275 | } |
embeddedartists | 0:0fdadbc3d852 | 276 | |
embeddedartists | 0:0fdadbc3d852 | 277 | EaLcdBoard::Result EaLcdBoard::getPowerDownSeq(char* buf, int len) { |
embeddedartists | 0:0fdadbc3d852 | 278 | store_t h; |
embeddedartists | 0:0fdadbc3d852 | 279 | |
embeddedartists | 4:b32cf4ef45c5 | 280 | if (buf == NULL) { |
embeddedartists | 4:b32cf4ef45c5 | 281 | return InvalidArgument; |
embeddedartists | 4:b32cf4ef45c5 | 282 | } |
embeddedartists | 4:b32cf4ef45c5 | 283 | |
embeddedartists | 0:0fdadbc3d852 | 284 | getStore(&h); |
embeddedartists | 0:0fdadbc3d852 | 285 | |
embeddedartists | 0:0fdadbc3d852 | 286 | if (h.magic != LCDB_MAGIC) { |
embeddedartists | 0:0fdadbc3d852 | 287 | return InvalidStorage; |
embeddedartists | 0:0fdadbc3d852 | 288 | } |
embeddedartists | 0:0fdadbc3d852 | 289 | |
embeddedartists | 0:0fdadbc3d852 | 290 | if ((h.tsOff-h.pdOff) > len) { |
embeddedartists | 0:0fdadbc3d852 | 291 | return BufferTooSmall; |
embeddedartists | 0:0fdadbc3d852 | 292 | } |
embeddedartists | 0:0fdadbc3d852 | 293 | |
embeddedartists | 0:0fdadbc3d852 | 294 | eepromRead((uint8_t*)buf, h.pdOff, |
embeddedartists | 0:0fdadbc3d852 | 295 | (h.tsOff-h.pdOff)); |
embeddedartists | 0:0fdadbc3d852 | 296 | |
embeddedartists | 0:0fdadbc3d852 | 297 | return Ok; |
embeddedartists | 0:0fdadbc3d852 | 298 | } |
embeddedartists | 0:0fdadbc3d852 | 299 | |
embeddedartists | 4:b32cf4ef45c5 | 300 | EaLcdBoard::Result EaLcdBoard::getTouchParameters(TouchParams_t* params) { |
embeddedartists | 4:b32cf4ef45c5 | 301 | store_t h; |
embeddedartists | 4:b32cf4ef45c5 | 302 | |
embeddedartists | 4:b32cf4ef45c5 | 303 | if (params == NULL) { |
embeddedartists | 4:b32cf4ef45c5 | 304 | return InvalidArgument; |
embeddedartists | 4:b32cf4ef45c5 | 305 | } |
embeddedartists | 4:b32cf4ef45c5 | 306 | |
embeddedartists | 4:b32cf4ef45c5 | 307 | getStore(&h); |
embeddedartists | 4:b32cf4ef45c5 | 308 | |
embeddedartists | 4:b32cf4ef45c5 | 309 | if (h.magic != LCDB_MAGIC) { |
embeddedartists | 4:b32cf4ef45c5 | 310 | return InvalidStorage; |
embeddedartists | 4:b32cf4ef45c5 | 311 | } |
embeddedartists | 4:b32cf4ef45c5 | 312 | |
embeddedartists | 4:b32cf4ef45c5 | 313 | |
embeddedartists | 4:b32cf4ef45c5 | 314 | if (eepromRead((uint8_t*)params, h.tsOff, |
embeddedartists | 4:b32cf4ef45c5 | 315 | (h.end-h.tsOff)) == -1) { |
embeddedartists | 4:b32cf4ef45c5 | 316 | return InvalidStorage; |
embeddedartists | 4:b32cf4ef45c5 | 317 | } |
embeddedartists | 4:b32cf4ef45c5 | 318 | |
embeddedartists | 4:b32cf4ef45c5 | 319 | |
embeddedartists | 4:b32cf4ef45c5 | 320 | if (params->panelId <= TouchPanelInvalidFirst |
embeddedartists | 4:b32cf4ef45c5 | 321 | || params->panelId >= TouchPanelInvalidLast) { |
embeddedartists | 4:b32cf4ef45c5 | 322 | params->panelId = TouchPanelUnknown; |
embeddedartists | 4:b32cf4ef45c5 | 323 | } |
embeddedartists | 4:b32cf4ef45c5 | 324 | |
embeddedartists | 4:b32cf4ef45c5 | 325 | |
embeddedartists | 4:b32cf4ef45c5 | 326 | return Ok; |
embeddedartists | 4:b32cf4ef45c5 | 327 | } |
embeddedartists | 4:b32cf4ef45c5 | 328 | |
embeddedartists | 4:b32cf4ef45c5 | 329 | EaLcdBoard::Result EaLcdBoard::storeParameters( |
embeddedartists | 4:b32cf4ef45c5 | 330 | const char* lcdName, |
embeddedartists | 4:b32cf4ef45c5 | 331 | const char* lcdMfg, |
embeddedartists | 4:b32cf4ef45c5 | 332 | LcdController::Config* cfg, |
embeddedartists | 4:b32cf4ef45c5 | 333 | const char* initSeqStr, |
embeddedartists | 4:b32cf4ef45c5 | 334 | const char* pdSeqStr, |
embeddedartists | 4:b32cf4ef45c5 | 335 | TouchParams_t* touch, |
embeddedartists | 4:b32cf4ef45c5 | 336 | bool controlWp) |
embeddedartists | 4:b32cf4ef45c5 | 337 | { |
embeddedartists | 4:b32cf4ef45c5 | 338 | store_t h; |
embeddedartists | 4:b32cf4ef45c5 | 339 | nxp_lcd_param_t lcdParam; |
embeddedartists | 4:b32cf4ef45c5 | 340 | |
embeddedartists | 4:b32cf4ef45c5 | 341 | if (lcdName == NULL || lcdMfg == NULL || cfg == NULL |
embeddedartists | 4:b32cf4ef45c5 | 342 | || initSeqStr == NULL || pdSeqStr == NULL) { |
embeddedartists | 4:b32cf4ef45c5 | 343 | return InvalidArgument; |
embeddedartists | 4:b32cf4ef45c5 | 344 | |
embeddedartists | 4:b32cf4ef45c5 | 345 | } |
embeddedartists | 4:b32cf4ef45c5 | 346 | |
embeddedartists | 4:b32cf4ef45c5 | 347 | |
embeddedartists | 4:b32cf4ef45c5 | 348 | lcdParam.h_back_porch = cfg->horizontalBackPorch; |
embeddedartists | 4:b32cf4ef45c5 | 349 | lcdParam.h_front_porch = cfg->horizontalFrontPorch; |
embeddedartists | 4:b32cf4ef45c5 | 350 | lcdParam.h_sync_pulse_width = cfg->hsync; |
embeddedartists | 4:b32cf4ef45c5 | 351 | lcdParam.pixels_per_line = cfg->width; |
embeddedartists | 4:b32cf4ef45c5 | 352 | lcdParam.v_back_porch = cfg->verticalBackPorch; |
embeddedartists | 4:b32cf4ef45c5 | 353 | lcdParam.v_front_porch = cfg->verticalFrontPorch; |
embeddedartists | 4:b32cf4ef45c5 | 354 | lcdParam.v_sync_pulse_width = cfg->vsync; |
embeddedartists | 4:b32cf4ef45c5 | 355 | lcdParam.lines_per_panel = cfg->height; |
embeddedartists | 4:b32cf4ef45c5 | 356 | lcdParam.invert_output_enable = (cfg->invertOutputEnable ? 1 : 0); |
embeddedartists | 4:b32cf4ef45c5 | 357 | lcdParam.invert_panel_clock = (cfg->invertPanelClock ? 1 : 0); |
embeddedartists | 4:b32cf4ef45c5 | 358 | lcdParam.invert_hsync = (cfg->invertHsync ? 1 : 0); |
embeddedartists | 4:b32cf4ef45c5 | 359 | lcdParam.invert_vsync = (cfg->invertVsync ? 1 : 0); |
embeddedartists | 4:b32cf4ef45c5 | 360 | lcdParam.ac_bias_frequency = cfg->acBias; |
embeddedartists | 4:b32cf4ef45c5 | 361 | lcdParam.optimal_clock = cfg->optimalClock; |
embeddedartists | 4:b32cf4ef45c5 | 362 | lcdParam.lcd_panel_type = (nxp_lcd_panel_t)cfg->panelType; |
embeddedartists | 4:b32cf4ef45c5 | 363 | lcdParam.dual_panel = (cfg->dualPanel ? 1 : 0); |
embeddedartists | 4:b32cf4ef45c5 | 364 | |
embeddedartists | 4:b32cf4ef45c5 | 365 | |
embeddedartists | 4:b32cf4ef45c5 | 366 | h.magic = LCDB_MAGIC; |
embeddedartists | 4:b32cf4ef45c5 | 367 | strncpy((char*)h.lcd_name, lcdName, 30); |
embeddedartists | 4:b32cf4ef45c5 | 368 | strncpy((char*)h.lcd_mfg, lcdMfg, 30); |
embeddedartists | 4:b32cf4ef45c5 | 369 | |
embeddedartists | 4:b32cf4ef45c5 | 370 | h.lcdParamOff = sizeof(store_t); |
embeddedartists | 4:b32cf4ef45c5 | 371 | h.initOff = h.lcdParamOff + sizeof(nxp_lcd_param_t); |
embeddedartists | 4:b32cf4ef45c5 | 372 | h.pdOff = h.initOff + strlen(initSeqStr)+1; |
embeddedartists | 4:b32cf4ef45c5 | 373 | h.tsOff = h.pdOff + strlen(pdSeqStr)+1; |
embeddedartists | 4:b32cf4ef45c5 | 374 | h.end = h.tsOff + sizeof(TouchParams_t); |
embeddedartists | 4:b32cf4ef45c5 | 375 | |
embeddedartists | 4:b32cf4ef45c5 | 376 | if (controlWp) setWriteProtect(false); |
embeddedartists | 4:b32cf4ef45c5 | 377 | eepromWrite((uint8_t*)&h, 0, h.lcdParamOff); |
embeddedartists | 4:b32cf4ef45c5 | 378 | eepromWrite((uint8_t*)&lcdParam, h.lcdParamOff, (h.initOff-h.lcdParamOff)); |
embeddedartists | 4:b32cf4ef45c5 | 379 | eepromWrite((uint8_t*)initSeqStr, h.initOff, (h.pdOff-h.initOff)); |
embeddedartists | 4:b32cf4ef45c5 | 380 | eepromWrite((uint8_t*)pdSeqStr, h.pdOff, (h.tsOff-h.pdOff)); |
embeddedartists | 4:b32cf4ef45c5 | 381 | eepromWrite((uint8_t*)touch, h.tsOff, (h.end-h.tsOff)); |
embeddedartists | 4:b32cf4ef45c5 | 382 | if (controlWp) setWriteProtect(true); |
embeddedartists | 4:b32cf4ef45c5 | 383 | |
embeddedartists | 4:b32cf4ef45c5 | 384 | return Ok; |
embeddedartists | 4:b32cf4ef45c5 | 385 | } |
embeddedartists | 4:b32cf4ef45c5 | 386 | |
embeddedartists | 0:0fdadbc3d852 | 387 | EaLcdBoard::Result EaLcdBoard::getStore(store_t* store) { |
embeddedartists | 0:0fdadbc3d852 | 388 | int num = 0; |
embeddedartists | 0:0fdadbc3d852 | 389 | |
embeddedartists | 0:0fdadbc3d852 | 390 | if (store == NULL) return InvalidArgument; |
embeddedartists | 0:0fdadbc3d852 | 391 | |
embeddedartists | 0:0fdadbc3d852 | 392 | num = eepromRead((uint8_t*)store, 0, sizeof(store_t)); |
embeddedartists | 0:0fdadbc3d852 | 393 | if (num < (int)sizeof(store_t)) { |
embeddedartists | 0:0fdadbc3d852 | 394 | return InvalidStorage; |
embeddedartists | 0:0fdadbc3d852 | 395 | } |
embeddedartists | 0:0fdadbc3d852 | 396 | |
embeddedartists | 0:0fdadbc3d852 | 397 | return Ok; |
embeddedartists | 0:0fdadbc3d852 | 398 | } |
embeddedartists | 0:0fdadbc3d852 | 399 | |
embeddedartists | 0:0fdadbc3d852 | 400 | // ########################### |
embeddedartists | 0:0fdadbc3d852 | 401 | // An EEPROM is used for persistent storage |
embeddedartists | 0:0fdadbc3d852 | 402 | // ########################### |
embeddedartists | 0:0fdadbc3d852 | 403 | |
embeddedartists | 0:0fdadbc3d852 | 404 | int EaLcdBoard::eepromRead(uint8_t* buf, uint16_t offset, uint16_t len) { |
embeddedartists | 0:0fdadbc3d852 | 405 | int i = 0; |
embeddedartists | 0:0fdadbc3d852 | 406 | char off[2]; |
embeddedartists | 4:b32cf4ef45c5 | 407 | uint16_t retLen = 0; |
embeddedartists | 0:0fdadbc3d852 | 408 | |
embeddedartists | 0:0fdadbc3d852 | 409 | if (len > LCDB_EEPROM_TOTAL_SIZE || offset+len > LCDB_EEPROM_TOTAL_SIZE) { |
embeddedartists | 0:0fdadbc3d852 | 410 | return -1; |
embeddedartists | 0:0fdadbc3d852 | 411 | } |
embeddedartists | 0:0fdadbc3d852 | 412 | |
embeddedartists | 4:b32cf4ef45c5 | 413 | wait_ms(10); |
embeddedartists | 4:b32cf4ef45c5 | 414 | |
embeddedartists | 0:0fdadbc3d852 | 415 | off[0] = ((offset >> 8) & 0xff); |
embeddedartists | 0:0fdadbc3d852 | 416 | off[1] = (offset & 0xff); |
embeddedartists | 0:0fdadbc3d852 | 417 | |
embeddedartists | 4:b32cf4ef45c5 | 418 | do { |
embeddedartists | 4:b32cf4ef45c5 | 419 | if (_i2c.write(LCDB_EEPROM_I2C_ADDR, (char*)off, 2) != 0) break; |
embeddedartists | 4:b32cf4ef45c5 | 420 | for ( i = 0; i < 0x2000; i++); |
embeddedartists | 4:b32cf4ef45c5 | 421 | if (_i2c.read(LCDB_EEPROM_I2C_ADDR, (char*)buf, len) != 0) break; |
embeddedartists | 0:0fdadbc3d852 | 422 | |
embeddedartists | 4:b32cf4ef45c5 | 423 | retLen = len; |
embeddedartists | 4:b32cf4ef45c5 | 424 | } while(0); |
embeddedartists | 4:b32cf4ef45c5 | 425 | |
embeddedartists | 4:b32cf4ef45c5 | 426 | return retLen; |
embeddedartists | 0:0fdadbc3d852 | 427 | } |
embeddedartists | 0:0fdadbc3d852 | 428 | |
embeddedartists | 0:0fdadbc3d852 | 429 | int EaLcdBoard::eepromWrite(uint8_t* buf, uint16_t offset, uint16_t len) { |
embeddedartists | 0:0fdadbc3d852 | 430 | int16_t written = 0; |
embeddedartists | 0:0fdadbc3d852 | 431 | uint16_t wLen = 0; |
embeddedartists | 0:0fdadbc3d852 | 432 | uint16_t off = offset; |
embeddedartists | 0:0fdadbc3d852 | 433 | uint8_t tmp[LCDB_EEPROM_PAGE_SIZE+2]; |
embeddedartists | 0:0fdadbc3d852 | 434 | |
embeddedartists | 0:0fdadbc3d852 | 435 | if (len > LCDB_EEPROM_TOTAL_SIZE || offset+len > LCDB_EEPROM_TOTAL_SIZE) { |
embeddedartists | 0:0fdadbc3d852 | 436 | return -1; |
embeddedartists | 0:0fdadbc3d852 | 437 | } |
embeddedartists | 0:0fdadbc3d852 | 438 | |
embeddedartists | 4:b32cf4ef45c5 | 439 | wait_ms(1); |
embeddedartists | 4:b32cf4ef45c5 | 440 | |
embeddedartists | 0:0fdadbc3d852 | 441 | wLen = LCDB_EEPROM_PAGE_SIZE - (off % LCDB_EEPROM_PAGE_SIZE); |
embeddedartists | 0:0fdadbc3d852 | 442 | wLen = MIN(wLen, len); |
embeddedartists | 0:0fdadbc3d852 | 443 | |
embeddedartists | 0:0fdadbc3d852 | 444 | while (len) { |
embeddedartists | 0:0fdadbc3d852 | 445 | tmp[0] = ((off >> 8) & 0xff); |
embeddedartists | 0:0fdadbc3d852 | 446 | tmp[1] = (off & 0xff); |
embeddedartists | 0:0fdadbc3d852 | 447 | memcpy(&tmp[2], (void*)&buf[written], wLen); |
embeddedartists | 4:b32cf4ef45c5 | 448 | if (_i2c.write(LCDB_EEPROM_I2C_ADDR, (char*)tmp, wLen+2) != 0) break; |
embeddedartists | 0:0fdadbc3d852 | 449 | |
embeddedartists | 0:0fdadbc3d852 | 450 | // delay to wait for a write cycle |
embeddedartists | 0:0fdadbc3d852 | 451 | //eepromDelay(); |
embeddedartists | 4:b32cf4ef45c5 | 452 | wait_ms(10); |
embeddedartists | 0:0fdadbc3d852 | 453 | |
embeddedartists | 0:0fdadbc3d852 | 454 | len -= wLen; |
embeddedartists | 0:0fdadbc3d852 | 455 | written += wLen; |
embeddedartists | 0:0fdadbc3d852 | 456 | off += wLen; |
embeddedartists | 0:0fdadbc3d852 | 457 | |
embeddedartists | 0:0fdadbc3d852 | 458 | wLen = MIN(LCDB_EEPROM_PAGE_SIZE, len); |
embeddedartists | 0:0fdadbc3d852 | 459 | } |
embeddedartists | 0:0fdadbc3d852 | 460 | |
embeddedartists | 0:0fdadbc3d852 | 461 | return written; |
embeddedartists | 0:0fdadbc3d852 | 462 | } |
embeddedartists | 0:0fdadbc3d852 | 463 | |
embeddedartists | 0:0fdadbc3d852 | 464 | // ########################### |
embeddedartists | 0:0fdadbc3d852 | 465 | // string parsing (initialization and power down strings) |
embeddedartists | 0:0fdadbc3d852 | 466 | // ########################### |
embeddedartists | 0:0fdadbc3d852 | 467 | |
embeddedartists | 0:0fdadbc3d852 | 468 | EaLcdBoard::Result EaLcdBoard::parseInitString(char* str, LcdController::Config* cfg) { |
embeddedartists | 0:0fdadbc3d852 | 469 | char* c = NULL; |
embeddedartists | 0:0fdadbc3d852 | 470 | uint32_t len = 0; |
embeddedartists | 0:0fdadbc3d852 | 471 | Result result = Ok; |
embeddedartists | 0:0fdadbc3d852 | 472 | |
embeddedartists | 0:0fdadbc3d852 | 473 | if (str == NULL) { |
embeddedartists | 0:0fdadbc3d852 | 474 | return InvalidCommandString; |
embeddedartists | 0:0fdadbc3d852 | 475 | } |
embeddedartists | 0:0fdadbc3d852 | 476 | |
embeddedartists | 0:0fdadbc3d852 | 477 | while(*str != '\0') { |
embeddedartists | 0:0fdadbc3d852 | 478 | |
embeddedartists | 0:0fdadbc3d852 | 479 | // skip whitespaces |
embeddedartists | 0:0fdadbc3d852 | 480 | while(*str == ' ') { |
embeddedartists | 0:0fdadbc3d852 | 481 | str++; |
embeddedartists | 0:0fdadbc3d852 | 482 | } |
embeddedartists | 0:0fdadbc3d852 | 483 | |
embeddedartists | 0:0fdadbc3d852 | 484 | c = str; |
embeddedartists | 0:0fdadbc3d852 | 485 | |
embeddedartists | 0:0fdadbc3d852 | 486 | // find end of command |
embeddedartists | 0:0fdadbc3d852 | 487 | while(*str != ',' && *str != '\0') { |
embeddedartists | 0:0fdadbc3d852 | 488 | str++; |
embeddedartists | 0:0fdadbc3d852 | 489 | } |
embeddedartists | 0:0fdadbc3d852 | 490 | |
embeddedartists | 0:0fdadbc3d852 | 491 | len = (str-c); |
embeddedartists | 0:0fdadbc3d852 | 492 | |
embeddedartists | 0:0fdadbc3d852 | 493 | if (*str == ',') { |
embeddedartists | 0:0fdadbc3d852 | 494 | str++; |
embeddedartists | 0:0fdadbc3d852 | 495 | } |
embeddedartists | 0:0fdadbc3d852 | 496 | |
embeddedartists | 0:0fdadbc3d852 | 497 | switch (*c++) { |
embeddedartists | 0:0fdadbc3d852 | 498 | |
embeddedartists | 0:0fdadbc3d852 | 499 | case 'v': |
embeddedartists | 0:0fdadbc3d852 | 500 | result = checkVersion(c, len-1); |
embeddedartists | 0:0fdadbc3d852 | 501 | break; |
embeddedartists | 0:0fdadbc3d852 | 502 | |
embeddedartists | 0:0fdadbc3d852 | 503 | // sequence control command (pca9532) |
embeddedartists | 0:0fdadbc3d852 | 504 | case 'c': |
embeddedartists | 0:0fdadbc3d852 | 505 | execSeqCtrl(c, len-1); |
embeddedartists | 0:0fdadbc3d852 | 506 | break; |
embeddedartists | 0:0fdadbc3d852 | 507 | |
embeddedartists | 0:0fdadbc3d852 | 508 | // delay |
embeddedartists | 0:0fdadbc3d852 | 509 | case 'd': |
embeddedartists | 0:0fdadbc3d852 | 510 | execDelay(c, len-1); |
embeddedartists | 0:0fdadbc3d852 | 511 | break; |
embeddedartists | 0:0fdadbc3d852 | 512 | |
embeddedartists | 0:0fdadbc3d852 | 513 | // open lcd (init LCD controller) |
embeddedartists | 0:0fdadbc3d852 | 514 | case 'o': |
embeddedartists | 0:0fdadbc3d852 | 515 | |
embeddedartists | 0:0fdadbc3d852 | 516 | if (cfg != NULL) { |
embeddedartists | 0:0fdadbc3d852 | 517 | |
embeddedartists | 0:0fdadbc3d852 | 518 | if (lcdCtrl.open(cfg) != 0) { |
embeddedartists | 0:0fdadbc3d852 | 519 | result = LcdAccessError; |
embeddedartists | 0:0fdadbc3d852 | 520 | } |
embeddedartists | 0:0fdadbc3d852 | 521 | } |
embeddedartists | 0:0fdadbc3d852 | 522 | |
embeddedartists | 0:0fdadbc3d852 | 523 | else { |
embeddedartists | 0:0fdadbc3d852 | 524 | result = InvalidArgument; |
embeddedartists | 0:0fdadbc3d852 | 525 | } |
embeddedartists | 0:0fdadbc3d852 | 526 | |
embeddedartists | 0:0fdadbc3d852 | 527 | break; |
embeddedartists | 0:0fdadbc3d852 | 528 | |
embeddedartists | 4:b32cf4ef45c5 | 529 | // exec pin set |
embeddedartists | 4:b32cf4ef45c5 | 530 | case 'p': |
embeddedartists | 4:b32cf4ef45c5 | 531 | execPinSet(c, len-1); |
embeddedartists | 4:b32cf4ef45c5 | 532 | break; |
embeddedartists | 4:b32cf4ef45c5 | 533 | |
embeddedartists | 0:0fdadbc3d852 | 534 | } |
embeddedartists | 0:0fdadbc3d852 | 535 | |
embeddedartists | 0:0fdadbc3d852 | 536 | if (result != Ok) { |
embeddedartists | 0:0fdadbc3d852 | 537 | break; |
embeddedartists | 0:0fdadbc3d852 | 538 | } |
embeddedartists | 0:0fdadbc3d852 | 539 | |
embeddedartists | 0:0fdadbc3d852 | 540 | |
embeddedartists | 0:0fdadbc3d852 | 541 | } |
embeddedartists | 0:0fdadbc3d852 | 542 | |
embeddedartists | 0:0fdadbc3d852 | 543 | |
embeddedartists | 0:0fdadbc3d852 | 544 | return result; |
embeddedartists | 0:0fdadbc3d852 | 545 | } |
embeddedartists | 0:0fdadbc3d852 | 546 | |
embeddedartists | 0:0fdadbc3d852 | 547 | EaLcdBoard::Result EaLcdBoard::checkVersion(char* v, uint32_t len) { |
embeddedartists | 0:0fdadbc3d852 | 548 | uint32_t ver = str_to_uint(v, len); |
embeddedartists | 0:0fdadbc3d852 | 549 | |
embeddedartists | 0:0fdadbc3d852 | 550 | if (ver > LCDB_SEQ_VER) { |
embeddedartists | 0:0fdadbc3d852 | 551 | return VersionNotSupported; |
embeddedartists | 0:0fdadbc3d852 | 552 | } |
embeddedartists | 0:0fdadbc3d852 | 553 | |
embeddedartists | 0:0fdadbc3d852 | 554 | return Ok; |
embeddedartists | 0:0fdadbc3d852 | 555 | } |
embeddedartists | 0:0fdadbc3d852 | 556 | |
embeddedartists | 0:0fdadbc3d852 | 557 | EaLcdBoard::Result EaLcdBoard::execDelay(char* del, uint32_t len) { |
embeddedartists | 0:0fdadbc3d852 | 558 | wait_ms(str_to_uint(del, len)); |
embeddedartists | 0:0fdadbc3d852 | 559 | |
embeddedartists | 0:0fdadbc3d852 | 560 | return Ok; |
embeddedartists | 0:0fdadbc3d852 | 561 | } |
embeddedartists | 0:0fdadbc3d852 | 562 | |
embeddedartists | 0:0fdadbc3d852 | 563 | EaLcdBoard::Result EaLcdBoard::execSeqCtrl(char* cmd, uint32_t len) { |
embeddedartists | 0:0fdadbc3d852 | 564 | |
embeddedartists | 0:0fdadbc3d852 | 565 | switch (*cmd++) { |
embeddedartists | 0:0fdadbc3d852 | 566 | |
embeddedartists | 0:0fdadbc3d852 | 567 | // display enable |
embeddedartists | 0:0fdadbc3d852 | 568 | case 'd': |
embeddedartists | 0:0fdadbc3d852 | 569 | setDisplayEnableSignal(*cmd == '1'); |
embeddedartists | 0:0fdadbc3d852 | 570 | break; |
embeddedartists | 0:0fdadbc3d852 | 571 | |
embeddedartists | 0:0fdadbc3d852 | 572 | // backlight contrast |
embeddedartists | 0:0fdadbc3d852 | 573 | case 'c': |
embeddedartists | 0:0fdadbc3d852 | 574 | setBacklightContrast(str_to_uint(cmd, len)); |
embeddedartists | 0:0fdadbc3d852 | 575 | break; |
embeddedartists | 0:0fdadbc3d852 | 576 | |
embeddedartists | 0:0fdadbc3d852 | 577 | // 3v3 enable |
embeddedartists | 0:0fdadbc3d852 | 578 | case '3': |
embeddedartists | 0:0fdadbc3d852 | 579 | set3V3Signal(*cmd == '1'); |
embeddedartists | 0:0fdadbc3d852 | 580 | break; |
embeddedartists | 0:0fdadbc3d852 | 581 | |
embeddedartists | 0:0fdadbc3d852 | 582 | // 5v enable |
embeddedartists | 0:0fdadbc3d852 | 583 | case '5': |
embeddedartists | 0:0fdadbc3d852 | 584 | set5VSignal(*cmd == '1'); |
embeddedartists | 0:0fdadbc3d852 | 585 | break; |
embeddedartists | 0:0fdadbc3d852 | 586 | } |
embeddedartists | 0:0fdadbc3d852 | 587 | |
embeddedartists | 0:0fdadbc3d852 | 588 | return Ok; |
embeddedartists | 0:0fdadbc3d852 | 589 | } |
embeddedartists | 0:0fdadbc3d852 | 590 | |
embeddedartists | 4:b32cf4ef45c5 | 591 | #ifdef PORT_PIN_BUG_IN_MBED_SDK |
embeddedartists | 4:b32cf4ef45c5 | 592 | static PinName port_pin2(PortName port, int pin_n) { |
embeddedartists | 4:b32cf4ef45c5 | 593 | return (PinName)(((port << 5) | pin_n)); |
embeddedartists | 4:b32cf4ef45c5 | 594 | } |
embeddedartists | 4:b32cf4ef45c5 | 595 | #endif |
embeddedartists | 4:b32cf4ef45c5 | 596 | |
embeddedartists | 4:b32cf4ef45c5 | 597 | |
embeddedartists | 4:b32cf4ef45c5 | 598 | EaLcdBoard::Result EaLcdBoard::execPinSet(char* cmd, uint32_t len) { |
embeddedartists | 4:b32cf4ef45c5 | 599 | |
embeddedartists | 4:b32cf4ef45c5 | 600 | PortName port; |
embeddedartists | 4:b32cf4ef45c5 | 601 | |
embeddedartists | 4:b32cf4ef45c5 | 602 | do { |
embeddedartists | 4:b32cf4ef45c5 | 603 | // cmd: 0_02=1 means p0.2 = 1 |
embeddedartists | 4:b32cf4ef45c5 | 604 | if (len < 6) break; |
embeddedartists | 4:b32cf4ef45c5 | 605 | if (cmd[1] != '_' || cmd[4] != '=') break; |
embeddedartists | 4:b32cf4ef45c5 | 606 | |
embeddedartists | 4:b32cf4ef45c5 | 607 | // port |
embeddedartists | 4:b32cf4ef45c5 | 608 | int portnum = cmd[0] - '0'; |
embeddedartists | 4:b32cf4ef45c5 | 609 | if (portnum < 0 || portnum > 5) break; |
embeddedartists | 4:b32cf4ef45c5 | 610 | port = (PortName)portnum; |
embeddedartists | 4:b32cf4ef45c5 | 611 | |
embeddedartists | 4:b32cf4ef45c5 | 612 | // pin |
embeddedartists | 4:b32cf4ef45c5 | 613 | int pinnum = (10*(cmd[2]-'0'))+ cmd[3]-'0'; |
embeddedartists | 4:b32cf4ef45c5 | 614 | if (pinnum < 0 || pinnum > 31) break; |
embeddedartists | 4:b32cf4ef45c5 | 615 | |
embeddedartists | 4:b32cf4ef45c5 | 616 | // value |
embeddedartists | 4:b32cf4ef45c5 | 617 | int value = cmd[5]-'0'; |
embeddedartists | 4:b32cf4ef45c5 | 618 | if (!(value == 0 || value == 1)) break; |
embeddedartists | 4:b32cf4ef45c5 | 619 | |
embeddedartists | 4:b32cf4ef45c5 | 620 | #ifdef PORT_PIN_BUG_IN_MBED_SDK |
embeddedartists | 4:b32cf4ef45c5 | 621 | PinName pin = port_pin2(port, pinnum); |
embeddedartists | 4:b32cf4ef45c5 | 622 | #else |
embeddedartists | 4:b32cf4ef45c5 | 623 | PinName pin = port_pin(port, pinnum); |
embeddedartists | 4:b32cf4ef45c5 | 624 | #endif |
embeddedartists | 4:b32cf4ef45c5 | 625 | |
embeddedartists | 4:b32cf4ef45c5 | 626 | gpio_t gp; |
embeddedartists | 4:b32cf4ef45c5 | 627 | gpio_init(&gp, pin, PIN_OUTPUT); |
embeddedartists | 4:b32cf4ef45c5 | 628 | gpio_write(&gp, value); |
embeddedartists | 4:b32cf4ef45c5 | 629 | |
embeddedartists | 4:b32cf4ef45c5 | 630 | return Ok; |
embeddedartists | 4:b32cf4ef45c5 | 631 | |
embeddedartists | 4:b32cf4ef45c5 | 632 | } while (false); |
embeddedartists | 4:b32cf4ef45c5 | 633 | |
embeddedartists | 4:b32cf4ef45c5 | 634 | |
embeddedartists | 4:b32cf4ef45c5 | 635 | return InvalidCommandString; |
embeddedartists | 4:b32cf4ef45c5 | 636 | } |
embeddedartists | 4:b32cf4ef45c5 | 637 | |
embeddedartists | 4:b32cf4ef45c5 | 638 | |
embeddedartists | 0:0fdadbc3d852 | 639 | // ########################### |
embeddedartists | 0:0fdadbc3d852 | 640 | // PCA9532 is used as a control inteface to the display. |
embeddedartists | 0:0fdadbc3d852 | 641 | // voltages can be turned on/off and backlight can be controlled. |
embeddedartists | 0:0fdadbc3d852 | 642 | // ########################### |
embeddedartists | 0:0fdadbc3d852 | 643 | |
embeddedartists | 0:0fdadbc3d852 | 644 | // Helper function to set LED states |
embeddedartists | 0:0fdadbc3d852 | 645 | void EaLcdBoard::setLsStates(uint16_t states, uint8_t* ls, uint8_t mode) |
embeddedartists | 0:0fdadbc3d852 | 646 | { |
embeddedartists | 0:0fdadbc3d852 | 647 | #define IS_LED_SET(bit, x) ( ( ((x) & (bit)) != 0 ) ? 1 : 0 ) |
embeddedartists | 0:0fdadbc3d852 | 648 | |
embeddedartists | 0:0fdadbc3d852 | 649 | int i = 0; |
embeddedartists | 0:0fdadbc3d852 | 650 | |
embeddedartists | 0:0fdadbc3d852 | 651 | for (i = 0; i < 4; i++) { |
embeddedartists | 0:0fdadbc3d852 | 652 | |
embeddedartists | 0:0fdadbc3d852 | 653 | ls[i] |= ( (IS_LED_SET(0x0001, states)*mode << 0) |
embeddedartists | 0:0fdadbc3d852 | 654 | | (IS_LED_SET(0x0002, states)*mode << 2) |
embeddedartists | 0:0fdadbc3d852 | 655 | | (IS_LED_SET(0x0004, states)*mode << 4) |
embeddedartists | 0:0fdadbc3d852 | 656 | | (IS_LED_SET(0x0008, states)*mode << 6) ); |
embeddedartists | 0:0fdadbc3d852 | 657 | |
embeddedartists | 0:0fdadbc3d852 | 658 | states >>= 4; |
embeddedartists | 0:0fdadbc3d852 | 659 | } |
embeddedartists | 0:0fdadbc3d852 | 660 | } |
embeddedartists | 0:0fdadbc3d852 | 661 | |
embeddedartists | 0:0fdadbc3d852 | 662 | void EaLcdBoard::setLeds(void) |
embeddedartists | 0:0fdadbc3d852 | 663 | { |
embeddedartists | 0:0fdadbc3d852 | 664 | uint8_t buf[5]; |
embeddedartists | 0:0fdadbc3d852 | 665 | uint8_t ls[4] = {0,0,0,0}; |
embeddedartists | 0:0fdadbc3d852 | 666 | uint16_t states = _ledStateShadow; |
embeddedartists | 0:0fdadbc3d852 | 667 | |
embeddedartists | 0:0fdadbc3d852 | 668 | // LEDs in On/Off state |
embeddedartists | 0:0fdadbc3d852 | 669 | setLsStates(states, ls, LCDB_LS_MODE_ON); |
embeddedartists | 0:0fdadbc3d852 | 670 | |
embeddedartists | 0:0fdadbc3d852 | 671 | // set the LEDs that should blink |
embeddedartists | 0:0fdadbc3d852 | 672 | setLsStates(_blink0Shadow, ls, LCDB_LS_MODE_BLINK0); |
embeddedartists | 0:0fdadbc3d852 | 673 | setLsStates(_blink1Shadow, ls, LCDB_LS_MODE_BLINK1); |
embeddedartists | 0:0fdadbc3d852 | 674 | |
embeddedartists | 0:0fdadbc3d852 | 675 | buf[0] = LCDB_PCA9532_LS0 | LCDB_PCA9532_AUTO_INC; |
embeddedartists | 0:0fdadbc3d852 | 676 | buf[1] = ls[0]; |
embeddedartists | 0:0fdadbc3d852 | 677 | buf[2] = ls[1]; |
embeddedartists | 0:0fdadbc3d852 | 678 | buf[3] = ls[2]; |
embeddedartists | 0:0fdadbc3d852 | 679 | buf[4] = ls[3]; |
embeddedartists | 0:0fdadbc3d852 | 680 | |
embeddedartists | 0:0fdadbc3d852 | 681 | _i2c.write(LCDB_PCA9532_I2C_ADDR, (char*)buf, 5); |
embeddedartists | 0:0fdadbc3d852 | 682 | } |
embeddedartists | 0:0fdadbc3d852 | 683 | |
embeddedartists | 0:0fdadbc3d852 | 684 | void EaLcdBoard::pca9532_setLeds (uint16_t ledOnMask, uint16_t ledOffMask) |
embeddedartists | 0:0fdadbc3d852 | 685 | { |
embeddedartists | 0:0fdadbc3d852 | 686 | // turn off leds |
embeddedartists | 0:0fdadbc3d852 | 687 | _ledStateShadow &= (~(ledOffMask) & 0xffff); |
embeddedartists | 0:0fdadbc3d852 | 688 | |
embeddedartists | 0:0fdadbc3d852 | 689 | // ledOnMask has priority over ledOffMask |
embeddedartists | 0:0fdadbc3d852 | 690 | _ledStateShadow |= ledOnMask; |
embeddedartists | 0:0fdadbc3d852 | 691 | |
embeddedartists | 0:0fdadbc3d852 | 692 | // turn off blinking |
embeddedartists | 0:0fdadbc3d852 | 693 | _blink0Shadow &= (~(ledOffMask) & 0xffff); |
embeddedartists | 0:0fdadbc3d852 | 694 | _blink1Shadow &= (~(ledOffMask) & 0xffff); |
embeddedartists | 0:0fdadbc3d852 | 695 | |
embeddedartists | 0:0fdadbc3d852 | 696 | setLeds(); |
embeddedartists | 0:0fdadbc3d852 | 697 | } |
embeddedartists | 0:0fdadbc3d852 | 698 | |
embeddedartists | 0:0fdadbc3d852 | 699 | void EaLcdBoard::pca9532_setBlink0Period(uint8_t period) |
embeddedartists | 0:0fdadbc3d852 | 700 | { |
embeddedartists | 0:0fdadbc3d852 | 701 | uint8_t buf[2]; |
embeddedartists | 0:0fdadbc3d852 | 702 | |
embeddedartists | 0:0fdadbc3d852 | 703 | buf[0] = LCDB_PCA9532_PSC0; |
embeddedartists | 0:0fdadbc3d852 | 704 | buf[1] = period; |
embeddedartists | 0:0fdadbc3d852 | 705 | |
embeddedartists | 0:0fdadbc3d852 | 706 | _i2c.write(LCDB_PCA9532_I2C_ADDR, (char*)buf, 2); |
embeddedartists | 0:0fdadbc3d852 | 707 | } |
embeddedartists | 0:0fdadbc3d852 | 708 | |
embeddedartists | 0:0fdadbc3d852 | 709 | void EaLcdBoard::pca9532_setBlink0Duty(uint8_t duty) |
embeddedartists | 0:0fdadbc3d852 | 710 | { |
embeddedartists | 0:0fdadbc3d852 | 711 | uint8_t buf[2]; |
embeddedartists | 0:0fdadbc3d852 | 712 | uint32_t tmp = duty; |
embeddedartists | 0:0fdadbc3d852 | 713 | if (tmp > 100) { |
embeddedartists | 0:0fdadbc3d852 | 714 | tmp = 100; |
embeddedartists | 0:0fdadbc3d852 | 715 | } |
embeddedartists | 0:0fdadbc3d852 | 716 | |
embeddedartists | 0:0fdadbc3d852 | 717 | tmp = (255 * tmp)/100; |
embeddedartists | 0:0fdadbc3d852 | 718 | |
embeddedartists | 0:0fdadbc3d852 | 719 | buf[0] = LCDB_PCA9532_PWM0; |
embeddedartists | 0:0fdadbc3d852 | 720 | buf[1] = tmp; |
embeddedartists | 0:0fdadbc3d852 | 721 | |
embeddedartists | 0:0fdadbc3d852 | 722 | _i2c.write(LCDB_PCA9532_I2C_ADDR, (char*)buf, 2); |
embeddedartists | 0:0fdadbc3d852 | 723 | } |
embeddedartists | 0:0fdadbc3d852 | 724 | |
embeddedartists | 0:0fdadbc3d852 | 725 | void EaLcdBoard::pca9532_setBlink0Leds(uint16_t ledMask) |
embeddedartists | 0:0fdadbc3d852 | 726 | { |
embeddedartists | 0:0fdadbc3d852 | 727 | _blink0Shadow |= ledMask; |
embeddedartists | 0:0fdadbc3d852 | 728 | setLeds(); |
embeddedartists | 0:0fdadbc3d852 | 729 | } |
embeddedartists | 0:0fdadbc3d852 | 730 | |
embeddedartists | 4:b32cf4ef45c5 | 731 | void EaLcdBoard::setWriteProtect(bool enable) |
embeddedartists | 4:b32cf4ef45c5 | 732 | { |
embeddedartists | 4:b32cf4ef45c5 | 733 | if (enable) { |
embeddedartists | 4:b32cf4ef45c5 | 734 | pca9532_setLeds(0, LCDB_EEPROM_WP); |
embeddedartists | 4:b32cf4ef45c5 | 735 | } else { |
embeddedartists | 4:b32cf4ef45c5 | 736 | pca9532_setLeds(LCDB_EEPROM_WP, 0); |
embeddedartists | 4:b32cf4ef45c5 | 737 | } |
embeddedartists | 4:b32cf4ef45c5 | 738 | } |
embeddedartists | 4:b32cf4ef45c5 | 739 | |
embeddedartists | 0:0fdadbc3d852 | 740 | void EaLcdBoard::set3V3Signal(bool enabled) { |
embeddedartists | 0:0fdadbc3d852 | 741 | if (enabled) { |
embeddedartists | 0:0fdadbc3d852 | 742 | pca9532_setLeds(LCDB_CTRL_3V3, 0); |
embeddedartists | 0:0fdadbc3d852 | 743 | } else { |
embeddedartists | 0:0fdadbc3d852 | 744 | pca9532_setLeds(0, LCDB_CTRL_3V3); |
embeddedartists | 0:0fdadbc3d852 | 745 | } |
embeddedartists | 0:0fdadbc3d852 | 746 | } |
embeddedartists | 0:0fdadbc3d852 | 747 | |
embeddedartists | 0:0fdadbc3d852 | 748 | void EaLcdBoard::set5VSignal(bool enabled) { |
embeddedartists | 0:0fdadbc3d852 | 749 | if (enabled) { |
embeddedartists | 0:0fdadbc3d852 | 750 | pca9532_setLeds(LCDB_CTRL_5V, 0); |
embeddedartists | 0:0fdadbc3d852 | 751 | } else { |
embeddedartists | 0:0fdadbc3d852 | 752 | pca9532_setLeds(0, LCDB_CTRL_5V); |
embeddedartists | 0:0fdadbc3d852 | 753 | } |
embeddedartists | 0:0fdadbc3d852 | 754 | } |
embeddedartists | 0:0fdadbc3d852 | 755 | |
embeddedartists | 0:0fdadbc3d852 | 756 | void EaLcdBoard::setDisplayEnableSignal(bool enabled) { |
embeddedartists | 0:0fdadbc3d852 | 757 | if (!enabled) { |
embeddedartists | 0:0fdadbc3d852 | 758 | pca9532_setLeds(LCDB_CTRL_DISP_EN, 0); |
embeddedartists | 0:0fdadbc3d852 | 759 | } else { |
embeddedartists | 0:0fdadbc3d852 | 760 | pca9532_setLeds(0, LCDB_CTRL_DISP_EN); |
embeddedartists | 0:0fdadbc3d852 | 761 | } |
embeddedartists | 0:0fdadbc3d852 | 762 | } |
embeddedartists | 0:0fdadbc3d852 | 763 | |
embeddedartists | 0:0fdadbc3d852 | 764 | void EaLcdBoard::setBacklightContrast(uint32_t value) { |
embeddedartists | 0:0fdadbc3d852 | 765 | |
embeddedartists | 0:0fdadbc3d852 | 766 | if (value > 100) return; |
embeddedartists | 0:0fdadbc3d852 | 767 | |
embeddedartists | 0:0fdadbc3d852 | 768 | pca9532_setBlink0Duty(100-value); |
embeddedartists | 0:0fdadbc3d852 | 769 | pca9532_setBlink0Period(0); |
embeddedartists | 0:0fdadbc3d852 | 770 | pca9532_setBlink0Leds(LCDB_CTRL_BL_C); |
embeddedartists | 0:0fdadbc3d852 | 771 | } |
embeddedartists | 0:0fdadbc3d852 | 772 | |
embeddedartists | 0:0fdadbc3d852 | 773 | |
embeddedartists | 0:0fdadbc3d852 | 774 | // convert string to integer |
embeddedartists | 0:0fdadbc3d852 | 775 | static uint32_t str_to_uint(char* str, uint32_t len) |
embeddedartists | 0:0fdadbc3d852 | 776 | { |
embeddedartists | 0:0fdadbc3d852 | 777 | uint32_t val = 0; |
embeddedartists | 0:0fdadbc3d852 | 778 | |
embeddedartists | 0:0fdadbc3d852 | 779 | while(len > 0 && *str <= '9' && *str >= '0') { |
embeddedartists | 0:0fdadbc3d852 | 780 | val = (val * 10) + (*str - '0'); |
embeddedartists | 0:0fdadbc3d852 | 781 | str++; |
embeddedartists | 0:0fdadbc3d852 | 782 | len--; |
embeddedartists | 0:0fdadbc3d852 | 783 | } |
embeddedartists | 0:0fdadbc3d852 | 784 | |
embeddedartists | 0:0fdadbc3d852 | 785 | return val; |
embeddedartists | 0:0fdadbc3d852 | 786 | } |
embeddedartists | 0:0fdadbc3d852 | 787 | |
embeddedartists | 0:0fdadbc3d852 | 788 |