Mbed 4dGenie class

Dependents:   Genie_Test 039847382-S3_DS1621_and_LCD_V1

This is a work in progress.

4dGenie class to use with 4dLCD screens that are using the genie environment.

There are still some rare occasions where the 4dLCD might crash, for now i have no solution to this except doing a reset of the 4dLCD.

Please make sure to have the most up to date PmmC loaded on the screen.

usage example :

Mbed4dGenie test program

#include "mbed.h"
#include "mbed_genie.h"

DigitalOut myled(LED1);
/*
    The Mbed4dGenie class requires 3 parameters
    1 - Tx pin
    2 - Rx pin
    3 - Reset pin
*/
Mbed4dGenie lcd4d(PTE0,PTE1,PTB9);



int main() {
    int temp = 0;
printf("Mbed Genie demo \n\r");
lcd4d.Start();


 /*
 for example, in this loop we increment the thermometer0 object from 0 to 100
 */
 
    while(1) {
        if(temp >= 100)
        {
            temp = -1;
        }
        else
        {
            temp++;
        }

        lcd4d.genieWriteObject(GENIE_OBJ_LED_DIGITS,1,temp);

        myled = 1;
        wait(0.05);
        myled = 0;
        wait(0.05);
    }
}
Committer:
chris215
Date:
Fri Feb 21 02:47:32 2014 +0000
Revision:
1:95e0e194a412
Parent:
0:d2ed5a44c802
Child:
2:f283764fe9b7
fixed some warnings

Who changed what in which revision?

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