diff --git a/libraries/GpioCtrl/GpioCtrl.cpp b/libraries/GpioCtrl/GpioCtrl.cpp new file mode 100644 index 0000000000000000000000000000000000000000..19ba58edd9caf863e516729baeb58b1180623eb3 --- /dev/null +++ b/libraries/GpioCtrl/GpioCtrl.cpp @@ -0,0 +1,165 @@ +//----------------------------------------------------------------------------- +// Thema: Social Manufacturing Network / Development Environment +// Datei: GpioCtrl.cpp +// Editor: Robert Patzke +// URI/URL: www.mfp-portal.de +//----------------------------------------------------------------------------- +// Lizenz: CC-BY-SA (siehe Wikipedia: Creative Commons) +// + +#include "GpioCtrl.h" + +// -------------------------------------------------------------------------- +// Konstruktoren +// -------------------------------------------------------------------------- +// + +GpioCtrl::GpioCtrl(IntrfGpio *inGpioPtr, int inPeriod) +{ + gpioPtr = inGpioPtr; + period = inPeriod; +} + +// -------------------------------------------------------------------------- +// Konfigurationen +// -------------------------------------------------------------------------- +// + + + +// -------------------------------------------------------------------------- +// Anwendungsfunktionen allgemein +// -------------------------------------------------------------------------- +// +void GpioCtrl::run() +{ + BlinkPtr blinkPtr; + + for(int i = 0; i < MaxGpioElements; i++) + { + // ----------------------------------------------------------------------- + // run blink + // ----------------------------------------------------------------------- + // + blinkPtr = &blinkEl[i]; + + if(blinkPtr->doBlink && (blinkPtr->portRef != NULL)) + { + // Blinken wird aktiviert/deaktiviert + // -------------------------------------------------------- + if(!blinkPtr->blinked) // Noch kein Blinken + { + if(!blinkPtr->portSet) // Port noch nicht gesetzt + { + if(blinkPtr->invPort) + gpioPtr->clr(blinkPtr->portRef); + else + gpioPtr->set(blinkPtr->portRef); + blinkPtr->portSet = true; + } + + if(blinkPtr->blinkLen > 0) + blinkPtr->blinkLen--; + else + { + blinkPtr->blinked = true; + blinkPtr->blinkLen = blinkPtr->blinkLenSet; + } + } + else // blinked + { + if(blinkPtr->portSet) // Port ist gesetzt + { + if(blinkPtr->invPort) + gpioPtr->set(blinkPtr->portRef); + else + gpioPtr->clr(blinkPtr->portRef); + blinkPtr->portSet = false; + } + + if(blinkPtr->repeatPause > 0) + { + blinkPtr->repeatPause--; + } + else if(blinkPtr->repeat > 0) + { + blinkPtr->repeat--; + blinkPtr->repeatPause = blinkPtr->repeatPauseSet; + blinkPtr->blinked = false; + } + else + { + if(blinkPtr->blinkPause > 0) + blinkPtr->blinkPause--; + else + { + blinkPtr->blinked = false; + blinkPtr->blinkPause = blinkPtr->blinkPauseSet; + blinkPtr->repeat = blinkPtr->repeatSet; + blinkPtr->repeatPause = blinkPtr->repeatPauseSet; + } + } + } + // -------------------------------------------------------- + } // doBlink, portRef + } // for +} // run + +// -------------------------------------------------------------------------- +// Anwendungsfunktionen Steuerung der Pins +// -------------------------------------------------------------------------- +// + +void GpioCtrl::blink(GpioExtRefPtr portRef, int chn, int len, int pause) +{ + blink(portRef,chn,len,0,pause,0,false); +} + +void GpioCtrl::blink(GpioExtRefPtr portRef, int chn, int len, int pause, bool invert) +{ + blink(portRef,chn,len,0,pause,0,invert); +} + +void GpioCtrl::blink(GpioExtRefPtr portRef, int chn, int len, int wait, int pause, int repeat, bool invert) +{ + BlinkPtr blinkPtr; + int calc; + + if(chn < 0 || chn >= MaxGpioElements) return; + if(len <= 0) return; + if(period == 0) return; + + blinkPtr = &blinkEl[chn]; + blinkPtr->portRef = portRef; + blinkPtr->invPort = invert; + + calc = (1000 * len) / period; + if(calc == 0) + calc = 1; + blinkPtr->blinkLen = blinkPtr->blinkLenSet = calc; + + calc = (1000 * pause) / period; + if(calc == 0) + calc = 1; + blinkPtr->blinkPause = blinkPtr->blinkPauseSet = calc; + + if(repeat != 0) + { + blinkPtr->repeat = blinkPtr->repeatSet = repeat; + + calc = (1000 * wait) / period; + if(calc == 0) + calc = 1; + blinkPtr->repeatPause = blinkPtr->repeatPauseSet = calc; + } + + blinkPtr->blinked = false; + blinkPtr->doBlink = true; + blinkPtr->portSet = false; +} + + +// ---------------------------------------------------------------------------- +// Ereignisbearbeitung und Interrupts +// ---------------------------------------------------------------------------- +// diff --git a/libraries/GpioCtrl/GpioCtrl.h b/libraries/GpioCtrl/GpioCtrl.h new file mode 100644 index 0000000000000000000000000000000000000000..8374bdd884b86a50990246476af128ec7702471b --- /dev/null +++ b/libraries/GpioCtrl/GpioCtrl.h @@ -0,0 +1,91 @@ +//----------------------------------------------------------------------------- +// Thema: Social Manufacturing Network / Development Environment +// Datei: GpioCtrl.h +// Editor: Robert Patzke +// URI/URL: www.mfp-portal.de +//----------------------------------------------------------------------------- +// Lizenz: CC-BY-SA (siehe Wikipedia: Creative Commons) +// +#ifndef GpioCtrl_h +#define GpioCtrl_h +//----------------------------------------------------------------------------- + +#include "stdio.h" +#include "IntrfGpio.h" + +#define MaxGpioElements 4 + +class GpioCtrl +{ + // -------------------------------------------------------------------------- + // spezifische Datentypen + // -------------------------------------------------------------------------- + // + typedef struct _Blink + { + int blinkLen; + int blinkLenSet; + int blinkPause; + int blinkPauseSet; + int repeat; + int repeatSet; + int repeatPause; + int repeatPauseSet; + bool doBlink; + bool blinked; + bool portSet; + bool invPort; + GpioExtRefPtr portRef; + } Blink, *BlinkPtr; + +private: + // -------------------------------------------------------------------------- + // lokale Variablen + // -------------------------------------------------------------------------- + // + IntrfGpio *gpioPtr; // Referenz auf Pin-Treiber + Blink blinkEl[MaxGpioElements]; // Liste der Blinkelemente + int period; // Aufrufperiode in Mikrosekunden + + // -------------------------------------------------------------------------- + // lokale Funktionen + // -------------------------------------------------------------------------- + // + +public: + // -------------------------------------------------------------------------- + // Konstruktoren + // -------------------------------------------------------------------------- + // + GpioCtrl(IntrfGpio *inGpioPtr, int inPeriod); + + // -------------------------------------------------------------------------- + // Konfigurationen + // -------------------------------------------------------------------------- + // + + // -------------------------------------------------------------------------- + // Anwendungsfunktionen + // -------------------------------------------------------------------------- + // + void run(); + void blink(GpioExtRefPtr portRef, int chn, int len, int pause); + void blink(GpioExtRefPtr portRef, int chn, int len, int pause, bool invert); + void blink(GpioExtRefPtr portRef, int chn, int len, int wait, int pause, int repeat); + void blink(GpioExtRefPtr portRef, int chn, int len, int wait, int pause, int repeat, bool invert); + + + // ---------------------------------------------------------------------------- + // Ereignisbearbeitung und Interrupts + // ---------------------------------------------------------------------------- + // + + // -------------------------------------------------------------------------- + // Debugging und globale Variablen + // -------------------------------------------------------------------------- + // + +}; + +//----------------------------------------------------------------------------- +#endif // GpioCtrl_h diff --git a/libraries/nRF52840Gpio/nRF52840Gpio.cpp b/libraries/nRF52840Gpio/nRF52840Gpio.cpp index 47a25ddebcff11a2d9ef003cf83ddf1be250d057..57f3a89ec14be8bbf2aa21fa59f87a5675f6aee9 100644 --- a/libraries/nRF52840Gpio/nRF52840Gpio.cpp +++ b/libraries/nRF52840Gpio/nRF52840Gpio.cpp @@ -85,7 +85,7 @@ GpioError nRF52840Gpio::config(int nrFrom, int nrTo, unsigned int cnfBits, GpioE tmpMask = IfDrvPullDown | IfDrvPullUp; if((cnfBits & tmpMask) == tmpMask) return (GEcdictPar); - cnfValue = getCnfValue(cnfBits); + cnfValue = getCnfValue(cnfBits); // spezifische Bits setzen tmpMask = 0; // Bedienen des angegebenen Bereiches @@ -93,9 +93,9 @@ GpioError nRF52840Gpio::config(int nrFrom, int nrTo, unsigned int cnfBits, GpioE for(int i = nrFrom; i <= nrTo; i++) { portNum = (i & 0x0E0) >> 5; - pinNum = i & 0x01F; + pinNum = i & 0x01F; // 0 ... 31 - tmpMask |= (1 << i); + tmpMask |= (1 << pinNum); if(portNum == 0) gpioPtr = NrfGpioPtr0; @@ -116,7 +116,7 @@ GpioError nRF52840Gpio::config(int nr, unsigned int cnfBits, GpioExtRefPtr refPt return(config(nr,nr,cnfBits, refPtr)); } -GpioError nRF52840Gpio::config(GpioExtMask mask, unsigned int cnfBits, GpioExtRefPtr refPtr) +GpioError nRF52840Gpio::config(GpioExtMask *maskPtr, unsigned int cnfBits, GpioExtRefPtr refPtr) { GpioError retv = GEnoError; dword cnfVal; @@ -135,12 +135,12 @@ GpioError nRF52840Gpio::config(GpioExtMask mask, unsigned int cnfBits, GpioExtRe for(int i = 0; i < 32; i++) { - if(mask.port == 0) + if(maskPtr->port == 0) gpioPtr = NrfGpioPtr0; else gpioPtr = NrfGpioPtr1; - if(mask.pins & chkMask) + if(maskPtr->pins & chkMask) gpioPtr->PIN_CNF[i] = cnfVal; chkMask <<= 1; @@ -149,7 +149,7 @@ GpioError nRF52840Gpio::config(GpioExtMask mask, unsigned int cnfBits, GpioExtRe if(refPtr != NULL) { refPtr->ioPtr = (dword *) gpioPtr; - refPtr->pins = mask.pins; + refPtr->pins = maskPtr->pins; } return(retv); @@ -183,7 +183,7 @@ GpioError nRF52840Gpio::configArd(ArdMask ardMask, unsigned int cnfBits) break; } - return config(ioMask, cnfBits, NULL); + return config(&ioMask, cnfBits, NULL); } @@ -192,6 +192,25 @@ GpioError nRF52840Gpio::configArd(ArdMask ardMask, unsigned int cnfBits) // Anwendungsfunktionen // -------------------------------------------------------------------------- // +bool nRF52840Gpio::isSet(GpioExtRefPtr ioRefPtr) +{ + gpioPtr = (nrfGpioPtr) ioRefPtr->ioPtr; + return(gpioPtr->IN & ioRefPtr->pins); +} + +bool nRF52840Gpio::anySet(GpioExtRefPtr ioRefPtr) +{ + gpioPtr = (nrfGpioPtr) ioRefPtr->ioPtr; + return(gpioPtr->IN & ioRefPtr->pins); +} + +bool nRF52840Gpio::allSet(GpioExtRefPtr ioRefPtr) +{ + gpioPtr = (nrfGpioPtr) ioRefPtr->ioPtr; + return((gpioPtr->IN & ioRefPtr->pins) == ioRefPtr->pins); +} + + void nRF52840Gpio::read(GpioExtRefPtr ioRefPtr, GpioExtValPtr valPtr) { gpioPtr = (nrfGpioPtr) ioRefPtr->ioPtr; diff --git a/libraries/nRF52840Gpio/nRF52840Gpio.h b/libraries/nRF52840Gpio/nRF52840Gpio.h index addf5ad533ddfecabd2c540824238c278a117998..0bf899dac62db0ff73fa3f58953a6ed37fccc910 100644 --- a/libraries/nRF52840Gpio/nRF52840Gpio.h +++ b/libraries/nRF52840Gpio/nRF52840Gpio.h @@ -110,6 +110,7 @@ typedef struct _nrfGpio #define ArdD11 P1(1) #define ArdD12 P1(8) #define ArdD13 P0(13) +#define ArdLedGn P1(9) #define ArdD2Mask (1 << 11) #define ArdD3Mask (1 << 12) @@ -150,7 +151,7 @@ public: dword getCnfValue(unsigned int cnfBits); GpioError config(int nr, unsigned int cnfBits, GpioExtRefPtr refPtr); GpioError config(int nrFrom, int nrTo, unsigned int cnfBits, GpioExtRefPtr refPtr); - GpioError config(GpioExtMask mask, unsigned int cnfBits, GpioExtRefPtr refPtr); + GpioError config(GpioExtMaskPtr maskPtr, unsigned int cnfBits, GpioExtRefPtr refPtr); GpioError configArd(ArdMask ardMask, unsigned int cnfBits); @@ -158,6 +159,9 @@ public: // Anwendungsfunktionen // -------------------------------------------------------------------------- // + bool isSet(GpioExtRefPtr ioRef); + bool allSet(GpioExtRefPtr ioRef); + bool anySet(GpioExtRefPtr ioRef); void read(GpioExtRefPtr ioRef, GpioExtValPtr valPtr); dword readArd(ArdMask ardMask); diff --git a/sketches/SoaapBleSlave/SoaapBleSlave.h b/sketches/SoaapBleSlave/SoaapBleSlave.h index 84bf1f4243b3b5f477a99f99819ef95061c2cf35..fc5dd65c3254e6f98e1c2cbdb3c04d42eaa12df2 100644 --- a/sketches/SoaapBleSlave/SoaapBleSlave.h +++ b/sketches/SoaapBleSlave/SoaapBleSlave.h @@ -19,6 +19,7 @@ #include "StateMachine.h" #include "nRF52840Gpio.h" +#include "GpioCtrl.h" #include "nRF52840Twi.h" #include "SensorLSM9DS1.h" @@ -62,6 +63,7 @@ void smSensGetErrors() ; void smDebugProcMeas(); void smSensGetTimeOuts() ; void smSensGetRunCounts() ; +void smTestIO(); void smTempTesting(); void smTestAdcMem(); #endif diff --git a/sketches/SoaapBleSlave/SoaapBleSlave.ino b/sketches/SoaapBleSlave/SoaapBleSlave.ino index e2c03755245a1e74d71dc505a0e14aad0d63b515..70acbc983e06ac0682f3b734b5e8f7fa5ca943fe 100644 --- a/sketches/SoaapBleSlave/SoaapBleSlave.ino +++ b/sketches/SoaapBleSlave/SoaapBleSlave.ino @@ -46,7 +46,7 @@ char *StartMsg = #ifdef SlaveADR4 "(Adr=4), " #endif - "Version 20221024-1 " + "Version 20221107-1 " }; LoopCheck lc; @@ -71,12 +71,13 @@ Monitor mon(modeEcho | modeNl,0,&lc); char *infoThis = { -"SOAAP BLE Slave Version 22.09.25-1\r\n" -"c0 Abschalten der periodischen Meldung\r\n" -"c1 Auslesen BlePoll-Debug-Register\r\n" -"c2 Steuern/Analysieren des Polling\r\n" -"c3 Steuern/Analysieren der Messwerterfassung\r\n" -"c4 Temporäre lokale Tests\r\n" + "SOAAP BLE Slave Version 22.09.25-1\r\n" + "c0 Abschalten der periodischen Meldung\r\n" + "c1 Auslesen BlePoll-Debug-Register\r\n" + "c2 Steuern/Analysieren des Polling\r\n" + "c3 Steuern/Analysieren der Messwerterfassung\r\n" + "c4 Testen von Peripheriezugriffen\r\n" + "c5 Temporäre lokale Tests\r\n" }; #endif @@ -145,8 +146,19 @@ SensorLSM9DS1 sens((IntrfTw *) &twi, SensorCycle); ProcMeas proc((IntrfMeas *) &sens); // Vorauswertung der Messwerte +GpioExtRef LedRot; +// Handle für den Zugriff auf eine rote LED an Pin D11 +GpioExtRef LedGreen; +// Handle für die grüne LED auf dem Nano Board + nRF52840Gpio gpio; -// Zugriff auf die Anschlüsse des Board +// Zugriff auf die digitalen Anschlüsse des Board + +#define GpioCycleTime 500 +// Zykluszeit (in Mikrosekunden) bei der Ansteuerung digitaler I/Os + +GpioCtrl ioCtrl((IntrfGpio *) &gpio, GpioCycleTime); +// Instanz zur Ansteuerung der Peripherie (Blinken, etc.) bool getValues(PlpType plpType, byte *dest); // Vorwärtsreferenz für Datenübergabe @@ -155,12 +167,22 @@ bool xchgCtrl(PlpType plpType, byte *dest, byte *src, int sSize); // Vorwärtsreferenz für Steuerungsaustausch nRF52840Adc adc; +// Anwendung des A/D-Wandlers void setup() { TwiParams twiPar; // Parameter für den I2C-Bus - gpio.configArd(ArdA0A3, IfDrvInput | IfDrvPullUp); + // Einschalten der roten LED (am Pin D11 des Arduino-Board) + // bei der SOAAP-Anwendung + // + gpio.config(ArdD11, IfDrvOutput | IfDrvOpenDrain | IfDrvStrongLow, &LedRot); + //ioCtrl.blink(&LedRot, 0, 2, 998, true); + ioCtrl.blink(&LedRot, 0, 2, 200, 398, 2, true); + + // Ausschalten der grünen LED (auf dem Arduino-Board) + // + gpio.config(ArdLedGn, IfDrvInput, &LedGreen); #ifdef DebugTerminal mon.config(6); // 6 Anzeigekanäle, die von ArduinoMonTerm aufgebaut werden @@ -268,18 +290,23 @@ void loop() if(lc.timerMicro(lcTimer2, ProcMeasCycle, 0)) proc.run(); + // Alle 500 Mikrosekunden erfolgt der Aufruf der Peripheriesteuerung + // + if(lc.timerMicro(lcTimer3, GpioCycleTime, 0)) + ioCtrl.run(); + #ifdef DebugTerminal // Alle 5 Millisekunden wird die Zustandsmaschine für // betriebliche Abläufe aufgerufen // - if(lc.timerMilli(lcTimer3, smCycleTime, 0)) + if(lc.timerMilli(lcTimer4, smCycleTime, 0)) { sm.run(); } // Jede halbe Sekunde erfolgt die Ausgabe der Version // - if(lc.timerMilli(lcTimer4, 500, 0)) + if(lc.timerMilli(lcTimer5, 500, 0)) { if(!mon.cFlag[0]) { @@ -455,6 +482,8 @@ void smCheckJobs() else if(mon.cFlag[3] && !mon.busy) sm.enter(smCheckSens); else if(mon.cFlag[4] && !mon.busy) + sm.enter(smTestIO); + else if(mon.cFlag[5] && !mon.busy) sm.enter(smTempTesting); } @@ -1124,7 +1153,43 @@ void smSensGetRunCounts() } // ---------------------------------------------------------------------------- -// (4) Temporäres Testen lokaler Speicher und Funktionen +// (4) Testen von Peripheriezugriffen +// ---------------------------------------------------------------------------- +// + +void smTestIO() +{ + if(sm.firstEnter()) + { + mon.print((char *) "Testen der Peripheriezugriffe "); + mon.lastKeyIn = ':'; + } + + if(mon.lastKeyIn == ':') return; + + charOut[0] = mon.lastKeyIn; + charOut[1] = '\0'; + mon.println(charOut); + + if(mon.lastKeyIn == '0' || mon.lastKeyIn == ' ') + { + mon.cFlag[4] = false; + mon.print((char *) "-- Schleifenabbruch - drücke Enter"); + sm.enter(smCheckJobs); + } + else if(mon.lastKeyIn == 's' || mon.lastKeyIn == 'S') + { + mon.print("ConfStru = "); + mon.print((byte *) &LedRot.ioPtr,4,' '); + mon.print(" / "); + mon.println((byte *) &LedRot.pins,4,' '); + } + sm.resetEnter(); +} + + +// ---------------------------------------------------------------------------- +// (5) Temporäres Testen lokaler Speicher und Funktionen // ---------------------------------------------------------------------------- // @@ -1144,7 +1209,7 @@ void smTempTesting() if(mon.lastKeyIn == '0' || mon.lastKeyIn == ' ') { - mon.cFlag[4] = false; + mon.cFlag[5] = false; mon.print((char *) "-- Schleifenabbruch - drücke Enter"); sm.enter(smCheckJobs); }