4D display working with Gecko board STK3600
Fork of 4dGENIE by
Diff: mbed_genie.cpp
- Revision:
- 6:f4d3977b0eae
- Parent:
- 3:11c49c49cd1a
- Child:
- 7:6edb20845684
diff -r 11c49c49cd1a -r f4d3977b0eae mbed_genie.cpp --- a/mbed_genie.cpp Sun Feb 23 17:32:37 2014 +0000 +++ b/mbed_genie.cpp Fri Jul 04 02:44:49 2014 +0000 @@ -1,540 +1,73 @@ - #include "mbed.h" #include "mbed_genie.h" -Serial pc(USBTX,USBRX); - Mbed4dGenie::Mbed4dGenie(PinName TxPin,PinName RxPin, PinName resetpin) : _screen(TxPin,RxPin) , _reset(resetpin) { //reset the 4d screen - _reset = 1; - wait(0.25); _reset = 0; - _genieLinkStates[4] = GENIE_LINK_IDLE; - _genieLinkStates[3] = GENIE_LINK_IDLE; - _genieLinkStates[2] = GENIE_LINK_IDLE; - _genieLinkStates[1] = GENIE_LINK_IDLE; - _genieLinkStates[0] = GENIE_LINK_IDLE; - _genieLinkState = &_genieLinkStates[0]; - - _genieTimeout = TIMEOUT_PERIOD; - _genieError = ERROR_NONE; - rxframe_count = 0; - - _genieUserHandler = NULL; - _screen.attach(this,&Mbed4dGenie::RxIrqHandler,Serial::RxIrq); - _t.start(); -} -void Mbed4dGenie::genieAttachEventHandler(genieUserEventHandlerPtr handler) -{ - _genieUserHandler = handler; -} -void Mbed4dGenie::RxIrqHandler(void) -{ - do - { - genieDoEvents(); - } - while(_screen.readable ()); + _screen.baud(9600); } -//////////////////////// _genieGetchar ////////////////////////// -// -// Get a character from the selected Genie serial port -// -// Returns: ERROR_NOHANDLER if an Rx handler has not -// been defined -// ERROR_NOCHAR if no bytes have beeb received -// The char if there was one to get -// Sets: _genieError with any errors encountered -// -uint8_t Mbed4dGenie::_genieGetchar() { - - _genieError = ERROR_NONE; - - return (_screen.getc()); -} -///////////////////// _genieSetLinkState //////////////////////// -// -// Set the logical state of the link to the display. -// -// Parms: uint16_t newstate, a value to be written to the -// link's _genieLinkState variable. Valid values are -// GENIE_LINK_IDLE 0 -// GENIE_LINK_WFAN 1 // waiting for Ack or Nak -// GENIE_LINK_WF_RXREPORT 2 // waiting for a report frame -// GENIE_LINK_RXREPORT 3 // receiving a report frame -// GENIE_LINK_RXEVENT 4 // receiving an event frame -// GENIE_LINK_SHDN 5 -// -void Mbed4dGenie::_genieSetLinkState (uint16_t newstate) { +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(); - *_genieLinkState = newstate; - - - if (newstate == GENIE_LINK_RXREPORT || \ - newstate == GENIE_LINK_RXEVENT) - rxframe_count = 0; -} - - -/////////////////////// _genieGetLinkState ////////////////////// -// -// Get the current logical state of the link to the display. -// -uint16_t Mbed4dGenie::_genieGetLinkState (void) { - return *_genieLinkState; + _t.start(); } -/////////////////////// _geniePutchar /////////////////////////// -// -// Output the supplied character to the Genie display over -// the selected serial port -// -void Mbed4dGenie::_geniePutchar (uint8_t c) { - // if (screen != NULL) - _screen.putc(c); -} -////////////////////// _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 { - _genieError = ERROR_REPLY_OVR; - _handleError(); - 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; -} -////////////////////// _genieWaitForIdle //////////////////////// -// -// Wait for the link to become idle or for the timeout period, -// whichever comes first. -// -void Mbed4dGenie::_genieWaitForIdle (void) { - uint16_t do_event_result; - long timeout = _t.read_ms() + _genieTimeout; - - for ( ; _t.read_ms() < timeout;) { - - - do_event_result = genieDoEvents(); - // if there was a character received from the - // display restart the timeout because doEvents - // is in the process of receiving something - if (do_event_result == GENIE_EVENT_RXCHAR) { - timeout = _t.read_ms() + _genieTimeout; - return; - } - - if (_genieGetLinkState() == GENIE_LINK_IDLE) { - return; - } - } - _genieError = ERROR_TIMEOUT; - _handleError(); - return; -} ///////////////////////// genieWriteObject ////////////////////// // // Write data to an object on the display // -uint16_t Mbed4dGenie::genieWriteObject (uint16_t object, uint16_t index, uint16_t data) +int8_t Mbed4dGenie::genieWriteObject (uint16_t object, uint16_t index, uint16_t data) { - uint16_t msb, lsb ; - uint8_t checksum ; - - - _genieWaitForIdle(); - - - lsb = data&0xFF; - msb = (data>>8) & 0xFF; - - - _genieError = ERROR_NONE; - - - _geniePutchar(GENIE_WRITE_OBJ) ; checksum = GENIE_WRITE_OBJ ; - _geniePutchar(object) ; checksum ^= object ; - _geniePutchar(index) ; checksum ^= index ; - _geniePutchar(msb) ; checksum ^= msb; - _geniePutchar(lsb) ; checksum ^= lsb; - _geniePutchar(checksum) ; - - - _geniePushLinkState(GENIE_LINK_WFAN); - return GENIE_EVENT_NONE; -} -/////////////////////// genieWriteContrast ////////////////////// -// -// Alter the display contrast (backlight) -// -// Parms: uint8_t value: The required contrast setting, only -// values from 0 to 15 are valid. 0 or 1 for most displays -// and 0 to 15 for the uLCD-43 -// -void Mbed4dGenie::genieWriteContrast (uint16_t value) { - unsigned int checksum ; - - - _genieWaitForIdle(); - - - _geniePutchar(GENIE_WRITE_CONTRAST) ; checksum = GENIE_WRITE_CONTRAST ; - _geniePutchar(value) ; checksum ^= value ; - _geniePutchar(checksum) ; - - - _geniePushLinkState(GENIE_LINK_WFAN); - - -} -//////////////////////// _genieWriteStrX /////////////////////// -// -// Non-user function used by genieWriteStr() and genieWriteStrU() -// -int Mbed4dGenie::_genieWriteStrX (uint16_t code, uint16_t index, char *string) -{ - char *p ; - unsigned int checksum ; - int len = strlen (string) ; - - - if (len > 255) - return -1 ; - - - _genieWaitForIdle(); - + uint16_t msb, lsb ; + uint8_t checksum ; + + lsb = data&0xFF; + msb = (data>>8) & 0xFF; + + _screen.putc(GENIE_WRITE_OBJ) ; + checksum = GENIE_WRITE_OBJ ; + _screen.putc(object) ; + checksum ^= object ; + _screen.putc(index) ; + checksum ^= index ; + _screen.putc(msb) ; + checksum ^= msb; + _screen.putc(lsb) ; + checksum ^= lsb; + _screen.putc(checksum) ; + + - _geniePutchar(code) ; checksum = code ; - _geniePutchar(index) ; checksum ^= index ; - _geniePutchar((unsigned char)len) ; checksum ^= len ; - for (p = string ; *p ; ++p) { - _geniePutchar (*p) ; - checksum ^= *p ; - } - _geniePutchar(checksum) ; - - - _geniePushLinkState(GENIE_LINK_WFAN); - - - return 0 ; -} -/////////////////////// genieWriteStr //////////////////////// -// -// Write a string to the display (ASCII) -// -uint16_t Mbed4dGenie::genieWriteStr (uint16_t index, char *string) { - - return _genieWriteStrX (GENIE_WRITE_STR, index, string); -} -/////////////////////// genieWriteStrU //////////////////////// -// -// Write a string to the display (Unicode) -// -uint16_t Mbed4dGenie::genieWriteStrU (uint16_t index, char *string) { - - return _genieWriteStrX (GENIE_WRITE_STRU, index, string); - -} -////////////////////////////////////////////////////////////// -// Number of fatal errors encountered -//static int _genieFatalErrors = 0; -////////////////////// genieGetEventData //////////////////////// -// -// Returns the LSB and MSB of the event's data combined into -// a single uint16 -// -// The data is transmitted from the display in big-endian format -// and stored the same so the user can't just access it as an int -// directly from the structure. -// -uint16_t Mbed4dGenie::genieGetEventData (genieFrame * e) { - return (e->reportObject.data_msb << 8) + e->reportObject.data_lsb; -} - - - - -//////////////////////// genieEventIs /////////////////////////// -// -// Compares the cmd, object and index fields of the event's -// structure. -// -// Returns: TRUE if all the fields match the caller's parms -// FALSE if any of them don't -// -bool Mbed4dGenie::genieEventIs(genieFrame * e, uint8_t cmd, uint8_t object, uint8_t index) { - - - return (e->reportObject.cmd == cmd && - e->reportObject.object == object && - e->reportObject.index == index); - - -} - -////////////////////// _geniePushLinkState ////////////////////// -// -// Push a link state onto a FILO stack -// -void Mbed4dGenie::_geniePushLinkState (uint8_t newstate) { - - - _genieLinkState++; - _genieSetLinkState(newstate); - - + return Mbed4dGenie::WaitForAnswer(); } -////////////////////// _geniePopLinkState ////////////////////// -// -// Pop a link state from a FILO stack -// -void Mbed4dGenie::_geniePopLinkState (void) { - if (_genieLinkState > &_genieLinkStates[0]) { - *_genieLinkState = 0xFF; - _genieLinkState--; - } -} - -///////////////// _genieFlushSerialInput /////////////////// -// -// Removes and discards all characters from the currently -// used serial port's Rx buffer. -// -void Mbed4dGenie::_genieFlushSerialInput(void) { - do { - _genieGetchar(); - } while (_genieError != ERROR_NOCHAR); -} - -///////////////////////// _handleError ///////////////////////// -// -// So far really just a debugging aid, but can be enhanced to -// help recover from errors. -// -void Mbed4dGenie::_handleError (void) { -} - - - - -////////////////////// _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; -} -bool Mbed4dGenie::GenieReadable(void){ - if (_screen.readable()) - { - return TRUE; - } - else - { - return FALSE; - } -} -///////////////////////// genieDoEvents ///////////////////////// -// -// This is the heart of the Genie comms state machine. -// -uint16_t Mbed4dGenie::genieDoEvents (void) { - uint8_t c; - static uint8_t rx_data[6]; - static uint8_t checksum = 0; - - if (GenieReadable()) - { - c = _genieGetchar(); - //pc.putc(c); - - //////////////////////////////////////////// - // - // If there are no characters to process and we have - // queued events call the user's handler function. - // - if (_genieError == ERROR_NOCHAR) { - //pc.printf("EventCalled!\n\r"); - if (_genieEventQueue.n_events > 0 && _genieUserHandler!= NULL) (_genieUserHandler)(); - return GENIE_EVENT_NONE; - } - - /////////////////////////////////////////// - // - // Main state machine - // - switch (_genieGetLinkState()) { - case GENIE_LINK_IDLE: - switch (c) { - case GENIE_REPORT_EVENT: - // event frame out of the blue, set the link state - // and fall through to the frame-accumulate code - // at the end of this function - _geniePushLinkState(GENIE_LINK_RXEVENT); - break; - - default: - // error, bad character, no other character - // is acceptable in this state - return GENIE_EVENT_RXCHAR; - - } - break; - - case GENIE_LINK_WFAN: - switch (c) { - +int8_t Mbed4dGenie::WaitForAnswer() +{ + int8_t operation_result = 0; - case GENIE_ACK: - _geniePopLinkState(); - return GENIE_EVENT_RXCHAR; - - - case GENIE_NAK: - _geniePopLinkState(); - _genieError = ERROR_NAK; - _handleError(); - return GENIE_EVENT_RXCHAR; - - case GENIE_REPORT_EVENT: - // event frame out of the blue while waiting for an ACK - // save/set the link state and fall through to the - // frame-accumulate code at the end of this function - _geniePushLinkState(GENIE_LINK_RXEVENT); - break; - - - case GENIE_REPORT_OBJ: - default: - // error, bad character - return GENIE_EVENT_RXCHAR; - } - break; - - - case GENIE_LINK_WF_RXREPORT: // waiting for the first byte of a report - switch (c) { - - case GENIE_REPORT_EVENT: - // event frame out of the blue while waiting for the first - // byte of a report frame - // save/set the link state and fall through to the - // frame-accumulate code at the end of this function - _geniePushLinkState(GENIE_LINK_RXEVENT); - break; - - - case GENIE_REPORT_OBJ: - // first byte of a report frame - // replace the GENIE_LINK_WF_RXREPORT link state - // with GENIE_LINK_RXREPORT to indicate that we - // are now receiving a report frame - _geniePopLinkState(); - _geniePushLinkState(GENIE_LINK_RXREPORT); - break; - - - case GENIE_ACK: - case GENIE_NAK: - default: - // error, bad character - return GENIE_EVENT_RXCHAR; - // break; - } - - - case GENIE_LINK_RXREPORT: // already receiving report - case GENIE_LINK_RXEVENT: // already receiving event - default: - break; - - } - - - /////////////////////////////////////////////////////// - // We get here if we are in the process of receiving - // a report or event frame. Accumulate GENIE_FRAME_SIZE - // bytes into a local buffer then queue them as a frame - // into the event queue - // - if (_genieGetLinkState() == GENIE_LINK_RXREPORT || \ - _genieGetLinkState() == GENIE_LINK_RXEVENT) { - - checksum = (rxframe_count == 0) ? c : checksum ^ c; - - - rx_data[rxframe_count] = c; - - - if (rxframe_count == GENIE_FRAME_SIZE -1) { - //pc.printf("FrameReceived!\n\r"); - // all bytes received, if the CS is good - // queue the frame and restore the link state - if (checksum == 0) { - _genieEnqueueEvent(rx_data); - if (_genieEventQueue.n_events > 0 && _genieUserHandler!= NULL) (_genieUserHandler)(); - //return GENIE_EVENT_NONE; - rxframe_count = 0; - // revert the link state to whatever it was before - // we started accumulating this frame - _geniePopLinkState(); - return GENIE_EVENT_RXCHAR; - } else { - _genieError = ERROR_BAD_CS; - _handleError(); - } - } - rxframe_count++; - return GENIE_EVENT_RXCHAR; - } - } - return GENIE_EVENT_NONE; + long timeout = _t.read_ms() + TIMEOUT_PERIOD; + long timerReading = 0; + while(operation_result != GENIE_ACK && operation_result != ERROR_NAK && timerReading < timeout) + { + if(_screen.readable()) + operation_result = _screen.getc(); + timerReading = _t.read_ms(); + } + + if(operation_result == ERROR_NAK) + { + return ERROR_NONE; + } + else if(timerReading >= timeout) + { + return ERROR_TIMEOUT; + } + return ERROR_NONE; } \ No newline at end of file