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:
Sat Jul 05 15:11:57 2014 +0000
Revision:
7:6edb20845684
Parent:
6:f4d3977b0eae
Child:
8:b5ba0df2d0db
Restored rx by interrupt feature. Added following features : read_obj, write_str, userHandler callback when frame is received. Ran stable for 12 hours.

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 2:f283764fe9b7 10 }
chris215 6:f4d3977b0eae 11 void Mbed4dGenie::Start()
chris215 6:f4d3977b0eae 12 {
chris215 6:f4d3977b0eae 13 _reset = 1;
chris215 7:6edb20845684 14 wait(3.0); //4D datasheet says that the screen can take up to 3000 ms before
chris215 7:6edb20845684 15 //becomming responsive to serial commands.
chris215 7:6edb20845684 16 _t.start();
chris215 7:6edb20845684 17 Reset();
chris215 7:6edb20845684 18 _genieFlushEventQueue();
chris215 7:6edb20845684 19 _screen.attach(this,&Mbed4dGenie::RxIrqHandler,Serial::RxIrq);
chris215 7:6edb20845684 20 }
chris215 7:6edb20845684 21
chris215 7:6edb20845684 22
chris215 7:6edb20845684 23 void Mbed4dGenie::RxIrqHandler(void)
chris215 7:6edb20845684 24 {
chris215 7:6edb20845684 25 char c;
chris215 7:6edb20845684 26 //Loop to read all byte present in UART FIFO
chris215 7:6edb20845684 27 do
chris215 7:6edb20845684 28 {
chris215 7:6edb20845684 29 c = _screen.getc();
chris215 7:6edb20845684 30 ManageReceiveData(c);
chris215 7:6edb20845684 31 }
chris215 7:6edb20845684 32 while(_screen.readable());
chris215 7:6edb20845684 33 }
chris215 7:6edb20845684 34
chris215 7:6edb20845684 35 void Mbed4dGenie::ManageReceiveData(char data)
chris215 7:6edb20845684 36 {
chris215 7:6edb20845684 37 switch(state)
chris215 7:6edb20845684 38 {
chris215 7:6edb20845684 39 case CommIdle:
chris215 2:f283764fe9b7 40
chris215 7:6edb20845684 41 if(data == GENIE_ACK || data == GENIE_NAK)
chris215 7:6edb20845684 42 {
chris215 7:6edb20845684 43 LastResponse = data;
chris215 7:6edb20845684 44 }
chris215 7:6edb20845684 45 else if(data == GENIE_REPORT_OBJ || data == GENIE_REPORT_EVENT)
chris215 7:6edb20845684 46 {
chris215 7:6edb20845684 47 checksum = data;
chris215 7:6edb20845684 48 rx_data[rxframe_count++] = data;
chris215 7:6edb20845684 49 state = CommInProgress;
chris215 7:6edb20845684 50 LastResponse = NO_RESPONSE;
chris215 7:6edb20845684 51 }
chris215 7:6edb20845684 52 break;
chris215 7:6edb20845684 53
chris215 7:6edb20845684 54
chris215 7:6edb20845684 55 case CommInProgress:
chris215 7:6edb20845684 56 checksum = checksum ^ data;
chris215 7:6edb20845684 57 rx_data[rxframe_count++] = data;
chris215 7:6edb20845684 58
chris215 7:6edb20845684 59 if(rxframe_count >= GENIE_FRAME_SIZE)
chris215 7:6edb20845684 60 {
chris215 7:6edb20845684 61 if (checksum == 0) {
chris215 7:6edb20845684 62 _genieEnqueueEvent(rx_data);
chris215 7:6edb20845684 63 if(_genieUserHandler != NULL)
chris215 7:6edb20845684 64 {
chris215 7:6edb20845684 65 (_genieUserHandler)();
chris215 7:6edb20845684 66 }
chris215 7:6edb20845684 67 }
chris215 7:6edb20845684 68 state = CommIdle;
chris215 7:6edb20845684 69 rxframe_count = 0;
chris215 7:6edb20845684 70 LastResponse = NO_RESPONSE;
chris215 7:6edb20845684 71 }
chris215 7:6edb20845684 72 break;
chris215 7:6edb20845684 73 default:
chris215 7:6edb20845684 74 state = CommIdle;
chris215 7:6edb20845684 75 rxframe_count = 0;
chris215 7:6edb20845684 76 LastResponse = NO_RESPONSE;
chris215 7:6edb20845684 77 break;
chris215 7:6edb20845684 78 }
chris215 2:f283764fe9b7 79 }
chris215 2:f283764fe9b7 80
chris215 7:6edb20845684 81
chris215 2:f283764fe9b7 82 ///////////////////////// genieWriteObject //////////////////////
chris215 0:d2ed5a44c802 83 //
chris215 2:f283764fe9b7 84 // Write data to an object on the display
chris215 0:d2ed5a44c802 85 //
chris215 6:f4d3977b0eae 86 int8_t Mbed4dGenie::genieWriteObject (uint16_t object, uint16_t index, uint16_t data)
chris215 2:f283764fe9b7 87 {
chris215 6:f4d3977b0eae 88 uint16_t msb, lsb ;
chris215 6:f4d3977b0eae 89 uint8_t checksum ;
chris215 6:f4d3977b0eae 90
chris215 7:6edb20845684 91 //wait for interface to be ready before sending stuff
chris215 7:6edb20845684 92 if(WaitForIdle())
chris215 7:6edb20845684 93 return ERROR_RESYNC;
chris215 7:6edb20845684 94
chris215 6:f4d3977b0eae 95 lsb = data&0xFF;
chris215 6:f4d3977b0eae 96 msb = (data>>8) & 0xFF;
chris215 6:f4d3977b0eae 97
chris215 6:f4d3977b0eae 98 _screen.putc(GENIE_WRITE_OBJ) ;
chris215 6:f4d3977b0eae 99 checksum = GENIE_WRITE_OBJ ;
chris215 6:f4d3977b0eae 100 _screen.putc(object) ;
chris215 6:f4d3977b0eae 101 checksum ^= object ;
chris215 6:f4d3977b0eae 102 _screen.putc(index) ;
chris215 6:f4d3977b0eae 103 checksum ^= index ;
chris215 6:f4d3977b0eae 104 _screen.putc(msb) ;
chris215 6:f4d3977b0eae 105 checksum ^= msb;
chris215 6:f4d3977b0eae 106 _screen.putc(lsb) ;
chris215 6:f4d3977b0eae 107 checksum ^= lsb;
chris215 6:f4d3977b0eae 108 _screen.putc(checksum) ;
chris215 6:f4d3977b0eae 109
chris215 7:6edb20845684 110 return Mbed4dGenie::WaitForAnswer();
chris215 7:6edb20845684 111 }
chris215 7:6edb20845684 112 int8_t Mbed4dGenie::genieWriteStr (uint16_t index, char *string)
chris215 7:6edb20845684 113 {
chris215 7:6edb20845684 114 char *p ;
chris215 7:6edb20845684 115 unsigned int checksum ;
chris215 7:6edb20845684 116 int len = strlen (string) ;
chris215 7:6edb20845684 117
chris215 7:6edb20845684 118
chris215 7:6edb20845684 119 if (len > 255)
chris215 7:6edb20845684 120 return -1 ;
chris215 7:6edb20845684 121
chris215 7:6edb20845684 122
chris215 7:6edb20845684 123 //wait for interface to be ready before sending stuff
chris215 7:6edb20845684 124 if(WaitForIdle())
chris215 7:6edb20845684 125 return ERROR_RESYNC;
chris215 7:6edb20845684 126
chris215 7:6edb20845684 127
chris215 7:6edb20845684 128 _screen.putc(GENIE_WRITE_STR) ; checksum = GENIE_WRITE_STR ;
chris215 7:6edb20845684 129 _screen.putc(index) ; checksum ^= index ;
chris215 7:6edb20845684 130 _screen.putc((unsigned char)len) ; checksum ^= len ;
chris215 7:6edb20845684 131 for (p = string ; *p ; ++p) {
chris215 7:6edb20845684 132 _screen.putc (*p) ;
chris215 7:6edb20845684 133 checksum ^= *p ;
chris215 7:6edb20845684 134 }
chris215 7:6edb20845684 135 _screen.putc(checksum) ;
chris215 2:f283764fe9b7 136
chris215 7:6edb20845684 137 return Mbed4dGenie::WaitForAnswer();
chris215 7:6edb20845684 138 }
chris215 7:6edb20845684 139 int8_t Mbed4dGenie::genieReadObj (uint16_t object, uint16_t index)
chris215 7:6edb20845684 140 {
chris215 7:6edb20845684 141 //wait for interface to be ready before sending stuff
chris215 7:6edb20845684 142 if(WaitForIdle())
chris215 7:6edb20845684 143 return ERROR_RESYNC;
chris215 7:6edb20845684 144 unsigned int checksum ;
chris215 7:6edb20845684 145
chris215 7:6edb20845684 146 _screen.putc(GENIE_READ_OBJ) ; checksum = GENIE_READ_OBJ ;
chris215 7:6edb20845684 147 _screen.putc(object) ; checksum ^= object ;
chris215 7:6edb20845684 148 _screen.putc(index) ; checksum ^= index ;
chris215 7:6edb20845684 149 _screen.putc(checksum) ;
chris215 7:6edb20845684 150
chris215 7:6edb20845684 151 return 0;//Mbed4dGenie::WaitForAnswer();
chris215 0:d2ed5a44c802 152 }
chris215 7:6edb20845684 153 void Mbed4dGenie::writec(char data)
chris215 7:6edb20845684 154 {
chris215 7:6edb20845684 155 _screen.putc(data);
chris215 7:6edb20845684 156 }
chris215 7:6edb20845684 157 bool Mbed4dGenie::WaitForIdle()
chris215 7:6edb20845684 158 {
chris215 7:6edb20845684 159 long timeout = _t.read_ms() + TIMEOUT_PERIOD;
chris215 7:6edb20845684 160 long timerReading = 0;
chris215 7:6edb20845684 161
chris215 7:6edb20845684 162 while(timerReading < timeout && state != CommIdle)
chris215 7:6edb20845684 163 {
chris215 7:6edb20845684 164 timerReading = _t.read_ms();
chris215 7:6edb20845684 165 }
chris215 7:6edb20845684 166 LastResponse = 0;
chris215 7:6edb20845684 167 return (timerReading >= timeout);
chris215 7:6edb20845684 168 }
chris215 0:d2ed5a44c802 169
chris215 6:f4d3977b0eae 170 int8_t Mbed4dGenie::WaitForAnswer()
chris215 6:f4d3977b0eae 171 {
chris215 0:d2ed5a44c802 172
chris215 6:f4d3977b0eae 173 long timeout = _t.read_ms() + TIMEOUT_PERIOD;
chris215 6:f4d3977b0eae 174 long timerReading = 0;
chris215 7:6edb20845684 175 while(LastResponse != GENIE_ACK && LastResponse != ERROR_NAK && timerReading < timeout)
chris215 6:f4d3977b0eae 176 {
chris215 6:f4d3977b0eae 177 timerReading = _t.read_ms();
chris215 6:f4d3977b0eae 178 }
chris215 6:f4d3977b0eae 179
chris215 7:6edb20845684 180 if(LastResponse == ERROR_NAK)
chris215 6:f4d3977b0eae 181 {
chris215 6:f4d3977b0eae 182 return ERROR_NONE;
chris215 6:f4d3977b0eae 183 }
chris215 7:6edb20845684 184 else if(LastResponse >= timeout)
chris215 6:f4d3977b0eae 185 {
chris215 6:f4d3977b0eae 186 return ERROR_TIMEOUT;
chris215 6:f4d3977b0eae 187 }
chris215 6:f4d3977b0eae 188 return ERROR_NONE;
chris215 7:6edb20845684 189 }
chris215 7:6edb20845684 190
chris215 7:6edb20845684 191 void Mbed4dGenie::Reset(void)
chris215 7:6edb20845684 192 {
chris215 7:6edb20845684 193 LastResponse = NO_RESPONSE;
chris215 7:6edb20845684 194 state = CommIdle;
chris215 7:6edb20845684 195 while(_screen.readable())
chris215 7:6edb20845684 196 _screen.getc();
chris215 7:6edb20845684 197 }
chris215 7:6edb20845684 198
chris215 7:6edb20845684 199 ////////////////////// _genieFlushEventQueue ////////////////////
chris215 7:6edb20845684 200 //
chris215 7:6edb20845684 201 // Reset all the event queue variables and start from scratch.
chris215 7:6edb20845684 202 //
chris215 7:6edb20845684 203 void Mbed4dGenie::_genieFlushEventQueue(void) {
chris215 7:6edb20845684 204 _genieEventQueue.rd_index = 0;
chris215 7:6edb20845684 205 _genieEventQueue.wr_index = 0;
chris215 7:6edb20845684 206 _genieEventQueue.n_events = 0;
chris215 7:6edb20845684 207 }
chris215 7:6edb20845684 208
chris215 7:6edb20845684 209 ////////////////////// _genieEnqueueEvent ///////////////////
chris215 7:6edb20845684 210 //
chris215 7:6edb20845684 211 // Copy the bytes from a buffer supplied by the caller
chris215 7:6edb20845684 212 // to the input queue
chris215 7:6edb20845684 213 //
chris215 7:6edb20845684 214 // Parms: uint8_t * data, a pointer to the user's data
chris215 7:6edb20845684 215 //
chris215 7:6edb20845684 216 // Returns: TRUE if there was an empty location in the queue
chris215 7:6edb20845684 217 // to copy the data into
chris215 7:6edb20845684 218 // FALSE if not
chris215 7:6edb20845684 219 // Sets: ERROR_REPLY_OVR if there was no room in the queue
chris215 7:6edb20845684 220 //
chris215 7:6edb20845684 221 bool Mbed4dGenie::_genieEnqueueEvent (uint8_t * data) {
chris215 7:6edb20845684 222
chris215 7:6edb20845684 223
chris215 7:6edb20845684 224 if (_genieEventQueue.n_events < MAX_GENIE_EVENTS-2) {
chris215 7:6edb20845684 225 memcpy (&_genieEventQueue.frames[_genieEventQueue.wr_index], data,
chris215 7:6edb20845684 226 GENIE_FRAME_SIZE);
chris215 7:6edb20845684 227 _genieEventQueue.wr_index++;
chris215 7:6edb20845684 228 _genieEventQueue.wr_index &= MAX_GENIE_EVENTS -1;
chris215 7:6edb20845684 229 _genieEventQueue.n_events++;
chris215 7:6edb20845684 230 return TRUE;
chris215 7:6edb20845684 231 } else {
chris215 7:6edb20845684 232 return FALSE;
chris215 7:6edb20845684 233 }
chris215 7:6edb20845684 234 }
chris215 7:6edb20845684 235 ////////////////////// genieDequeueEvent ///////////////////
chris215 7:6edb20845684 236 //
chris215 7:6edb20845684 237 // Copy the bytes from a queued input event to a buffer supplied
chris215 7:6edb20845684 238 // by the caller.
chris215 7:6edb20845684 239 //
chris215 7:6edb20845684 240 // Parms: genieFrame * buff, a pointer to the user's buffer
chris215 7:6edb20845684 241 //
chris215 7:6edb20845684 242 // Returns: TRUE if there was an event to copy
chris215 7:6edb20845684 243 // FALSE if not
chris215 7:6edb20845684 244 //
chris215 7:6edb20845684 245 bool Mbed4dGenie::genieDequeueEvent(genieFrame * buff) {
chris215 7:6edb20845684 246
chris215 7:6edb20845684 247
chris215 7:6edb20845684 248 if (_genieEventQueue.n_events > 0) {
chris215 7:6edb20845684 249 memcpy (buff, &_genieEventQueue.frames[_genieEventQueue.rd_index],
chris215 7:6edb20845684 250 GENIE_FRAME_SIZE);
chris215 7:6edb20845684 251 _genieEventQueue.rd_index++;
chris215 7:6edb20845684 252 _genieEventQueue.rd_index &= MAX_GENIE_EVENTS -1;
chris215 7:6edb20845684 253 _genieEventQueue.n_events--;
chris215 7:6edb20845684 254 return TRUE;
chris215 7:6edb20845684 255 }
chris215 7:6edb20845684 256 return FALSE;
chris215 7:6edb20845684 257 }
chris215 7:6edb20845684 258 void Mbed4dGenie::genieAttachEventHandler(genieUserEventHandlerPtr handler)
chris215 7:6edb20845684 259 {
chris215 7:6edb20845684 260 _genieUserHandler = handler;
chris215 7:6edb20845684 261 }
chris215 7:6edb20845684 262 bool Mbed4dGenie::PendingFrames(void)
chris215 7:6edb20845684 263 {
chris215 7:6edb20845684 264 return (_genieEventQueue.n_events>0);
chris215 2:f283764fe9b7 265 }