programme bts

Dependencies:   mbed ID12RFID SDFileSystem

Committer:
valentinbruchet
Date:
Wed May 05 08:13:43 2021 +0000
Revision:
5:e104ec24b3fa
Programme BTS;

Who changed what in which revision?

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