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 01:42:46 2014 +0000
Revision:
0:d2ed5a44c802
Child:
1:95e0e194a412
Experimental library

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 0:d2ed5a44c802 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 0:d2ed5a44c802 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 0:d2ed5a44c802 321 }
chris215 0:d2ed5a44c802 322 }
chris215 0:d2ed5a44c802 323
chris215 0:d2ed5a44c802 324 ////////////////////// genieDequeueEvent ///////////////////
chris215 0:d2ed5a44c802 325 //
chris215 0:d2ed5a44c802 326 // Copy the bytes from a queued input event to a buffer supplied
chris215 0:d2ed5a44c802 327 // by the caller.
chris215 0:d2ed5a44c802 328 //
chris215 0:d2ed5a44c802 329 // Parms: genieFrame * buff, a pointer to the user's buffer
chris215 0:d2ed5a44c802 330 //
chris215 0:d2ed5a44c802 331 // Returns: TRUE if there was an event to copy
chris215 0:d2ed5a44c802 332 // FALSE if not
chris215 0:d2ed5a44c802 333 //
chris215 0:d2ed5a44c802 334 bool genieDequeueEvent(genieFrame * buff) {
chris215 0:d2ed5a44c802 335
chris215 0:d2ed5a44c802 336
chris215 0:d2ed5a44c802 337 if (_genieEventQueue.n_events > 0) {
chris215 0:d2ed5a44c802 338 memcpy (buff, &_genieEventQueue.frames[_genieEventQueue.rd_index],
chris215 0:d2ed5a44c802 339 GENIE_FRAME_SIZE);
chris215 0:d2ed5a44c802 340 _genieEventQueue.rd_index++;
chris215 0:d2ed5a44c802 341 _genieEventQueue.rd_index &= MAX_GENIE_EVENTS -1;
chris215 0:d2ed5a44c802 342 _genieEventQueue.n_events--;
chris215 0:d2ed5a44c802 343 return TRUE;
chris215 0:d2ed5a44c802 344 }
chris215 0:d2ed5a44c802 345 return FALSE;
chris215 0:d2ed5a44c802 346 }
chris215 0:d2ed5a44c802 347
chris215 0:d2ed5a44c802 348
chris215 0:d2ed5a44c802 349
chris215 0:d2ed5a44c802 350
chris215 0:d2ed5a44c802 351
chris215 0:d2ed5a44c802 352 ////////////////////// _genieWaitForIdle ////////////////////////
chris215 0:d2ed5a44c802 353 //
chris215 0:d2ed5a44c802 354 // Wait for the link to become idle or for the timeout period,
chris215 0:d2ed5a44c802 355 // whichever comes first.
chris215 0:d2ed5a44c802 356 //
chris215 0:d2ed5a44c802 357 void _genieWaitForIdle (void) {
chris215 0:d2ed5a44c802 358 uint16_t do_event_result;
chris215 0:d2ed5a44c802 359 long timeout = t.read_ms() + _genieTimeout;
chris215 0:d2ed5a44c802 360
chris215 0:d2ed5a44c802 361 for ( ; t.read_ms() < timeout;) {
chris215 0:d2ed5a44c802 362
chris215 0:d2ed5a44c802 363
chris215 0:d2ed5a44c802 364 do_event_result = genieDoEvents();
chris215 0:d2ed5a44c802 365 // if there was a character received from the
chris215 0:d2ed5a44c802 366 // display restart the timeout because doEvents
chris215 0:d2ed5a44c802 367 // is in the process of receiving something
chris215 0:d2ed5a44c802 368 if (do_event_result == GENIE_EVENT_RXCHAR) {
chris215 0:d2ed5a44c802 369 timeout = t.read_ms() + _genieTimeout;
chris215 0:d2ed5a44c802 370 return;
chris215 0:d2ed5a44c802 371 }
chris215 0:d2ed5a44c802 372
chris215 0:d2ed5a44c802 373 if (_genieGetLinkState() == GENIE_LINK_IDLE) {
chris215 0:d2ed5a44c802 374 return;
chris215 0:d2ed5a44c802 375 }
chris215 0:d2ed5a44c802 376 }
chris215 0:d2ed5a44c802 377 _genieError = ERROR_TIMEOUT;
chris215 0:d2ed5a44c802 378 _handleError();
chris215 0:d2ed5a44c802 379 return;
chris215 0:d2ed5a44c802 380 }
chris215 0:d2ed5a44c802 381
chris215 0:d2ed5a44c802 382 ///////////////////////// genieWriteObject //////////////////////
chris215 0:d2ed5a44c802 383 //
chris215 0:d2ed5a44c802 384 // Write data to an object on the display
chris215 0:d2ed5a44c802 385 //
chris215 0:d2ed5a44c802 386 uint16_t genieWriteObject (uint16_t object, uint16_t index, uint16_t data)
chris215 0:d2ed5a44c802 387 {
chris215 0:d2ed5a44c802 388 uint16_t msb, lsb ;
chris215 0:d2ed5a44c802 389 uint8_t checksum ;
chris215 0:d2ed5a44c802 390
chris215 0:d2ed5a44c802 391
chris215 0:d2ed5a44c802 392 _genieWaitForIdle();
chris215 0:d2ed5a44c802 393
chris215 0:d2ed5a44c802 394
chris215 0:d2ed5a44c802 395 lsb = data&0xFF;
chris215 0:d2ed5a44c802 396 msb = (data>>8) & 0xFF;
chris215 0:d2ed5a44c802 397
chris215 0:d2ed5a44c802 398
chris215 0:d2ed5a44c802 399 _genieError = ERROR_NONE;
chris215 0:d2ed5a44c802 400
chris215 0:d2ed5a44c802 401
chris215 0:d2ed5a44c802 402 _geniePutchar(GENIE_WRITE_OBJ) ; checksum = GENIE_WRITE_OBJ ;
chris215 0:d2ed5a44c802 403 _geniePutchar(object) ; checksum ^= object ;
chris215 0:d2ed5a44c802 404 _geniePutchar(index) ; checksum ^= index ;
chris215 0:d2ed5a44c802 405 _geniePutchar(msb) ; checksum ^= msb;
chris215 0:d2ed5a44c802 406 _geniePutchar(lsb) ; checksum ^= lsb;
chris215 0:d2ed5a44c802 407 _geniePutchar(checksum) ;
chris215 0:d2ed5a44c802 408
chris215 0:d2ed5a44c802 409
chris215 0:d2ed5a44c802 410 _geniePushLinkState(GENIE_LINK_WFAN);
chris215 0:d2ed5a44c802 411 }
chris215 0:d2ed5a44c802 412
chris215 0:d2ed5a44c802 413 /////////////////////// genieWriteContrast //////////////////////
chris215 0:d2ed5a44c802 414 //
chris215 0:d2ed5a44c802 415 // Alter the display contrast (backlight)
chris215 0:d2ed5a44c802 416 //
chris215 0:d2ed5a44c802 417 // Parms: uint8_t value: The required contrast setting, only
chris215 0:d2ed5a44c802 418 // values from 0 to 15 are valid. 0 or 1 for most displays
chris215 0:d2ed5a44c802 419 // and 0 to 15 for the uLCD-43
chris215 0:d2ed5a44c802 420 //
chris215 0:d2ed5a44c802 421 void genieWriteContrast (uint16_t value) {
chris215 0:d2ed5a44c802 422 unsigned int checksum ;
chris215 0:d2ed5a44c802 423
chris215 0:d2ed5a44c802 424
chris215 0:d2ed5a44c802 425 _genieWaitForIdle();
chris215 0:d2ed5a44c802 426
chris215 0:d2ed5a44c802 427
chris215 0:d2ed5a44c802 428 _geniePutchar(GENIE_WRITE_CONTRAST) ; checksum = GENIE_WRITE_CONTRAST ;
chris215 0:d2ed5a44c802 429 _geniePutchar(value) ; checksum ^= value ;
chris215 0:d2ed5a44c802 430 _geniePutchar(checksum) ;
chris215 0:d2ed5a44c802 431
chris215 0:d2ed5a44c802 432
chris215 0:d2ed5a44c802 433 _geniePushLinkState(GENIE_LINK_WFAN);
chris215 0:d2ed5a44c802 434
chris215 0:d2ed5a44c802 435
chris215 0:d2ed5a44c802 436 }
chris215 0:d2ed5a44c802 437
chris215 0:d2ed5a44c802 438
chris215 0:d2ed5a44c802 439 //////////////////////// _genieWriteStrX ///////////////////////
chris215 0:d2ed5a44c802 440 //
chris215 0:d2ed5a44c802 441 // Non-user function used by genieWriteStr() and genieWriteStrU()
chris215 0:d2ed5a44c802 442 //
chris215 0:d2ed5a44c802 443 static int _genieWriteStrX (uint16_t code, uint16_t index, char *string)
chris215 0:d2ed5a44c802 444 {
chris215 0:d2ed5a44c802 445 char *p ;
chris215 0:d2ed5a44c802 446 unsigned int checksum ;
chris215 0:d2ed5a44c802 447 int len = strlen (string) ;
chris215 0:d2ed5a44c802 448
chris215 0:d2ed5a44c802 449
chris215 0:d2ed5a44c802 450 if (len > 255)
chris215 0:d2ed5a44c802 451 return -1 ;
chris215 0:d2ed5a44c802 452
chris215 0:d2ed5a44c802 453
chris215 0:d2ed5a44c802 454 _genieWaitForIdle();
chris215 0:d2ed5a44c802 455
chris215 0:d2ed5a44c802 456
chris215 0:d2ed5a44c802 457 _geniePutchar(code) ; checksum = code ;
chris215 0:d2ed5a44c802 458 _geniePutchar(index) ; checksum ^= index ;
chris215 0:d2ed5a44c802 459 _geniePutchar((unsigned char)len) ; checksum ^= len ;
chris215 0:d2ed5a44c802 460 for (p = string ; *p ; ++p) {
chris215 0:d2ed5a44c802 461 _geniePutchar (*p) ;
chris215 0:d2ed5a44c802 462 checksum ^= *p ;
chris215 0:d2ed5a44c802 463 }
chris215 0:d2ed5a44c802 464 _geniePutchar(checksum) ;
chris215 0:d2ed5a44c802 465
chris215 0:d2ed5a44c802 466
chris215 0:d2ed5a44c802 467 _geniePushLinkState(GENIE_LINK_WFAN);
chris215 0:d2ed5a44c802 468
chris215 0:d2ed5a44c802 469
chris215 0:d2ed5a44c802 470 return 0 ;
chris215 0:d2ed5a44c802 471 }
chris215 0:d2ed5a44c802 472 /////////////////////// genieWriteStr ////////////////////////
chris215 0:d2ed5a44c802 473 //
chris215 0:d2ed5a44c802 474 // Write a string to the display (ASCII)
chris215 0:d2ed5a44c802 475 //
chris215 0:d2ed5a44c802 476 uint16_t genieWriteStr (uint16_t index, char *string) {
chris215 0:d2ed5a44c802 477
chris215 0:d2ed5a44c802 478 return _genieWriteStrX (GENIE_WRITE_STR, index, string);
chris215 0:d2ed5a44c802 479 }
chris215 0:d2ed5a44c802 480
chris215 0:d2ed5a44c802 481
chris215 0:d2ed5a44c802 482 /////////////////////// genieWriteStrU ////////////////////////
chris215 0:d2ed5a44c802 483 //
chris215 0:d2ed5a44c802 484 // Write a string to the display (Unicode)
chris215 0:d2ed5a44c802 485 //
chris215 0:d2ed5a44c802 486 uint16_t genieWriteStrU (uint16_t index, char *string) {
chris215 0:d2ed5a44c802 487
chris215 0:d2ed5a44c802 488
chris215 0:d2ed5a44c802 489 return _genieWriteStrX (GENIE_WRITE_STRU, index, string);
chris215 0:d2ed5a44c802 490
chris215 0:d2ed5a44c802 491
chris215 0:d2ed5a44c802 492 }
chris215 0:d2ed5a44c802 493 /////////////////// genieAttachEventHandler //////////////////////
chris215 0:d2ed5a44c802 494 //
chris215 0:d2ed5a44c802 495 // "Attaches" a pointer to the users event handler by writing
chris215 0:d2ed5a44c802 496 // the pointer into the variable used by doEVents()
chris215 0:d2ed5a44c802 497 //
chris215 0:d2ed5a44c802 498 void genieAttachEventHandler (genieUserEventHandlerPtr handler) {
chris215 0:d2ed5a44c802 499 _genieUserHandler = handler;
chris215 0:d2ed5a44c802 500 }
chris215 0:d2ed5a44c802 501
chris215 0:d2ed5a44c802 502
chris215 0:d2ed5a44c802 503 ////////////////////// _genieEnqueueEvent ///////////////////
chris215 0:d2ed5a44c802 504 //
chris215 0:d2ed5a44c802 505 // Copy the bytes from a buffer supplied by the caller
chris215 0:d2ed5a44c802 506 // to the input queue
chris215 0:d2ed5a44c802 507 //
chris215 0:d2ed5a44c802 508 // Parms: uint8_t * data, a pointer to the user's data
chris215 0:d2ed5a44c802 509 //
chris215 0:d2ed5a44c802 510 // Returns: TRUE if there was an empty location in the queue
chris215 0:d2ed5a44c802 511 // to copy the data into
chris215 0:d2ed5a44c802 512 // FALSE if not
chris215 0:d2ed5a44c802 513 // Sets: ERROR_REPLY_OVR if there was no room in the queue
chris215 0:d2ed5a44c802 514 //
chris215 0:d2ed5a44c802 515 bool _genieEnqueueEvent (uint8_t * data) {
chris215 0:d2ed5a44c802 516
chris215 0:d2ed5a44c802 517
chris215 0:d2ed5a44c802 518 if (_genieEventQueue.n_events < MAX_GENIE_EVENTS-2) {
chris215 0:d2ed5a44c802 519 memcpy (&_genieEventQueue.frames[_genieEventQueue.wr_index], data,
chris215 0:d2ed5a44c802 520 GENIE_FRAME_SIZE);
chris215 0:d2ed5a44c802 521 _genieEventQueue.wr_index++;
chris215 0:d2ed5a44c802 522 _genieEventQueue.wr_index &= MAX_GENIE_EVENTS -1;
chris215 0:d2ed5a44c802 523 _genieEventQueue.n_events++;
chris215 0:d2ed5a44c802 524 return TRUE;
chris215 0:d2ed5a44c802 525 } else {
chris215 0:d2ed5a44c802 526 _genieError = ERROR_REPLY_OVR;
chris215 0:d2ed5a44c802 527 _handleError();
chris215 0:d2ed5a44c802 528 return FALSE;
chris215 0:d2ed5a44c802 529 }
chris215 0:d2ed5a44c802 530 }
chris215 0:d2ed5a44c802 531 ///////////////////// _genieSetLinkState ////////////////////////
chris215 0:d2ed5a44c802 532 //
chris215 0:d2ed5a44c802 533 // Set the logical state of the link to the display.
chris215 0:d2ed5a44c802 534 //
chris215 0:d2ed5a44c802 535 // Parms: uint16_t newstate, a value to be written to the
chris215 0:d2ed5a44c802 536 // link's _genieLinkState variable. Valid values are
chris215 0:d2ed5a44c802 537 // GENIE_LINK_IDLE 0
chris215 0:d2ed5a44c802 538 // GENIE_LINK_WFAN 1 // waiting for Ack or Nak
chris215 0:d2ed5a44c802 539 // GENIE_LINK_WF_RXREPORT 2 // waiting for a report frame
chris215 0:d2ed5a44c802 540 // GENIE_LINK_RXREPORT 3 // receiving a report frame
chris215 0:d2ed5a44c802 541 // GENIE_LINK_RXEVENT 4 // receiving an event frame
chris215 0:d2ed5a44c802 542 // GENIE_LINK_SHDN 5
chris215 0:d2ed5a44c802 543 //
chris215 0:d2ed5a44c802 544 void _genieSetLinkState (uint16_t newstate) {
chris215 0:d2ed5a44c802 545
chris215 0:d2ed5a44c802 546 *_genieLinkState = newstate;
chris215 0:d2ed5a44c802 547
chris215 0:d2ed5a44c802 548
chris215 0:d2ed5a44c802 549 if (newstate == GENIE_LINK_RXREPORT || \
chris215 0:d2ed5a44c802 550 newstate == GENIE_LINK_RXEVENT)
chris215 0:d2ed5a44c802 551 rxframe_count = 0;
chris215 0:d2ed5a44c802 552 }
chris215 0:d2ed5a44c802 553
chris215 0:d2ed5a44c802 554
chris215 0:d2ed5a44c802 555 /////////////////////// _genieGetLinkState //////////////////////
chris215 0:d2ed5a44c802 556 //
chris215 0:d2ed5a44c802 557 // Get the current logical state of the link to the display.
chris215 0:d2ed5a44c802 558 //
chris215 0:d2ed5a44c802 559 uint16_t _genieGetLinkState (void) {
chris215 0:d2ed5a44c802 560 return *_genieLinkState;
chris215 0:d2ed5a44c802 561 }
chris215 0:d2ed5a44c802 562
chris215 0:d2ed5a44c802 563 /////////////////////// _geniePutchar ///////////////////////////
chris215 0:d2ed5a44c802 564 //
chris215 0:d2ed5a44c802 565 // Output the supplied character to the Genie display over
chris215 0:d2ed5a44c802 566 // the selected serial port
chris215 0:d2ed5a44c802 567 //
chris215 0:d2ed5a44c802 568 void _geniePutchar (uint8_t c) {
chris215 0:d2ed5a44c802 569 // if (screen != NULL)
chris215 0:d2ed5a44c802 570 screen.putc(c);
chris215 0:d2ed5a44c802 571 }
chris215 0:d2ed5a44c802 572
chris215 0:d2ed5a44c802 573
chris215 0:d2ed5a44c802 574 //////////////////////// _genieGetchar //////////////////////////
chris215 0:d2ed5a44c802 575 //
chris215 0:d2ed5a44c802 576 // Get a character from the selected Genie serial port
chris215 0:d2ed5a44c802 577 //
chris215 0:d2ed5a44c802 578 // Returns: ERROR_NOHANDLER if an Rx handler has not
chris215 0:d2ed5a44c802 579 // been defined
chris215 0:d2ed5a44c802 580 // ERROR_NOCHAR if no bytes have beeb received
chris215 0:d2ed5a44c802 581 // The char if there was one to get
chris215 0:d2ed5a44c802 582 // Sets: _genieError with any errors encountered
chris215 0:d2ed5a44c802 583 //
chris215 0:d2ed5a44c802 584 uint8_t _genieGetchar() {
chris215 0:d2ed5a44c802 585 uint16_t result;
chris215 0:d2ed5a44c802 586
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 }