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);
    }
}
Revision:
2:f283764fe9b7
Parent:
1:95e0e194a412
Child:
3:11c49c49cd1a
--- 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