programme bts

Dependencies:   mbed ID12RFID SDFileSystem

Files at this revision

API Documentation at this revision

Comitter:
valentinbruchet
Date:
Wed May 05 08:13:43 2021 +0000
Parent:
4:3269abcc9c73
Commit message:
Programme BTS;

Changed in this revision

ID12RFID.lib Show annotated file Show diff for this revision Revisions of this file
SDFileSystem.lib Show annotated file Show diff for this revision Revisions of this file
eeprom_flash.cpp Show diff for this revision Revisions of this file
main.cpp Show annotated file Show diff for this revision Revisions of this file
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
diff -r 3269abcc9c73 -r e104ec24b3fa ID12RFID.lib
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ID12RFID.lib	Wed May 05 08:13:43 2021 +0000
@@ -0,0 +1,1 @@
+https://os.mbed.com/users/simon/code/ID12RFID/#f04afa911cf5
diff -r 3269abcc9c73 -r e104ec24b3fa SDFileSystem.lib
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SDFileSystem.lib	Wed May 05 08:13:43 2021 +0000
@@ -0,0 +1,1 @@
+https://os.mbed.com/users/valentinbruchet/code/SDFileSystem/#bb0a603a0f79
diff -r 3269abcc9c73 -r e104ec24b3fa eeprom_flash.cpp
--- a/eeprom_flash.cpp	Tue Mar 16 14:58:12 2021 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,166 +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 functions
-* 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 tab[40]= {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40};
-int adresse = 0x00;
-int lecture;
-pc.baud(9600);
-/* Ecriture*/
-enableEEPROMWriting(); //autorisation d'ecriture dans l'eeprom
-writeEEPROMHalfWord(adresse, tab[0]);
-writeEEPROMHalfWord(adresse+2, tab[1]);
-writeEEPROMHalfWord(adresse+4, tab[2]);
-writeEEPROMHalfWord(adresse+6, tab[3]);
-writeEEPROMHalfWord(adresse+8, tab[4]);
-writeEEPROMHalfWord(adresse+10, tab[5]);
-writeEEPROMHalfWord(adresse+12, tab[6]);
-writeEEPROMHalfWord(adresse+14, tab[7]);
-writeEEPROMHalfWord(adresse+16, tab[8]);
-writeEEPROMHalfWord(adresse+18, tab[9]);
-writeEEPROMHalfWord(adresse+20, tab[10]);
-writeEEPROMHalfWord(adresse+22, tab[11]);
-writeEEPROMHalfWord(adresse+24, tab[12]);
-writeEEPROMHalfWord(adresse+26, tab[13]);
-writeEEPROMHalfWord(adresse+28, tab[14]);
-writeEEPROMHalfWord(adresse+30, tab[15]);
-writeEEPROMHalfWord(adresse+32, tab[16]);
-writeEEPROMHalfWord(adresse+34, tab[17]);
-writeEEPROMHalfWord(adresse+36, tab[18]);
-writeEEPROMHalfWord(adresse+38, tab[19]);
-writeEEPROMHalfWord(adresse+40, tab[20]);
-writeEEPROMHalfWord(adresse+42, tab[21]);
-writeEEPROMHalfWord(adresse+44, tab[22]);
-writeEEPROMHalfWord(adresse+46, tab[23]);
-writeEEPROMHalfWord(adresse+48, tab[24]);
-writeEEPROMHalfWord(adresse+50, tab[25]);
-writeEEPROMHalfWord(adresse+52, tab[26]);
-writeEEPROMHalfWord(adresse+54, tab[27]);
-writeEEPROMHalfWord(adresse+56, tab[28]);
-writeEEPROMHalfWord(adresse+58, tab[29]);
-writeEEPROMHalfWord(adresse+60, tab[30]);
-writeEEPROMHalfWord(adresse+62, tab[31]);
-writeEEPROMHalfWord(adresse+64, tab[32]);
-writeEEPROMHalfWord(adresse+66, tab[33]);
-writeEEPROMHalfWord(adresse+68, tab[34]);
-writeEEPROMHalfWord(adresse+70, tab[35]);
-writeEEPROMHalfWord(adresse+72, tab[36]);
-writeEEPROMHalfWord(adresse+74, tab[37]);
-writeEEPROMHalfWord(adresse+76, tab[38]);
-writeEEPROMHalfWord(adresse+78, tab[39]);
-disableEEPROMWriting(); //Interdiction d'ecriture
-myled=!myled;
-wait(0.5);
-myled=!myled;
-wait(0.5);
-/*lecture et affichage*/
-lecture=readEEPROMHalfWord(adresse);
-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);
-lecture=readEEPROMHalfWord(adresse+6);
-pc.printf ("valeur lue: %d\n\r",lecture);
-lecture=readEEPROMHalfWord(adresse+8);
-pc.printf ("valeur lue: %d\n\r",lecture);
-lecture=readEEPROMHalfWord(adresse+10);
-pc.printf ("valeur lue: %d\n\r",lecture);
-lecture=readEEPROMHalfWord(adresse+12);
-pc.printf ("valeur lue: %d\n\r",lecture);
-lecture=readEEPROMHalfWord(adresse+14);
-pc.printf ("valeur lue: %d\n\r",lecture);
-lecture=readEEPROMHalfWord(adresse+16);
-pc.printf ("valeur lue: %d\n\r",lecture);
-lecture=readEEPROMHalfWord(adresse+18);
-pc.printf ("valeur lue: %d\n\r",lecture);
-lecture=readEEPROMHalfWord(adresse+20);
-pc.printf ("valeur lue: %d\n\r",lecture);
-lecture=readEEPROMHalfWord(adresse+22);
-pc.printf ("valeur lue: %d\n\r",lecture);
-lecture=readEEPROMHalfWord(adresse+24);
-pc.printf ("valeur lue: %d\n\r",lecture);
-lecture=readEEPROMHalfWord(adresse+26);
-pc.printf ("valeur lue: %d\n\r",lecture);
-lecture=readEEPROMHalfWord(adresse+28);
-pc.printf ("valeur lue: %d\n\r",lecture);
-lecture=readEEPROMHalfWord(adresse+30);
-pc.printf ("valeur lue: %d\n\r",lecture);
-lecture=readEEPROMHalfWord(adresse+32);
-pc.printf ("valeur lue: %d\n\r",lecture);
-lecture=readEEPROMHalfWord(adresse+34);
-pc.printf ("valeur lue: %d\n\r",lecture);
-lecture=readEEPROMHalfWord(adresse+36);
-pc.printf ("valeur lue: %d\n\r",lecture);
-lecture=readEEPROMHalfWord(adresse+38);
-pc.printf ("valeur lue: %d\n\r",lecture);
-lecture=readEEPROMHalfWord(adresse+40);
-pc.printf ("valeur lue: %d\n\r",lecture);
-lecture=readEEPROMHalfWord(adresse+42);
-pc.printf ("valeur lue: %d\n\r",lecture);
-lecture=readEEPROMHalfWord(adresse+44);
-pc.printf ("valeur lue: %d\n\r",lecture);
-lecture=readEEPROMHalfWord(adresse+46);
-pc.printf ("valeur lue: %d\n\r",lecture);
-lecture=readEEPROMHalfWord(adresse+48);
-pc.printf ("valeur lue: %d\n\r",lecture);
-lecture=readEEPROMHalfWord(adresse+50);
-pc.printf ("valeur lue: %d\n\r",lecture);
-lecture=readEEPROMHalfWord(adresse+52);
-pc.printf ("valeur lue: %d\n\r",lecture);
-lecture=readEEPROMHalfWord(adresse+54);
-pc.printf ("valeur lue: %d\n\r",lecture);
-lecture=readEEPROMHalfWord(adresse+56);
-pc.printf ("valeur lue: %d\n\r",lecture);
-lecture=readEEPROMHalfWord(adresse+58);
-pc.printf ("valeur lue: %d\n\r",lecture);
-lecture=readEEPROMHalfWord(adresse+60);
-pc.printf ("valeur lue: %d\n\r",lecture);
-lecture=readEEPROMHalfWord(adresse+62);
-pc.printf ("valeur lue: %d\n\r",lecture);
-lecture=readEEPROMHalfWord(adresse+64);
-pc.printf ("valeur lue: %d\n\r",lecture);
-lecture=readEEPROMHalfWord(adresse+68);
-pc.printf ("valeur lue: %d\n\r",lecture);
-lecture=readEEPROMHalfWord(adresse+70);
-pc.printf ("valeur lue: %d\n\r",lecture);
-lecture=readEEPROMHalfWord(adresse+72);
-pc.printf ("valeur lue: %d\n\r",lecture);
-lecture=readEEPROMHalfWord(adresse+76);
-pc.printf ("valeur lue: %d\n\r",lecture);
-lecture=readEEPROMHalfWord(adresse+78);
-pc.printf ("valeur lue: %d\n\r",lecture);
-while(1);
-}
diff -r 3269abcc9c73 -r e104ec24b3fa main.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Wed May 05 08:13:43 2021 +0000
@@ -0,0 +1,282 @@
+#include "mbed.h"
+#include "mbed_genie.h"
+#include "eeprom_flash.h"
+#include "SDFileSystem.h"
+#include "ID12RFID.h"
+
+Serial pc(USBTX, USBRX);
+ID12RFID rfid(PA_10);
+
+DigitalOut myled(LED1);
+DigitalOut led1(PA_8);
+DigitalOut led2(PB_14);
+DigitalOut led3(PB_11);
+DigitalOut led4(PA_11);
+DigitalOut led5(PA_12);
+DigitalOut led6(PC_5);
+DigitalOut led7(PC_6);
+DigitalOut led8(PC_8);
+DigitalOut ledmasse(PB_3);
+
+int flag_contraste;
+int valeur_clavier;
+int i;
+unsigned int lecture;
+int chrono = 99;
+int led = 99;
+int tab[40] = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40};
+int code1 = 49;
+int code2 = 50;
+int code3 = 51;
+int y = 15;
+int flag = 0;
+int adressetempo = 0x0000;
+int adresserfid = 0x00000000;
+unsigned int tempo1, tempo2, tempo3, tempo4, tempo5, tempo6, tempo7,tempo8, rfid1, rfid2, rfid3, rfid4, rfid5;
+
+
+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();
+}
+
+HAL_StatusTypeDef writeEEPROMWord(uint32_t address, uint32_t data)
+{
+    HAL_StatusTypeDef status;
+    address = address + EEPROM_START_ADDRESS;
+    status = HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, address, data);
+    return status;
+}
+
+uint32_t readEEPROMWord(uint32_t address)
+{
+    uint32_t val = 0;
+    address = address + EEPROM_START_ADDRESS;
+    val = *(__IO uint32_t*)address;
+    return val;
+}
+
+void myGenieEventHandler(void)
+{
+    genieFrame Event;
+    genieDequeueEvent(&Event);
+    if(Event.reportObject.cmd == GENIE_REPORT_EVENT) 
+    {
+        if (Event.reportObject.object == GENIE_OBJ_KEYBOARD)
+             { 
+                if (Event.reportObject.index == 0)
+                {
+                    valeur_clavier = Event.reportObject.data_lsb;
+                    printf("%c\n\r", valeur_clavier);
+                    if ((valeur_clavier == code1) || (valeur_clavier== code2) || (valeur_clavier == code3))
+                    {
+                        printf("Acces autorise\n\r");
+                    }
+                    else
+                    {
+                        printf("Acces refuse\n\r");
+                    }
+                }
+             }
+        if (Event.reportObject.object == GENIE_OBJ_4DBUTTON)
+        {              
+            if (Event.reportObject.index == 3) //Start
+            {
+                printf("Depart\n\r");
+                flag=1;
+            }
+            if (Event.reportObject.index == 5) //Stop
+            {
+                printf("Stop\n\r");
+                flag=0;
+            }
+            /*if (Event.reportObject.index == 8) // Contraste +
+            { 
+                if (y<15)
+                { 
+                 y++;
+                 printf("Contraste=%d\r\n",y);
+                 flag_contraste=1;
+                }
+                genieWriteContrast(y);
+            }
+            if (Event.reportObject.index == 7) // Contraste -
+            { 
+                if (y>0)
+                {
+                    y--;
+                    printf("Contraste=%d\r\n",y);
+                    flag_contraste=1;
+                }
+                genieWriteContrast(y);
+            }*/
+            if (Event.reportObject.index == 6) //Lecture tempo
+                {
+                SDFileSystem sd(PA_7, PA_6, PA_5, PB_6, "sd");
+                char numberstring[100];      
+                FILE *fp = fopen("/sd/valeur_temporisation.txt", "r");
+                fgets(numberstring, 100, fp);  
+                    
+                if(fp == NULL)
+                {
+                    error("Impossible d'ouvrir le fichier pour la lecture\n\r");
+                    fclose(fp);  
+                }
+                else
+                {
+                    printf("Lecture temporisation\n\r");
+                    enableEEPROMWriting();
+                    sscanf(numberstring, "%d", &tempo1);
+                    writeEEPROMWord(adressetempo, tempo1);
+                    lecture=readEEPROMWord(adressetempo);
+                    printf ("eeprom: %d\n\r",lecture);
+                    printf ("carte : %d\n\r",tempo1);
+                    sscanf(numberstring+3, "%d", &tempo2);
+                    writeEEPROMWord(adressetempo+4, tempo2);
+                    lecture=readEEPROMWord(adressetempo+4);
+                    printf ("eeprom: %d\n\r",lecture);
+                    printf ("carte : %d\n\r",tempo2);
+                    sscanf(numberstring+6, "%d", &tempo3);
+                    writeEEPROMWord(adressetempo+8, tempo3);
+                    lecture=readEEPROMWord(adressetempo+8);
+                    printf ("eeprom: %d\n\r",lecture);
+                    printf ("carte : %d\n\r",tempo3);
+                    sscanf(numberstring+9, "%d", &tempo4);
+                    writeEEPROMWord(adressetempo+12, tempo4);
+                    lecture=readEEPROMWord(adressetempo+12);
+                    printf ("eeprom: %d\n\r",lecture);
+                    printf ("carte : %d\n\r",tempo4);
+                    sscanf(numberstring+11, "%d", &tempo5);
+                    writeEEPROMWord(adressetempo+16, tempo5);
+                    lecture=readEEPROMWord(adressetempo+16);
+                    printf ("eeprom: %d\n\r",lecture);
+                    printf ("carte : %d\n\r",tempo5);
+                    sscanf(numberstring+14, "%d", &tempo6);
+                    writeEEPROMWord(adressetempo+20, tempo6);
+                    lecture=readEEPROMWord(adressetempo+20);
+                    printf ("eeprom: %d\n\r",lecture);
+                    printf ("carte : %d\n\r",tempo6);
+                    sscanf(numberstring+16, "%d", &tempo7);
+                    writeEEPROMWord(adressetempo+24, tempo7);
+                    lecture=readEEPROMWord(adressetempo+24);
+                    printf ("eeprom: %d\n\r",lecture);
+                    printf ("carte : %d\n\r",tempo7);
+                    sscanf(numberstring+18, "%d", &tempo8);
+                    writeEEPROMWord(adressetempo+28, tempo8);
+                    lecture=readEEPROMWord(adressetempo+28);
+                    printf ("eeprom: %d\n\r",lecture);
+                    printf ("carte : %d\n\r",tempo8);
+                    fclose(fp);                 
+                    printf("Lecture finie!\n\r");
+                    disableEEPROMWriting();
+                }
+                }
+            if (Event.reportObject.index == 7) //Lecture code RFID
+            {
+                SDFileSystem sd(PA_7, PA_6, PA_5, PB_6, "sd");
+                char numberrfid[100];
+                FILE *fp1 = fopen("/sd/valeur_rfid.txt", "r");
+                fgets(numberrfid, 100, fp1);    
+                
+                if(fp1 == NULL)
+                 {
+                    error("Impossible d'ouvrir le fichier pour la lecture\n\r");
+                }
+                flag = 2;
+                printf("Lecture code rfid\n\r");
+                enableEEPROMWriting();
+                sscanf(numberrfid, "%d", &rfid1);
+                writeEEPROMWord(adresserfid, rfid1);
+                lecture=readEEPROMWord(adresserfid);
+                printf ("eeprom: %d\n\r",lecture);
+                printf ("carte : %d\n\r", rfid1);
+                sscanf(numberrfid+8, "%d", &rfid2);
+                writeEEPROMWord(adresserfid+8, rfid2);
+                lecture=readEEPROMWord(adresserfid+8);
+                printf ("eeprom: %d\n\r",lecture);;
+                printf ("carte : %d\n\r", rfid2);
+                sscanf(numberrfid+17, "%d", &rfid3);
+                writeEEPROMWord(adresserfid+16, rfid3);
+                lecture=readEEPROMWord(adresserfid+16);
+                printf ("eeprom: %d\n\r",lecture);
+                printf ("carte : %d\n\r", rfid3);
+                sscanf(numberrfid+25, "%d", &rfid4);
+                writeEEPROMWord(adresserfid+24, rfid4);
+                lecture=readEEPROMWord(adresserfid+24);
+                printf ("eeprom: %d\n\r",lecture);
+                printf ("carte : %d\n\r", rfid4);
+                sscanf(numberrfid+34, "%d", &rfid5);
+                writeEEPROMWord(adresserfid+32, rfid5);
+                lecture=readEEPROMWord(adresserfid+32);
+                printf ("eeprom: %d\n\r",lecture);
+                printf ("carte : %d\n\r", rfid5);
+                fclose(fp1); 
+                printf("Lecture finie!\n\r");
+                disableEEPROMWriting();
+                } 
+            }
+    }
+        return; 
+}
+int main()
+{
+    pc.baud(9600);
+    ledmasse = 1;
+    SetupGenie();
+    genieAttachEventHandler(&myGenieEventHandler);
+    genieWriteContrast(15);
+    
+    while(1)
+    {
+        if (flag == 1) 
+        {
+            led1 = 1;
+            led2 = 1;
+            led3 = 1;
+            led4 = 1;
+            led5 = 0;
+            led6 = 0;
+            led7 = 0;
+            led8 = 0;
+            wait(1);
+            if (chrono == 0)
+            {
+                chrono=tab[i];
+                i=i+1;
+            }
+        }
+
+        else if(flag == 0)
+        {
+            led1 = 0;
+            led2 = 0;
+            led3 = 0;
+            led4 = 0;
+            led5 = 1;
+            led6 = 1;
+            led7 = 1;
+            led8 = 1;
+            chrono=tab[i];
+            wait(1);
+        }
+        else if(flag == 2)
+        {
+            if(rfid.read() == rfid1) 
+            {
+                printf("RFID Tag number : %d\n\r", rfid.read());
+                genieWriteObject(GENIE_OBJ_LED, 0x00, 1); 
+            }
+        }
+        /*if(rfid.read() == rfid1)
+            {
+                genieWriteObject(GENIE_OBJ_LED, 0x00, chrono); 
+            }*/
+    }
+}
\ No newline at end of file
diff -r 3269abcc9c73 -r e104ec24b3fa mbed_genie.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed_genie.cpp	Wed May 05 08:13:43 2021 +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(PC_10,PC_11);
+Serial pcusb(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(9600);
+    pcusb.baud(9600);
+    screen.attach(&RxIrqHandler,Serial::RxIrq);
+    t.start();
+ //   EventChk.attach(&TickerIrq,0.05);
+}
diff -r 3269abcc9c73 -r e104ec24b3fa mbed_genie.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed_genie.h	Wed May 05 08:13:43 2021 +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);
+