An forked version of Christian B's excellent library for controlling the 4D systems touch screen display

Dependents:   Genie_Test_Temperature

Fork of 4dGENIE by christian b

Committer:
langster1980
Date:
Sun Jul 06 22:16:49 2014 +0000
Revision:
9:d5855768a9b6
Parent:
8:b5ba0df2d0db
added genieGetEventData function in order to read rockerSW object

Who changed what in which revision?

UserRevisionLine numberNew contents of line
chris215 0:d2ed5a44c802 1 #include "mbed.h"
chris215 0:d2ed5a44c802 2 #include "mbed_genie.h"
chris215 0:d2ed5a44c802 3
chris215 3:11c49c49cd1a 4 Mbed4dGenie::Mbed4dGenie(PinName TxPin,PinName RxPin, PinName resetpin) : _screen(TxPin,RxPin) , _reset(resetpin)
chris215 2:f283764fe9b7 5 {
chris215 3:11c49c49cd1a 6 //reset the 4d screen
chris215 3:11c49c49cd1a 7 _reset = 0;
chris215 6:f4d3977b0eae 8 _screen.baud(9600);
chris215 7:6edb20845684 9 _genieUserHandler = NULL;
chris215 8:b5ba0df2d0db 10 RxStateTimeoutErrors = 0;
chris215 2:f283764fe9b7 11 }
chris215 6:f4d3977b0eae 12 void Mbed4dGenie::Start()
chris215 6:f4d3977b0eae 13 {
chris215 6:f4d3977b0eae 14 _reset = 1;
chris215 7:6edb20845684 15 wait(3.0); //4D datasheet says that the screen can take up to 3000 ms before
chris215 7:6edb20845684 16 //becomming responsive to serial commands.
chris215 7:6edb20845684 17 _t.start();
chris215 7:6edb20845684 18 Reset();
chris215 7:6edb20845684 19 _genieFlushEventQueue();
chris215 7:6edb20845684 20 _screen.attach(this,&Mbed4dGenie::RxIrqHandler,Serial::RxIrq);
chris215 7:6edb20845684 21 }
chris215 7:6edb20845684 22
chris215 7:6edb20845684 23
chris215 7:6edb20845684 24 void Mbed4dGenie::RxIrqHandler(void)
chris215 7:6edb20845684 25 {
chris215 7:6edb20845684 26 char c;
chris215 7:6edb20845684 27 //Loop to read all byte present in UART FIFO
chris215 7:6edb20845684 28 do
chris215 7:6edb20845684 29 {
chris215 7:6edb20845684 30 c = _screen.getc();
chris215 7:6edb20845684 31 ManageReceiveData(c);
chris215 7:6edb20845684 32 }
chris215 7:6edb20845684 33 while(_screen.readable());
chris215 7:6edb20845684 34 }
chris215 7:6edb20845684 35
chris215 7:6edb20845684 36 void Mbed4dGenie::ManageReceiveData(char data)
chris215 7:6edb20845684 37 {
chris215 7:6edb20845684 38 switch(state)
chris215 7:6edb20845684 39 {
chris215 7:6edb20845684 40 case CommIdle:
chris215 2:f283764fe9b7 41
chris215 7:6edb20845684 42 if(data == GENIE_ACK || data == GENIE_NAK)
chris215 7:6edb20845684 43 {
chris215 7:6edb20845684 44 LastResponse = data;
chris215 7:6edb20845684 45 }
chris215 7:6edb20845684 46 else if(data == GENIE_REPORT_OBJ || data == GENIE_REPORT_EVENT)
chris215 7:6edb20845684 47 {
chris215 8:b5ba0df2d0db 48 RxMaxTimeout = _t.read_ms() + RESYNC_PERIOD;
chris215 7:6edb20845684 49 checksum = data;
chris215 7:6edb20845684 50 rx_data[rxframe_count++] = data;
chris215 8:b5ba0df2d0db 51 state = CommInProgress;
chris215 7:6edb20845684 52 }
chris215 7:6edb20845684 53 break;
chris215 7:6edb20845684 54
chris215 7:6edb20845684 55
chris215 7:6edb20845684 56 case CommInProgress:
chris215 7:6edb20845684 57 checksum = checksum ^ data;
chris215 7:6edb20845684 58 rx_data[rxframe_count++] = data;
chris215 7:6edb20845684 59
chris215 7:6edb20845684 60 if(rxframe_count >= GENIE_FRAME_SIZE)
chris215 7:6edb20845684 61 {
chris215 7:6edb20845684 62 if (checksum == 0) {
chris215 7:6edb20845684 63 _genieEnqueueEvent(rx_data);
chris215 7:6edb20845684 64 if(_genieUserHandler != NULL)
chris215 7:6edb20845684 65 {
chris215 7:6edb20845684 66 (_genieUserHandler)();
chris215 7:6edb20845684 67 }
chris215 7:6edb20845684 68 }
chris215 7:6edb20845684 69 state = CommIdle;
chris215 7:6edb20845684 70 rxframe_count = 0;
chris215 7:6edb20845684 71 LastResponse = NO_RESPONSE;
chris215 7:6edb20845684 72 }
chris215 7:6edb20845684 73 break;
chris215 7:6edb20845684 74 default:
chris215 7:6edb20845684 75 state = CommIdle;
chris215 7:6edb20845684 76 rxframe_count = 0;
chris215 7:6edb20845684 77 LastResponse = NO_RESPONSE;
chris215 7:6edb20845684 78 break;
chris215 7:6edb20845684 79 }
chris215 2:f283764fe9b7 80 }
chris215 2:f283764fe9b7 81
chris215 7:6edb20845684 82
chris215 2:f283764fe9b7 83 ///////////////////////// genieWriteObject //////////////////////
chris215 0:d2ed5a44c802 84 //
chris215 2:f283764fe9b7 85 // Write data to an object on the display
chris215 0:d2ed5a44c802 86 //
chris215 6:f4d3977b0eae 87 int8_t Mbed4dGenie::genieWriteObject (uint16_t object, uint16_t index, uint16_t data)
chris215 2:f283764fe9b7 88 {
chris215 6:f4d3977b0eae 89 uint16_t msb, lsb ;
chris215 6:f4d3977b0eae 90 uint8_t checksum ;
chris215 6:f4d3977b0eae 91
chris215 7:6edb20845684 92 //wait for interface to be ready before sending stuff
chris215 7:6edb20845684 93 if(WaitForIdle())
chris215 7:6edb20845684 94 return ERROR_RESYNC;
chris215 7:6edb20845684 95
chris215 6:f4d3977b0eae 96 lsb = data&0xFF;
chris215 6:f4d3977b0eae 97 msb = (data>>8) & 0xFF;
chris215 6:f4d3977b0eae 98
chris215 6:f4d3977b0eae 99 _screen.putc(GENIE_WRITE_OBJ) ;
chris215 6:f4d3977b0eae 100 checksum = GENIE_WRITE_OBJ ;
chris215 6:f4d3977b0eae 101 _screen.putc(object) ;
chris215 6:f4d3977b0eae 102 checksum ^= object ;
chris215 6:f4d3977b0eae 103 _screen.putc(index) ;
chris215 6:f4d3977b0eae 104 checksum ^= index ;
chris215 6:f4d3977b0eae 105 _screen.putc(msb) ;
chris215 6:f4d3977b0eae 106 checksum ^= msb;
chris215 6:f4d3977b0eae 107 _screen.putc(lsb) ;
chris215 6:f4d3977b0eae 108 checksum ^= lsb;
chris215 6:f4d3977b0eae 109 _screen.putc(checksum) ;
chris215 6:f4d3977b0eae 110
chris215 7:6edb20845684 111 return Mbed4dGenie::WaitForAnswer();
chris215 7:6edb20845684 112 }
chris215 7:6edb20845684 113 int8_t Mbed4dGenie::genieWriteStr (uint16_t index, char *string)
chris215 7:6edb20845684 114 {
chris215 7:6edb20845684 115 char *p ;
chris215 7:6edb20845684 116 unsigned int checksum ;
chris215 7:6edb20845684 117 int len = strlen (string) ;
chris215 7:6edb20845684 118
chris215 7:6edb20845684 119
chris215 7:6edb20845684 120 if (len > 255)
chris215 7:6edb20845684 121 return -1 ;
chris215 7:6edb20845684 122
chris215 7:6edb20845684 123
chris215 7:6edb20845684 124 //wait for interface to be ready before sending stuff
chris215 7:6edb20845684 125 if(WaitForIdle())
chris215 7:6edb20845684 126 return ERROR_RESYNC;
chris215 7:6edb20845684 127
chris215 7:6edb20845684 128
chris215 7:6edb20845684 129 _screen.putc(GENIE_WRITE_STR) ; checksum = GENIE_WRITE_STR ;
chris215 7:6edb20845684 130 _screen.putc(index) ; checksum ^= index ;
chris215 7:6edb20845684 131 _screen.putc((unsigned char)len) ; checksum ^= len ;
chris215 7:6edb20845684 132 for (p = string ; *p ; ++p) {
chris215 7:6edb20845684 133 _screen.putc (*p) ;
chris215 7:6edb20845684 134 checksum ^= *p ;
chris215 7:6edb20845684 135 }
chris215 7:6edb20845684 136 _screen.putc(checksum) ;
chris215 2:f283764fe9b7 137
chris215 7:6edb20845684 138 return Mbed4dGenie::WaitForAnswer();
chris215 7:6edb20845684 139 }
chris215 7:6edb20845684 140 int8_t Mbed4dGenie::genieReadObj (uint16_t object, uint16_t index)
chris215 7:6edb20845684 141 {
chris215 7:6edb20845684 142 //wait for interface to be ready before sending stuff
chris215 7:6edb20845684 143 if(WaitForIdle())
chris215 7:6edb20845684 144 return ERROR_RESYNC;
chris215 7:6edb20845684 145 unsigned int checksum ;
chris215 7:6edb20845684 146
chris215 7:6edb20845684 147 _screen.putc(GENIE_READ_OBJ) ; checksum = GENIE_READ_OBJ ;
chris215 7:6edb20845684 148 _screen.putc(object) ; checksum ^= object ;
chris215 7:6edb20845684 149 _screen.putc(index) ; checksum ^= index ;
chris215 7:6edb20845684 150 _screen.putc(checksum) ;
chris215 7:6edb20845684 151
chris215 8:b5ba0df2d0db 152 //Here we dont wiat for a typical answer
chris215 8:b5ba0df2d0db 153 //The screen will respond with an NACK if the command was not understood, otherwise it will send a report object frame
chris215 8:b5ba0df2d0db 154 return WaitForReadAnswer();
chris215 0:d2ed5a44c802 155 }
langster1980 9:d5855768a9b6 156
langster1980 9:d5855768a9b6 157 ////////////////////// genieGetEventData ////////////////////////
langster1980 9:d5855768a9b6 158 //
langster1980 9:d5855768a9b6 159 // Returns the LSB and MSB of the event's data combined into
langster1980 9:d5855768a9b6 160 // a single uint16
langster1980 9:d5855768a9b6 161 //
langster1980 9:d5855768a9b6 162 // The data is transmitted from the display in big-endian format
langster1980 9:d5855768a9b6 163 // and stored the same so the user can't just access it as an int
langster1980 9:d5855768a9b6 164 // directly from the structure.
langster1980 9:d5855768a9b6 165 //
langster1980 9:d5855768a9b6 166 uint16_t Mbed4dGenie::genieGetEventData (genieFrame * e) {
langster1980 9:d5855768a9b6 167 return (e->reportObject.data_msb << 8) + e->reportObject.data_lsb;
langster1980 9:d5855768a9b6 168 }
langster1980 9:d5855768a9b6 169
chris215 7:6edb20845684 170 void Mbed4dGenie::writec(char data)
chris215 7:6edb20845684 171 {
chris215 7:6edb20845684 172 _screen.putc(data);
chris215 7:6edb20845684 173 }
chris215 7:6edb20845684 174 bool Mbed4dGenie::WaitForIdle()
chris215 7:6edb20845684 175 {
chris215 8:b5ba0df2d0db 176 if(state != CommIdle)
chris215 8:b5ba0df2d0db 177 {
chris215 8:b5ba0df2d0db 178 long timeout = _t.read_ms() + TIMEOUT_PERIOD;
chris215 8:b5ba0df2d0db 179 long timerReading = 0;
chris215 8:b5ba0df2d0db 180 if(_t.read_ms() >= RxMaxTimeout)
chris215 8:b5ba0df2d0db 181 {
chris215 8:b5ba0df2d0db 182 Reset();
chris215 8:b5ba0df2d0db 183 RxStateTimeoutErrors++;
chris215 8:b5ba0df2d0db 184 }
chris215 8:b5ba0df2d0db 185 while(timerReading < timeout && state != CommIdle)
chris215 8:b5ba0df2d0db 186 {
chris215 8:b5ba0df2d0db 187 timerReading = _t.read_ms();
chris215 8:b5ba0df2d0db 188 }
chris215 8:b5ba0df2d0db 189 LastResponse = 0;
chris215 8:b5ba0df2d0db 190 return (timerReading >= timeout);
chris215 8:b5ba0df2d0db 191 }
chris215 8:b5ba0df2d0db 192
chris215 8:b5ba0df2d0db 193 return false;
chris215 8:b5ba0df2d0db 194 }
chris215 8:b5ba0df2d0db 195
chris215 8:b5ba0df2d0db 196 int8_t Mbed4dGenie::WaitForReadAnswer()
chris215 8:b5ba0df2d0db 197 {
chris215 7:6edb20845684 198 long timeout = _t.read_ms() + TIMEOUT_PERIOD;
chris215 7:6edb20845684 199 long timerReading = 0;
chris215 8:b5ba0df2d0db 200 while(state == CommIdle && LastResponse != ERROR_NAK && timerReading < timeout)
chris215 7:6edb20845684 201 {
chris215 7:6edb20845684 202 timerReading = _t.read_ms();
chris215 7:6edb20845684 203 }
chris215 8:b5ba0df2d0db 204 if(LastResponse == ERROR_NAK)//check if the screen returned a NACK
chris215 8:b5ba0df2d0db 205 {
chris215 8:b5ba0df2d0db 206 LastResponse = NO_RESPONSE;
chris215 8:b5ba0df2d0db 207 return ERROR_NAK;
chris215 8:b5ba0df2d0db 208 }
chris215 8:b5ba0df2d0db 209 else if(LastResponse >= timeout) //check if we timed out while waiting for response
chris215 8:b5ba0df2d0db 210 {
chris215 8:b5ba0df2d0db 211 LastResponse = NO_RESPONSE;
chris215 8:b5ba0df2d0db 212 return ERROR_TIMEOUT;
chris215 8:b5ba0df2d0db 213 }
chris215 8:b5ba0df2d0db 214 //if we get here it means we didnt timeout and the screen did accept the command
chris215 8:b5ba0df2d0db 215 LastResponse = NO_RESPONSE;
chris215 8:b5ba0df2d0db 216 return ERROR_NONE;
chris215 7:6edb20845684 217 }
chris215 0:d2ed5a44c802 218
chris215 6:f4d3977b0eae 219 int8_t Mbed4dGenie::WaitForAnswer()
chris215 6:f4d3977b0eae 220 {
chris215 0:d2ed5a44c802 221
chris215 6:f4d3977b0eae 222 long timeout = _t.read_ms() + TIMEOUT_PERIOD;
chris215 6:f4d3977b0eae 223 long timerReading = 0;
chris215 7:6edb20845684 224 while(LastResponse != GENIE_ACK && LastResponse != ERROR_NAK && timerReading < timeout)
chris215 6:f4d3977b0eae 225 {
chris215 6:f4d3977b0eae 226 timerReading = _t.read_ms();
chris215 6:f4d3977b0eae 227 }
chris215 6:f4d3977b0eae 228
chris215 7:6edb20845684 229 if(LastResponse == ERROR_NAK)
chris215 6:f4d3977b0eae 230 {
chris215 8:b5ba0df2d0db 231 LastResponse = NO_RESPONSE;
chris215 8:b5ba0df2d0db 232 return ERROR_NAK;
chris215 6:f4d3977b0eae 233 }
chris215 7:6edb20845684 234 else if(LastResponse >= timeout)
chris215 6:f4d3977b0eae 235 {
chris215 8:b5ba0df2d0db 236 LastResponse = NO_RESPONSE;
chris215 6:f4d3977b0eae 237 return ERROR_TIMEOUT;
chris215 6:f4d3977b0eae 238 }
chris215 8:b5ba0df2d0db 239 LastResponse = NO_RESPONSE;
chris215 6:f4d3977b0eae 240 return ERROR_NONE;
chris215 7:6edb20845684 241 }
chris215 7:6edb20845684 242
chris215 7:6edb20845684 243 void Mbed4dGenie::Reset(void)
chris215 7:6edb20845684 244 {
chris215 7:6edb20845684 245 LastResponse = NO_RESPONSE;
chris215 7:6edb20845684 246 state = CommIdle;
chris215 7:6edb20845684 247 while(_screen.readable())
chris215 7:6edb20845684 248 _screen.getc();
chris215 7:6edb20845684 249 }
chris215 7:6edb20845684 250
chris215 7:6edb20845684 251 ////////////////////// _genieFlushEventQueue ////////////////////
chris215 7:6edb20845684 252 //
chris215 7:6edb20845684 253 // Reset all the event queue variables and start from scratch.
chris215 7:6edb20845684 254 //
chris215 7:6edb20845684 255 void Mbed4dGenie::_genieFlushEventQueue(void) {
chris215 7:6edb20845684 256 _genieEventQueue.rd_index = 0;
chris215 7:6edb20845684 257 _genieEventQueue.wr_index = 0;
chris215 7:6edb20845684 258 _genieEventQueue.n_events = 0;
chris215 7:6edb20845684 259 }
chris215 7:6edb20845684 260
chris215 7:6edb20845684 261 ////////////////////// _genieEnqueueEvent ///////////////////
chris215 7:6edb20845684 262 //
chris215 7:6edb20845684 263 // Copy the bytes from a buffer supplied by the caller
chris215 7:6edb20845684 264 // to the input queue
chris215 7:6edb20845684 265 //
chris215 7:6edb20845684 266 // Parms: uint8_t * data, a pointer to the user's data
chris215 7:6edb20845684 267 //
chris215 7:6edb20845684 268 // Returns: TRUE if there was an empty location in the queue
chris215 7:6edb20845684 269 // to copy the data into
chris215 7:6edb20845684 270 // FALSE if not
chris215 7:6edb20845684 271 // Sets: ERROR_REPLY_OVR if there was no room in the queue
chris215 7:6edb20845684 272 //
chris215 7:6edb20845684 273 bool Mbed4dGenie::_genieEnqueueEvent (uint8_t * data) {
chris215 7:6edb20845684 274
chris215 7:6edb20845684 275
chris215 7:6edb20845684 276 if (_genieEventQueue.n_events < MAX_GENIE_EVENTS-2) {
chris215 7:6edb20845684 277 memcpy (&_genieEventQueue.frames[_genieEventQueue.wr_index], data,
chris215 7:6edb20845684 278 GENIE_FRAME_SIZE);
chris215 7:6edb20845684 279 _genieEventQueue.wr_index++;
chris215 7:6edb20845684 280 _genieEventQueue.wr_index &= MAX_GENIE_EVENTS -1;
chris215 7:6edb20845684 281 _genieEventQueue.n_events++;
chris215 7:6edb20845684 282 return TRUE;
chris215 7:6edb20845684 283 } else {
chris215 7:6edb20845684 284 return FALSE;
chris215 7:6edb20845684 285 }
chris215 7:6edb20845684 286 }
chris215 7:6edb20845684 287 ////////////////////// genieDequeueEvent ///////////////////
chris215 7:6edb20845684 288 //
chris215 7:6edb20845684 289 // Copy the bytes from a queued input event to a buffer supplied
chris215 7:6edb20845684 290 // by the caller.
chris215 7:6edb20845684 291 //
chris215 7:6edb20845684 292 // Parms: genieFrame * buff, a pointer to the user's buffer
chris215 7:6edb20845684 293 //
chris215 7:6edb20845684 294 // Returns: TRUE if there was an event to copy
chris215 7:6edb20845684 295 // FALSE if not
chris215 7:6edb20845684 296 //
chris215 7:6edb20845684 297 bool Mbed4dGenie::genieDequeueEvent(genieFrame * buff) {
chris215 7:6edb20845684 298
chris215 7:6edb20845684 299
chris215 7:6edb20845684 300 if (_genieEventQueue.n_events > 0) {
chris215 7:6edb20845684 301 memcpy (buff, &_genieEventQueue.frames[_genieEventQueue.rd_index],
chris215 7:6edb20845684 302 GENIE_FRAME_SIZE);
chris215 7:6edb20845684 303 _genieEventQueue.rd_index++;
chris215 7:6edb20845684 304 _genieEventQueue.rd_index &= MAX_GENIE_EVENTS -1;
chris215 7:6edb20845684 305 _genieEventQueue.n_events--;
chris215 7:6edb20845684 306 return TRUE;
chris215 7:6edb20845684 307 }
chris215 7:6edb20845684 308 return FALSE;
chris215 7:6edb20845684 309 }
chris215 7:6edb20845684 310 void Mbed4dGenie::genieAttachEventHandler(genieUserEventHandlerPtr handler)
chris215 7:6edb20845684 311 {
chris215 7:6edb20845684 312 _genieUserHandler = handler;
chris215 7:6edb20845684 313 }
chris215 7:6edb20845684 314 bool Mbed4dGenie::PendingFrames(void)
chris215 7:6edb20845684 315 {
chris215 7:6edb20845684 316 return (_genieEventQueue.n_events>0);
chris215 2:f283764fe9b7 317 }