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 18:34:47 2014 +0000
Revision:
10:4d9f1be4a901
Parent:
9:b74deaac80f9
Child:
11:9196f72fc325
Added missing method "genieGetEventData"

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