Chrono
Dependencies: mbed SDFileSystem
Revision 5:e565265fdf23, committed 2020-04-07
- Comitter:
- pathae
- Date:
- Tue Apr 07 12:24:23 2020 +0000
- Parent:
- 4:f5cff5165941
- Commit message:
- Tir
Changed in this revision
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/SDFileSystem.lib Tue Apr 07 12:24:23 2020 +0000 @@ -0,0 +1,1 @@ +http://developer.mbed.org/users/neilt6/code/SDFileSystem/#3fa5eaf48e81
--- a/eeprom_flash.cpp Mon Apr 06 15:24:07 2020 +0000
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,78 +0,0 @@
-#include "mbed.h"
-#include "eeprom_flash.h"
-Serial pc(USBTX, USBRX); //Initalise PC serial comms
-DigitalOut myled(LED1);
-/*
- * Must call this first to enable writing
- */
-void enableEEPROMWriting() {
- HAL_StatusTypeDef status = HAL_FLASH_Unlock();
- FLASH_PageErase(EEPROM_START_ADDRESS); // required to re-write
- CLEAR_BIT(FLASH->CR, FLASH_CR_PER); // Bug fix: bit PER has been set in Flash_PageErase(), must clear it here
-}
-
-void disableEEPROMWriting() {
- HAL_FLASH_Lock();
-}
-
-/*
- * Writing function
- * Must call enableEEPROMWriting() first
- */
-HAL_StatusTypeDef writeEEPROMHalfWord(uint32_t address, uint16_t data) {
- HAL_StatusTypeDef status;
- address = address + EEPROM_START_ADDRESS;
- status = HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD, address, data);
- return status;
-}
-
-/*
- * Reading functions
- */
-uint16_t readEEPROMHalfWord(uint32_t address) {
- uint16_t val = 0;
- address = address + EEPROM_START_ADDRESS;
- val = *(__IO uint16_t*)address;
- return val;
-}
-
-//Programme de test
-
-int main() {
-int adresse = 0x00;
-char donnee1 = 11;
-char donnee2 = 22;
-char donnee3 = 33;
-int lecture;
-pc.baud(9600);
-
-/* Ecriture*/
-enableEEPROMWriting(); //autorisation d'ecriture dans l'eeprom
-writeEEPROMHalfWord(adresse, donnee1);
-writeEEPROMHalfWord(adresse+2, donnee2);
-writeEEPROMHalfWord(adresse+4, donnee3);
-disableEEPROMWriting(); //Interdiction d'ecriture
-
- myled=!myled;
- wait(0.5);
- myled=!myled;
- wait(0.5);
-
-/*lecture et affichage*/
-lecture=readEEPROMHalfWord(adresse);
-if (lecture==11)
- {
- myled=!myled;
- wait(0.5);
- myled=!myled;
- wait(0.5);
- myled=!myled;
- wait(0.5);
- }
-pc.printf ("valeur lue: %d\n\r",lecture);
-lecture=readEEPROMHalfWord(adresse+2);
-pc.printf ("valeur lue: %d\n\r",lecture);
-lecture=readEEPROMHalfWord(adresse+4);
-pc.printf ("valeur lue: %d\n\r",lecture);
- while(1);
-}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp Tue Apr 07 12:24:23 2020 +0000
@@ -0,0 +1,298 @@
+#include "mbed.h"
+#include "mbed_genie.h"
+#include "SDFileSystem.h"
+#include "eeprom_flash.h"
+SDFileSystem sd(D11, D12, D13, D10, "sd"); // the pinout on the mbed Cool Components workshop board
+AnalogIn TensionBatterie(A1);
+DigitalOut DELVERTE (PB_2);
+DigitalOut DELORANGE (PB_1);
+DigitalOut DELROUGE (PB_15,1);
+InterruptIn BOUTONPAUSE(USER_BUTTON);
+//Prototype des routines d'interruption
+void compt_secondes();
+void valeur_volt();
+int temps_global_secondes, temps_global_minutes, temps_global_heures, numero_tir1 = 1, numero_tir2 = 0, numero_tir_depart = 1, pause = 0,bloqueur, kchrono = 0,locker =0;
+int i = 15, j_tir = 0;
+int adresse = 0x00;
+char donnee1 = 11;
+char donnee2 = 22;
+char donnee3 = 33;
+float valeur_tension, valeur_analogique; // Permet d'avoir des mesures precises pour la tension
+ char cMonText[1024];
+ char cMonText2[1024];
+ char chiffre1[6];
+ char chrono[40];
+ char i1=0;
+ char j=0;
+ char k=0;
+ int val1;
+ char chiffre2[6];
+ char type_tir[40];
+ char i2=0;
+ char j2=0;
+ char k2=0;
+ int val2;
+//Déclaration des interruptions Ticker
+Ticker Horloge_Global_Seconde;
+Ticker Valeur_Tension_Volt;
+/*************************************************************************************************
+ Interruption générée automatiquement toutes les secondes pour décrémenter le compteur **
+*************************************************************************************************/
+//Must call this first to enable writing
+void enableEEPROMWriting() {
+ HAL_StatusTypeDef status = HAL_FLASH_Unlock();
+ FLASH_PageErase(EEPROM_START_ADDRESS); // required to re-write
+ CLEAR_BIT(FLASH->CR, FLASH_CR_PER); // Bug fix: bit PER has been set in Flash_PageErase(), must clear it here
+}
+void disableEEPROMWriting() {
+ HAL_FLASH_Lock();
+}
+//Writing function
+//Must call enableEEPROMWriting() first
+HAL_StatusTypeDef writeEEPROMHalfWord(uint32_t address, uint16_t data) {
+ HAL_StatusTypeDef status;
+ address = address + EEPROM_START_ADDRESS;
+ status = HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD, address, data);
+ return status;
+}
+//Reading functions
+uint16_t readEEPROMHalfWord(uint32_t address) {
+ uint16_t val = 0;
+ address = address + EEPROM_START_ADDRESS;
+ val = *(__IO uint16_t*)address;
+ return val;
+}
+
+void vidReadText(char * cTxt)
+{
+ unsigned char caractereActuel; // Début lecture SD
+ int iIndex=0;
+ FILE *fp = fopen("/sd/Temps.txt", "r");
+ if(fp == NULL)
+ {
+ error("Could not open file \n");
+ }
+ else
+ {
+ // Boucle de lecture des caractères un à un
+ strcpy(cTxt,"");
+ printf("\n\r");
+ do{
+ caractereActuel = fgetc(fp); // On lit le caractère
+ if(caractereActuel != 255) sprintf(cTxt,"%s%c",cTxt, caractereActuel); // On l'affiche
+ iIndex++;
+ } while (caractereActuel != 255);
+ fclose(fp);
+ } // Fin lecture SD
+}
+
+void vidReadText2(char * cTxt2)
+{
+ unsigned char caractereActuel2; // Début lecture SD 2
+ int iIndex2=0;
+ FILE *fp = fopen("/sd/Ordre.txt", "r");
+ if(fp == NULL)
+ {
+ error("Could not open file \n");
+ }
+ else
+ {
+ // Boucle de lecture des caractères un à un
+ strcpy(cTxt2,"");
+ printf("\n\r");
+ do{
+ caractereActuel2 = fgetc(fp); // On lit le caractère
+ if(caractereActuel2 != 255) sprintf(cTxt2,"%s%c",cTxt2, caractereActuel2); // On l'affiche
+ iIndex2++;
+ } while (caractereActuel2 != 255);
+ fclose(fp);
+ } // Fin lecture SD 2
+}
+
+
+ void compt_secondes() //-------------------------------- Compteur seconde ----------------------------------------
+ {
+ if(bloqueur == 0) // Début bloqueur
+ {
+ chrono[kchrono]=chrono[kchrono]-1;
+ genieWriteObject(GENIE_OBJ_LED_DIGITS, 0x00, chrono[kchrono]); //Ecrit sur Leddigits0 la valeur de chrono
+ genieWriteObject(GENIE_OBJ_GAUGE , 0x00, chrono[kchrono]);
+ temps_global_secondes = temps_global_secondes + 1;
+ genieWriteObject(GENIE_OBJ_LED_DIGITS, 0x01, temps_global_secondes);
+ if(temps_global_secondes == 60){
+ temps_global_secondes = 0;
+ temps_global_minutes = temps_global_minutes + 1;
+ genieWriteObject(GENIE_OBJ_LED_DIGITS, 0x02, temps_global_minutes);
+ if(temps_global_minutes == 60)
+ {
+ temps_global_minutes = 0;
+ temps_global_heures = temps_global_heures + 1;
+ genieWriteObject(GENIE_OBJ_LED_DIGITS, 0x03, temps_global_heures);
+ }
+ }
+
+ if (numero_tir_depart == 1){ // Début décompte
+ genieWriteObject(GENIE_OBJ_LED_DIGITS, 0x04, numero_tir1);
+ temps_global_secondes= 0;
+ genieWriteObject(GENIE_OBJ_LED_DIGITS, 0x02, temps_global_secondes);
+ temps_global_minutes = 0;
+ genieWriteObject(GENIE_OBJ_LED_DIGITS, 0x02, temps_global_minutes);
+ temps_global_heures = 0;
+ genieWriteObject(GENIE_OBJ_LED_DIGITS, 0x02, temps_global_heures);
+ numero_tir_depart++;
+ genieWriteObject(GENIE_OBJ_USER_LED, 0x00, 0);
+ }
+ if(chrono[kchrono] == 0){
+
+ if (type_tir[j_tir+1] == 0) // Tir normale
+ {
+ numero_tir1++;
+ genieWriteObject(GENIE_OBJ_LED_DIGITS, 0x04, numero_tir1);
+ genieWriteObject(GENIE_OBJ_USER_LED, 0x00, 0);
+ }
+
+ if (type_tir[j_tir+1] == 1) // Tir distance
+ {
+ numero_tir2++;
+ genieWriteObject(GENIE_OBJ_LED_DIGITS, 0x04, numero_tir2);
+ genieWriteObject(GENIE_OBJ_USER_LED, 0x00, 1);
+ }
+
+ j_tir++;
+ chrono[kchrono] = chrono[kchrono+1];
+ kchrono++;
+ } // Fin partie décompte seconde
+ } // Fin bloqueur
+ genieFrame Event;
+ genieDequeueEvent(&Event);
+ //event report from an object
+ if(Event.reportObject.cmd == GENIE_REPORT_EVENT) {
+ /*
+ for example here we check if we received a message from 4dbuttons objects
+ the index is the button number, refer to the 4dgenie project to know the index
+ */
+ if (Event.reportObject.object == GENIE_OBJ_4DBUTTON) { // If the Reported Message was from a button
+ if (Event.reportObject.index == 9) { // Début Enclenchement bouton 9
+ if (i<15)
+ {
+ i++;
+ }
+ genieWriteObject(GENIE_OBJ_LED_DIGITS, 0x05, i);
+ genieWriteContrast(i);
+ } // Fin Enclenchement bouton 9
+ if (Event.reportObject.index == 10) { // Début Enclenchement bouton 10
+ if (i>0)
+ {
+ i--;
+ }
+ genieWriteObject(GENIE_OBJ_LED_DIGITS, 0x05, i);
+ genieWriteContrast(i);
+ } // Fin Enclenchement bouton 10
+ if (Event.reportObject.index == 15) { // Début Enclenchement bouton 15
+ vidReadText(cMonText);
+ vidReadText2(cMonText2);
+ i1=0;
+ k=0;
+ i2=0;
+ k2=0;
+
+ while(cMonText[i1]!='*')
+ {
+ while(cMonText[i1]!=',')
+ {
+ chiffre1[j]=cMonText[i1];
+ i1++;
+ j++;
+ }
+ val1 = atoi(chiffre1);
+ chrono[k]=val1;
+ j=0;
+ i1++;
+ k++;
+ }
+i1=0;
+k=0;
+
+ while(cMonText2[i2]!='*')
+ {
+ while(cMonText2[i2]!=',')
+ {
+ chiffre2[j2]=cMonText2[i2];
+ i2++;
+ j2++;
+ }
+ val2 = atoi(chiffre2);
+ type_tir[k2]=val2;
+ j2=0;
+ i2++;
+ k2++;
+ }
+i2=0;
+k2=0;
+ } // Fin Enclenchement bouton 15
+
+ }
+ }
+ return;
+ }
+
+void valeur_volt() // ---------------------------------------------- Lecteur Tension ------------------------
+ {
+ valeur_analogique = TensionBatterie.read(); // Convertis la valeur obtenus entre 0 et 1
+ valeur_tension = valeur_analogique * 6; // On multiplie notre valeur obtenus pour avoir la tension d entree
+ genieWriteObject(GENIE_OBJ_METER , 0x00,valeur_tension);
+ return;
+ }
+
+void pause1()
+ {
+ if(pause == 0)
+ {
+ pause++;
+ }
+ else
+ {
+ pause--;
+ }
+ }
+
+/************************
+* Programme principal *
+*************************/
+
+int main()
+{
+
+ wait(3);
+ DELROUGE = 0;
+
+ /* Ecriture*/
+enableEEPROMWriting(); //autorisation d'ecriture dans l'eeprom
+writeEEPROMHalfWord(adresse, donnee1);
+writeEEPROMHalfWord(adresse+2, donnee2);
+writeEEPROMHalfWord(adresse+4, donnee3);
+disableEEPROMWriting(); //Interdiction d'ecriture
+
+ SetupGenie();
+ genieWriteContrast(i); //Permet de modifier la luminosite
+ genieWriteObject(GENIE_OBJ_LED_DIGITS, 0x05, i);
+ BOUTONPAUSE.fall(&pause1);
+//Initialisation de l'interruption "Ticker" toutes les secondes
+ Horloge_Global_Seconde.attach(&compt_secondes,1); //Appel de la fonction toutes les secondes.
+ Valeur_Tension_Volt.attach(&valeur_volt,30);
+
+ while(1) {
+ if(pause == 0)
+ {
+ DELVERTE = 0;
+ DELORANGE = 1;
+ bloqueur = 1;
+ }
+ if(pause == 1)
+ {
+ DELVERTE = 1;
+ DELORANGE = 0;
+ bloqueur = 0;
+ }
+ } // Fin while
+} // Fin main
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed_genie.cpp Tue Apr 07 12:24:23 2020 +0000
@@ -0,0 +1,617 @@
+
+#include "mbed.h"
+#include "mbed_genie.h"
+
+DigitalOut genieReset(PC_7); //genie reset pin on pin 8 of the mbed
+
+Serial screen(PA_9,PA_10);
+Serial pc(USBTX,USBRX);
+Timer t;
+
+
+
+void _genieFlushEventQueue (void);
+void _handleError (void);
+void _geniePutchar (uint8_t c);
+uint8_t _genieGetchar (void);
+void _genieSetLinkState (uint16_t newstate);
+uint16_t _genieGetLinkState (void);
+bool _genieEnqueueEvent (uint8_t * data);
+//////////////////////////////////////////////////////////////
+// A structure to hold up to MAX_GENIE_EVENTS events receive
+// from the display
+//
+static genieEventQueueStruct _genieEventQueue;
+
+//////////////////////////////////////////////////////////////
+// Pointer to the user's event handler function
+//
+static genieUserEventHandlerPtr _genieUserHandler = NULL;
+
+
+//////////////////////////////////////////////////////////////
+// Simple 5-deep stack for the link state, this allows
+// genieDoEvents() to save the current state, receive a frame,
+// then restore the state
+//
+static uint8_t _genieLinkStates[5] = {GENIE_LINK_IDLE};
+//
+// Stack pointer
+//
+static uint8_t *_genieLinkState = &_genieLinkStates[0];
+
+
+//////////////////////////////////////////////////////////////
+// Number of mS the genieGetChar() function will wait before
+// giving up on the display
+static int _genieTimeout = TIMEOUT_PERIOD;
+
+
+//////////////////////////////////////////////////////////////
+// Number of times we have had a timeout
+static int _genieTimeouts = 0;
+
+
+//////////////////////////////////////////////////////////////
+// Global error variable
+static int _genieError = ERROR_NONE;
+
+
+
+
+static uint8_t rxframe_count = 0;
+
+
+//////////////////////////////////////////////////////////////
+// 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 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 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 _geniePushLinkState (uint8_t newstate) {
+
+
+ _genieLinkState++;
+ _genieSetLinkState(newstate);
+
+
+}
+
+
+////////////////////// _geniePopLinkState //////////////////////
+//
+// Pop a link state from a FILO stack
+//
+void _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 _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 _handleError (void) {
+// Serial2.write (_genieError + (1<<5));
+// if (_genieError == GENIE_NAK) genieResync();
+}
+
+
+
+
+////////////////////// _genieFlushEventQueue ////////////////////
+//
+// Reset all the event queue variables and start from scratch.
+//
+void _genieFlushEventQueue(void) {
+ _genieEventQueue.rd_index = 0;
+ _genieEventQueue.wr_index = 0;
+ _genieEventQueue.n_events = 0;
+}
+bool GenieReadable(void){
+ if (screen.readable())
+ {
+ return TRUE;
+ }
+ else
+ {
+ return FALSE;
+ }
+}
+///////////////////////// genieDoEvents /////////////////////////
+//
+// This is the heart of the Genie comms state machine.
+//
+uint16_t 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) {
+
+
+ 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;
+ }
+ }
+}
+
+////////////////////// 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 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 _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 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);
+}
+
+/////////////////////// 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 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()
+//
+static int _genieWriteStrX (uint16_t code, uint16_t index, char *string)
+{
+ char *p ;
+ unsigned int checksum ;
+ int len = strlen (string) ;
+
+
+ if (len > 255)
+ return -1 ;
+
+
+ _genieWaitForIdle();
+
+
+ _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 genieWriteStr (uint16_t index, char *string) {
+
+ return _genieWriteStrX (GENIE_WRITE_STR, index, string);
+}
+
+
+/////////////////////// genieWriteStrU ////////////////////////
+//
+// Write a string to the display (Unicode)
+//
+uint16_t genieWriteStrU (uint16_t index, char *string) {
+
+
+ return _genieWriteStrX (GENIE_WRITE_STRU, index, string);
+
+
+}
+/////////////////// genieAttachEventHandler //////////////////////
+//
+// "Attaches" a pointer to the users event handler by writing
+// the pointer into the variable used by doEVents()
+//
+void genieAttachEventHandler (genieUserEventHandlerPtr handler) {
+ _genieUserHandler = handler;
+}
+
+
+////////////////////// _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 _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;
+ }
+}
+///////////////////// _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 _genieSetLinkState (uint16_t newstate) {
+
+ *_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 _genieGetLinkState (void) {
+ return *_genieLinkState;
+}
+
+/////////////////////// _geniePutchar ///////////////////////////
+//
+// Output the supplied character to the Genie display over
+// the selected serial port
+//
+void _geniePutchar (uint8_t c) {
+ // if (screen != NULL)
+ screen.putc(c);
+}
+
+
+//////////////////////// _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 _genieGetchar() {
+ uint16_t result;
+
+
+ _genieError = ERROR_NONE;
+
+ return (screen.getc());
+}
+
+void RxIrqHandler(void)
+{
+ do
+ {
+ genieDoEvents();
+ }
+ while(screen.readable ());
+}
+
+
+void TickerIrq(void)
+{
+}
+
+
+void SetupGenie(void)
+{
+ screen.baud(19200);
+ pc.baud(19200);
+ screen.attach(&RxIrqHandler,Serial::RxIrq);
+ //t.start();
+ // EventChk.attach(&TickerIrq,0.05);
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed_genie.h Tue Apr 07 12:24:23 2020 +0000
@@ -0,0 +1,136 @@
+#undef GENIE_DEBUG
+
+#define GENIE_VERSION "GenieMbed 17-Nov-2013"
+
+// Genie commands & replys:
+
+#define GENIE_ACK 0x06
+#define GENIE_NAK 0x15
+
+#define TIMEOUT_PERIOD 500
+#define RESYNC_PERIOD 100
+
+#define GENIE_READ_OBJ 0
+#define GENIE_WRITE_OBJ 1
+#define GENIE_WRITE_STR 2
+#define GENIE_WRITE_STRU 3
+#define GENIE_WRITE_CONTRAST 4
+#define GENIE_REPORT_OBJ 5
+#define GENIE_REPORT_EVENT 7
+
+// Objects
+// the manual says:
+// Note: Object IDs may change with future releases; it is not
+// advisable to code their values as constants.
+
+#define GENIE_OBJ_DIPSW 0
+#define GENIE_OBJ_KNOB 1
+#define GENIE_OBJ_ROCKERSW 2
+#define GENIE_OBJ_ROTARYSW 3
+#define GENIE_OBJ_SLIDER 4
+#define GENIE_OBJ_TRACKBAR 5
+#define GENIE_OBJ_WINBUTTON 6
+#define GENIE_OBJ_ANGULAR_METER 7
+#define GENIE_OBJ_COOL_GAUGE 8
+#define GENIE_OBJ_CUSTOM_DIGITS 9
+#define GENIE_OBJ_FORM 10
+#define GENIE_OBJ_GAUGE 11
+#define GENIE_OBJ_IMAGE 12
+#define GENIE_OBJ_KEYBOARD 13
+#define GENIE_OBJ_LED 14
+#define GENIE_OBJ_LED_DIGITS 15
+#define GENIE_OBJ_METER 16
+#define GENIE_OBJ_STRINGS 17
+#define GENIE_OBJ_THERMOMETER 18
+#define GENIE_OBJ_USER_LED 19
+#define GENIE_OBJ_VIDEO 20
+#define GENIE_OBJ_STATIC_TEXT 21
+#define GENIE_OBJ_SOUND 22
+#define GENIE_OBJ_TIMER 23
+#define GENIE_OBJ_SPECTRUM 24
+#define GENIE_OBJ_SCOPE 25
+#define GENIE_OBJ_TANK 26
+#define GENIE_OBJ_USERIMAGES 27
+#define GENIE_OBJ_PINOUTPUT 28
+#define GENIE_OBJ_PININPUT 29
+#define GENIE_OBJ_4DBUTTON 30
+#define GENIE_OBJ_ANIBUTTON 31
+#define GENIE_OBJ_COLORPICKER 32
+#define GENIE_OBJ_USERBUTTON 33
+
+// 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
+#define ERROR_NOHANDLER -2 // 254 0xFE
+#define ERROR_NOCHAR -3 // 253 0xFD
+#define ERROR_NAK -4 // 252 0xFC
+#define ERROR_REPLY_OVR -5 // 251 0xFB
+#define ERROR_RESYNC -6 // 250 0xFA
+#define ERROR_NODISPLAY -7 // 249 0xF9
+#define ERROR_BAD_CS -8 // 248 0xF8
+
+#define GENIE_LINK_IDLE 0
+#define GENIE_LINK_WFAN 1 // waiting for Ack or Nak
+#define GENIE_LINK_WF_RXREPORT 2 // waiting for a report frame
+#define GENIE_LINK_RXREPORT 3 // receiving a report frame
+#define GENIE_LINK_RXEVENT 4 // receiving an event frame
+#define GENIE_LINK_SHDN 5
+
+#define GENIE_EVENT_NONE 0
+#define GENIE_EVENT_RXCHAR 1
+
+#ifndef TRUE
+#define TRUE (1==1)
+#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);
+