Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Revision 0:e1ef1c6666f3, committed 2014-01-29
- Comitter:
- langster1980
- Date:
- Wed Jan 29 23:04:22 2014 +0000
- Commit message:
- 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
Changed in this revision
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp Wed Jan 29 23:04:22 2014 +0000
@@ -0,0 +1,234 @@
+/* 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 led 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 LEDS
+1 to 4 appropriately
+
+*/
+
+#include "mbed.h"
+#include "mbed_genie.h"
+
+DigitalOut led1(LED1);
+DigitalOut led2(LED2);
+DigitalOut led3(LED3);
+DigitalOut led4(LED4);
+
+bool winButton0Status = false; //holds the "status" of winButton0 object.
+bool userLed0Status = false; //hold the "status" of userLed0 object.
+
+bool winButton1Status = false; //holds the "status" of winButton1 object.
+bool userLed1Status = false; //hold the "status" of userLed1 object.
+
+bool winButton2Status = false; //holds the "status" of winButton2 object.
+bool userLed2Status = false; //hold the "status" of userLed2 object.
+
+bool winButton3Status = false; //holds the "status" of winButton3 object.
+bool userLed3Status = false; //hold the "status" of userLed3 object.
+
+
+//Event handler for the 4d Systems display
+void myGenieEventHandler(void)
+{
+ genieFrame Event;
+ genieDequeueEvent(&Event);
+
+ if(Event.reportObject.cmd == GENIE_REPORT_EVENT) {
+
+ // If the Reported Message was from winbutton0 and userLed0 is off
+
+ if (Event.reportObject.object == GENIE_OBJ_WINBUTTON) {
+ if ((Event.reportObject.index == 0) && (userLed0Status==false)) {
+ printf("LED1 High \r\n");
+ wait(0.1);
+ winButton0Status=true;
+ }
+ }
+
+ // If the Reported Message was from winbutton0 and userLed0 is on
+
+ if (Event.reportObject.object == GENIE_OBJ_WINBUTTON) {
+ if ((Event.reportObject.index == 0) && (userLed0Status == true)) {
+ printf("LED1 Low \r\n");
+ wait(0.1);
+ winButton0Status=false;
+ }
+ }
+
+ // If the Reported Message was from winbutton1 and userLed1 is off
+
+ if (Event.reportObject.object == GENIE_OBJ_WINBUTTON) {
+ if ((Event.reportObject.index == 1) && (userLed1Status==false)) {
+ printf("LED2 High \r\n");
+ wait(0.1);
+ winButton1Status=true;
+ }
+ }
+
+ // If the Reported Message was from winbutton1 and userLed1 is on
+
+ if (Event.reportObject.object == GENIE_OBJ_WINBUTTON) {
+ if ((Event.reportObject.index == 1) && (userLed1Status == true)) {
+ printf("LED2 Low \r\n");
+ wait(0.1);
+ winButton1Status=false;
+ }
+ }
+
+ // If the Reported Message was from winbutton2 and userLed2 is off
+
+ if (Event.reportObject.object == GENIE_OBJ_WINBUTTON) {
+ if ((Event.reportObject.index == 2) && (userLed2Status==false)) {
+ printf("LED High \r\n");
+ wait(0.1);
+ winButton2Status=true;
+ }
+ }
+
+ // If the Reported Message was from winbutton2 and userLed2 is on
+
+ if (Event.reportObject.object == GENIE_OBJ_WINBUTTON) {
+ if ((Event.reportObject.index == 2) && (userLed2Status == true)) {
+ printf("LED Low \r\n");
+ wait(0.1);
+ winButton2Status=false;
+ }
+ }
+
+ // If the Reported Message was from winbutton3 and userLed3 is off
+
+ if (Event.reportObject.object == GENIE_OBJ_WINBUTTON) {
+ if ((Event.reportObject.index == 3) && (userLed3Status==false)) {
+ printf("LED High \r\n");
+ wait(0.1);
+ winButton3Status=true;
+ }
+ }
+
+ // If the Reported Message was from winbutton3 and userLed3 is on
+
+ if (Event.reportObject.object == GENIE_OBJ_WINBUTTON) {
+ if ((Event.reportObject.index == 3) && (userLed3Status == true)) {
+ printf("LED Low \r\n");
+ wait(0.1);
+ winButton3Status=false;
+ }
+ }
+ }
+}
+
+
+int main()
+{
+
+ SetupGenie();
+
+ genieAttachEventHandler(&myGenieEventHandler);
+
+ printf("Langsters's mbed Visi-Genie LED demo \r\n");
+
+ genieWriteContrast(15); //set screen contrast to full brightness
+
+ while(1) {
+
+ //check if winButton0 is High & set LED0 High
+
+ if (winButton0Status == true) {
+ printf("Button 0 in On State! \r\n"); //send button status message
+ genieWriteObject(GENIE_OBJ_USER_LED, 0x00, 1); // set virtual LED0 High
+ wait(0.1); // wait 100uS
+ led1 = 1; // set actual LED1 High
+ userLed0Status = true; // set userLed0Status High
+
+ }
+
+ //check if winButton0 is low & set LED low
+
+ else if (winButton0Status == false) {
+ printf("Button 0 in Off state! \r\n"); //send button status message
+ genieWriteObject(GENIE_OBJ_USER_LED, 0x00, 0); // set virtual LED0 Low
+ wait(0.1); // wait 100uS
+ led1 = 0; // set actual LED1 Low
+ userLed0Status = false; //set userLed0Status Low
+
+ }
+
+ //check if winButton1 is High & set LED High
+
+ if (winButton1Status == true) {
+ printf("Button 1 in On State! \r\n"); //send button status message
+ genieWriteObject(GENIE_OBJ_USER_LED, 0x01, 1); // set virtual LED0 High
+ wait(0.1); // wait 100uS
+ led2 = 1; // set actual LED2 High
+ userLed1Status = true; // set userLed1Status High
+
+ }
+
+ //check if winButton1 is low & set LED low
+
+ else if (winButton1Status == false) {
+ printf("Button 1 in Off state! \r\n"); //send button status message
+ genieWriteObject(GENIE_OBJ_USER_LED, 0x01, 0); // set virtual LED0 Low
+ wait(0.1); // wait 100uS
+ led2 = 0; // set actual LED1 Low
+ userLed1Status = false; //set userLed1Status Low
+
+ }
+
+ //check if winButton2 is High & set LED High
+
+ if (winButton2Status == true) {
+ printf("Button 2 in On State! \r\n"); //send button status message
+ genieWriteObject(GENIE_OBJ_USER_LED, 0x02, 1); // set virtual LED0 High
+ wait(0.1); // wait 100uS
+ led3 = 1; // set actual LED2 High
+ userLed2Status = true; // set userLed1Status High
+
+ }
+
+ //check if winButton2 is low & set LED low
+
+ else if (winButton2Status == false) {
+ printf("Button 2 in Off state! \r\n"); //send button status message
+ genieWriteObject(GENIE_OBJ_USER_LED, 0x02, 0); // set virtual LED0 Low
+ wait(0.1); // wait 100uS
+ led3 = 0; // set actual LED1 Low
+ userLed2Status = false; //set userLed1Status Low
+
+ }
+
+ //check if winButton3 is High & set LED High
+
+ if (winButton3Status == true) {
+ printf("Button 3 in On State! \r\n"); //send button status message
+ genieWriteObject(GENIE_OBJ_USER_LED, 0x03, 1); // set virtual LED0 High
+ wait(0.1); // wait 100uS
+ led4 = 1; // set actual LED2 High
+ userLed3Status = true; // set userLed1Status High
+
+ }
+
+ //check if winButton2 is low & set LED low
+
+ else if (winButton3Status == false) {
+ printf("Button 3 in Off state! \r\n"); //send button status message
+ genieWriteObject(GENIE_OBJ_USER_LED, 0x03, 0); // set virtual LED0 Low
+ wait(0.1); // wait 100uS
+ led4 = 0; // set actual LED1 Low
+ userLed3Status = false; //set userLed1Status Low
+
+ }
+
+
+ }
+
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed.bld Wed Jan 29 23:04:22 2014 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/mbed_official/code/mbed/builds/a9913a65894f \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed_genie.cpp Wed Jan 29 23:04:22 2014 +0000
@@ -0,0 +1,613 @@
+
+#include "mbed.h"
+#include "mbed_genie.h"
+
+DigitalOut genieReset(p8); //genie reset pin on pin 8 of the mbed
+
+Serial screen(p9,p10);
+Serial pc(USBTX,USBRX);
+Timer t;
+
+
+
+void _genieFlushEventQueue (void);
+void _handleError (void);
+void _geniePutchar (uint8_t c);
+uint8_t _genieGetchar (void);
+void _genieSetLinkState (uint16_t newstate);
+uint16_t _genieGetLinkState (void);
+bool _genieEnqueueEvent (uint8_t * data);
+//////////////////////////////////////////////////////////////
+// A structure to hold up to MAX_GENIE_EVENTS events receive
+// from the display
+//
+static genieEventQueueStruct _genieEventQueue;
+
+//////////////////////////////////////////////////////////////
+// Pointer to the user's event handler function
+//
+static genieUserEventHandlerPtr _genieUserHandler = NULL;
+
+
+//////////////////////////////////////////////////////////////
+// Simple 5-deep stack for the link state, this allows
+// genieDoEvents() to save the current state, receive a frame,
+// then restore the state
+//
+static uint8_t _genieLinkStates[5] = {GENIE_LINK_IDLE};
+//
+// Stack pointer
+//
+static uint8_t *_genieLinkState = &_genieLinkStates[0];
+
+
+//////////////////////////////////////////////////////////////
+// Number of mS the genieGetChar() function will wait before
+// giving up on the display
+static int _genieTimeout = TIMEOUT_PERIOD;
+
+
+//////////////////////////////////////////////////////////////
+// Number of times we have had a timeout
+static int _genieTimeouts = 0;
+
+
+//////////////////////////////////////////////////////////////
+// Global error variable
+static int _genieError = ERROR_NONE;
+
+
+
+
+static uint8_t rxframe_count = 0;
+
+
+//////////////////////////////////////////////////////////////
+// Number of fatal errors encountered
+static int _genieFatalErrors = 0;
+////////////////////// genieGetEventData ////////////////////////
+//
+// Returns the LSB and MSB of the event's data combined into
+// a single uint16
+//
+// The data is transmitted from the display in big-endian format
+// and stored the same so the user can't just access it as an int
+// directly from the structure.
+//
+uint16_t genieGetEventData (genieFrame * e) {
+ return (e->reportObject.data_msb << 8) + e->reportObject.data_lsb;
+}
+
+//////////////////////// genieEventIs ///////////////////////////
+//
+// Compares the cmd, object and index fields of the event's
+// structure.
+//
+// Returns: TRUE if all the fields match the caller's parms
+// FALSE if any of them don't
+//
+bool genieEventIs(genieFrame * e, uint8_t cmd, uint8_t object, uint8_t index) {
+
+
+ return (e->reportObject.cmd == cmd &&
+ e->reportObject.object == object &&
+ e->reportObject.index == index);
+
+}
+
+////////////////////// _geniePushLinkState //////////////////////
+//
+// Push a link state onto a FILO stack
+//
+void _geniePushLinkState (uint8_t newstate) {
+
+
+ _genieLinkState++;
+ _genieSetLinkState(newstate);
+
+
+}
+
+
+////////////////////// _geniePopLinkState //////////////////////
+//
+// Pop a link state from a FILO stack
+//
+void _geniePopLinkState (void) {
+ if (_genieLinkState > &_genieLinkStates[0]) {
+ *_genieLinkState = 0xFF;
+ _genieLinkState--;
+ }
+}
+
+///////////////// _genieFlushSerialInput ///////////////////
+//
+// Removes and discards all characters from the currently
+// used serial port's Rx buffer.
+//
+void _genieFlushSerialInput(void) {
+ do {
+ _genieGetchar();
+ } while (_genieError != ERROR_NOCHAR);
+}
+
+///////////////////////// _handleError /////////////////////////
+//
+// So far really just a debugging aid, but can be enhanced to
+// help recover from errors.
+//
+void _handleError (void) {
+// Serial2.write (_genieError + (1<<5));
+// if (_genieError == GENIE_NAK) genieResync();
+}
+
+
+
+
+////////////////////// _genieFlushEventQueue ////////////////////
+//
+// Reset all the event queue variables and start from scratch.
+//
+void _genieFlushEventQueue(void) {
+ _genieEventQueue.rd_index = 0;
+ _genieEventQueue.wr_index = 0;
+ _genieEventQueue.n_events = 0;
+}
+bool GenieReadable(void){
+ if (screen.readable())
+ {
+ return TRUE;
+ }
+ else
+ {
+ return FALSE;
+ }
+}
+///////////////////////// genieDoEvents /////////////////////////
+//
+// This is the heart of the Genie comms state machine.
+//
+uint16_t genieDoEvents (void) {
+ uint8_t c;
+ static uint8_t rx_data[6];
+ static uint8_t checksum = 0;
+
+ if (GenieReadable())
+ {
+ c = _genieGetchar();
+ //pc.putc(c);
+
+ ////////////////////////////////////////////
+ //
+ // If there are no characters to process and we have
+ // queued events call the user's handler function.
+ //
+ if (_genieError == ERROR_NOCHAR) {
+ //pc.printf("EventCalled!\n\r");
+ if (_genieEventQueue.n_events > 0 && _genieUserHandler!= NULL) (_genieUserHandler)();
+ return GENIE_EVENT_NONE;
+ }
+
+ ///////////////////////////////////////////
+ //
+ // Main state machine
+ //
+ switch (_genieGetLinkState()) {
+ case GENIE_LINK_IDLE:
+ switch (c) {
+ case GENIE_REPORT_EVENT:
+ // event frame out of the blue, set the link state
+ // and fall through to the frame-accumulate code
+ // at the end of this function
+ _geniePushLinkState(GENIE_LINK_RXEVENT);
+ break;
+
+ default:
+ // error, bad character, no other character
+ // is acceptable in this state
+ return GENIE_EVENT_RXCHAR;
+
+ }
+ break;
+
+ case GENIE_LINK_WFAN:
+ switch (c) {
+
+
+ case GENIE_ACK:
+ _geniePopLinkState();
+ return GENIE_EVENT_RXCHAR;
+
+
+ case GENIE_NAK:
+ _geniePopLinkState();
+ _genieError = ERROR_NAK;
+ _handleError();
+ return GENIE_EVENT_RXCHAR;
+
+ case GENIE_REPORT_EVENT:
+ // event frame out of the blue while waiting for an ACK
+ // save/set the link state and fall through to the
+ // frame-accumulate code at the end of this function
+ _geniePushLinkState(GENIE_LINK_RXEVENT);
+ break;
+
+
+ case GENIE_REPORT_OBJ:
+ default:
+ // error, bad character
+ return GENIE_EVENT_RXCHAR;
+ }
+ break;
+
+
+ case GENIE_LINK_WF_RXREPORT: // waiting for the first byte of a report
+ switch (c) {
+
+ case GENIE_REPORT_EVENT:
+ // event frame out of the blue while waiting for the first
+ // byte of a report frame
+ // save/set the link state and fall through to the
+ // frame-accumulate code at the end of this function
+ _geniePushLinkState(GENIE_LINK_RXEVENT);
+ break;
+
+
+ case GENIE_REPORT_OBJ:
+ // first byte of a report frame
+ // replace the GENIE_LINK_WF_RXREPORT link state
+ // with GENIE_LINK_RXREPORT to indicate that we
+ // are now receiving a report frame
+ _geniePopLinkState();
+ _geniePushLinkState(GENIE_LINK_RXREPORT);
+ break;
+
+
+ case GENIE_ACK:
+ case GENIE_NAK:
+ default:
+ // error, bad character
+ return GENIE_EVENT_RXCHAR;
+ // break;
+ }
+
+
+ case GENIE_LINK_RXREPORT: // already receiving report
+ case GENIE_LINK_RXEVENT: // already receiving event
+ default:
+ break;
+
+ }
+
+
+ ///////////////////////////////////////////////////////
+ // We get here if we are in the process of receiving
+ // a report or event frame. Accumulate GENIE_FRAME_SIZE
+ // bytes into a local buffer then queue them as a frame
+ // into the event queue
+ //
+ if (_genieGetLinkState() == GENIE_LINK_RXREPORT || \
+ _genieGetLinkState() == GENIE_LINK_RXEVENT) {
+
+ checksum = (rxframe_count == 0) ? c : checksum ^ c;
+
+
+ rx_data[rxframe_count] = c;
+
+
+ if (rxframe_count == GENIE_FRAME_SIZE -1) {
+ //pc.printf("FrameReceived!\n\r");
+ // all bytes received, if the CS is good
+ // queue the frame and restore the link state
+ if (checksum == 0) {
+ _genieEnqueueEvent(rx_data);
+ if (_genieEventQueue.n_events > 0 && _genieUserHandler!= NULL) (_genieUserHandler)();
+ //return GENIE_EVENT_NONE;
+ rxframe_count = 0;
+ // revert the link state to whatever it was before
+ // we started accumulating this frame
+ _geniePopLinkState();
+ return GENIE_EVENT_RXCHAR;
+ } else {
+ _genieError = ERROR_BAD_CS;
+ _handleError();
+ }
+ }
+ rxframe_count++;
+ return GENIE_EVENT_RXCHAR;
+ }
+ }
+}
+
+////////////////////// genieDequeueEvent ///////////////////
+//
+// Copy the bytes from a queued input event to a buffer supplied
+// by the caller.
+//
+// Parms: genieFrame * buff, a pointer to the user's buffer
+//
+// Returns: TRUE if there was an event to copy
+// FALSE if not
+//
+bool genieDequeueEvent(genieFrame * buff) {
+
+
+ if (_genieEventQueue.n_events > 0) {
+ memcpy (buff, &_genieEventQueue.frames[_genieEventQueue.rd_index],
+ GENIE_FRAME_SIZE);
+ _genieEventQueue.rd_index++;
+ _genieEventQueue.rd_index &= MAX_GENIE_EVENTS -1;
+ _genieEventQueue.n_events--;
+ return TRUE;
+ }
+ return FALSE;
+}
+
+
+
+
+
+////////////////////// _genieWaitForIdle ////////////////////////
+//
+// Wait for the link to become idle or for the timeout period,
+// whichever comes first.
+//
+void _genieWaitForIdle (void) {
+ uint16_t do_event_result;
+ long timeout = t.read_ms() + _genieTimeout;
+
+ for ( ; t.read_ms() < timeout;) {
+
+
+ do_event_result = genieDoEvents();
+ // if there was a character received from the
+ // display restart the timeout because doEvents
+ // is in the process of receiving something
+ if (do_event_result == GENIE_EVENT_RXCHAR) {
+ timeout = t.read_ms() + _genieTimeout;
+ return;
+ }
+
+ if (_genieGetLinkState() == GENIE_LINK_IDLE) {
+ return;
+ }
+ }
+ _genieError = ERROR_TIMEOUT;
+ _handleError();
+ return;
+}
+
+///////////////////////// genieWriteObject //////////////////////
+//
+// Write data to an object on the display
+//
+uint16_t genieWriteObject (uint16_t object, uint16_t index, uint16_t data)
+{
+ uint16_t msb, lsb ;
+ uint8_t checksum ;
+
+
+ _genieWaitForIdle();
+
+
+ lsb = data&0xFF;
+ msb = (data>>8) & 0xFF;
+
+
+ _genieError = ERROR_NONE;
+
+
+ _geniePutchar(GENIE_WRITE_OBJ) ; checksum = GENIE_WRITE_OBJ ;
+ _geniePutchar(object) ; checksum ^= object ;
+ _geniePutchar(index) ; checksum ^= index ;
+ _geniePutchar(msb) ; checksum ^= msb;
+ _geniePutchar(lsb) ; checksum ^= lsb;
+ _geniePutchar(checksum) ;
+
+
+ _geniePushLinkState(GENIE_LINK_WFAN);
+}
+
+/////////////////////// genieWriteContrast //////////////////////
+//
+// Alter the display contrast (backlight)
+//
+// Parms: uint8_t value: The required contrast setting, only
+// values from 0 to 15 are valid. 0 or 1 for most displays
+// and 0 to 15 for the uLCD-43
+//
+void genieWriteContrast (uint16_t value) {
+ unsigned int checksum ;
+
+
+ _genieWaitForIdle();
+
+
+ _geniePutchar(GENIE_WRITE_CONTRAST) ; checksum = GENIE_WRITE_CONTRAST ;
+ _geniePutchar(value) ; checksum ^= value ;
+ _geniePutchar(checksum) ;
+
+
+ _geniePushLinkState(GENIE_LINK_WFAN);
+
+
+}
+
+
+//////////////////////// _genieWriteStrX ///////////////////////
+//
+// Non-user function used by genieWriteStr() and genieWriteStrU()
+//
+static int _genieWriteStrX (uint16_t code, uint16_t index, char *string)
+{
+ char *p ;
+ unsigned int checksum ;
+ int len = strlen (string) ;
+
+
+ if (len > 255)
+ return -1 ;
+
+
+ _genieWaitForIdle();
+
+
+ _geniePutchar(code) ; checksum = code ;
+ _geniePutchar(index) ; checksum ^= index ;
+ _geniePutchar((unsigned char)len) ; checksum ^= len ;
+ for (p = string ; *p ; ++p) {
+ _geniePutchar (*p) ;
+ checksum ^= *p ;
+ }
+ _geniePutchar(checksum) ;
+
+
+ _geniePushLinkState(GENIE_LINK_WFAN);
+
+
+ return 0 ;
+}
+/////////////////////// genieWriteStr ////////////////////////
+//
+// Write a string to the display (ASCII)
+//
+uint16_t genieWriteStr (uint16_t index, char *string) {
+
+ return _genieWriteStrX (GENIE_WRITE_STR, index, string);
+}
+
+
+/////////////////////// genieWriteStrU ////////////////////////
+//
+// Write a string to the display (Unicode)
+//
+uint16_t genieWriteStrU (uint16_t index, char *string) {
+
+
+ return _genieWriteStrX (GENIE_WRITE_STRU, index, string);
+
+
+}
+/////////////////// genieAttachEventHandler //////////////////////
+//
+// "Attaches" a pointer to the users event handler by writing
+// the pointer into the variable used by doEVents()
+//
+void genieAttachEventHandler (genieUserEventHandlerPtr handler) {
+ _genieUserHandler = handler;
+}
+
+
+////////////////////// _genieEnqueueEvent ///////////////////
+//
+// Copy the bytes from a buffer supplied by the caller
+// to the input queue
+//
+// Parms: uint8_t * data, a pointer to the user's data
+//
+// Returns: TRUE if there was an empty location in the queue
+// to copy the data into
+// FALSE if not
+// Sets: ERROR_REPLY_OVR if there was no room in the queue
+//
+bool _genieEnqueueEvent (uint8_t * data) {
+
+
+ if (_genieEventQueue.n_events < MAX_GENIE_EVENTS-2) {
+ memcpy (&_genieEventQueue.frames[_genieEventQueue.wr_index], data,
+ GENIE_FRAME_SIZE);
+ _genieEventQueue.wr_index++;
+ _genieEventQueue.wr_index &= MAX_GENIE_EVENTS -1;
+ _genieEventQueue.n_events++;
+ return TRUE;
+ } else {
+ _genieError = ERROR_REPLY_OVR;
+ _handleError();
+ return FALSE;
+ }
+}
+///////////////////// _genieSetLinkState ////////////////////////
+//
+// Set the logical state of the link to the display.
+//
+// Parms: uint16_t newstate, a value to be written to the
+// link's _genieLinkState variable. Valid values are
+// GENIE_LINK_IDLE 0
+// GENIE_LINK_WFAN 1 // waiting for Ack or Nak
+// GENIE_LINK_WF_RXREPORT 2 // waiting for a report frame
+// GENIE_LINK_RXREPORT 3 // receiving a report frame
+// GENIE_LINK_RXEVENT 4 // receiving an event frame
+// GENIE_LINK_SHDN 5
+//
+void _genieSetLinkState (uint16_t newstate) {
+
+ *_genieLinkState = newstate;
+
+
+ if (newstate == GENIE_LINK_RXREPORT || \
+ newstate == GENIE_LINK_RXEVENT)
+ rxframe_count = 0;
+}
+
+
+/////////////////////// _genieGetLinkState //////////////////////
+//
+// Get the current logical state of the link to the display.
+//
+uint16_t _genieGetLinkState (void) {
+ return *_genieLinkState;
+}
+
+/////////////////////// _geniePutchar ///////////////////////////
+//
+// Output the supplied character to the Genie display over
+// the selected serial port
+//
+void _geniePutchar (uint8_t c) {
+ // if (screen != NULL)
+ screen.putc(c);
+}
+
+
+//////////////////////// _genieGetchar //////////////////////////
+//
+// Get a character from the selected Genie serial port
+//
+// Returns: ERROR_NOHANDLER if an Rx handler has not
+// been defined
+// ERROR_NOCHAR if no bytes have beeb received
+// The char if there was one to get
+// Sets: _genieError with any errors encountered
+//
+uint8_t _genieGetchar() {
+ uint16_t result;
+
+
+ _genieError = ERROR_NONE;
+
+ return (screen.getc());
+}
+
+void RxIrqHandler(void)
+{
+ do
+ {
+ genieDoEvents();
+ }
+ while(screen.readable ());
+}
+
+
+void TickerIrq(void)
+{
+}
+
+
+void SetupGenie(void)
+{
+ screen.baud(9600);
+ pc.baud(9600);
+ screen.attach(&RxIrqHandler,Serial::RxIrq);
+ t.start();
+ // EventChk.attach(&TickerIrq,0.05);
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed_genie.h Wed Jan 29 23:04:22 2014 +0000
@@ -0,0 +1,136 @@
+#undef GENIE_DEBUG
+
+#define GENIE_VERSION "GenieMbed 17-Nov-2013"
+
+// Genie commands & replys:
+
+#define GENIE_ACK 0x06
+#define GENIE_NAK 0x15
+
+#define TIMEOUT_PERIOD 500
+#define RESYNC_PERIOD 100
+
+#define GENIE_READ_OBJ 0
+#define GENIE_WRITE_OBJ 1
+#define GENIE_WRITE_STR 2
+#define GENIE_WRITE_STRU 3
+#define GENIE_WRITE_CONTRAST 4
+#define GENIE_REPORT_OBJ 5
+#define GENIE_REPORT_EVENT 7
+
+// Objects
+// the manual says:
+// Note: Object IDs may change with future releases; it is not
+// advisable to code their values as constants.
+
+#define GENIE_OBJ_DIPSW 0
+#define GENIE_OBJ_KNOB 1
+#define GENIE_OBJ_ROCKERSW 2
+#define GENIE_OBJ_ROTARYSW 3
+#define GENIE_OBJ_SLIDER 4
+#define GENIE_OBJ_TRACKBAR 5
+#define GENIE_OBJ_WINBUTTON 6
+#define GENIE_OBJ_ANGULAR_METER 7
+#define GENIE_OBJ_COOL_GAUGE 8
+#define GENIE_OBJ_CUSTOM_DIGITS 9
+#define GENIE_OBJ_FORM 10
+#define GENIE_OBJ_GAUGE 11
+#define GENIE_OBJ_IMAGE 12
+#define GENIE_OBJ_KEYBOARD 13
+#define GENIE_OBJ_LED 14
+#define GENIE_OBJ_LED_DIGITS 15
+#define GENIE_OBJ_METER 16
+#define GENIE_OBJ_STRINGS 17
+#define GENIE_OBJ_THERMOMETER 18
+#define GENIE_OBJ_USER_LED 19
+#define GENIE_OBJ_VIDEO 20
+#define GENIE_OBJ_STATIC_TEXT 21
+#define GENIE_OBJ_SOUND 22
+#define GENIE_OBJ_TIMER 23
+#define GENIE_OBJ_SPECTRUM 24
+#define GENIE_OBJ_SCOPE 25
+#define GENIE_OBJ_TANK 26
+#define GENIE_OBJ_USERIMAGES 27
+#define GENIE_OBJ_PINOUTPUT 28
+#define GENIE_OBJ_PININPUT 29
+#define GENIE_OBJ_4DBUTTON 30
+#define GENIE_OBJ_ANIBUTTON 31
+#define GENIE_OBJ_COLORPICKER 32
+#define GENIE_OBJ_USERBUTTON 33
+
+// Structure to store replys returned from a display
+
+#define GENIE_FRAME_SIZE 6
+struct genieFrameReportObj {
+ uint8_t cmd;
+ uint8_t object;
+ uint8_t index;
+ uint8_t data_msb;
+ uint8_t data_lsb;
+};
+
+/////////////////////////////////////////////////////////////////////
+// The Genie frame definition
+//
+// The union allows the data to be referenced as an array of uint8_t
+// or a structure of type genieFrameReportObj, eg
+//
+// genieFrame f;
+// f.bytes[4];
+// f.reportObject.data_lsb
+//
+// both methods get the same byte
+//
+union genieFrame {
+ uint8_t bytes[GENIE_FRAME_SIZE];
+ genieFrameReportObj reportObject;
+};
+
+#define MAX_GENIE_EVENTS 16 // MUST be a power of 2
+#define MAX_GENIE_FATALS 10
+
+struct genieEventQueueStruct {
+ genieFrame frames[MAX_GENIE_EVENTS];
+ uint8_t rd_index;
+ uint8_t wr_index;
+ uint8_t n_events;
+};
+
+typedef void (*geniePutCharFuncPtr) (uint8_t c, uint32_t baud);
+typedef uint16_t (*genieGetCharFuncPtr) (void);
+typedef void (*genieUserEventHandlerPtr) (void);
+
+#define ERROR_NONE 0
+#define ERROR_TIMEOUT -1 // 255 0xFF
+#define ERROR_NOHANDLER -2 // 254 0xFE
+#define ERROR_NOCHAR -3 // 253 0xFD
+#define ERROR_NAK -4 // 252 0xFC
+#define ERROR_REPLY_OVR -5 // 251 0xFB
+#define ERROR_RESYNC -6 // 250 0xFA
+#define ERROR_NODISPLAY -7 // 249 0xF9
+#define ERROR_BAD_CS -8 // 248 0xF8
+
+#define GENIE_LINK_IDLE 0
+#define GENIE_LINK_WFAN 1 // waiting for Ack or Nak
+#define GENIE_LINK_WF_RXREPORT 2 // waiting for a report frame
+#define GENIE_LINK_RXREPORT 3 // receiving a report frame
+#define GENIE_LINK_RXEVENT 4 // receiving an event frame
+#define GENIE_LINK_SHDN 5
+
+#define GENIE_EVENT_NONE 0
+#define GENIE_EVENT_RXCHAR 1
+
+#ifndef TRUE
+#define TRUE (1==1)
+#define FALSE (!TRUE)
+#endif
+
+void SetupGenie(void);
+void genieAttachEventHandler (genieUserEventHandlerPtr handler);
+extern bool genieDequeueEvent (genieFrame * buff);
+extern bool genieEventIs (genieFrame * e, uint8_t cmd, uint8_t object, uint8_t index);
+extern uint16_t genieGetEventData (genieFrame * e);
+extern uint16_t genieWriteObject (uint16_t object, uint16_t index, uint16_t data);
+extern uint16_t genieWriteStr (uint16_t index, char *string);
+extern void genieWriteContrast (uint16_t value);
+