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); } }
Diff: mbed_genie.cpp
- Revision:
- 2:f283764fe9b7
- Parent:
- 1:95e0e194a412
- Child:
- 3:11c49c49cd1a
diff -r 95e0e194a412 -r f283764fe9b7 mbed_genie.cpp --- a/mbed_genie.cpp Fri Feb 21 02:47:32 2014 +0000 +++ b/mbed_genie.cpp Sun Feb 23 01:34:05 2014 +0000 @@ -2,64 +2,279 @@ #include "mbed.h" #include "mbed_genie.h" -Serial screen(p9,p10); Serial pc(USBTX,USBRX); -Timer t; +Mbed4dGenie::Mbed4dGenie(PinName TxPin,PinName RxPin) : _screen(TxPin,RxPin) +{ + _genieLinkStates[4] = GENIE_LINK_IDLE; + _genieLinkStates[3] = GENIE_LINK_IDLE; + _genieLinkStates[2] = GENIE_LINK_IDLE; + _genieLinkStates[1] = GENIE_LINK_IDLE; + _genieLinkStates[0] = GENIE_LINK_IDLE; + _genieLinkState = &_genieLinkStates[0]; + + _genieTimeout = TIMEOUT_PERIOD; + _genieError = ERROR_NONE; + rxframe_count = 0; + + _genieUserHandler = NULL; + _screen.attach(this,&Mbed4dGenie::RxIrqHandler,Serial::RxIrq); + _t.start(); +} +void Mbed4dGenie::genieAttachEventHandler(genieUserEventHandlerPtr handler) +{ + _genieUserHandler = handler; +} +void Mbed4dGenie::RxIrqHandler(void) +{ + do + { + //genieDoEvents(); + } + while(_screen.readable ()); +} +//////////////////////// _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 Mbed4dGenie::_genieGetchar() { + + _genieError = ERROR_NONE; + + return (_screen.getc()); +} +///////////////////// _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 Mbed4dGenie::_genieSetLinkState (uint16_t newstate) { + + *_genieLinkState = newstate; -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 + 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 Mbed4dGenie::_genieGetLinkState (void) { + return *_genieLinkState; +} + +/////////////////////// _geniePutchar /////////////////////////// +// +// Output the supplied character to the Genie display over +// the selected serial port +// +void Mbed4dGenie::_geniePutchar (uint8_t c) { + // if (screen != NULL) + _screen.putc(c); +} +////////////////////// _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 // -static genieEventQueueStruct _genieEventQueue; +// 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 Mbed4dGenie::_genieEnqueueEvent (uint8_t * data) { + -////////////////////////////////////////////////////////////// -// Pointer to the user's event handler function + 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; + } +} +////////////////////// genieDequeueEvent /////////////////// // -static genieUserEventHandlerPtr _genieUserHandler = NULL; +// 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 Mbed4dGenie::genieDequeueEvent(genieFrame * buff) { -////////////////////////////////////////////////////////////// -// Simple 5-deep stack for the link state, this allows -// genieDoEvents() to save the current state, receive a frame, -// then restore the state + 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. // -static uint8_t _genieLinkStates[5] = {GENIE_LINK_IDLE}; +void Mbed4dGenie::_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 ////////////////////// // -// Stack pointer +// Write data to an object on the display // -static uint8_t *_genieLinkState = &_genieLinkStates[0]; +uint16_t Mbed4dGenie::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) ; -////////////////////////////////////////////////////////////// -// Number of mS the genieGetChar() function will wait before -// giving up on the display -static int _genieTimeout = TIMEOUT_PERIOD; + _geniePushLinkState(GENIE_LINK_WFAN); + return GENIE_EVENT_NONE; +} +/////////////////////// 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 Mbed4dGenie::genieWriteContrast (uint16_t value) { + unsigned int checksum ; + + + _genieWaitForIdle(); -////////////////////////////////////////////////////////////// -// Number of times we have had a timeout -//static int _genieTimeouts = 0; + _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() +// +int Mbed4dGenie::_genieWriteStrX (uint16_t code, uint16_t index, char *string) +{ + char *p ; + unsigned int checksum ; + int len = strlen (string) ; -////////////////////////////////////////////////////////////// -// Global error variable -static int _genieError = ERROR_NONE; + 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 Mbed4dGenie::genieWriteStr (uint16_t index, char *string) { + + return _genieWriteStrX (GENIE_WRITE_STR, index, string); +} +/////////////////////// genieWriteStrU //////////////////////// +// +// Write a string to the display (Unicode) +// +uint16_t Mbed4dGenie::genieWriteStrU (uint16_t index, char *string) { -static uint8_t rxframe_count = 0; + return _genieWriteStrX (GENIE_WRITE_STRU, index, string); - +} ////////////////////////////////////////////////////////////// // Number of fatal errors encountered //static int _genieFatalErrors = 0; @@ -72,7 +287,7 @@ // and stored the same so the user can't just access it as an int // directly from the structure. // -uint16_t genieGetEventData (genieFrame * e) { +uint16_t Mbed4dGenie::genieGetEventData (genieFrame * e) { return (e->reportObject.data_msb << 8) + e->reportObject.data_lsb; } @@ -87,7 +302,7 @@ // 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) { +bool Mbed4dGenie::genieEventIs(genieFrame * e, uint8_t cmd, uint8_t object, uint8_t index) { return (e->reportObject.cmd == cmd && @@ -101,7 +316,7 @@ // // Push a link state onto a FILO stack // -void _geniePushLinkState (uint8_t newstate) { +void Mbed4dGenie::_geniePushLinkState (uint8_t newstate) { _genieLinkState++; @@ -115,7 +330,7 @@ // // Pop a link state from a FILO stack // -void _geniePopLinkState (void) { +void Mbed4dGenie::_geniePopLinkState (void) { if (_genieLinkState > &_genieLinkStates[0]) { *_genieLinkState = 0xFF; _genieLinkState--; @@ -127,7 +342,7 @@ // Removes and discards all characters from the currently // used serial port's Rx buffer. // -void _genieFlushSerialInput(void) { +void Mbed4dGenie::_genieFlushSerialInput(void) { do { _genieGetchar(); } while (_genieError != ERROR_NOCHAR); @@ -138,9 +353,7 @@ // 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(); +void Mbed4dGenie::_handleError (void) { } @@ -150,13 +363,13 @@ // // Reset all the event queue variables and start from scratch. // -void _genieFlushEventQueue(void) { +void Mbed4dGenie::_genieFlushEventQueue(void) { _genieEventQueue.rd_index = 0; _genieEventQueue.wr_index = 0; _genieEventQueue.n_events = 0; } -bool GenieReadable(void){ - if (screen.readable()) +bool Mbed4dGenie::GenieReadable(void){ + if (_screen.readable()) { return TRUE; } @@ -169,7 +382,7 @@ // // This is the heart of the Genie comms state machine. // -uint16_t genieDoEvents (void) { +uint16_t Mbed4dGenie::genieDoEvents (void) { uint8_t c; static uint8_t rx_data[6]; static uint8_t checksum = 0; @@ -320,294 +533,4 @@ } } return GENIE_EVENT_NONE; -} - -////////////////////// 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); - return GENIE_EVENT_NONE; -} - -/////////////////////// 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() { - - _genieError = ERROR_NONE; - - return (screen.getc()); -} - -void RxIrqHandler(void) -{ - do - { - genieDoEvents(); - } - while(screen.readable ()); -} - - -void TickerIrq(void) -{ -} - - -void SetupGenie(void) -{ - screen.attach(&RxIrqHandler,Serial::RxIrq); - t.start(); - // EventChk.attach(&TickerIrq,0.05); -} +} \ No newline at end of file