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:
11:9196f72fc325
Parent:
10:4d9f1be4a901
--- a/mbed_genie.cpp	Tue Jul 08 18:34:47 2014 +0000
+++ b/mbed_genie.cpp	Wed Mar 04 03:00:40 2015 +0000
@@ -9,17 +9,27 @@
     _genieUserHandler = NULL;
     RxStateTimeoutErrors = 0;
 }
+Mbed4dGenie::Mbed4dGenie(PinName TxPin,PinName RxPin, PinName resetpin,uint32_t baud) : _screen(TxPin,RxPin) , _reset(resetpin)
+{
+     //reset the 4d screen
+    _reset = 0;
+    _screen.baud(baud);
+    _genieUserHandler = NULL;
+    RxStateTimeoutErrors = 0;
+}
 void Mbed4dGenie::Start()
 {
     _reset = 1;
     wait(3.0);  //4D datasheet says that the screen can take up to 3000 ms before
                 //becomming responsive to serial commands.        
-    _t.start();
+    _waitTimer.start();
+    _receptionTimer.start();
     Reset();
     _genieFlushEventQueue();
     _screen.attach(this,&Mbed4dGenie::RxIrqHandler,Serial::RxIrq);
 }
 
+
 ////////////////////// genieGetEventData ////////////////////////
 //
 // Returns the LSB and MSB of the event's data combined into
@@ -40,8 +50,15 @@
     do
     {
         c = _screen.getc();
-        if(_t.read_ms() >= RxMaxTimeout && state == CommInProgress)
+        /*
+            check if we are in reception mode and if we timeout
+        */
+        if(_receptionTimer.read_ms() >= RxMaxTimeout && state == CommInProgress)
         {
+            /*
+                if we get here, it means something bad has happened and 
+                we need to reet communication status
+            */
             Reset();
         }
         ManageReceiveData(c);
@@ -61,7 +78,9 @@
             }   
             else if(data == GENIE_REPORT_OBJ || data == GENIE_REPORT_EVENT)
             {
-                RxMaxTimeout = _t.read_ms() + RESYNC_PERIOD;
+                //re-initialise the reception timer
+                _receptionTimer.reset();
+                RxMaxTimeout = _receptionTimer.read_ms() + RESYNC_PERIOD;
                 checksum = data;
                 rx_data[rxframe_count++] = data;
                 state = CommInProgress;              
@@ -175,18 +194,22 @@
 }
 bool Mbed4dGenie::WaitForIdle()
 {
+    /*
+        If the communication is still in progress
+        lets wait for it to finish or check/wait for timeout
+    */
     if(state != CommIdle)
     {
-        long timeout = _t.read_ms() + TIMEOUT_PERIOD;
+        long timeout = _receptionTimer.read_ms() + TIMEOUT_PERIOD;
         long timerReading = 0;
-        if(_t.read_ms() >= RxMaxTimeout)
+        if(_receptionTimer.read_ms() >= RxMaxTimeout)
         {
             Reset();
             RxStateTimeoutErrors++;
         }
         while(timerReading < timeout && state != CommIdle)
         {
-            timerReading = _t.read_ms();
+            timerReading = _receptionTimer.read_ms();
         }
         LastResponse = 0;
         return (timerReading >= timeout);
@@ -195,20 +218,26 @@
     return false;    
 }
 
+/*
+    Not used for now, since the screen will answer with either a report event or NAK
+    Since those two answers are so different, there is no efficient means to receive
+    both in interrupt. No wait to NAK will be done. DONT USE THIS FUNCTION ... YET
+*/
 int8_t Mbed4dGenie::WaitForReadAnswer()
 {
-    long timeout = _t.read_ms() + TIMEOUT_PERIOD;
+    _waitTimer.reset();
+    long timeout = _waitTimer.read_ms() + TIMEOUT_PERIOD;
     long timerReading = 0;
     while(state == CommIdle && LastResponse != ERROR_NAK && timerReading < timeout)
     {
-        timerReading = _t.read_ms();
+        timerReading = _waitTimer.read_ms();
     }
     if(LastResponse == ERROR_NAK)//check if the screen returned a NACK
     {
         LastResponse = NO_RESPONSE;
         return ERROR_NAK;
     }
-    else if(_t.read_ms() >= timeout) //check if we timed out while waiting for response
+    else if(_waitTimer.read_ms() >= timeout) //check if we timed out while waiting for response
     {   
     
         LastResponse = NO_RESPONSE;
@@ -221,12 +250,12 @@
 
 int8_t Mbed4dGenie::WaitForAnswer()
 {
-    
-    long timeout = _t.read_ms() + TIMEOUT_PERIOD;
+    _waitTimer.reset();
+    long timeout = _waitTimer.read_ms() + TIMEOUT_PERIOD;
     long timerReading = 0;
     while(LastResponse != GENIE_ACK && LastResponse != ERROR_NAK && timerReading < timeout)
     {
-        timerReading = _t.read_ms();
+        timerReading = _waitTimer.read_ms();
     }
            
     if(LastResponse == ERROR_NAK)
@@ -234,9 +263,9 @@
         LastResponse = NO_RESPONSE;
         return ERROR_NAK;
     }
-    else if(_t.read_ms() >= timeout)
+    else if(_waitTimer.read_ms() >= timeout)
     {   
-        printf("Current timer:%d ; timeout:%d\n\r",_t.read_ms(),timeout);
+        printf("Current timer:%d ; timeout:%d\n\r",_waitTimer.read_ms(),timeout);
         LastResponse = NO_RESPONSE;
         return ERROR_TIMEOUT;
     }
@@ -248,6 +277,8 @@
 {
     LastResponse = NO_RESPONSE;
     state = CommIdle;
+    _receptionTimer.reset();
+    _waitTimer.reset();
     while(_screen.readable())
         _screen.getc();
 }