4D display working with Gecko board STK3600

Dependents:   Genie_mbed_Gecko

Fork of 4dGENIE by christian b

Revision:
7:6edb20845684
Parent:
6:f4d3977b0eae
Child:
8:b5ba0df2d0db
--- a/mbed_genie.cpp	Fri Jul 04 02:44:49 2014 +0000
+++ b/mbed_genie.cpp	Sat Jul 05 15:11:57 2014 +0000
@@ -6,18 +6,79 @@
     //reset the 4d screen
     _reset = 0;
     _screen.baud(9600);
+    _genieUserHandler = NULL;
 }
 void Mbed4dGenie::Start()
 {
     _reset = 1;
-    wait(0.2);  //wait some time to let the lcd screen intialised itself
-    //empty the uart buffer
-    while(_screen.readable())
-        _screen.getc();
+    wait(3.0);  //4D datasheet says that the screen can take up to 3000 ms before
+                //becomming responsive to serial commands.        
+    _t.start();
+    Reset();
+    _genieFlushEventQueue();
+    _screen.attach(this,&Mbed4dGenie::RxIrqHandler,Serial::RxIrq);
+}
+
+
+void Mbed4dGenie::RxIrqHandler(void)
+{
+    char c;
+    //Loop to read all byte present in UART FIFO
+    do
+    {
+        c = _screen.getc();
+        ManageReceiveData(c);
+    }
+    while(_screen.readable());
+}
+
+void Mbed4dGenie::ManageReceiveData(char data)
+{
+    switch(state)
+    {
+        case CommIdle: 
         
-    _t.start();
+            if(data == GENIE_ACK || data == GENIE_NAK)
+            {
+                LastResponse = data;
+            }   
+            else if(data == GENIE_REPORT_OBJ || data == GENIE_REPORT_EVENT)
+            {
+                checksum = data;
+                rx_data[rxframe_count++] = data;
+                state = CommInProgress; 
+                LastResponse = NO_RESPONSE;             
+            }                     
+            break;
+        
+        
+        case CommInProgress: 
+            checksum = checksum ^ data;
+            rx_data[rxframe_count++] = data;
+            
+            if(rxframe_count >= GENIE_FRAME_SIZE)
+            {
+                if (checksum == 0) {
+                        _genieEnqueueEvent(rx_data); 
+                        if(_genieUserHandler != NULL)
+                        {
+                            (_genieUserHandler)();
+                        }
+                    } 
+                state = CommIdle;
+                rxframe_count = 0;
+                LastResponse = NO_RESPONSE;
+            }        
+            break;
+        default:
+            state = CommIdle;
+            rxframe_count = 0;
+            LastResponse = NO_RESPONSE;
+            break;
+    }
 }
 
+
 ///////////////////////// genieWriteObject //////////////////////
 //
 // Write data to an object on the display
@@ -27,6 +88,10 @@
     uint16_t msb, lsb ;
     uint8_t checksum ;
     
+    //wait for interface to be ready before sending stuff
+    if(WaitForIdle())
+        return ERROR_RESYNC;
+
     lsb = data&0xFF;
     msb = (data>>8) & 0xFF;
     
@@ -42,32 +107,159 @@
     checksum ^= lsb;
     _screen.putc(checksum) ;
     
-       
+     return Mbed4dGenie::WaitForAnswer();    
+}
+int8_t Mbed4dGenie::genieWriteStr (uint16_t index, char *string)
+{
+        char *p ;
+        unsigned int checksum ;
+        int len = strlen (string) ;
+
+
+        if (len > 255)
+        return -1 ;
+
+
+        //wait for interface to be ready before sending stuff
+        if(WaitForIdle())
+            return ERROR_RESYNC;
+
+
+        _screen.putc(GENIE_WRITE_STR) ;               checksum  = GENIE_WRITE_STR ;
+        _screen.putc(index) ;              checksum ^= index ;
+        _screen.putc((unsigned char)len) ; checksum ^= len ;
+        for (p = string ; *p ; ++p)        {
+                _screen.putc (*p) ;
+                checksum ^= *p ;
+        }
+        _screen.putc(checksum) ;
 
-     return  Mbed4dGenie::WaitForAnswer();    
+        return  Mbed4dGenie::WaitForAnswer();
+}
+int8_t  Mbed4dGenie::genieReadObj (uint16_t object, uint16_t index)
+{
+    //wait for interface to be ready before sending stuff
+    if(WaitForIdle())
+        return ERROR_RESYNC;
+    unsigned int checksum ;
+    
+    _screen.putc(GENIE_READ_OBJ) ;     checksum  = GENIE_READ_OBJ ;
+    _screen.putc(object) ;             checksum ^= object ;   
+    _screen.putc(index) ;              checksum ^= index ; 
+    _screen.putc(checksum) ;
+        
+    return  0;//Mbed4dGenie::WaitForAnswer();
 }
-
+void Mbed4dGenie::writec(char data)
+{
+    _screen.putc(data);
+}
+bool Mbed4dGenie::WaitForIdle()
+{
+    long timeout = _t.read_ms() + TIMEOUT_PERIOD;
+    long timerReading = 0;
+    
+    while(timerReading < timeout && state != CommIdle)
+    {
+        timerReading = _t.read_ms();
+    }
+    LastResponse = 0;
+    return (timerReading >= timeout);
+}
 
 int8_t Mbed4dGenie::WaitForAnswer()
 {
-    int8_t operation_result = 0; 
     
     long timeout = _t.read_ms() + TIMEOUT_PERIOD;
     long timerReading = 0;
-    while(operation_result != GENIE_ACK && operation_result != ERROR_NAK && timerReading < timeout)
+    while(LastResponse != GENIE_ACK && LastResponse != ERROR_NAK && timerReading < timeout)
     {
-        if(_screen.readable())
-            operation_result = _screen.getc();
         timerReading = _t.read_ms();
     }
            
-    if(operation_result == ERROR_NAK)
+    if(LastResponse == ERROR_NAK)
     {
         return ERROR_NONE;
     }
-    else if(timerReading >= timeout)
+    else if(LastResponse >= timeout)
     {   
         return ERROR_TIMEOUT;
     }
     return ERROR_NONE;
+}
+
+void Mbed4dGenie::Reset(void)
+{
+    LastResponse = NO_RESPONSE;
+    state = CommIdle;
+    while(_screen.readable())
+        _screen.getc();
+}
+
+////////////////////// _genieFlushEventQueue ////////////////////
+//
+// Reset all the event queue variables and start from scratch.
+//
+void Mbed4dGenie::_genieFlushEventQueue(void) {
+        _genieEventQueue.rd_index = 0;
+        _genieEventQueue.wr_index = 0;
+        _genieEventQueue.n_events = 0;
+}
+
+////////////////////// _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 Mbed4dGenie::_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 {
+                return FALSE;
+        }
+}
+////////////////////// 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 Mbed4dGenie::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;
+}
+void Mbed4dGenie::genieAttachEventHandler(genieUserEventHandlerPtr handler)
+{
+    _genieUserHandler = handler;
+}
+bool Mbed4dGenie::PendingFrames(void)
+{
+    return (_genieEventQueue.n_events>0);
 }
\ No newline at end of file