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
mbed_genie.cpp@7:6edb20845684, 2014-07-05 (annotated)
- Committer:
- chris215
- Date:
- Sat Jul 05 15:11:57 2014 +0000
- Revision:
- 7:6edb20845684
- Parent:
- 6:f4d3977b0eae
- Child:
- 8:b5ba0df2d0db
Restored rx by interrupt feature. Added following features : read_obj, write_str, userHandler callback when frame is received. Ran stable for 12 hours.
Who changed what in which revision?
User | Revision | Line number | New 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 | 2:f283764fe9b7 | 10 | } |
chris215 | 6:f4d3977b0eae | 11 | void Mbed4dGenie::Start() |
chris215 | 6:f4d3977b0eae | 12 | { |
chris215 | 6:f4d3977b0eae | 13 | _reset = 1; |
chris215 | 7:6edb20845684 | 14 | wait(3.0); //4D datasheet says that the screen can take up to 3000 ms before |
chris215 | 7:6edb20845684 | 15 | //becomming responsive to serial commands. |
chris215 | 7:6edb20845684 | 16 | _t.start(); |
chris215 | 7:6edb20845684 | 17 | Reset(); |
chris215 | 7:6edb20845684 | 18 | _genieFlushEventQueue(); |
chris215 | 7:6edb20845684 | 19 | _screen.attach(this,&Mbed4dGenie::RxIrqHandler,Serial::RxIrq); |
chris215 | 7:6edb20845684 | 20 | } |
chris215 | 7:6edb20845684 | 21 | |
chris215 | 7:6edb20845684 | 22 | |
chris215 | 7:6edb20845684 | 23 | void Mbed4dGenie::RxIrqHandler(void) |
chris215 | 7:6edb20845684 | 24 | { |
chris215 | 7:6edb20845684 | 25 | char c; |
chris215 | 7:6edb20845684 | 26 | //Loop to read all byte present in UART FIFO |
chris215 | 7:6edb20845684 | 27 | do |
chris215 | 7:6edb20845684 | 28 | { |
chris215 | 7:6edb20845684 | 29 | c = _screen.getc(); |
chris215 | 7:6edb20845684 | 30 | ManageReceiveData(c); |
chris215 | 7:6edb20845684 | 31 | } |
chris215 | 7:6edb20845684 | 32 | while(_screen.readable()); |
chris215 | 7:6edb20845684 | 33 | } |
chris215 | 7:6edb20845684 | 34 | |
chris215 | 7:6edb20845684 | 35 | void Mbed4dGenie::ManageReceiveData(char data) |
chris215 | 7:6edb20845684 | 36 | { |
chris215 | 7:6edb20845684 | 37 | switch(state) |
chris215 | 7:6edb20845684 | 38 | { |
chris215 | 7:6edb20845684 | 39 | case CommIdle: |
chris215 | 2:f283764fe9b7 | 40 | |
chris215 | 7:6edb20845684 | 41 | if(data == GENIE_ACK || data == GENIE_NAK) |
chris215 | 7:6edb20845684 | 42 | { |
chris215 | 7:6edb20845684 | 43 | LastResponse = data; |
chris215 | 7:6edb20845684 | 44 | } |
chris215 | 7:6edb20845684 | 45 | else if(data == GENIE_REPORT_OBJ || data == GENIE_REPORT_EVENT) |
chris215 | 7:6edb20845684 | 46 | { |
chris215 | 7:6edb20845684 | 47 | checksum = data; |
chris215 | 7:6edb20845684 | 48 | rx_data[rxframe_count++] = data; |
chris215 | 7:6edb20845684 | 49 | state = CommInProgress; |
chris215 | 7:6edb20845684 | 50 | LastResponse = NO_RESPONSE; |
chris215 | 7:6edb20845684 | 51 | } |
chris215 | 7:6edb20845684 | 52 | break; |
chris215 | 7:6edb20845684 | 53 | |
chris215 | 7:6edb20845684 | 54 | |
chris215 | 7:6edb20845684 | 55 | case CommInProgress: |
chris215 | 7:6edb20845684 | 56 | checksum = checksum ^ data; |
chris215 | 7:6edb20845684 | 57 | rx_data[rxframe_count++] = data; |
chris215 | 7:6edb20845684 | 58 | |
chris215 | 7:6edb20845684 | 59 | if(rxframe_count >= GENIE_FRAME_SIZE) |
chris215 | 7:6edb20845684 | 60 | { |
chris215 | 7:6edb20845684 | 61 | if (checksum == 0) { |
chris215 | 7:6edb20845684 | 62 | _genieEnqueueEvent(rx_data); |
chris215 | 7:6edb20845684 | 63 | if(_genieUserHandler != NULL) |
chris215 | 7:6edb20845684 | 64 | { |
chris215 | 7:6edb20845684 | 65 | (_genieUserHandler)(); |
chris215 | 7:6edb20845684 | 66 | } |
chris215 | 7:6edb20845684 | 67 | } |
chris215 | 7:6edb20845684 | 68 | state = CommIdle; |
chris215 | 7:6edb20845684 | 69 | rxframe_count = 0; |
chris215 | 7:6edb20845684 | 70 | LastResponse = NO_RESPONSE; |
chris215 | 7:6edb20845684 | 71 | } |
chris215 | 7:6edb20845684 | 72 | break; |
chris215 | 7:6edb20845684 | 73 | default: |
chris215 | 7:6edb20845684 | 74 | state = CommIdle; |
chris215 | 7:6edb20845684 | 75 | rxframe_count = 0; |
chris215 | 7:6edb20845684 | 76 | LastResponse = NO_RESPONSE; |
chris215 | 7:6edb20845684 | 77 | break; |
chris215 | 7:6edb20845684 | 78 | } |
chris215 | 2:f283764fe9b7 | 79 | } |
chris215 | 2:f283764fe9b7 | 80 | |
chris215 | 7:6edb20845684 | 81 | |
chris215 | 2:f283764fe9b7 | 82 | ///////////////////////// genieWriteObject ////////////////////// |
chris215 | 0:d2ed5a44c802 | 83 | // |
chris215 | 2:f283764fe9b7 | 84 | // Write data to an object on the display |
chris215 | 0:d2ed5a44c802 | 85 | // |
chris215 | 6:f4d3977b0eae | 86 | int8_t Mbed4dGenie::genieWriteObject (uint16_t object, uint16_t index, uint16_t data) |
chris215 | 2:f283764fe9b7 | 87 | { |
chris215 | 6:f4d3977b0eae | 88 | uint16_t msb, lsb ; |
chris215 | 6:f4d3977b0eae | 89 | uint8_t checksum ; |
chris215 | 6:f4d3977b0eae | 90 | |
chris215 | 7:6edb20845684 | 91 | //wait for interface to be ready before sending stuff |
chris215 | 7:6edb20845684 | 92 | if(WaitForIdle()) |
chris215 | 7:6edb20845684 | 93 | return ERROR_RESYNC; |
chris215 | 7:6edb20845684 | 94 | |
chris215 | 6:f4d3977b0eae | 95 | lsb = data&0xFF; |
chris215 | 6:f4d3977b0eae | 96 | msb = (data>>8) & 0xFF; |
chris215 | 6:f4d3977b0eae | 97 | |
chris215 | 6:f4d3977b0eae | 98 | _screen.putc(GENIE_WRITE_OBJ) ; |
chris215 | 6:f4d3977b0eae | 99 | checksum = GENIE_WRITE_OBJ ; |
chris215 | 6:f4d3977b0eae | 100 | _screen.putc(object) ; |
chris215 | 6:f4d3977b0eae | 101 | checksum ^= object ; |
chris215 | 6:f4d3977b0eae | 102 | _screen.putc(index) ; |
chris215 | 6:f4d3977b0eae | 103 | checksum ^= index ; |
chris215 | 6:f4d3977b0eae | 104 | _screen.putc(msb) ; |
chris215 | 6:f4d3977b0eae | 105 | checksum ^= msb; |
chris215 | 6:f4d3977b0eae | 106 | _screen.putc(lsb) ; |
chris215 | 6:f4d3977b0eae | 107 | checksum ^= lsb; |
chris215 | 6:f4d3977b0eae | 108 | _screen.putc(checksum) ; |
chris215 | 6:f4d3977b0eae | 109 | |
chris215 | 7:6edb20845684 | 110 | return Mbed4dGenie::WaitForAnswer(); |
chris215 | 7:6edb20845684 | 111 | } |
chris215 | 7:6edb20845684 | 112 | int8_t Mbed4dGenie::genieWriteStr (uint16_t index, char *string) |
chris215 | 7:6edb20845684 | 113 | { |
chris215 | 7:6edb20845684 | 114 | char *p ; |
chris215 | 7:6edb20845684 | 115 | unsigned int checksum ; |
chris215 | 7:6edb20845684 | 116 | int len = strlen (string) ; |
chris215 | 7:6edb20845684 | 117 | |
chris215 | 7:6edb20845684 | 118 | |
chris215 | 7:6edb20845684 | 119 | if (len > 255) |
chris215 | 7:6edb20845684 | 120 | return -1 ; |
chris215 | 7:6edb20845684 | 121 | |
chris215 | 7:6edb20845684 | 122 | |
chris215 | 7:6edb20845684 | 123 | //wait for interface to be ready before sending stuff |
chris215 | 7:6edb20845684 | 124 | if(WaitForIdle()) |
chris215 | 7:6edb20845684 | 125 | return ERROR_RESYNC; |
chris215 | 7:6edb20845684 | 126 | |
chris215 | 7:6edb20845684 | 127 | |
chris215 | 7:6edb20845684 | 128 | _screen.putc(GENIE_WRITE_STR) ; checksum = GENIE_WRITE_STR ; |
chris215 | 7:6edb20845684 | 129 | _screen.putc(index) ; checksum ^= index ; |
chris215 | 7:6edb20845684 | 130 | _screen.putc((unsigned char)len) ; checksum ^= len ; |
chris215 | 7:6edb20845684 | 131 | for (p = string ; *p ; ++p) { |
chris215 | 7:6edb20845684 | 132 | _screen.putc (*p) ; |
chris215 | 7:6edb20845684 | 133 | checksum ^= *p ; |
chris215 | 7:6edb20845684 | 134 | } |
chris215 | 7:6edb20845684 | 135 | _screen.putc(checksum) ; |
chris215 | 2:f283764fe9b7 | 136 | |
chris215 | 7:6edb20845684 | 137 | return Mbed4dGenie::WaitForAnswer(); |
chris215 | 7:6edb20845684 | 138 | } |
chris215 | 7:6edb20845684 | 139 | int8_t Mbed4dGenie::genieReadObj (uint16_t object, uint16_t index) |
chris215 | 7:6edb20845684 | 140 | { |
chris215 | 7:6edb20845684 | 141 | //wait for interface to be ready before sending stuff |
chris215 | 7:6edb20845684 | 142 | if(WaitForIdle()) |
chris215 | 7:6edb20845684 | 143 | return ERROR_RESYNC; |
chris215 | 7:6edb20845684 | 144 | unsigned int checksum ; |
chris215 | 7:6edb20845684 | 145 | |
chris215 | 7:6edb20845684 | 146 | _screen.putc(GENIE_READ_OBJ) ; checksum = GENIE_READ_OBJ ; |
chris215 | 7:6edb20845684 | 147 | _screen.putc(object) ; checksum ^= object ; |
chris215 | 7:6edb20845684 | 148 | _screen.putc(index) ; checksum ^= index ; |
chris215 | 7:6edb20845684 | 149 | _screen.putc(checksum) ; |
chris215 | 7:6edb20845684 | 150 | |
chris215 | 7:6edb20845684 | 151 | return 0;//Mbed4dGenie::WaitForAnswer(); |
chris215 | 0:d2ed5a44c802 | 152 | } |
chris215 | 7:6edb20845684 | 153 | void Mbed4dGenie::writec(char data) |
chris215 | 7:6edb20845684 | 154 | { |
chris215 | 7:6edb20845684 | 155 | _screen.putc(data); |
chris215 | 7:6edb20845684 | 156 | } |
chris215 | 7:6edb20845684 | 157 | bool Mbed4dGenie::WaitForIdle() |
chris215 | 7:6edb20845684 | 158 | { |
chris215 | 7:6edb20845684 | 159 | long timeout = _t.read_ms() + TIMEOUT_PERIOD; |
chris215 | 7:6edb20845684 | 160 | long timerReading = 0; |
chris215 | 7:6edb20845684 | 161 | |
chris215 | 7:6edb20845684 | 162 | while(timerReading < timeout && state != CommIdle) |
chris215 | 7:6edb20845684 | 163 | { |
chris215 | 7:6edb20845684 | 164 | timerReading = _t.read_ms(); |
chris215 | 7:6edb20845684 | 165 | } |
chris215 | 7:6edb20845684 | 166 | LastResponse = 0; |
chris215 | 7:6edb20845684 | 167 | return (timerReading >= timeout); |
chris215 | 7:6edb20845684 | 168 | } |
chris215 | 0:d2ed5a44c802 | 169 | |
chris215 | 6:f4d3977b0eae | 170 | int8_t Mbed4dGenie::WaitForAnswer() |
chris215 | 6:f4d3977b0eae | 171 | { |
chris215 | 0:d2ed5a44c802 | 172 | |
chris215 | 6:f4d3977b0eae | 173 | long timeout = _t.read_ms() + TIMEOUT_PERIOD; |
chris215 | 6:f4d3977b0eae | 174 | long timerReading = 0; |
chris215 | 7:6edb20845684 | 175 | while(LastResponse != GENIE_ACK && LastResponse != ERROR_NAK && timerReading < timeout) |
chris215 | 6:f4d3977b0eae | 176 | { |
chris215 | 6:f4d3977b0eae | 177 | timerReading = _t.read_ms(); |
chris215 | 6:f4d3977b0eae | 178 | } |
chris215 | 6:f4d3977b0eae | 179 | |
chris215 | 7:6edb20845684 | 180 | if(LastResponse == ERROR_NAK) |
chris215 | 6:f4d3977b0eae | 181 | { |
chris215 | 6:f4d3977b0eae | 182 | return ERROR_NONE; |
chris215 | 6:f4d3977b0eae | 183 | } |
chris215 | 7:6edb20845684 | 184 | else if(LastResponse >= timeout) |
chris215 | 6:f4d3977b0eae | 185 | { |
chris215 | 6:f4d3977b0eae | 186 | return ERROR_TIMEOUT; |
chris215 | 6:f4d3977b0eae | 187 | } |
chris215 | 6:f4d3977b0eae | 188 | return ERROR_NONE; |
chris215 | 7:6edb20845684 | 189 | } |
chris215 | 7:6edb20845684 | 190 | |
chris215 | 7:6edb20845684 | 191 | void Mbed4dGenie::Reset(void) |
chris215 | 7:6edb20845684 | 192 | { |
chris215 | 7:6edb20845684 | 193 | LastResponse = NO_RESPONSE; |
chris215 | 7:6edb20845684 | 194 | state = CommIdle; |
chris215 | 7:6edb20845684 | 195 | while(_screen.readable()) |
chris215 | 7:6edb20845684 | 196 | _screen.getc(); |
chris215 | 7:6edb20845684 | 197 | } |
chris215 | 7:6edb20845684 | 198 | |
chris215 | 7:6edb20845684 | 199 | ////////////////////// _genieFlushEventQueue //////////////////// |
chris215 | 7:6edb20845684 | 200 | // |
chris215 | 7:6edb20845684 | 201 | // Reset all the event queue variables and start from scratch. |
chris215 | 7:6edb20845684 | 202 | // |
chris215 | 7:6edb20845684 | 203 | void Mbed4dGenie::_genieFlushEventQueue(void) { |
chris215 | 7:6edb20845684 | 204 | _genieEventQueue.rd_index = 0; |
chris215 | 7:6edb20845684 | 205 | _genieEventQueue.wr_index = 0; |
chris215 | 7:6edb20845684 | 206 | _genieEventQueue.n_events = 0; |
chris215 | 7:6edb20845684 | 207 | } |
chris215 | 7:6edb20845684 | 208 | |
chris215 | 7:6edb20845684 | 209 | ////////////////////// _genieEnqueueEvent /////////////////// |
chris215 | 7:6edb20845684 | 210 | // |
chris215 | 7:6edb20845684 | 211 | // Copy the bytes from a buffer supplied by the caller |
chris215 | 7:6edb20845684 | 212 | // to the input queue |
chris215 | 7:6edb20845684 | 213 | // |
chris215 | 7:6edb20845684 | 214 | // Parms: uint8_t * data, a pointer to the user's data |
chris215 | 7:6edb20845684 | 215 | // |
chris215 | 7:6edb20845684 | 216 | // Returns: TRUE if there was an empty location in the queue |
chris215 | 7:6edb20845684 | 217 | // to copy the data into |
chris215 | 7:6edb20845684 | 218 | // FALSE if not |
chris215 | 7:6edb20845684 | 219 | // Sets: ERROR_REPLY_OVR if there was no room in the queue |
chris215 | 7:6edb20845684 | 220 | // |
chris215 | 7:6edb20845684 | 221 | bool Mbed4dGenie::_genieEnqueueEvent (uint8_t * data) { |
chris215 | 7:6edb20845684 | 222 | |
chris215 | 7:6edb20845684 | 223 | |
chris215 | 7:6edb20845684 | 224 | if (_genieEventQueue.n_events < MAX_GENIE_EVENTS-2) { |
chris215 | 7:6edb20845684 | 225 | memcpy (&_genieEventQueue.frames[_genieEventQueue.wr_index], data, |
chris215 | 7:6edb20845684 | 226 | GENIE_FRAME_SIZE); |
chris215 | 7:6edb20845684 | 227 | _genieEventQueue.wr_index++; |
chris215 | 7:6edb20845684 | 228 | _genieEventQueue.wr_index &= MAX_GENIE_EVENTS -1; |
chris215 | 7:6edb20845684 | 229 | _genieEventQueue.n_events++; |
chris215 | 7:6edb20845684 | 230 | return TRUE; |
chris215 | 7:6edb20845684 | 231 | } else { |
chris215 | 7:6edb20845684 | 232 | return FALSE; |
chris215 | 7:6edb20845684 | 233 | } |
chris215 | 7:6edb20845684 | 234 | } |
chris215 | 7:6edb20845684 | 235 | ////////////////////// genieDequeueEvent /////////////////// |
chris215 | 7:6edb20845684 | 236 | // |
chris215 | 7:6edb20845684 | 237 | // Copy the bytes from a queued input event to a buffer supplied |
chris215 | 7:6edb20845684 | 238 | // by the caller. |
chris215 | 7:6edb20845684 | 239 | // |
chris215 | 7:6edb20845684 | 240 | // Parms: genieFrame * buff, a pointer to the user's buffer |
chris215 | 7:6edb20845684 | 241 | // |
chris215 | 7:6edb20845684 | 242 | // Returns: TRUE if there was an event to copy |
chris215 | 7:6edb20845684 | 243 | // FALSE if not |
chris215 | 7:6edb20845684 | 244 | // |
chris215 | 7:6edb20845684 | 245 | bool Mbed4dGenie::genieDequeueEvent(genieFrame * buff) { |
chris215 | 7:6edb20845684 | 246 | |
chris215 | 7:6edb20845684 | 247 | |
chris215 | 7:6edb20845684 | 248 | if (_genieEventQueue.n_events > 0) { |
chris215 | 7:6edb20845684 | 249 | memcpy (buff, &_genieEventQueue.frames[_genieEventQueue.rd_index], |
chris215 | 7:6edb20845684 | 250 | GENIE_FRAME_SIZE); |
chris215 | 7:6edb20845684 | 251 | _genieEventQueue.rd_index++; |
chris215 | 7:6edb20845684 | 252 | _genieEventQueue.rd_index &= MAX_GENIE_EVENTS -1; |
chris215 | 7:6edb20845684 | 253 | _genieEventQueue.n_events--; |
chris215 | 7:6edb20845684 | 254 | return TRUE; |
chris215 | 7:6edb20845684 | 255 | } |
chris215 | 7:6edb20845684 | 256 | return FALSE; |
chris215 | 7:6edb20845684 | 257 | } |
chris215 | 7:6edb20845684 | 258 | void Mbed4dGenie::genieAttachEventHandler(genieUserEventHandlerPtr handler) |
chris215 | 7:6edb20845684 | 259 | { |
chris215 | 7:6edb20845684 | 260 | _genieUserHandler = handler; |
chris215 | 7:6edb20845684 | 261 | } |
chris215 | 7:6edb20845684 | 262 | bool Mbed4dGenie::PendingFrames(void) |
chris215 | 7:6edb20845684 | 263 | { |
chris215 | 7:6edb20845684 | 264 | return (_genieEventQueue.n_events>0); |
chris215 | 2:f283764fe9b7 | 265 | } |