Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependents: Genie_Test_Temperature
Fork of 4dGENIE by
Revision 6:f4d3977b0eae, committed 2014-07-04
- Comitter:
- chris215
- Date:
- Fri Jul 04 02:44:49 2014 +0000
- Parent:
- 3:11c49c49cd1a
- Child:
- 7:6edb20845684
- Commit message:
- Redesign of the 4dGENIE class. Right now, the class is only capable of writting to screen objects(excluding string objects)
Changed in this revision
| mbed_genie.cpp | Show annotated file Show diff for this revision Revisions of this file |
| mbed_genie.h | Show annotated file Show diff for this revision Revisions of this file |
--- 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
--- a/mbed_genie.h Sun Feb 23 17:32:37 2014 +0000
+++ b/mbed_genie.h Fri Jul 04 02:44:49 2014 +0000
@@ -1,7 +1,3 @@
-#undef GENIE_DEBUG
-
-#define GENIE_VERSION "GenieMbed 17-Nov-2013"
-
// Genie commands & replys:
#define GENIE_ACK 0x06
@@ -61,44 +57,6 @@
// Structure to store replys returned from a display
#define GENIE_FRAME_SIZE 6
-struct genieFrameReportObj {
- uint8_t cmd;
- uint8_t object;
- uint8_t index;
- uint8_t data_msb;
- uint8_t data_lsb;
-};
-
-/////////////////////////////////////////////////////////////////////
-// The Genie frame definition
-//
-// The union allows the data to be referenced as an array of uint8_t
-// or a structure of type genieFrameReportObj, eg
-//
-// genieFrame f;
-// f.bytes[4];
-// f.reportObject.data_lsb
-//
-// both methods get the same byte
-//
-union genieFrame {
- uint8_t bytes[GENIE_FRAME_SIZE];
- genieFrameReportObj reportObject;
-};
-
-#define MAX_GENIE_EVENTS 16 // MUST be a power of 2
-#define MAX_GENIE_FATALS 10
-
-struct genieEventQueueStruct {
- genieFrame frames[MAX_GENIE_EVENTS];
- uint8_t rd_index;
- uint8_t wr_index;
- uint8_t n_events;
-};
-
-typedef void (*geniePutCharFuncPtr) (uint8_t c, uint32_t baud);
-typedef uint16_t (*genieGetCharFuncPtr) (void);
-typedef void (*genieUserEventHandlerPtr) (void);
#define ERROR_NONE 0
#define ERROR_TIMEOUT -1 // 255 0xFF
@@ -125,72 +83,35 @@
#define FALSE (!TRUE)
#endif
-void SetupGenie(void);
-void genieAttachEventHandler (genieUserEventHandlerPtr handler);
-extern bool genieDequeueEvent (genieFrame * buff);
-extern bool genieEventIs (genieFrame * e, uint8_t cmd, uint8_t object, uint8_t index);
-extern uint16_t genieGetEventData (genieFrame * e);
-extern uint16_t genieWriteObject (uint16_t object, uint16_t index, uint16_t data);
-extern uint16_t genieWriteStr (uint16_t index, char *string);
-extern void genieWriteContrast (uint16_t value);
-
class Mbed4dGenie{
public:
+ /*
+ Constructor to initialise the pins used to control the lcd screen
+ Note: When the class is first initialised, the lcd screen will be put
+ in reset and kept reset until Start() is called
+ */
Mbed4dGenie(PinName TxPin,PinName RxPin, PinName resetpin);
- void genieAttachEventHandler (genieUserEventHandlerPtr handler);
- uint16_t genieWriteStrU (uint16_t index, char *string);
- uint16_t genieWriteStr (uint16_t index, char *string);
- void genieWriteContrast (uint16_t value);
- uint16_t genieWriteObject (uint16_t object, uint16_t index, uint16_t data);
- bool genieDequeueEvent(genieFrame * buff);
- uint16_t genieGetEventData (genieFrame * e);
- bool genieEventIs(genieFrame * e, uint8_t cmd, uint8_t object, uint8_t index);
- bool GenieReadable(void);
- uint16_t genieDoEvents (void);
+ /*
+ Deassert the reset pin and give some time to the lcd to
+ initialise itself before sending any commands.
+ */
+ void Start();
+ /*
+ Generic command to write data to a Genie object
+ returns the status code of operation
+ */
+ int8_t genieWriteObject (uint16_t object, uint16_t index, uint16_t data);
- private:
- void RxIrqHandler(void);
- uint8_t _genieGetchar(void);
- void _geniePutchar (uint8_t c);
- uint16_t _genieGetLinkState (void);
- void _genieSetLinkState (uint16_t newstate);
- bool _genieEnqueueEvent (uint8_t * data);
- int _genieWriteStrX (uint16_t code, uint16_t index, char *string);
- void _genieWaitForIdle (void);
- void _geniePushLinkState (uint8_t newstate);
- void _geniePopLinkState (void);
- void _genieFlushSerialInput(void);
- void _handleError (void);
- void _genieFlushEventQueue(void);
-
+ private:
+ /*
+ Wait for the screen to aknowledge the command
+ returns the status code of operation
+ */
+ int8_t WaitForAnswer();
+
+
+
Serial _screen;
+ DigitalOut _reset;
Timer _t;
- DigitalOut _reset;
- //////////////////////////////////////////////////////////////
- // Pointer to the user's event handler function
- //
- genieUserEventHandlerPtr _genieUserHandler;
- //////////////////////////////////////////////////////////////
- // A structure to hold up to MAX_GENIE_EVENTS events receive
- // from the display
- //
- genieEventQueueStruct _genieEventQueue;
- //////////////////////////////////////////////////////////////
- // Simple 5-deep stack for the link state, this allows
- // genieDoEvents() to save the current state, receive a frame,
- // then restore the state
- //
- uint8_t _genieLinkStates[5];
- //
- // Stack pointer
- //
- uint8_t *_genieLinkState;
- //////////////////////////////////////////////////////////////
- // Number of mS the genieGetChar() function will wait before
- // giving up on the display
- int _genieTimeout;
- //////////////////////////////////////////////////////////////
- // Global error variable
- int _genieError;
- uint8_t rxframe_count;
- };
+ };
\ No newline at end of file
