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);
    }
}
Committer:
chris215
Date:
Tue Jul 08 15:52:26 2014 +0000
Revision:
9:b74deaac80f9
Parent:
8:b5ba0df2d0db
Child:
10:4d9f1be4a901
Improved stability. Improved communication errors handling.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
chris215 0:d2ed5a44c802 1 #include "mbed.h"
chris215 0:d2ed5a44c802 2 #include "mbed_genie.h"
chris215 0:d2ed5a44c802 3
chris215 3:11c49c49cd1a 4 Mbed4dGenie::Mbed4dGenie(PinName TxPin,PinName RxPin, PinName resetpin) : _screen(TxPin,RxPin) , _reset(resetpin)
chris215 2:f283764fe9b7 5 {
chris215 3:11c49c49cd1a 6 //reset the 4d screen
chris215 3:11c49c49cd1a 7 _reset = 0;
chris215 6:f4d3977b0eae 8 _screen.baud(9600);
chris215 7:6edb20845684 9 _genieUserHandler = NULL;
chris215 8:b5ba0df2d0db 10 RxStateTimeoutErrors = 0;
chris215 2:f283764fe9b7 11 }
chris215 6:f4d3977b0eae 12 void Mbed4dGenie::Start()
chris215 6:f4d3977b0eae 13 {
chris215 6:f4d3977b0eae 14 _reset = 1;
chris215 7:6edb20845684 15 wait(3.0); //4D datasheet says that the screen can take up to 3000 ms before
chris215 7:6edb20845684 16 //becomming responsive to serial commands.
chris215 7:6edb20845684 17 _t.start();
chris215 7:6edb20845684 18 Reset();
chris215 7:6edb20845684 19 _genieFlushEventQueue();
chris215 7:6edb20845684 20 _screen.attach(this,&Mbed4dGenie::RxIrqHandler,Serial::RxIrq);
chris215 7:6edb20845684 21 }
chris215 7:6edb20845684 22
chris215 7:6edb20845684 23
chris215 7:6edb20845684 24 void Mbed4dGenie::RxIrqHandler(void)
chris215 7:6edb20845684 25 {
chris215 7:6edb20845684 26 char c;
chris215 7:6edb20845684 27 //Loop to read all byte present in UART FIFO
chris215 7:6edb20845684 28 do
chris215 7:6edb20845684 29 {
chris215 7:6edb20845684 30 c = _screen.getc();
chris215 9:b74deaac80f9 31 if(_t.read_ms() >= RxMaxTimeout && state == CommInProgress)
chris215 9:b74deaac80f9 32 {
chris215 9:b74deaac80f9 33 Reset();
chris215 9:b74deaac80f9 34 }
chris215 7:6edb20845684 35 ManageReceiveData(c);
chris215 7:6edb20845684 36 }
chris215 7:6edb20845684 37 while(_screen.readable());
chris215 7:6edb20845684 38 }
chris215 7:6edb20845684 39
chris215 7:6edb20845684 40 void Mbed4dGenie::ManageReceiveData(char data)
chris215 7:6edb20845684 41 {
chris215 7:6edb20845684 42 switch(state)
chris215 7:6edb20845684 43 {
chris215 7:6edb20845684 44 case CommIdle:
chris215 2:f283764fe9b7 45
chris215 7:6edb20845684 46 if(data == GENIE_ACK || data == GENIE_NAK)
chris215 7:6edb20845684 47 {
chris215 7:6edb20845684 48 LastResponse = data;
chris215 7:6edb20845684 49 }
chris215 7:6edb20845684 50 else if(data == GENIE_REPORT_OBJ || data == GENIE_REPORT_EVENT)
chris215 7:6edb20845684 51 {
chris215 8:b5ba0df2d0db 52 RxMaxTimeout = _t.read_ms() + RESYNC_PERIOD;
chris215 7:6edb20845684 53 checksum = data;
chris215 7:6edb20845684 54 rx_data[rxframe_count++] = data;
chris215 8:b5ba0df2d0db 55 state = CommInProgress;
chris215 7:6edb20845684 56 }
chris215 7:6edb20845684 57 break;
chris215 7:6edb20845684 58
chris215 7:6edb20845684 59
chris215 7:6edb20845684 60 case CommInProgress:
chris215 7:6edb20845684 61 checksum = checksum ^ data;
chris215 7:6edb20845684 62 rx_data[rxframe_count++] = data;
chris215 7:6edb20845684 63
chris215 7:6edb20845684 64 if(rxframe_count >= GENIE_FRAME_SIZE)
chris215 7:6edb20845684 65 {
chris215 7:6edb20845684 66 if (checksum == 0) {
chris215 7:6edb20845684 67 _genieEnqueueEvent(rx_data);
chris215 7:6edb20845684 68 if(_genieUserHandler != NULL)
chris215 7:6edb20845684 69 {
chris215 7:6edb20845684 70 (_genieUserHandler)();
chris215 7:6edb20845684 71 }
chris215 7:6edb20845684 72 }
chris215 7:6edb20845684 73 state = CommIdle;
chris215 7:6edb20845684 74 rxframe_count = 0;
chris215 7:6edb20845684 75 LastResponse = NO_RESPONSE;
chris215 7:6edb20845684 76 }
chris215 7:6edb20845684 77 break;
chris215 7:6edb20845684 78 default:
chris215 7:6edb20845684 79 state = CommIdle;
chris215 7:6edb20845684 80 rxframe_count = 0;
chris215 7:6edb20845684 81 LastResponse = NO_RESPONSE;
chris215 7:6edb20845684 82 break;
chris215 7:6edb20845684 83 }
chris215 2:f283764fe9b7 84 }
chris215 2:f283764fe9b7 85
chris215 7:6edb20845684 86
chris215 2:f283764fe9b7 87 ///////////////////////// genieWriteObject //////////////////////
chris215 0:d2ed5a44c802 88 //
chris215 2:f283764fe9b7 89 // Write data to an object on the display
chris215 0:d2ed5a44c802 90 //
chris215 6:f4d3977b0eae 91 int8_t Mbed4dGenie::genieWriteObject (uint16_t object, uint16_t index, uint16_t data)
chris215 2:f283764fe9b7 92 {
chris215 6:f4d3977b0eae 93 uint16_t msb, lsb ;
chris215 6:f4d3977b0eae 94 uint8_t checksum ;
chris215 6:f4d3977b0eae 95
chris215 7:6edb20845684 96 //wait for interface to be ready before sending stuff
chris215 7:6edb20845684 97 if(WaitForIdle())
chris215 7:6edb20845684 98 return ERROR_RESYNC;
chris215 7:6edb20845684 99
chris215 6:f4d3977b0eae 100 lsb = data&0xFF;
chris215 6:f4d3977b0eae 101 msb = (data>>8) & 0xFF;
chris215 6:f4d3977b0eae 102
chris215 6:f4d3977b0eae 103 _screen.putc(GENIE_WRITE_OBJ) ;
chris215 6:f4d3977b0eae 104 checksum = GENIE_WRITE_OBJ ;
chris215 6:f4d3977b0eae 105 _screen.putc(object) ;
chris215 6:f4d3977b0eae 106 checksum ^= object ;
chris215 6:f4d3977b0eae 107 _screen.putc(index) ;
chris215 6:f4d3977b0eae 108 checksum ^= index ;
chris215 6:f4d3977b0eae 109 _screen.putc(msb) ;
chris215 6:f4d3977b0eae 110 checksum ^= msb;
chris215 6:f4d3977b0eae 111 _screen.putc(lsb) ;
chris215 6:f4d3977b0eae 112 checksum ^= lsb;
chris215 6:f4d3977b0eae 113 _screen.putc(checksum) ;
chris215 6:f4d3977b0eae 114
chris215 7:6edb20845684 115 return Mbed4dGenie::WaitForAnswer();
chris215 7:6edb20845684 116 }
chris215 7:6edb20845684 117 int8_t Mbed4dGenie::genieWriteStr (uint16_t index, char *string)
chris215 7:6edb20845684 118 {
chris215 7:6edb20845684 119 char *p ;
chris215 7:6edb20845684 120 unsigned int checksum ;
chris215 7:6edb20845684 121 int len = strlen (string) ;
chris215 7:6edb20845684 122
chris215 7:6edb20845684 123
chris215 7:6edb20845684 124 if (len > 255)
chris215 7:6edb20845684 125 return -1 ;
chris215 7:6edb20845684 126
chris215 7:6edb20845684 127
chris215 7:6edb20845684 128 //wait for interface to be ready before sending stuff
chris215 7:6edb20845684 129 if(WaitForIdle())
chris215 7:6edb20845684 130 return ERROR_RESYNC;
chris215 7:6edb20845684 131
chris215 7:6edb20845684 132
chris215 7:6edb20845684 133 _screen.putc(GENIE_WRITE_STR) ; checksum = GENIE_WRITE_STR ;
chris215 7:6edb20845684 134 _screen.putc(index) ; checksum ^= index ;
chris215 7:6edb20845684 135 _screen.putc((unsigned char)len) ; checksum ^= len ;
chris215 7:6edb20845684 136 for (p = string ; *p ; ++p) {
chris215 7:6edb20845684 137 _screen.putc (*p) ;
chris215 7:6edb20845684 138 checksum ^= *p ;
chris215 7:6edb20845684 139 }
chris215 7:6edb20845684 140 _screen.putc(checksum) ;
chris215 2:f283764fe9b7 141
chris215 7:6edb20845684 142 return Mbed4dGenie::WaitForAnswer();
chris215 7:6edb20845684 143 }
chris215 7:6edb20845684 144 int8_t Mbed4dGenie::genieReadObj (uint16_t object, uint16_t index)
chris215 7:6edb20845684 145 {
chris215 7:6edb20845684 146 //wait for interface to be ready before sending stuff
chris215 7:6edb20845684 147 if(WaitForIdle())
chris215 7:6edb20845684 148 return ERROR_RESYNC;
chris215 7:6edb20845684 149 unsigned int checksum ;
chris215 7:6edb20845684 150
chris215 7:6edb20845684 151 _screen.putc(GENIE_READ_OBJ) ; checksum = GENIE_READ_OBJ ;
chris215 7:6edb20845684 152 _screen.putc(object) ; checksum ^= object ;
chris215 7:6edb20845684 153 _screen.putc(index) ; checksum ^= index ;
chris215 7:6edb20845684 154 _screen.putc(checksum) ;
chris215 7:6edb20845684 155
chris215 8:b5ba0df2d0db 156 //Here we dont wiat for a typical answer
chris215 8:b5ba0df2d0db 157 //The screen will respond with an NACK if the command was not understood, otherwise it will send a report object frame
chris215 9:b74deaac80f9 158 return 0;//WaitForReadAnswer();
chris215 0:d2ed5a44c802 159 }
chris215 7:6edb20845684 160 void Mbed4dGenie::writec(char data)
chris215 7:6edb20845684 161 {
chris215 7:6edb20845684 162 _screen.putc(data);
chris215 7:6edb20845684 163 }
chris215 7:6edb20845684 164 bool Mbed4dGenie::WaitForIdle()
chris215 7:6edb20845684 165 {
chris215 8:b5ba0df2d0db 166 if(state != CommIdle)
chris215 8:b5ba0df2d0db 167 {
chris215 8:b5ba0df2d0db 168 long timeout = _t.read_ms() + TIMEOUT_PERIOD;
chris215 8:b5ba0df2d0db 169 long timerReading = 0;
chris215 8:b5ba0df2d0db 170 if(_t.read_ms() >= RxMaxTimeout)
chris215 8:b5ba0df2d0db 171 {
chris215 8:b5ba0df2d0db 172 Reset();
chris215 8:b5ba0df2d0db 173 RxStateTimeoutErrors++;
chris215 8:b5ba0df2d0db 174 }
chris215 8:b5ba0df2d0db 175 while(timerReading < timeout && state != CommIdle)
chris215 8:b5ba0df2d0db 176 {
chris215 8:b5ba0df2d0db 177 timerReading = _t.read_ms();
chris215 8:b5ba0df2d0db 178 }
chris215 8:b5ba0df2d0db 179 LastResponse = 0;
chris215 8:b5ba0df2d0db 180 return (timerReading >= timeout);
chris215 8:b5ba0df2d0db 181 }
chris215 8:b5ba0df2d0db 182
chris215 8:b5ba0df2d0db 183 return false;
chris215 8:b5ba0df2d0db 184 }
chris215 8:b5ba0df2d0db 185
chris215 8:b5ba0df2d0db 186 int8_t Mbed4dGenie::WaitForReadAnswer()
chris215 8:b5ba0df2d0db 187 {
chris215 7:6edb20845684 188 long timeout = _t.read_ms() + TIMEOUT_PERIOD;
chris215 7:6edb20845684 189 long timerReading = 0;
chris215 8:b5ba0df2d0db 190 while(state == CommIdle && LastResponse != ERROR_NAK && timerReading < timeout)
chris215 7:6edb20845684 191 {
chris215 7:6edb20845684 192 timerReading = _t.read_ms();
chris215 7:6edb20845684 193 }
chris215 8:b5ba0df2d0db 194 if(LastResponse == ERROR_NAK)//check if the screen returned a NACK
chris215 8:b5ba0df2d0db 195 {
chris215 8:b5ba0df2d0db 196 LastResponse = NO_RESPONSE;
chris215 8:b5ba0df2d0db 197 return ERROR_NAK;
chris215 8:b5ba0df2d0db 198 }
chris215 9:b74deaac80f9 199 else if(_t.read_ms() >= timeout) //check if we timed out while waiting for response
chris215 8:b5ba0df2d0db 200 {
chris215 9:b74deaac80f9 201
chris215 8:b5ba0df2d0db 202 LastResponse = NO_RESPONSE;
chris215 8:b5ba0df2d0db 203 return ERROR_TIMEOUT;
chris215 8:b5ba0df2d0db 204 }
chris215 8:b5ba0df2d0db 205 //if we get here it means we didnt timeout and the screen did accept the command
chris215 8:b5ba0df2d0db 206 LastResponse = NO_RESPONSE;
chris215 8:b5ba0df2d0db 207 return ERROR_NONE;
chris215 7:6edb20845684 208 }
chris215 0:d2ed5a44c802 209
chris215 6:f4d3977b0eae 210 int8_t Mbed4dGenie::WaitForAnswer()
chris215 6:f4d3977b0eae 211 {
chris215 0:d2ed5a44c802 212
chris215 6:f4d3977b0eae 213 long timeout = _t.read_ms() + TIMEOUT_PERIOD;
chris215 6:f4d3977b0eae 214 long timerReading = 0;
chris215 7:6edb20845684 215 while(LastResponse != GENIE_ACK && LastResponse != ERROR_NAK && timerReading < timeout)
chris215 6:f4d3977b0eae 216 {
chris215 6:f4d3977b0eae 217 timerReading = _t.read_ms();
chris215 6:f4d3977b0eae 218 }
chris215 6:f4d3977b0eae 219
chris215 7:6edb20845684 220 if(LastResponse == ERROR_NAK)
chris215 6:f4d3977b0eae 221 {
chris215 8:b5ba0df2d0db 222 LastResponse = NO_RESPONSE;
chris215 8:b5ba0df2d0db 223 return ERROR_NAK;
chris215 6:f4d3977b0eae 224 }
chris215 9:b74deaac80f9 225 else if(_t.read_ms() >= timeout)
chris215 6:f4d3977b0eae 226 {
chris215 9:b74deaac80f9 227 printf("Current timer:%d ; timeout:%d\n\r",_t.read_ms(),timeout);
chris215 8:b5ba0df2d0db 228 LastResponse = NO_RESPONSE;
chris215 6:f4d3977b0eae 229 return ERROR_TIMEOUT;
chris215 6:f4d3977b0eae 230 }
chris215 8:b5ba0df2d0db 231 LastResponse = NO_RESPONSE;
chris215 6:f4d3977b0eae 232 return ERROR_NONE;
chris215 7:6edb20845684 233 }
chris215 7:6edb20845684 234
chris215 7:6edb20845684 235 void Mbed4dGenie::Reset(void)
chris215 7:6edb20845684 236 {
chris215 7:6edb20845684 237 LastResponse = NO_RESPONSE;
chris215 7:6edb20845684 238 state = CommIdle;
chris215 7:6edb20845684 239 while(_screen.readable())
chris215 7:6edb20845684 240 _screen.getc();
chris215 7:6edb20845684 241 }
chris215 7:6edb20845684 242
chris215 7:6edb20845684 243 ////////////////////// _genieFlushEventQueue ////////////////////
chris215 7:6edb20845684 244 //
chris215 7:6edb20845684 245 // Reset all the event queue variables and start from scratch.
chris215 7:6edb20845684 246 //
chris215 7:6edb20845684 247 void Mbed4dGenie::_genieFlushEventQueue(void) {
chris215 7:6edb20845684 248 _genieEventQueue.rd_index = 0;
chris215 7:6edb20845684 249 _genieEventQueue.wr_index = 0;
chris215 7:6edb20845684 250 _genieEventQueue.n_events = 0;
chris215 7:6edb20845684 251 }
chris215 7:6edb20845684 252
chris215 7:6edb20845684 253 ////////////////////// _genieEnqueueEvent ///////////////////
chris215 7:6edb20845684 254 //
chris215 7:6edb20845684 255 // Copy the bytes from a buffer supplied by the caller
chris215 7:6edb20845684 256 // to the input queue
chris215 7:6edb20845684 257 //
chris215 7:6edb20845684 258 // Parms: uint8_t * data, a pointer to the user's data
chris215 7:6edb20845684 259 //
chris215 7:6edb20845684 260 // Returns: TRUE if there was an empty location in the queue
chris215 7:6edb20845684 261 // to copy the data into
chris215 7:6edb20845684 262 // FALSE if not
chris215 7:6edb20845684 263 // Sets: ERROR_REPLY_OVR if there was no room in the queue
chris215 7:6edb20845684 264 //
chris215 7:6edb20845684 265 bool Mbed4dGenie::_genieEnqueueEvent (uint8_t * data) {
chris215 7:6edb20845684 266
chris215 7:6edb20845684 267
chris215 7:6edb20845684 268 if (_genieEventQueue.n_events < MAX_GENIE_EVENTS-2) {
chris215 7:6edb20845684 269 memcpy (&_genieEventQueue.frames[_genieEventQueue.wr_index], data,
chris215 7:6edb20845684 270 GENIE_FRAME_SIZE);
chris215 7:6edb20845684 271 _genieEventQueue.wr_index++;
chris215 7:6edb20845684 272 _genieEventQueue.wr_index &= MAX_GENIE_EVENTS -1;
chris215 7:6edb20845684 273 _genieEventQueue.n_events++;
chris215 7:6edb20845684 274 return TRUE;
chris215 7:6edb20845684 275 } else {
chris215 7:6edb20845684 276 return FALSE;
chris215 7:6edb20845684 277 }
chris215 7:6edb20845684 278 }
chris215 7:6edb20845684 279 ////////////////////// genieDequeueEvent ///////////////////
chris215 7:6edb20845684 280 //
chris215 7:6edb20845684 281 // Copy the bytes from a queued input event to a buffer supplied
chris215 7:6edb20845684 282 // by the caller.
chris215 7:6edb20845684 283 //
chris215 7:6edb20845684 284 // Parms: genieFrame * buff, a pointer to the user's buffer
chris215 7:6edb20845684 285 //
chris215 7:6edb20845684 286 // Returns: TRUE if there was an event to copy
chris215 7:6edb20845684 287 // FALSE if not
chris215 7:6edb20845684 288 //
chris215 7:6edb20845684 289 bool Mbed4dGenie::genieDequeueEvent(genieFrame * buff) {
chris215 7:6edb20845684 290
chris215 7:6edb20845684 291
chris215 7:6edb20845684 292 if (_genieEventQueue.n_events > 0) {
chris215 7:6edb20845684 293 memcpy (buff, &_genieEventQueue.frames[_genieEventQueue.rd_index],
chris215 7:6edb20845684 294 GENIE_FRAME_SIZE);
chris215 7:6edb20845684 295 _genieEventQueue.rd_index++;
chris215 7:6edb20845684 296 _genieEventQueue.rd_index &= MAX_GENIE_EVENTS -1;
chris215 7:6edb20845684 297 _genieEventQueue.n_events--;
chris215 7:6edb20845684 298 return TRUE;
chris215 7:6edb20845684 299 }
chris215 7:6edb20845684 300 return FALSE;
chris215 7:6edb20845684 301 }
chris215 7:6edb20845684 302 void Mbed4dGenie::genieAttachEventHandler(genieUserEventHandlerPtr handler)
chris215 7:6edb20845684 303 {
chris215 7:6edb20845684 304 _genieUserHandler = handler;
chris215 7:6edb20845684 305 }
chris215 7:6edb20845684 306 bool Mbed4dGenie::PendingFrames(void)
chris215 7:6edb20845684 307 {
chris215 7:6edb20845684 308 return (_genieEventQueue.n_events>0);
chris215 2:f283764fe9b7 309 }