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); +