A demonstration of how to drive the onboard LEDS on the LPC1768 via a 4.3 inch touch-screen display from 4D Systems

Dependencies:   mbed

A quick example program to show how to use the mbed LPC1768 with the 4D systems 4.3 inch capacitive touch screen.

The display has four vitual winButton objects which when touched change the state of four virtual led (userLed) objects. The winButton objects on change of state send a serial message out to the Mbed serial port on pins 9 and 10.

This message tells the mbed to drive actual corresponding virtual and actual LEDS 1 to 4 appropriately.

/media/uploads/langster1980/2014-01-29_23.39.14.jpg

for more information people can check out my blog post on the subject here:

http://langster1980.blogspot.co.uk/2014/01/mbed-controlling-4d-systems-ulcd-43pct.html

Committer:
langster1980
Date:
Wed Jan 29 23:04:22 2014 +0000
Revision:
0:e1ef1c6666f3
1st Version of a tutorial on how to drive the onboard LEDS on an LPC1768 via a 4D systems 4.3 inch touch screen display

Who changed what in which revision?

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