Chrono

Dependencies:   mbed SDFileSystem

Committer:
pathae
Date:
Tue Apr 07 12:24:23 2020 +0000
Revision:
5:e565265fdf23
Tir

Who changed what in which revision?

UserRevisionLine numberNew contents of line
pathae 5:e565265fdf23 1
pathae 5:e565265fdf23 2 #include "mbed.h"
pathae 5:e565265fdf23 3 #include "mbed_genie.h"
pathae 5:e565265fdf23 4
pathae 5:e565265fdf23 5 DigitalOut genieReset(PC_7); //genie reset pin on pin 8 of the mbed
pathae 5:e565265fdf23 6
pathae 5:e565265fdf23 7 Serial screen(PA_9,PA_10);
pathae 5:e565265fdf23 8 Serial pc(USBTX,USBRX);
pathae 5:e565265fdf23 9 Timer t;
pathae 5:e565265fdf23 10
pathae 5:e565265fdf23 11
pathae 5:e565265fdf23 12
pathae 5:e565265fdf23 13 void _genieFlushEventQueue (void);
pathae 5:e565265fdf23 14 void _handleError (void);
pathae 5:e565265fdf23 15 void _geniePutchar (uint8_t c);
pathae 5:e565265fdf23 16 uint8_t _genieGetchar (void);
pathae 5:e565265fdf23 17 void _genieSetLinkState (uint16_t newstate);
pathae 5:e565265fdf23 18 uint16_t _genieGetLinkState (void);
pathae 5:e565265fdf23 19 bool _genieEnqueueEvent (uint8_t * data);
pathae 5:e565265fdf23 20 //////////////////////////////////////////////////////////////
pathae 5:e565265fdf23 21 // A structure to hold up to MAX_GENIE_EVENTS events receive
pathae 5:e565265fdf23 22 // from the display
pathae 5:e565265fdf23 23 //
pathae 5:e565265fdf23 24 static genieEventQueueStruct _genieEventQueue;
pathae 5:e565265fdf23 25
pathae 5:e565265fdf23 26 //////////////////////////////////////////////////////////////
pathae 5:e565265fdf23 27 // Pointer to the user's event handler function
pathae 5:e565265fdf23 28 //
pathae 5:e565265fdf23 29 static genieUserEventHandlerPtr _genieUserHandler = NULL;
pathae 5:e565265fdf23 30
pathae 5:e565265fdf23 31
pathae 5:e565265fdf23 32 //////////////////////////////////////////////////////////////
pathae 5:e565265fdf23 33 // Simple 5-deep stack for the link state, this allows
pathae 5:e565265fdf23 34 // genieDoEvents() to save the current state, receive a frame,
pathae 5:e565265fdf23 35 // then restore the state
pathae 5:e565265fdf23 36 //
pathae 5:e565265fdf23 37 static uint8_t _genieLinkStates[5] = {GENIE_LINK_IDLE};
pathae 5:e565265fdf23 38 //
pathae 5:e565265fdf23 39 // Stack pointer
pathae 5:e565265fdf23 40 //
pathae 5:e565265fdf23 41 static uint8_t *_genieLinkState = &_genieLinkStates[0];
pathae 5:e565265fdf23 42
pathae 5:e565265fdf23 43
pathae 5:e565265fdf23 44 //////////////////////////////////////////////////////////////
pathae 5:e565265fdf23 45 // Number of mS the genieGetChar() function will wait before
pathae 5:e565265fdf23 46 // giving up on the display
pathae 5:e565265fdf23 47 static int _genieTimeout = TIMEOUT_PERIOD;
pathae 5:e565265fdf23 48
pathae 5:e565265fdf23 49
pathae 5:e565265fdf23 50 //////////////////////////////////////////////////////////////
pathae 5:e565265fdf23 51 // Number of times we have had a timeout
pathae 5:e565265fdf23 52 static int _genieTimeouts = 0;
pathae 5:e565265fdf23 53
pathae 5:e565265fdf23 54
pathae 5:e565265fdf23 55 //////////////////////////////////////////////////////////////
pathae 5:e565265fdf23 56 // Global error variable
pathae 5:e565265fdf23 57 static int _genieError = ERROR_NONE;
pathae 5:e565265fdf23 58
pathae 5:e565265fdf23 59
pathae 5:e565265fdf23 60
pathae 5:e565265fdf23 61
pathae 5:e565265fdf23 62 static uint8_t rxframe_count = 0;
pathae 5:e565265fdf23 63
pathae 5:e565265fdf23 64
pathae 5:e565265fdf23 65 //////////////////////////////////////////////////////////////
pathae 5:e565265fdf23 66 // Number of fatal errors encountered
pathae 5:e565265fdf23 67 static int _genieFatalErrors = 0;
pathae 5:e565265fdf23 68 ////////////////////// genieGetEventData ////////////////////////
pathae 5:e565265fdf23 69 //
pathae 5:e565265fdf23 70 // Returns the LSB and MSB of the event's data combined into
pathae 5:e565265fdf23 71 // a single uint16
pathae 5:e565265fdf23 72 //
pathae 5:e565265fdf23 73 // The data is transmitted from the display in big-endian format
pathae 5:e565265fdf23 74 // and stored the same so the user can't just access it as an int
pathae 5:e565265fdf23 75 // directly from the structure.
pathae 5:e565265fdf23 76 //
pathae 5:e565265fdf23 77 uint16_t genieGetEventData (genieFrame * e) {
pathae 5:e565265fdf23 78 return (e->reportObject.data_msb << 8) + e->reportObject.data_lsb;
pathae 5:e565265fdf23 79 }
pathae 5:e565265fdf23 80
pathae 5:e565265fdf23 81
pathae 5:e565265fdf23 82
pathae 5:e565265fdf23 83
pathae 5:e565265fdf23 84 //////////////////////// genieEventIs ///////////////////////////
pathae 5:e565265fdf23 85 //
pathae 5:e565265fdf23 86 // Compares the cmd, object and index fields of the event's
pathae 5:e565265fdf23 87 // structure.
pathae 5:e565265fdf23 88 //
pathae 5:e565265fdf23 89 // Returns: TRUE if all the fields match the caller's parms
pathae 5:e565265fdf23 90 // FALSE if any of them don't
pathae 5:e565265fdf23 91 //
pathae 5:e565265fdf23 92 bool genieEventIs(genieFrame * e, uint8_t cmd, uint8_t object, uint8_t index) {
pathae 5:e565265fdf23 93
pathae 5:e565265fdf23 94
pathae 5:e565265fdf23 95 return (e->reportObject.cmd == cmd &&
pathae 5:e565265fdf23 96 e->reportObject.object == object &&
pathae 5:e565265fdf23 97 e->reportObject.index == index);
pathae 5:e565265fdf23 98
pathae 5:e565265fdf23 99
pathae 5:e565265fdf23 100 }
pathae 5:e565265fdf23 101
pathae 5:e565265fdf23 102 ////////////////////// _geniePushLinkState //////////////////////
pathae 5:e565265fdf23 103 //
pathae 5:e565265fdf23 104 // Push a link state onto a FILO stack
pathae 5:e565265fdf23 105 //
pathae 5:e565265fdf23 106 void _geniePushLinkState (uint8_t newstate) {
pathae 5:e565265fdf23 107
pathae 5:e565265fdf23 108
pathae 5:e565265fdf23 109 _genieLinkState++;
pathae 5:e565265fdf23 110 _genieSetLinkState(newstate);
pathae 5:e565265fdf23 111
pathae 5:e565265fdf23 112
pathae 5:e565265fdf23 113 }
pathae 5:e565265fdf23 114
pathae 5:e565265fdf23 115
pathae 5:e565265fdf23 116 ////////////////////// _geniePopLinkState //////////////////////
pathae 5:e565265fdf23 117 //
pathae 5:e565265fdf23 118 // Pop a link state from a FILO stack
pathae 5:e565265fdf23 119 //
pathae 5:e565265fdf23 120 void _geniePopLinkState (void) {
pathae 5:e565265fdf23 121 if (_genieLinkState > &_genieLinkStates[0]) {
pathae 5:e565265fdf23 122 *_genieLinkState = 0xFF;
pathae 5:e565265fdf23 123 _genieLinkState--;
pathae 5:e565265fdf23 124 }
pathae 5:e565265fdf23 125 }
pathae 5:e565265fdf23 126
pathae 5:e565265fdf23 127 ///////////////// _genieFlushSerialInput ///////////////////
pathae 5:e565265fdf23 128 //
pathae 5:e565265fdf23 129 // Removes and discards all characters from the currently
pathae 5:e565265fdf23 130 // used serial port's Rx buffer.
pathae 5:e565265fdf23 131 //
pathae 5:e565265fdf23 132 void _genieFlushSerialInput(void) {
pathae 5:e565265fdf23 133 do {
pathae 5:e565265fdf23 134 _genieGetchar();
pathae 5:e565265fdf23 135 } while (_genieError != ERROR_NOCHAR);
pathae 5:e565265fdf23 136 }
pathae 5:e565265fdf23 137
pathae 5:e565265fdf23 138 ///////////////////////// _handleError /////////////////////////
pathae 5:e565265fdf23 139 //
pathae 5:e565265fdf23 140 // So far really just a debugging aid, but can be enhanced to
pathae 5:e565265fdf23 141 // help recover from errors.
pathae 5:e565265fdf23 142 //
pathae 5:e565265fdf23 143 void _handleError (void) {
pathae 5:e565265fdf23 144 // Serial2.write (_genieError + (1<<5));
pathae 5:e565265fdf23 145 // if (_genieError == GENIE_NAK) genieResync();
pathae 5:e565265fdf23 146 }
pathae 5:e565265fdf23 147
pathae 5:e565265fdf23 148
pathae 5:e565265fdf23 149
pathae 5:e565265fdf23 150
pathae 5:e565265fdf23 151 ////////////////////// _genieFlushEventQueue ////////////////////
pathae 5:e565265fdf23 152 //
pathae 5:e565265fdf23 153 // Reset all the event queue variables and start from scratch.
pathae 5:e565265fdf23 154 //
pathae 5:e565265fdf23 155 void _genieFlushEventQueue(void) {
pathae 5:e565265fdf23 156 _genieEventQueue.rd_index = 0;
pathae 5:e565265fdf23 157 _genieEventQueue.wr_index = 0;
pathae 5:e565265fdf23 158 _genieEventQueue.n_events = 0;
pathae 5:e565265fdf23 159 }
pathae 5:e565265fdf23 160 bool GenieReadable(void){
pathae 5:e565265fdf23 161 if (screen.readable())
pathae 5:e565265fdf23 162 {
pathae 5:e565265fdf23 163 return TRUE;
pathae 5:e565265fdf23 164 }
pathae 5:e565265fdf23 165 else
pathae 5:e565265fdf23 166 {
pathae 5:e565265fdf23 167 return FALSE;
pathae 5:e565265fdf23 168 }
pathae 5:e565265fdf23 169 }
pathae 5:e565265fdf23 170 ///////////////////////// genieDoEvents /////////////////////////
pathae 5:e565265fdf23 171 //
pathae 5:e565265fdf23 172 // This is the heart of the Genie comms state machine.
pathae 5:e565265fdf23 173 //
pathae 5:e565265fdf23 174 uint16_t genieDoEvents (void) {
pathae 5:e565265fdf23 175 uint8_t c;
pathae 5:e565265fdf23 176 static uint8_t rx_data[6];
pathae 5:e565265fdf23 177 static uint8_t checksum = 0;
pathae 5:e565265fdf23 178
pathae 5:e565265fdf23 179 if (GenieReadable())
pathae 5:e565265fdf23 180 {
pathae 5:e565265fdf23 181 c = _genieGetchar();
pathae 5:e565265fdf23 182 //pc.putc(c);
pathae 5:e565265fdf23 183
pathae 5:e565265fdf23 184 ////////////////////////////////////////////
pathae 5:e565265fdf23 185 //
pathae 5:e565265fdf23 186 // If there are no characters to process and we have
pathae 5:e565265fdf23 187 // queued events call the user's handler function.
pathae 5:e565265fdf23 188 //
pathae 5:e565265fdf23 189 if (_genieError == ERROR_NOCHAR) {
pathae 5:e565265fdf23 190 //pc.printf("EventCalled!\n\r");
pathae 5:e565265fdf23 191 if (_genieEventQueue.n_events > 0 && _genieUserHandler!= NULL) (_genieUserHandler)();
pathae 5:e565265fdf23 192 return GENIE_EVENT_NONE;
pathae 5:e565265fdf23 193 }
pathae 5:e565265fdf23 194
pathae 5:e565265fdf23 195 ///////////////////////////////////////////
pathae 5:e565265fdf23 196 //
pathae 5:e565265fdf23 197 // Main state machine
pathae 5:e565265fdf23 198 //
pathae 5:e565265fdf23 199 switch (_genieGetLinkState()) {
pathae 5:e565265fdf23 200 case GENIE_LINK_IDLE:
pathae 5:e565265fdf23 201 switch (c) {
pathae 5:e565265fdf23 202 case GENIE_REPORT_EVENT:
pathae 5:e565265fdf23 203 // event frame out of the blue, set the link state
pathae 5:e565265fdf23 204 // and fall through to the frame-accumulate code
pathae 5:e565265fdf23 205 // at the end of this function
pathae 5:e565265fdf23 206 _geniePushLinkState(GENIE_LINK_RXEVENT);
pathae 5:e565265fdf23 207 break;
pathae 5:e565265fdf23 208
pathae 5:e565265fdf23 209 default:
pathae 5:e565265fdf23 210 // error, bad character, no other character
pathae 5:e565265fdf23 211 // is acceptable in this state
pathae 5:e565265fdf23 212 return GENIE_EVENT_RXCHAR;
pathae 5:e565265fdf23 213
pathae 5:e565265fdf23 214 }
pathae 5:e565265fdf23 215 break;
pathae 5:e565265fdf23 216
pathae 5:e565265fdf23 217 case GENIE_LINK_WFAN:
pathae 5:e565265fdf23 218 switch (c) {
pathae 5:e565265fdf23 219
pathae 5:e565265fdf23 220
pathae 5:e565265fdf23 221 case GENIE_ACK:
pathae 5:e565265fdf23 222 _geniePopLinkState();
pathae 5:e565265fdf23 223 return GENIE_EVENT_RXCHAR;
pathae 5:e565265fdf23 224
pathae 5:e565265fdf23 225
pathae 5:e565265fdf23 226 case GENIE_NAK:
pathae 5:e565265fdf23 227 _geniePopLinkState();
pathae 5:e565265fdf23 228 _genieError = ERROR_NAK;
pathae 5:e565265fdf23 229 _handleError();
pathae 5:e565265fdf23 230 return GENIE_EVENT_RXCHAR;
pathae 5:e565265fdf23 231
pathae 5:e565265fdf23 232 case GENIE_REPORT_EVENT:
pathae 5:e565265fdf23 233 // event frame out of the blue while waiting for an ACK
pathae 5:e565265fdf23 234 // save/set the link state and fall through to the
pathae 5:e565265fdf23 235 // frame-accumulate code at the end of this function
pathae 5:e565265fdf23 236 _geniePushLinkState(GENIE_LINK_RXEVENT);
pathae 5:e565265fdf23 237 break;
pathae 5:e565265fdf23 238
pathae 5:e565265fdf23 239
pathae 5:e565265fdf23 240 case GENIE_REPORT_OBJ:
pathae 5:e565265fdf23 241 default:
pathae 5:e565265fdf23 242 // error, bad character
pathae 5:e565265fdf23 243 return GENIE_EVENT_RXCHAR;
pathae 5:e565265fdf23 244 }
pathae 5:e565265fdf23 245 break;
pathae 5:e565265fdf23 246
pathae 5:e565265fdf23 247
pathae 5:e565265fdf23 248 case GENIE_LINK_WF_RXREPORT: // waiting for the first byte of a report
pathae 5:e565265fdf23 249 switch (c) {
pathae 5:e565265fdf23 250
pathae 5:e565265fdf23 251 case GENIE_REPORT_EVENT:
pathae 5:e565265fdf23 252 // event frame out of the blue while waiting for the first
pathae 5:e565265fdf23 253 // byte of a report frame
pathae 5:e565265fdf23 254 // save/set the link state and fall through to the
pathae 5:e565265fdf23 255 // frame-accumulate code at the end of this function
pathae 5:e565265fdf23 256 _geniePushLinkState(GENIE_LINK_RXEVENT);
pathae 5:e565265fdf23 257 break;
pathae 5:e565265fdf23 258
pathae 5:e565265fdf23 259
pathae 5:e565265fdf23 260 case GENIE_REPORT_OBJ:
pathae 5:e565265fdf23 261 // first byte of a report frame
pathae 5:e565265fdf23 262 // replace the GENIE_LINK_WF_RXREPORT link state
pathae 5:e565265fdf23 263 // with GENIE_LINK_RXREPORT to indicate that we
pathae 5:e565265fdf23 264 // are now receiving a report frame
pathae 5:e565265fdf23 265 _geniePopLinkState();
pathae 5:e565265fdf23 266 _geniePushLinkState(GENIE_LINK_RXREPORT);
pathae 5:e565265fdf23 267 break;
pathae 5:e565265fdf23 268
pathae 5:e565265fdf23 269
pathae 5:e565265fdf23 270 case GENIE_ACK:
pathae 5:e565265fdf23 271 case GENIE_NAK:
pathae 5:e565265fdf23 272 default:
pathae 5:e565265fdf23 273 // error, bad character
pathae 5:e565265fdf23 274 return GENIE_EVENT_RXCHAR;
pathae 5:e565265fdf23 275 // break;
pathae 5:e565265fdf23 276 }
pathae 5:e565265fdf23 277
pathae 5:e565265fdf23 278
pathae 5:e565265fdf23 279 case GENIE_LINK_RXREPORT: // already receiving report
pathae 5:e565265fdf23 280 case GENIE_LINK_RXEVENT: // already receiving event
pathae 5:e565265fdf23 281 default:
pathae 5:e565265fdf23 282 break;
pathae 5:e565265fdf23 283
pathae 5:e565265fdf23 284 }
pathae 5:e565265fdf23 285
pathae 5:e565265fdf23 286
pathae 5:e565265fdf23 287 ///////////////////////////////////////////////////////
pathae 5:e565265fdf23 288 // We get here if we are in the process of receiving
pathae 5:e565265fdf23 289 // a report or event frame. Accumulate GENIE_FRAME_SIZE
pathae 5:e565265fdf23 290 // bytes into a local buffer then queue them as a frame
pathae 5:e565265fdf23 291 // into the event queue
pathae 5:e565265fdf23 292 //
pathae 5:e565265fdf23 293 if (_genieGetLinkState() == GENIE_LINK_RXREPORT || \
pathae 5:e565265fdf23 294 _genieGetLinkState() == GENIE_LINK_RXEVENT) {
pathae 5:e565265fdf23 295
pathae 5:e565265fdf23 296 checksum = (rxframe_count == 0) ? c : checksum ^ c;
pathae 5:e565265fdf23 297
pathae 5:e565265fdf23 298
pathae 5:e565265fdf23 299 rx_data[rxframe_count] = c;
pathae 5:e565265fdf23 300
pathae 5:e565265fdf23 301
pathae 5:e565265fdf23 302 if (rxframe_count == GENIE_FRAME_SIZE -1) {
pathae 5:e565265fdf23 303 //pc.printf("FrameReceived!\n\r");
pathae 5:e565265fdf23 304 // all bytes received, if the CS is good
pathae 5:e565265fdf23 305 // queue the frame and restore the link state
pathae 5:e565265fdf23 306 if (checksum == 0) {
pathae 5:e565265fdf23 307 _genieEnqueueEvent(rx_data);
pathae 5:e565265fdf23 308 if (_genieEventQueue.n_events > 0 && _genieUserHandler!= NULL) (_genieUserHandler)();
pathae 5:e565265fdf23 309 //return GENIE_EVENT_NONE;
pathae 5:e565265fdf23 310 rxframe_count = 0;
pathae 5:e565265fdf23 311 // revert the link state to whatever it was before
pathae 5:e565265fdf23 312 // we started accumulating this frame
pathae 5:e565265fdf23 313 _geniePopLinkState();
pathae 5:e565265fdf23 314 return GENIE_EVENT_RXCHAR;
pathae 5:e565265fdf23 315 } else {
pathae 5:e565265fdf23 316 _genieError = ERROR_BAD_CS;
pathae 5:e565265fdf23 317 _handleError();
pathae 5:e565265fdf23 318 }
pathae 5:e565265fdf23 319 }
pathae 5:e565265fdf23 320 rxframe_count++;
pathae 5:e565265fdf23 321 return GENIE_EVENT_RXCHAR;
pathae 5:e565265fdf23 322 }
pathae 5:e565265fdf23 323 }
pathae 5:e565265fdf23 324 }
pathae 5:e565265fdf23 325
pathae 5:e565265fdf23 326 ////////////////////// genieDequeueEvent ///////////////////
pathae 5:e565265fdf23 327 //
pathae 5:e565265fdf23 328 // Copy the bytes from a queued input event to a buffer supplied
pathae 5:e565265fdf23 329 // by the caller.
pathae 5:e565265fdf23 330 //
pathae 5:e565265fdf23 331 // Parms: genieFrame * buff, a pointer to the user's buffer
pathae 5:e565265fdf23 332 //
pathae 5:e565265fdf23 333 // Returns: TRUE if there was an event to copy
pathae 5:e565265fdf23 334 // FALSE if not
pathae 5:e565265fdf23 335 //
pathae 5:e565265fdf23 336 bool genieDequeueEvent(genieFrame * buff) {
pathae 5:e565265fdf23 337
pathae 5:e565265fdf23 338
pathae 5:e565265fdf23 339 if (_genieEventQueue.n_events > 0) {
pathae 5:e565265fdf23 340 memcpy (buff, &_genieEventQueue.frames[_genieEventQueue.rd_index],
pathae 5:e565265fdf23 341 GENIE_FRAME_SIZE);
pathae 5:e565265fdf23 342 _genieEventQueue.rd_index++;
pathae 5:e565265fdf23 343 _genieEventQueue.rd_index &= MAX_GENIE_EVENTS -1;
pathae 5:e565265fdf23 344 _genieEventQueue.n_events--;
pathae 5:e565265fdf23 345 return TRUE;
pathae 5:e565265fdf23 346 }
pathae 5:e565265fdf23 347 return FALSE;
pathae 5:e565265fdf23 348 }
pathae 5:e565265fdf23 349
pathae 5:e565265fdf23 350
pathae 5:e565265fdf23 351
pathae 5:e565265fdf23 352
pathae 5:e565265fdf23 353
pathae 5:e565265fdf23 354 ////////////////////// _genieWaitForIdle ////////////////////////
pathae 5:e565265fdf23 355 //
pathae 5:e565265fdf23 356 // Wait for the link to become idle or for the timeout period,
pathae 5:e565265fdf23 357 // whichever comes first.
pathae 5:e565265fdf23 358 //
pathae 5:e565265fdf23 359 void _genieWaitForIdle (void) {
pathae 5:e565265fdf23 360 uint16_t do_event_result;
pathae 5:e565265fdf23 361 long timeout = t.read_ms() + _genieTimeout;
pathae 5:e565265fdf23 362
pathae 5:e565265fdf23 363 for ( ; t.read_ms() < timeout;) {
pathae 5:e565265fdf23 364
pathae 5:e565265fdf23 365
pathae 5:e565265fdf23 366 do_event_result = genieDoEvents();
pathae 5:e565265fdf23 367 // if there was a character received from the
pathae 5:e565265fdf23 368 // display restart the timeout because doEvents
pathae 5:e565265fdf23 369 // is in the process of receiving something
pathae 5:e565265fdf23 370 if (do_event_result == GENIE_EVENT_RXCHAR) {
pathae 5:e565265fdf23 371 timeout = t.read_ms() + _genieTimeout;
pathae 5:e565265fdf23 372 return;
pathae 5:e565265fdf23 373 }
pathae 5:e565265fdf23 374
pathae 5:e565265fdf23 375 if (_genieGetLinkState() == GENIE_LINK_IDLE) {
pathae 5:e565265fdf23 376 return;
pathae 5:e565265fdf23 377 }
pathae 5:e565265fdf23 378 }
pathae 5:e565265fdf23 379 _genieError = ERROR_TIMEOUT;
pathae 5:e565265fdf23 380 _handleError();
pathae 5:e565265fdf23 381 return;
pathae 5:e565265fdf23 382 }
pathae 5:e565265fdf23 383
pathae 5:e565265fdf23 384 ///////////////////////// genieWriteObject //////////////////////
pathae 5:e565265fdf23 385 //
pathae 5:e565265fdf23 386 // Write data to an object on the display
pathae 5:e565265fdf23 387 //
pathae 5:e565265fdf23 388 uint16_t genieWriteObject (uint16_t object, uint16_t index, uint16_t data)
pathae 5:e565265fdf23 389 {
pathae 5:e565265fdf23 390 uint16_t msb, lsb ;
pathae 5:e565265fdf23 391 uint8_t checksum ;
pathae 5:e565265fdf23 392
pathae 5:e565265fdf23 393
pathae 5:e565265fdf23 394 _genieWaitForIdle();
pathae 5:e565265fdf23 395
pathae 5:e565265fdf23 396
pathae 5:e565265fdf23 397 lsb = data&0xFF;
pathae 5:e565265fdf23 398 msb = (data>>8) & 0xFF;
pathae 5:e565265fdf23 399
pathae 5:e565265fdf23 400
pathae 5:e565265fdf23 401 _genieError = ERROR_NONE;
pathae 5:e565265fdf23 402
pathae 5:e565265fdf23 403
pathae 5:e565265fdf23 404 _geniePutchar(GENIE_WRITE_OBJ) ; checksum = GENIE_WRITE_OBJ ;
pathae 5:e565265fdf23 405 _geniePutchar(object) ; checksum ^= object ;
pathae 5:e565265fdf23 406 _geniePutchar(index) ; checksum ^= index ;
pathae 5:e565265fdf23 407 _geniePutchar(msb) ; checksum ^= msb;
pathae 5:e565265fdf23 408 _geniePutchar(lsb) ; checksum ^= lsb;
pathae 5:e565265fdf23 409 _geniePutchar(checksum) ;
pathae 5:e565265fdf23 410
pathae 5:e565265fdf23 411
pathae 5:e565265fdf23 412 _geniePushLinkState(GENIE_LINK_WFAN);
pathae 5:e565265fdf23 413 }
pathae 5:e565265fdf23 414
pathae 5:e565265fdf23 415 /////////////////////// genieWriteContrast //////////////////////
pathae 5:e565265fdf23 416 //
pathae 5:e565265fdf23 417 // Alter the display contrast (backlight)
pathae 5:e565265fdf23 418 //
pathae 5:e565265fdf23 419 // Parms: uint8_t value: The required contrast setting, only
pathae 5:e565265fdf23 420 // values from 0 to 15 are valid. 0 or 1 for most displays
pathae 5:e565265fdf23 421 // and 0 to 15 for the uLCD-43
pathae 5:e565265fdf23 422 //
pathae 5:e565265fdf23 423 void genieWriteContrast (uint16_t value) {
pathae 5:e565265fdf23 424 unsigned int checksum ;
pathae 5:e565265fdf23 425
pathae 5:e565265fdf23 426
pathae 5:e565265fdf23 427 _genieWaitForIdle();
pathae 5:e565265fdf23 428
pathae 5:e565265fdf23 429
pathae 5:e565265fdf23 430 _geniePutchar(GENIE_WRITE_CONTRAST) ; checksum = GENIE_WRITE_CONTRAST ;
pathae 5:e565265fdf23 431 _geniePutchar(value) ; checksum ^= value ;
pathae 5:e565265fdf23 432 _geniePutchar(checksum) ;
pathae 5:e565265fdf23 433
pathae 5:e565265fdf23 434
pathae 5:e565265fdf23 435 _geniePushLinkState(GENIE_LINK_WFAN);
pathae 5:e565265fdf23 436
pathae 5:e565265fdf23 437
pathae 5:e565265fdf23 438 }
pathae 5:e565265fdf23 439
pathae 5:e565265fdf23 440
pathae 5:e565265fdf23 441 //////////////////////// _genieWriteStrX ///////////////////////
pathae 5:e565265fdf23 442 //
pathae 5:e565265fdf23 443 // Non-user function used by genieWriteStr() and genieWriteStrU()
pathae 5:e565265fdf23 444 //
pathae 5:e565265fdf23 445 static int _genieWriteStrX (uint16_t code, uint16_t index, char *string)
pathae 5:e565265fdf23 446 {
pathae 5:e565265fdf23 447 char *p ;
pathae 5:e565265fdf23 448 unsigned int checksum ;
pathae 5:e565265fdf23 449 int len = strlen (string) ;
pathae 5:e565265fdf23 450
pathae 5:e565265fdf23 451
pathae 5:e565265fdf23 452 if (len > 255)
pathae 5:e565265fdf23 453 return -1 ;
pathae 5:e565265fdf23 454
pathae 5:e565265fdf23 455
pathae 5:e565265fdf23 456 _genieWaitForIdle();
pathae 5:e565265fdf23 457
pathae 5:e565265fdf23 458
pathae 5:e565265fdf23 459 _geniePutchar(code) ; checksum = code ;
pathae 5:e565265fdf23 460 _geniePutchar(index) ; checksum ^= index ;
pathae 5:e565265fdf23 461 _geniePutchar((unsigned char)len) ; checksum ^= len ;
pathae 5:e565265fdf23 462 for (p = string ; *p ; ++p) {
pathae 5:e565265fdf23 463 _geniePutchar (*p) ;
pathae 5:e565265fdf23 464 checksum ^= *p ;
pathae 5:e565265fdf23 465 }
pathae 5:e565265fdf23 466 _geniePutchar(checksum) ;
pathae 5:e565265fdf23 467
pathae 5:e565265fdf23 468
pathae 5:e565265fdf23 469 _geniePushLinkState(GENIE_LINK_WFAN);
pathae 5:e565265fdf23 470
pathae 5:e565265fdf23 471
pathae 5:e565265fdf23 472 return 0 ;
pathae 5:e565265fdf23 473 }
pathae 5:e565265fdf23 474 /////////////////////// genieWriteStr ////////////////////////
pathae 5:e565265fdf23 475 //
pathae 5:e565265fdf23 476 // Write a string to the display (ASCII)
pathae 5:e565265fdf23 477 //
pathae 5:e565265fdf23 478 uint16_t genieWriteStr (uint16_t index, char *string) {
pathae 5:e565265fdf23 479
pathae 5:e565265fdf23 480 return _genieWriteStrX (GENIE_WRITE_STR, index, string);
pathae 5:e565265fdf23 481 }
pathae 5:e565265fdf23 482
pathae 5:e565265fdf23 483
pathae 5:e565265fdf23 484 /////////////////////// genieWriteStrU ////////////////////////
pathae 5:e565265fdf23 485 //
pathae 5:e565265fdf23 486 // Write a string to the display (Unicode)
pathae 5:e565265fdf23 487 //
pathae 5:e565265fdf23 488 uint16_t genieWriteStrU (uint16_t index, char *string) {
pathae 5:e565265fdf23 489
pathae 5:e565265fdf23 490
pathae 5:e565265fdf23 491 return _genieWriteStrX (GENIE_WRITE_STRU, index, string);
pathae 5:e565265fdf23 492
pathae 5:e565265fdf23 493
pathae 5:e565265fdf23 494 }
pathae 5:e565265fdf23 495 /////////////////// genieAttachEventHandler //////////////////////
pathae 5:e565265fdf23 496 //
pathae 5:e565265fdf23 497 // "Attaches" a pointer to the users event handler by writing
pathae 5:e565265fdf23 498 // the pointer into the variable used by doEVents()
pathae 5:e565265fdf23 499 //
pathae 5:e565265fdf23 500 void genieAttachEventHandler (genieUserEventHandlerPtr handler) {
pathae 5:e565265fdf23 501 _genieUserHandler = handler;
pathae 5:e565265fdf23 502 }
pathae 5:e565265fdf23 503
pathae 5:e565265fdf23 504
pathae 5:e565265fdf23 505 ////////////////////// _genieEnqueueEvent ///////////////////
pathae 5:e565265fdf23 506 //
pathae 5:e565265fdf23 507 // Copy the bytes from a buffer supplied by the caller
pathae 5:e565265fdf23 508 // to the input queue
pathae 5:e565265fdf23 509 //
pathae 5:e565265fdf23 510 // Parms: uint8_t * data, a pointer to the user's data
pathae 5:e565265fdf23 511 //
pathae 5:e565265fdf23 512 // Returns: TRUE if there was an empty location in the queue
pathae 5:e565265fdf23 513 // to copy the data into
pathae 5:e565265fdf23 514 // FALSE if not
pathae 5:e565265fdf23 515 // Sets: ERROR_REPLY_OVR if there was no room in the queue
pathae 5:e565265fdf23 516 //
pathae 5:e565265fdf23 517 bool _genieEnqueueEvent (uint8_t * data) {
pathae 5:e565265fdf23 518
pathae 5:e565265fdf23 519
pathae 5:e565265fdf23 520 if (_genieEventQueue.n_events < MAX_GENIE_EVENTS-2) {
pathae 5:e565265fdf23 521 memcpy (&_genieEventQueue.frames[_genieEventQueue.wr_index], data,
pathae 5:e565265fdf23 522 GENIE_FRAME_SIZE);
pathae 5:e565265fdf23 523 _genieEventQueue.wr_index++;
pathae 5:e565265fdf23 524 _genieEventQueue.wr_index &= MAX_GENIE_EVENTS -1;
pathae 5:e565265fdf23 525 _genieEventQueue.n_events++;
pathae 5:e565265fdf23 526 return TRUE;
pathae 5:e565265fdf23 527 } else {
pathae 5:e565265fdf23 528 _genieError = ERROR_REPLY_OVR;
pathae 5:e565265fdf23 529 _handleError();
pathae 5:e565265fdf23 530 return FALSE;
pathae 5:e565265fdf23 531 }
pathae 5:e565265fdf23 532 }
pathae 5:e565265fdf23 533 ///////////////////// _genieSetLinkState ////////////////////////
pathae 5:e565265fdf23 534 //
pathae 5:e565265fdf23 535 // Set the logical state of the link to the display.
pathae 5:e565265fdf23 536 //
pathae 5:e565265fdf23 537 // Parms: uint16_t newstate, a value to be written to the
pathae 5:e565265fdf23 538 // link's _genieLinkState variable. Valid values are
pathae 5:e565265fdf23 539 // GENIE_LINK_IDLE 0
pathae 5:e565265fdf23 540 // GENIE_LINK_WFAN 1 // waiting for Ack or Nak
pathae 5:e565265fdf23 541 // GENIE_LINK_WF_RXREPORT 2 // waiting for a report frame
pathae 5:e565265fdf23 542 // GENIE_LINK_RXREPORT 3 // receiving a report frame
pathae 5:e565265fdf23 543 // GENIE_LINK_RXEVENT 4 // receiving an event frame
pathae 5:e565265fdf23 544 // GENIE_LINK_SHDN 5
pathae 5:e565265fdf23 545 //
pathae 5:e565265fdf23 546 void _genieSetLinkState (uint16_t newstate) {
pathae 5:e565265fdf23 547
pathae 5:e565265fdf23 548 *_genieLinkState = newstate;
pathae 5:e565265fdf23 549
pathae 5:e565265fdf23 550
pathae 5:e565265fdf23 551 if (newstate == GENIE_LINK_RXREPORT || \
pathae 5:e565265fdf23 552 newstate == GENIE_LINK_RXEVENT)
pathae 5:e565265fdf23 553 rxframe_count = 0;
pathae 5:e565265fdf23 554 }
pathae 5:e565265fdf23 555
pathae 5:e565265fdf23 556
pathae 5:e565265fdf23 557 /////////////////////// _genieGetLinkState //////////////////////
pathae 5:e565265fdf23 558 //
pathae 5:e565265fdf23 559 // Get the current logical state of the link to the display.
pathae 5:e565265fdf23 560 //
pathae 5:e565265fdf23 561 uint16_t _genieGetLinkState (void) {
pathae 5:e565265fdf23 562 return *_genieLinkState;
pathae 5:e565265fdf23 563 }
pathae 5:e565265fdf23 564
pathae 5:e565265fdf23 565 /////////////////////// _geniePutchar ///////////////////////////
pathae 5:e565265fdf23 566 //
pathae 5:e565265fdf23 567 // Output the supplied character to the Genie display over
pathae 5:e565265fdf23 568 // the selected serial port
pathae 5:e565265fdf23 569 //
pathae 5:e565265fdf23 570 void _geniePutchar (uint8_t c) {
pathae 5:e565265fdf23 571 // if (screen != NULL)
pathae 5:e565265fdf23 572 screen.putc(c);
pathae 5:e565265fdf23 573 }
pathae 5:e565265fdf23 574
pathae 5:e565265fdf23 575
pathae 5:e565265fdf23 576 //////////////////////// _genieGetchar //////////////////////////
pathae 5:e565265fdf23 577 //
pathae 5:e565265fdf23 578 // Get a character from the selected Genie serial port
pathae 5:e565265fdf23 579 //
pathae 5:e565265fdf23 580 // Returns: ERROR_NOHANDLER if an Rx handler has not
pathae 5:e565265fdf23 581 // been defined
pathae 5:e565265fdf23 582 // ERROR_NOCHAR if no bytes have beeb received
pathae 5:e565265fdf23 583 // The char if there was one to get
pathae 5:e565265fdf23 584 // Sets: _genieError with any errors encountered
pathae 5:e565265fdf23 585 //
pathae 5:e565265fdf23 586 uint8_t _genieGetchar() {
pathae 5:e565265fdf23 587 uint16_t result;
pathae 5:e565265fdf23 588
pathae 5:e565265fdf23 589
pathae 5:e565265fdf23 590 _genieError = ERROR_NONE;
pathae 5:e565265fdf23 591
pathae 5:e565265fdf23 592 return (screen.getc());
pathae 5:e565265fdf23 593 }
pathae 5:e565265fdf23 594
pathae 5:e565265fdf23 595 void RxIrqHandler(void)
pathae 5:e565265fdf23 596 {
pathae 5:e565265fdf23 597 do
pathae 5:e565265fdf23 598 {
pathae 5:e565265fdf23 599 genieDoEvents();
pathae 5:e565265fdf23 600 }
pathae 5:e565265fdf23 601 while(screen.readable ());
pathae 5:e565265fdf23 602 }
pathae 5:e565265fdf23 603
pathae 5:e565265fdf23 604
pathae 5:e565265fdf23 605 void TickerIrq(void)
pathae 5:e565265fdf23 606 {
pathae 5:e565265fdf23 607 }
pathae 5:e565265fdf23 608
pathae 5:e565265fdf23 609
pathae 5:e565265fdf23 610 void SetupGenie(void)
pathae 5:e565265fdf23 611 {
pathae 5:e565265fdf23 612 screen.baud(19200);
pathae 5:e565265fdf23 613 pc.baud(19200);
pathae 5:e565265fdf23 614 screen.attach(&RxIrqHandler,Serial::RxIrq);
pathae 5:e565265fdf23 615 //t.start();
pathae 5:e565265fdf23 616 // EventChk.attach(&TickerIrq,0.05);
pathae 5:e565265fdf23 617 }