diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..fb4390bb88d0d8e2d8555c4adf1ab184a2badd1e --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +.gitignore +.pio +.vscode diff --git a/libraries/BlePoll/library.json b/libraries/BlePoll/library.json new file mode 100644 index 0000000000000000000000000000000000000000..527c6851ecc4967d9c38005a9e6175f17bff48ab --- /dev/null +++ b/libraries/BlePoll/library.json @@ -0,0 +1,4 @@ +{ + "name": "BlePoll", + "version": "0.0.1+20221111" + } \ No newline at end of file diff --git a/libraries/ComRingBuf/library.json b/libraries/ComRingBuf/library.json new file mode 100644 index 0000000000000000000000000000000000000000..57784042d87eec4ac24aff6895992bda25c14a39 --- /dev/null +++ b/libraries/ComRingBuf/library.json @@ -0,0 +1,4 @@ +{ + "name": "ComRingBuf", + "version": "0.0.1+20221111" +} \ No newline at end of file diff --git a/libraries/EulerAngles/library.json b/libraries/EulerAngles/library.json new file mode 100644 index 0000000000000000000000000000000000000000..06c82fefc8dfeeed76cf9a118afc7c1884013dbe --- /dev/null +++ b/libraries/EulerAngles/library.json @@ -0,0 +1,4 @@ +{ + "name": "EulerAngles", + "version": "0.0.1+20221111" + } \ No newline at end of file diff --git a/libraries/GpioCtrl/library.json b/libraries/GpioCtrl/library.json new file mode 100644 index 0000000000000000000000000000000000000000..175b326846e0682478750036c2d21d8da585a3dd --- /dev/null +++ b/libraries/GpioCtrl/library.json @@ -0,0 +1,4 @@ +{ + "name": "GpioCtrl", + "version": "0.0.1+20221111" + } \ No newline at end of file diff --git a/libraries/LoopCheck/examplesLinux/testCppArduino.cpp b/libraries/LoopCheck/examplesLinux/testCppArduino.cpp old mode 100755 new mode 100644 diff --git a/libraries/LoopCheck/examplesWindows/README.md b/libraries/LoopCheck/examplesWindows/README.md new file mode 100644 index 0000000000000000000000000000000000000000..1951370fc38c00f3b8548bb0d765bdfe39596efe --- /dev/null +++ b/libraries/LoopCheck/examplesWindows/README.md @@ -0,0 +1,2 @@ +Zur Kompatibilität mit platformIO wurde die Datei testLoopCheck umbenannt. +Wenn die Datei verwendet werden soll, muss die Dateiendung wieder auf .cpp geändert werden. \ No newline at end of file diff --git a/libraries/LoopCheck/examplesWindows/testLoopCheck.cpp b/libraries/LoopCheck/examplesWindows/testLoopCheck.txt old mode 100755 new mode 100644 similarity index 97% rename from libraries/LoopCheck/examplesWindows/testLoopCheck.cpp rename to libraries/LoopCheck/examplesWindows/testLoopCheck.txt index cce3a51c0a5160c513ab8913d8763005647e9cf5..86ed449253fe4eb2f4b5a3207525df16bc057cbd --- a/libraries/LoopCheck/examplesWindows/testLoopCheck.cpp +++ b/libraries/LoopCheck/examplesWindows/testLoopCheck.txt @@ -1,145 +1,145 @@ -//----------------------------------------------------------------------------- -// Thema: Social Manufacturing Network / Software Loop Checking and Timing -// Datei: testLoopCheck.cpp -// Editor: Robert Patzke -// URI/URL: www.mfp-portal.de -//----------------------------------------------------------------------------- -// Lizenz: CC-BY-SA (see Wikipedia: Creative Commons) -// -// This program was developed and tested with Visual Studio 2010 -// Following configuration has to be done in C/C++ -> Preprocessor Definitions -// -// UseGithubPath -// Visual Studio searches for includes in the environment of the sources. -// With the switch UseGithubPath the #include directives in source files are -// relativ to the structure of the tree as it is used on Github repository. -// So it will work after simple copying the tree from Github. -// -// smnDEFBYBUILD -// With this switch the first part of file environment.h will be used. -// It is possible to use environment.h for many purposes. -// Without defining smnDEFBYBUILD the file has to be edited to fit to your IDE -// and your microcontroller targets -// -// smnWIN32_VS -// This switch opens a list of definitions in environment.h controlling -// conditional compilation in many source files - -#include <stdlib.h> -#include <stdio.h> -#include <time.h> -#include <sys/timeb.h> - -#include "../LoopCheck.h" - -LoopCheck loopCheck; - -int main(int argc, char *argv[]) -{ - time_t timeSec; - struct tm *timeStructPtr; - struct timeb ftimeStruct; - lcDateTime dateTime; - int msecOldPC, msecOldLC, msecOldOP; - int secOldPC, secOldLC, secOldOP; - LoopStatistics statistic; - - // ------------------------------------------------------------------------- - // setup - // ------------------------------------------------------------------------- - // - printf("Testing simulation of Arduino with Windows\n"); - printf("Check loop behaviour with LoopCheck, demonstrate clocks\n"); - - // Getting PC time with milliseconds resolution - // - ftime(&ftimeStruct); - timeSec = ftimeStruct.time; - timeStructPtr = gmtime(&timeSec); - - // Preparing some Variables to calculate and show time difference - // - msecOldPC = msecOldLC = dateTime.Millisecond = ftimeStruct.millitm; - secOldPC = secOldLC = dateTime.Second = timeStructPtr->tm_sec; - - // Setting the software clock of LoopCheck to PC time - // - dateTime.Minute = timeStructPtr->tm_min; - dateTime.Hour = timeStructPtr->tm_hour; - dateTime.Day = timeStructPtr->tm_mday; - dateTime.Month = timeStructPtr->tm_mon + 1; - dateTime.Year = timeStructPtr->tm_year + 1900; - - loopCheck.setDateTime(dateTime); - - // ------------------------------------------------------------------------- - // loop - // ------------------------------------------------------------------------- - // - while(1) - { - loopCheck.begin(); // this function has to be called first in loop - // ----------------------------------------------------------------------- - - // Comparing the software clock with the PC clock and showing the difference - // - if(loopCheck.timerMilli(0,1000,0)) - { - // - // This gets true once every second (1000 milliseconds) - // The error is that of the PC counter (clock or performance timer) - - // Get the current PC time with milliseconds - // - ftime(&ftimeStruct); - timeSec = ftimeStruct.time; - timeStructPtr = gmtime(&timeSec); - - // Get the current time of LoopCheck software clock - // - loopCheck.getDateTime(&dateTime); - - // Show the PC time and the LoopCheck time and their differences to the last measurement - // a second back (do not mind the overflow error with the distance) - // - printf("PC Time = %02d:%02d:%02d,%03d Diff=%4d LC Time = %02d:%02d:%02d,%03d Diff=%4d\n", - timeStructPtr->tm_hour, timeStructPtr->tm_min, timeStructPtr->tm_sec, ftimeStruct.millitm, - ftimeStruct.millitm - msecOldPC + 1000*(timeStructPtr->tm_sec - secOldPC), - dateTime.Hour, dateTime.Minute, dateTime.Second, dateTime.Millisecond, - dateTime.Millisecond - msecOldLC + 1000*(dateTime.Second - secOldLC)); - // - // You will see, that the timer of LoopCheck is rather accurate. - // The variation of repetition time is less than 1% with some exceptions. - // Also the LoopCheck software clock is nearly perfect, because the - // underlaying counters are synchronised to the OS clock - - // preperation for the measurement of next cycle - // - msecOldPC = ftimeStruct.millitm; - msecOldLC = dateTime.Millisecond; - secOldPC = timeStructPtr->tm_sec; - secOldLC = dateTime.Second; - - // to show the difference between microcontrollers and OS based computers - // we will look into the statistics of LoopCheck - // - loopCheck.getStatistics(&statistic); - - // alarmCount is incremented, whenever the time between 2 loops exceeds PeriodMinTime - // (adjust PeriodMinTime in LoopCheck.h for your target system) - // - printf("Loop violations: %4d ", statistic.alarmCount); - // - // we have also a classification of exceeding the millisecond of loop cycle time - // counting the number of exceedings indexed by number of milliseconds. - // - for(int i = 0; i < LoopScreeningGrades - 1; i++) - printf(" %2dms: %4d", i+1 , statistic.rtSreening[i]); - printf(" >%2dms: %4d\r\n\n", LoopScreeningGrades - 1, statistic.rtSreening[LoopScreeningGrades - 1]); - - } - - // ----------------------------------------------------------------------- - loopCheck.end(); // this function has to be called last in the loop - } -} +//----------------------------------------------------------------------------- +// Thema: Social Manufacturing Network / Software Loop Checking and Timing +// Datei: testLoopCheck.cpp +// Editor: Robert Patzke +// URI/URL: www.mfp-portal.de +//----------------------------------------------------------------------------- +// Lizenz: CC-BY-SA (see Wikipedia: Creative Commons) +// +// This program was developed and tested with Visual Studio 2010 +// Following configuration has to be done in C/C++ -> Preprocessor Definitions +// +// UseGithubPath +// Visual Studio searches for includes in the environment of the sources. +// With the switch UseGithubPath the #include directives in source files are +// relativ to the structure of the tree as it is used on Github repository. +// So it will work after simple copying the tree from Github. +// +// smnDEFBYBUILD +// With this switch the first part of file environment.h will be used. +// It is possible to use environment.h for many purposes. +// Without defining smnDEFBYBUILD the file has to be edited to fit to your IDE +// and your microcontroller targets +// +// smnWIN32_VS +// This switch opens a list of definitions in environment.h controlling +// conditional compilation in many source files + +#include <stdlib.h> +#include <stdio.h> +#include <time.h> +#include <sys/timeb.h> + +#include "../LoopCheck.h" + +LoopCheck loopCheck; + +int main(int argc, char *argv[]) +{ + time_t timeSec; + struct tm *timeStructPtr; + struct timeb ftimeStruct; + lcDateTime dateTime; + int msecOldPC, msecOldLC, msecOldOP; + int secOldPC, secOldLC, secOldOP; + LoopStatistics statistic; + + // ------------------------------------------------------------------------- + // setup + // ------------------------------------------------------------------------- + // + printf("Testing simulation of Arduino with Windows\n"); + printf("Check loop behaviour with LoopCheck, demonstrate clocks\n"); + + // Getting PC time with milliseconds resolution + // + ftime(&ftimeStruct); + timeSec = ftimeStruct.time; + timeStructPtr = gmtime(&timeSec); + + // Preparing some Variables to calculate and show time difference + // + msecOldPC = msecOldLC = dateTime.Millisecond = ftimeStruct.millitm; + secOldPC = secOldLC = dateTime.Second = timeStructPtr->tm_sec; + + // Setting the software clock of LoopCheck to PC time + // + dateTime.Minute = timeStructPtr->tm_min; + dateTime.Hour = timeStructPtr->tm_hour; + dateTime.Day = timeStructPtr->tm_mday; + dateTime.Month = timeStructPtr->tm_mon + 1; + dateTime.Year = timeStructPtr->tm_year + 1900; + + loopCheck.setDateTime(dateTime); + + // ------------------------------------------------------------------------- + // loop + // ------------------------------------------------------------------------- + // + while(1) + { + loopCheck.begin(); // this function has to be called first in loop + // ----------------------------------------------------------------------- + + // Comparing the software clock with the PC clock and showing the difference + // + if(loopCheck.timerMilli(0,1000,0)) + { + // + // This gets true once every second (1000 milliseconds) + // The error is that of the PC counter (clock or performance timer) + + // Get the current PC time with milliseconds + // + ftime(&ftimeStruct); + timeSec = ftimeStruct.time; + timeStructPtr = gmtime(&timeSec); + + // Get the current time of LoopCheck software clock + // + loopCheck.getDateTime(&dateTime); + + // Show the PC time and the LoopCheck time and their differences to the last measurement + // a second back (do not mind the overflow error with the distance) + // + printf("PC Time = %02d:%02d:%02d,%03d Diff=%4d LC Time = %02d:%02d:%02d,%03d Diff=%4d\n", + timeStructPtr->tm_hour, timeStructPtr->tm_min, timeStructPtr->tm_sec, ftimeStruct.millitm, + ftimeStruct.millitm - msecOldPC + 1000*(timeStructPtr->tm_sec - secOldPC), + dateTime.Hour, dateTime.Minute, dateTime.Second, dateTime.Millisecond, + dateTime.Millisecond - msecOldLC + 1000*(dateTime.Second - secOldLC)); + // + // You will see, that the timer of LoopCheck is rather accurate. + // The variation of repetition time is less than 1% with some exceptions. + // Also the LoopCheck software clock is nearly perfect, because the + // underlaying counters are synchronised to the OS clock + + // preperation for the measurement of next cycle + // + msecOldPC = ftimeStruct.millitm; + msecOldLC = dateTime.Millisecond; + secOldPC = timeStructPtr->tm_sec; + secOldLC = dateTime.Second; + + // to show the difference between microcontrollers and OS based computers + // we will look into the statistics of LoopCheck + // + loopCheck.getStatistics(&statistic); + + // alarmCount is incremented, whenever the time between 2 loops exceeds PeriodMinTime + // (adjust PeriodMinTime in LoopCheck.h for your target system) + // + printf("Loop violations: %4d ", statistic.alarmCount); + // + // we have also a classification of exceeding the millisecond of loop cycle time + // counting the number of exceedings indexed by number of milliseconds. + // + for(int i = 0; i < LoopScreeningGrades - 1; i++) + printf(" %2dms: %4d", i+1 , statistic.rtSreening[i]); + printf(" >%2dms: %4d\r\n\n", LoopScreeningGrades - 1, statistic.rtSreening[LoopScreeningGrades - 1]); + + } + + // ----------------------------------------------------------------------- + loopCheck.end(); // this function has to be called last in the loop + } +} diff --git a/libraries/LoopCheck/library.json b/libraries/LoopCheck/library.json new file mode 100644 index 0000000000000000000000000000000000000000..56fba8defed884a44260e6f801b9c333fb39beb4 --- /dev/null +++ b/libraries/LoopCheck/library.json @@ -0,0 +1,32 @@ +{ + "name": "LoopCheck", + "version": "0.0.1+20221111", + "examples": [ + { + "name": "lcBlink", + "base": "examples", + "files": ["lcBlink.ino"] + }, + { + "name": "lcStatistics", + "base": "examples", + "files": ["lcStatistics.ino"] + }, + { + "name": "testCppArduino", + "base": "examplesLinux", + "files": ["testArduino.cpp"] + }, + { + "name": "testLoopCheck", + "base": "examplesWindows", + "files": ["testLoopCheck.cpp"] + } +], +"built": { + "srcFilter" : ["-<./examples>","-<./examplesLinux>","-<./examplesWindows>"] +}, +"export":{ + "exclude" : ["./examples", "./examplesLinux","./examplesWindows"] +} +} \ No newline at end of file diff --git a/libraries/MidiNotes/library.json b/libraries/MidiNotes/library.json new file mode 100644 index 0000000000000000000000000000000000000000..42acf47ed2c1b38686923000d11bd00cb9b2c212 --- /dev/null +++ b/libraries/MidiNotes/library.json @@ -0,0 +1,4 @@ +{ + "name": "MidiNotes", + "version": "0.0.1+20221111" +} \ No newline at end of file diff --git a/libraries/Monitor/library.json b/libraries/Monitor/library.json new file mode 100644 index 0000000000000000000000000000000000000000..0509f4e9768d95b29910c8ca3d55c095650902fc --- /dev/null +++ b/libraries/Monitor/library.json @@ -0,0 +1,4 @@ +{ + "name": "Monitor", + "version": "0.0.1+20221111" +} \ No newline at end of file diff --git a/libraries/ProcMeas/ProcMeas.h b/libraries/ProcMeas/ProcMeas.h index e0b14eb39e112aee919620b74143b2df9adad6f8..7dd48d389a7708bdecc34a50c04e1e4c73801de0 100644 --- a/libraries/ProcMeas/ProcMeas.h +++ b/libraries/ProcMeas/ProcMeas.h @@ -17,6 +17,7 @@ #include "EulerAngles.h" //#define ProcMeasDebug +#define RAD_TO_DEG 57.2957795 typedef enum _PmState { diff --git a/libraries/ProcMeas/library.json b/libraries/ProcMeas/library.json new file mode 100644 index 0000000000000000000000000000000000000000..b488de4d38daf60b767c23192ce4ccd3be8450c6 --- /dev/null +++ b/libraries/ProcMeas/library.json @@ -0,0 +1,4 @@ +{ + "name": "ProcMeas", + "version": "0.0.1+20221111" + } \ No newline at end of file diff --git a/libraries/SensorLSM9DS1/library.json b/libraries/SensorLSM9DS1/library.json new file mode 100644 index 0000000000000000000000000000000000000000..4e9466a6450bbe943a0e52aa20b41f7de08a23f9 --- /dev/null +++ b/libraries/SensorLSM9DS1/library.json @@ -0,0 +1,4 @@ +{ + "name": "SensorLSM9DS1", + "version": "0.0.1+20221111" +} \ No newline at end of file diff --git a/libraries/SoaapComDue/library.json b/libraries/SoaapComDue/library.json new file mode 100644 index 0000000000000000000000000000000000000000..d2f55321143f4a081f460f39124d5d13150a1d44 --- /dev/null +++ b/libraries/SoaapComDue/library.json @@ -0,0 +1,4 @@ +{ + "name": "SoaapComDue", + "version": "0.0.1+20221111" + } \ No newline at end of file diff --git a/libraries/SoaapMsg/library.json b/libraries/SoaapMsg/library.json new file mode 100644 index 0000000000000000000000000000000000000000..7b6bd50a4921c2a714accaec5852e2d737a2b501 --- /dev/null +++ b/libraries/SoaapMsg/library.json @@ -0,0 +1,4 @@ +{ + "name": "SoaapMsg", + "version": "0.0.1+20221111" +} \ No newline at end of file diff --git a/libraries/StateMachine/library.json b/libraries/StateMachine/library.json new file mode 100644 index 0000000000000000000000000000000000000000..2a474a268173ce0290524721d59648c7aab7bf4f --- /dev/null +++ b/libraries/StateMachine/library.json @@ -0,0 +1,4 @@ +{ + "name": "StateMachine", + "version": "0.0.1+20221111" +} \ No newline at end of file diff --git a/libraries/environment/SoaapBleMaster.h b/libraries/environment/SoaapBleMaster.h new file mode 100644 index 0000000000000000000000000000000000000000..98bd22eb99c0839cf9f5ad554dd116b21c0afd81 --- /dev/null +++ b/libraries/environment/SoaapBleMaster.h @@ -0,0 +1,63 @@ +// ---------------------------------------------------------------------------- +// SoaapBleMaster.h +// Beispielhafte Anwendung SOAAP / Steuerung optischer und akustischer Ausgaben +// Kommunikation über BLE-Funkanäle mit Bewerbungstelegrammen +// P o l l i n g - M a s t e r +// ---------------------------------------------------------------------------- +// Editor: Robert Patzke +// URI/URL: www.mfp-portal.de +//----------------------------------------------------------------------------- +// Lizenz: CC-BY-SA (wikipedia: Creative Commons) +// Datum: 1. November 2021 +// Letzte Bearbeitung: 15. März 2022 +// + +#ifndef SoaapBleMaster_h +#define SoaapBleMaster_h + +// Vordefinitionen, Festlegungen zur Kompilierung +// +#define DebugTerminal +// Mit dieser Definition werden die Klasse Monitor und weitere Testmethoden +// eingebunden, womit ein anwendungsorientiertes Debugging möglich ist + +//#define TEST001 +// Ausgaben an serielle schnittstelle zur Prüfung der ap-Zustandsmaschine + +#include "LoopCheck.h" +#include "StateMachine.h" +#include "nRF52840Radio.h" +#include "BlePoll.h" +#include "ComRingBuf.h" +#include "nRF52840Ser.h" +#include "SoaapMsg.h" +#include "Monitor.h" + +// ---------------------------------------------------------------------------- +// Vorwärtsreferenzen +// ---------------------------------------------------------------------------- +// +void ctrlIdle(); +void ctrlInit(); +void sendCtrl(); +void checkCtrl(); + +void apInit(); +void apWaitDE(); +void apWaitMeas(); +void apProcMeas(); + + +#ifdef DebugTerminal +// ---------------------- +void smInit() ; +void smCheckJobs() ; +void smDebDword() ; +void smCtrlPolling() ; +void smWaitPolling() ; +void smReadPollValues() ; +void smCheckSer(); +// ---------------------- +#endif + +#endif /* SoaapBleMaster_h */ diff --git a/libraries/environment/SoaapBleSlave.h b/libraries/environment/SoaapBleSlave.h new file mode 100644 index 0000000000000000000000000000000000000000..f3ae7f7500126e35f19524b4188a3044d43dfaf4 --- /dev/null +++ b/libraries/environment/SoaapBleSlave.h @@ -0,0 +1,43 @@ +#ifndef SoaapBleSlave_h +#define SoaapBleSlave_h + +#include "LoopCheck.h" +#include "StateMachine.h" +#include "nRF52840Radio.h" +#include "BlePoll.h" +#include "ComRingBuf.h" +#include "nRF52840Ser.h" +#include "SoaapMsg.h" +#include "Monitor.h" +#include "nRF52840Twi.h" +#include "SensorLSM9DS1.h" +#include "nRF52840Gpio.h" + +//#define SlaveACM1 +bool sendData(PlpType plpType, byte *dest); +bool getValues(PlpType plpType, byte *dest); +void smInit(); +void smCheckJobs(); +void smCheckSens(); + +void smDebDword(); +void smCtrlPolling(); +void smWaitPolling(); +void smSensReset1(); +void smSensReset2(); + +void smSensGetValues1(); +void smSensGetValues2(); +void smSensGetValues3(); +void smSensGetValues4(); +void smSensGetValues5(); +void smSensGetValues6(); +void smSensGetValues7(); + +void smSensGetSoaapValues(); +void smSensDebugValues(); + +void smSensGetErrors(); +void smSensGetTimeOuts(); +void smSensGetRunCounts(); +#endif \ No newline at end of file diff --git a/libraries/environment/library.json b/libraries/environment/library.json new file mode 100644 index 0000000000000000000000000000000000000000..13cd151661d616282166233e4d7f94c730d33ffb --- /dev/null +++ b/libraries/environment/library.json @@ -0,0 +1,4 @@ +{ + "name": "environment", + "version": "0.0.1+20221111" +} \ No newline at end of file diff --git a/libraries/nRF52840Adc/library.json b/libraries/nRF52840Adc/library.json new file mode 100644 index 0000000000000000000000000000000000000000..34aead1af121d937c5c4f658936056488164ba75 --- /dev/null +++ b/libraries/nRF52840Adc/library.json @@ -0,0 +1,4 @@ +{ + "name": "nRF52840Adc", + "version": "0.0.1+20221111" + } \ No newline at end of file diff --git a/libraries/nRF52840Gpio/library.json b/libraries/nRF52840Gpio/library.json new file mode 100644 index 0000000000000000000000000000000000000000..1a10197e5509b12cdfbaa8f2525d2e6815f752b5 --- /dev/null +++ b/libraries/nRF52840Gpio/library.json @@ -0,0 +1,4 @@ +{ + "name": "nRF52840Gpio", + "version": "0.0.1+20221111" +} \ No newline at end of file diff --git a/libraries/nRF52840Radio/library.json b/libraries/nRF52840Radio/library.json new file mode 100644 index 0000000000000000000000000000000000000000..8568e9fd5255175d8c97ec82276e1907e92c6510 --- /dev/null +++ b/libraries/nRF52840Radio/library.json @@ -0,0 +1,4 @@ +{ + "name": "nRF52840Radio", + "version": "0.0.1+20221111" +} \ No newline at end of file diff --git a/libraries/nRF52840Ser/library.json b/libraries/nRF52840Ser/library.json new file mode 100644 index 0000000000000000000000000000000000000000..bbed5cb3f23e8e3959de73f22e3a7a53a83ae1f5 --- /dev/null +++ b/libraries/nRF52840Ser/library.json @@ -0,0 +1,4 @@ +{ + "name": "nRF52840Ser", + "version": "0.0.1+20221111" +} \ No newline at end of file diff --git a/libraries/nRF52840Twi/library.json b/libraries/nRF52840Twi/library.json new file mode 100644 index 0000000000000000000000000000000000000000..80e483a17ee2b4a59e61f9e1fedc40132554e2e1 --- /dev/null +++ b/libraries/nRF52840Twi/library.json @@ -0,0 +1,4 @@ +{ + "name": "nRF52840Twi", + "version": "0.0.1+20221111" +} \ No newline at end of file diff --git a/sketches/_PIO_Sketches/Karger/22_11_11_1_BLE_Master_Soaap/include/README b/sketches/_PIO_Sketches/Karger/22_11_11_1_BLE_Master_Soaap/include/README new file mode 100644 index 0000000000000000000000000000000000000000..194dcd43252dcbeb2044ee38510415041a0e7b47 --- /dev/null +++ b/sketches/_PIO_Sketches/Karger/22_11_11_1_BLE_Master_Soaap/include/README @@ -0,0 +1,39 @@ + +This directory is intended for project header files. + +A header file is a file containing C declarations and macro definitions +to be shared between several project source files. You request the use of a +header file in your project source file (C, C++, etc) located in `src` folder +by including it, with the C preprocessing directive `#include'. + +```src/main.c + +#include "header.h" + +int main (void) +{ + ... +} +``` + +Including a header file produces the same results as copying the header file +into each source file that needs it. Such copying would be time-consuming +and error-prone. With a header file, the related declarations appear +in only one place. If they need to be changed, they can be changed in one +place, and programs that include the header file will automatically use the +new version when next recompiled. The header file eliminates the labor of +finding and changing all the copies as well as the risk that a failure to +find one copy will result in inconsistencies within a program. + +In C, the usual convention is to give header files names that end with `.h'. +It is most portable to use only letters, digits, dashes, and underscores in +header file names, and at most one dot. + +Read more about using header files in official GCC documentation: + +* Include Syntax +* Include Operation +* Once-Only Headers +* Computed Includes + +https://gcc.gnu.org/onlinedocs/cpp/Header-Files.html diff --git a/sketches/_PIO_Sketches/Karger/22_11_11_1_BLE_Master_Soaap/lib/README b/sketches/_PIO_Sketches/Karger/22_11_11_1_BLE_Master_Soaap/lib/README new file mode 100644 index 0000000000000000000000000000000000000000..6debab1e8b4c3faa0d06f4ff44bce343ce2cdcbf --- /dev/null +++ b/sketches/_PIO_Sketches/Karger/22_11_11_1_BLE_Master_Soaap/lib/README @@ -0,0 +1,46 @@ + +This directory is intended for project specific (private) libraries. +PlatformIO will compile them to static libraries and link into executable file. + +The source code of each library should be placed in a an own separate directory +("lib/your_library_name/[here are source files]"). + +For example, see a structure of the following two libraries `Foo` and `Bar`: + +|--lib +| | +| |--Bar +| | |--docs +| | |--examples +| | |--src +| | |- Bar.c +| | |- Bar.h +| | |- library.json (optional, custom build options, etc) https://docs.platformio.org/page/librarymanager/config.html +| | +| |--Foo +| | |- Foo.c +| | |- Foo.h +| | +| |- README --> THIS FILE +| +|- platformio.ini +|--src + |- main.c + +and a contents of `src/main.c`: +``` +#include <Foo.h> +#include <Bar.h> + +int main (void) +{ + ... +} + +``` + +PlatformIO Library Dependency Finder will find automatically dependent +libraries scanning project source files. + +More information about PlatformIO Library Dependency Finder +- https://docs.platformio.org/page/librarymanager/ldf.html diff --git a/sketches/_PIO_Sketches/Karger/22_11_11_1_BLE_Master_Soaap/platformio.ini b/sketches/_PIO_Sketches/Karger/22_11_11_1_BLE_Master_Soaap/platformio.ini new file mode 100644 index 0000000000000000000000000000000000000000..8aee3f8409f7d237a786c4c5e2ee2a67547dd416 --- /dev/null +++ b/sketches/_PIO_Sketches/Karger/22_11_11_1_BLE_Master_Soaap/platformio.ini @@ -0,0 +1,38 @@ +; PlatformIO Project Configuration File +; +; Build options: build flags, source filter +; Upload options: custom upload port, speed and extra flags +; Library options: dependencies, extra library storages +; Advanced options: extra scripting +; +; Please visit documentation for the other options and examples +; https://docs.platformio.org/page/projectconf.html + +[env:nano33ble] +platform = nordicnrf52 +board = nano33ble +framework = arduino +upload_port = COM3 +build_flags = + -DsmnDEFBYBUILD -DsmnNANOBLE33 -DsmnDEBUG -DDegugTerminal +;Anstelle der relativen Pfade können auch lokale Syslinks verwendet werden(siehe unten). +;Diese aber bitte NICHT committen! +lib_deps = + ..\..\..\..\libraries\BlePoll + ..\..\..\..\libraries\environment + ..\..\..\..\libraries\ComRingBuf + ..\..\..\..\libraries\LoopCheck + ..\..\..\..\libraries\MidiNotes + ..\..\..\..\libraries\Monitor + ..\..\..\..\libraries\nRF52840Gpio + ..\..\..\..\libraries\nRF52840Radio + ..\..\..\..\libraries\nRF52840Ser + ..\..\..\..\libraries\nRF52840Twi + ..\..\..\..\libraries\SensorLSM9DS1 + ..\..\..\..\libraries\SoaapMsg + ..\..\..\..\libraries\StateMachine + ..\..\..\..\libraries\nRF52840Adc + ..\..\..\..\libraries\ProcMeas + ..\..\..\..\libraries\EulerAngles + ..\..\..\..\libraries\GpioCtrl + ;symlink://C:\Users\lenna\OneDrive\Dokumente\Git\SOAAP\libraries\SoaapComDue \ No newline at end of file diff --git a/sketches/_PIO_Sketches/Karger/22_11_11_1_BLE_Master_Soaap/src/SoaapBleMidiMaster.h b/sketches/_PIO_Sketches/Karger/22_11_11_1_BLE_Master_Soaap/src/SoaapBleMidiMaster.h new file mode 100644 index 0000000000000000000000000000000000000000..9bb0445f1db6ca2ab7082d767361e1a084332643 --- /dev/null +++ b/sketches/_PIO_Sketches/Karger/22_11_11_1_BLE_Master_Soaap/src/SoaapBleMidiMaster.h @@ -0,0 +1,127 @@ +// ---------------------------------------------------------------------------- +// SoaapBleMidiMaster.h +// Beispielhafte Anwendung SOAAP / Steuerung optischer und akustischer Ausgaben +// Kommunikation über BLE-Funkanäle mit Bewerbungstelegrammen +// P o l l i n g - M a s t e r +// ---------------------------------------------------------------------------- +// Editor: Robert Patzke +// URI/URL: www.mfp-portal.de +//----------------------------------------------------------------------------- +// Lizenz: CC-BY-SA (wikipedia: Creative Commons) +// Datum: 26. April 2022 +// Letzte Bearbeitung: 15. März 2022 +// + +#ifndef SoaapBleMidiMaster_h +#define SoaapBleMidiMaster_h + +// Vordefinitionen, Festlegungen zur Kompilierung +// + +//#define DebugTerminal +// Mit dieser Definition werden die Klasse Monitor und weitere Testmethoden +// eingebunden, womit ein anwendungsorientiertes Debugging möglich ist +// Diese Definition wird in der Projektumgebung des Entwicklungssystems gesetzt +// (z.B. Arduino Compile Options bei Eclipse/Sloeber) + +//#define TEST001 +// Ausgaben an serielle schnittstelle zur Prüfung der ap-Zustandsmaschine +#define testOut(x) smnSerial.print(x) + + +#include "LoopCheck.h" +#include "StateMachine.h" +#include "nRF52840Radio.h" +#include "MidiNotes.h" +#include "BlePoll.h" +#include "ComRingBuf.h" +#include "nRF52840Ser.h" +#include "Monitor.h" + +// ---------------------------------------------------------------------------- +// Datentypen +// ---------------------------------------------------------------------------- +// +typedef struct _Value2Midi +{ + short borderLowAz; + short borderHighAz; + short borderLowAy; + short borderHighAy; + short borderLowAx; + short borderHighAx; + + byte lowNote; + byte highNote; + +} Value2Midi, *Value2MidiPtr; + +enum Meas2Midi +{ + NoteType, + NoteVal, + NoteVel +}; + +typedef struct _MidiBorders +{ + byte low; + byte high; +} MidiBorders, *MiniBordersPtr; + +typedef struct _Posture2Midi +{ + float offsetRoll; + float borderLowRoll; + float borderHighRoll; + float koeffRoll; + float offsetPitch; + float borderLowPitch; + float borderHighPitch; + float koeffPitch; + float offsetYaw; + float borderLowYaw; + float borderHighYaw; + float koeffYaw; + Meas2Midi aimRoll; + Meas2Midi aimPitch; + Meas2Midi aimYaw; + byte signAreaValue[4]; + byte signAreaCtrl[4]; + MidiBorders midiBords[3]; +} Posture2Midi, *Posture2MidiPtr; + +// ---------------------------------------------------------------------------- +// Vorwärtsreferenzen +// ---------------------------------------------------------------------------- +// +void apInit(); +void apWaitDE(); +void apWaitMeas(); +void apProcMeas(); +void apCheckValues(); +void apCalcResult(); +void apSetResult(); +void apTestController(); + +void setParM1(); +void setParM2(); +void setParP1(); +void setParP2(); + + +#ifdef DebugTerminal +// ---------------------- +void smInit() ; +void smCheckJobs() ; +void smDebDword() ; +void smCtrlPolling() ; +void smWaitPolling() ; +void smReadPollValues() ; +void smCheckApp(); +void smMode4Slave(); +void smMode4SlaveIn(); +// ---------------------- +#endif + +#endif SoaapBleMidiMaster_h diff --git a/sketches/_PIO_Sketches/Karger/22_11_11_1_BLE_Master_Soaap/src/main.cpp b/sketches/_PIO_Sketches/Karger/22_11_11_1_BLE_Master_Soaap/src/main.cpp new file mode 100644 index 0000000000000000000000000000000000000000..b2577ce24c6307e36242ce5ce34e0b78f618d7e9 --- /dev/null +++ b/sketches/_PIO_Sketches/Karger/22_11_11_1_BLE_Master_Soaap/src/main.cpp @@ -0,0 +1,1184 @@ +// ---------------------------------------------------------------------------- +// SoaapBleMidiMaster.ino +// Beispielhafte Anwendung SOAAP / Steuerung optischer und akustischer Ausgaben +// Kommunikation über BLE-Funkanäle mit Bewerbungstelegrammen +// P o l l i n g - M a s t e r +// ---------------------------------------------------------------------------- +// Editor: Robert Patzke +// URI/URL: www.hs-hannover.de +//----------------------------------------------------------------------------- +// Lizenz: CC-BY-SA (wikipedia: Creative Commons) +// Datum: 26. April 2022 +// Letzte Bearbeitung: +// + +#include "Arduino.h" +#include "SoaapBleMidiMaster.h" + +// ---------------------------------------------------------------------------- +LoopCheck lc; +// ---------------------------------------------------------------------------- +// Eine statische Instanz der Klasse LoopCheck +// Darüber wird das Zeitverhalten gesteuert (Software-Timer) und geprüft + +// ---------------------------------------------------------------------------- +nRF52840Radio bleCom; +// ---------------------------------------------------------------------------- +// Eine statische Instanz der Klasse nRF52840Radio +// Darüber wird direkt die CPU (nRF52840) auf dem Arduino-Board zum Senden und +// Empfangen von BLE-Beacons angesprochen. + + +#define bleCycleTime 250 +// ---------------------------------------------------------------------------- +BlePoll blePoll((IntrfRadio *) &bleCom, micros); +// ---------------------------------------------------------------------------- +// Eine statische Instanz der Klasse BlePoll +// Darüber werden das Polling des Masters als auch die Antworten der Slaves +// gesteuert. Es können Geräte entwickelt werden, die nur Master oder Slave +// sind und solche mit Doppelfunktion, wenn kein expliziter Master +// eingesetzt und das Netzwerk über Spontan-Master quasi dezentral +// betrieben werden soll. +// ----- Parameter ------------------------------------------------------------ +// <&bleCom> Die Klasse (vom angenommenen Typ IntrfRadio), die die Daten- +// übertragung abwickelt. Hier wird eine Instanz von nRF52840Radio +// angebunden. Für andere Hardware kann eine entsprechende Klasse +// verwendet werden, die von IntrfRadio abgeleitet wurde. +// <micros> Eine Funktion, die die verstrichene Zeit in Mikrosekunden gibt. +// Damit werden Zeiten (z.B. Time-Out) berechnet. +// Wird hier der Wert NULL übergeben, dann werden die Zeiten aus +// dem Aufrufzyklus (bleCycleTime) in Mikrosekunden berechnet, +// was hier einer Auflösung von 250 Mikrosekunden entspricht. + +#define NrOfSlavesToPoll 5 +// Die Anzahl der Slaves, die der Master aufrufen soll (Polling). +// Es wird grundsätzlich mit der Adresse 1 begonnen und nach dem Aufruf die +// Adresse inkrementiert, also immer die Slaves Adr = 1 bis +// Adr = NrOfSlavesToPoll+1 aufgerufen. +// ACHTUNG! +// Diese Zahl muss kleiner/gleich der in BlePoll.h definierten maximalen +// Anzahl der Slaves (MAXSLAVE) sein, weil die Ressourcen darüber statisch +// festgelegt werden. + +Value2Midi val2midArr[NrOfSlavesToPoll + 1]; +Posture2Midi post2midArr[NrOfSlavesToPoll + 1]; +// Jeder Slave bekommt spezifische Value->Midi-Parameter. +// Index 0 steht für eventuelle Parameter des Masters + +SerParams ttyParams; +// ---------------------------------------------------------------------------- +nRF52840Ser tty; +// ---------------------------------------------------------------------------- +// Eine statische Instanz der Klasse nRF52840Ser (UART) +// Darüber werden die seriellen Schnittstellen (UARTE0 und UARTE1) des +// nRF52840 bedient. +// Die Parameter werden in einer Struktur <SerParams> über die Funktion +// <begin(...)> gesetzt. + +#define sndBufSize 256 +byte sndBuffer[sndBufSize]; +// ---------------------------------------------------------------------------- +ComRingBuf crb; +// ---------------------------------------------------------------------------- +// Eine statische Instanz der Klasse <ComRingBuf> +// Damit wird ein Ringpuffer aufgebaut, der eine serielle Schnittstelle bedient. +// Der Speicher muss extra eingerichtet und mit der Funktion +// <setWriteBuffer(sndBufSize, sndBuffer)> übergeben werden. +// Die Klasse für die serielle Schnittstelle muss von <IntrfSerial> abgeleitet +// sein, die Instanz wird mit der Funktion <begin(...)> übergeben. + +#define MidiCycle 1000 +MidiNotes midi1,midi2; + +#define appCycleTime 1000 +StateMachine ap(apInit, NULL, appCycleTime); +// Eine statische Instanz für die Zustandsmaschine, die hier für die +// Anwendung (App) von SOAAP eingesetzt wird +// ----- Parameter ------------------------------------------------------------ +// <smInit> Der zuerst aufgerufene Zustand (Funktion). Weitere Zustände +// werden in den weiteren Zustandsfunktionen eingesetzt. +// <NULL> Hier kann eine weitere Zustandsfunktion angegeben werden, +// die dann grundsätzlich vor dem Verzweigen in einen Zustand +// aufgerufen wird. +// <smCycleTime> Die Zukluszeit (Takt) der Zustandsmaschine in Mikrosekunden + + +#ifdef DebugTerminal +// ---------------------------------------------------------------------------- +// Zum Debuggen und weitere Analysen der Programmumgebung und Funktionstests +// Es ist ein (richtiges) Terminal erforderlich, mit dem einzelnen Zeichen +// direkt abgeschickt und die eintreffenden direkt angezeigt werden. +// ---------------------------------------------------------------------------- +#define smCycleTime 5 +StateMachine sm(smInit, NULL, smCycleTime); +// Eine statische Instanz für die Zustandsmaschine, die hier für allgemeine +// Steuerungen, Überwachungen und zum Debugging verwendet wird +// ----- Parameter ------------------------------------------------------------ +// <smInit> Der zuerst aufgerufene Zustand (Funktion). Weitere Zustände +// werden in den weiteren Zustandsfunktionen eingesetzt. +// <NULL> Hier kann eine weitere Zustandsfunktion angegeben werden, +// die dann grundsätzlich vor dem Verzweigen in einen Zustand +// aufgerufen wird. +// <smCycleTime> Die Zukluszeit (Takt) der Zustandsmaschine in Millisekunden + +char *infoThis = +{ +"SOAAP BLE Master Midi Version 22.09.24-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 Werte auslesen\r\n" +"c4 Anwendung analysieren\r\n" +"c5 Meldung an Slave senden\r\n" +}; + + +Monitor mon(modeEcho | modeNl,0,&lc); +// Eine statische Instanz (mit Konstruktordaten) der Klasse Monitor +// Darüber wird mit (direkten) Terminals (z.B. VT100) kommuniziert +// Unter Linux werden hier GtkTerm (siehe Internet) und +// ArduinoMonTerm (eigene Entwicklung mit grafischen Wertanzeigen) eingesetzt. +// Das in den IDEs integrierte Terminal ist dafür meistens nicht geeigent, +// weil damit keine direkte Kommunikation (getipptes Zeichen sofort gesendet) +// möglich ist. +// ----- Parameter ------------------------------------------------------------ +// <mode Echo> Alle eintreffenden Zeichen werden sofort zurückgesendet +// <mode NL> Vor der Ausgabe des Prompt (M>) erfolgt CR/LF +// <0> Für Speicherzugriffe wird von 32 Bit ARM ausgegangen +// <&lc> Für Zeitüberwachungen und entsprechende statisctische Daten +// greift die Monitor-Klasse auf die LoopCheck-Klasse zu +// ---------------------------------------------------------------------------- +#endif + + +BlePoll::AppType appType; + +// ============================================================================ +void setup() +// ============================================================================ +{ + bleCom.begin(); // Initialisierung der Datenübertragung + //bleCom.setPower(0x08); // Maximale Sendeleistung bei nRF52840 + // TEST + bleCom.setPower(0x0FC); // Reduzierte Sendeleistung beim Schreibtisch-Test + + //appType = BlePoll::atDevSOAAP; + appType = BlePoll::atSOAAP2; + + blePoll.begin(BlePoll::ctMASTER, NrOfSlavesToPoll, appType, 10000); + // Initialisierung des Polling mit folgenden Parametern: + // <BlePoll::ctMASTER> Es wird ein Master eingerichtet + // <NrOfSlavesToPoll> Anzahl gepollter Slaves (s.o.) + // <BlePoll::atSOAAP> Spezielle Anwendung SOAAP + // <10000> INT-Watchdog-Timeout beim Lesen in Mikrosekunden + + blePoll.setEmptyPollParams(2000, 500, 2000); + // Setzen der Parameter für das leere Polling zur Feststellung der + // vorhandenen Slaves und Aufbau einer Poll-Liste für den Datenaustausch + // ----- Parameter ---------------------------------------------------------- + // <2000> Anzahl der Poll-Durchläufe, solange kein Slave gefunden wird + // <500> Anzahl weiterer Durchläufe, nachdem wenigstens ein Slave gefunden ist + // <2000> Time-Out (Zeit für Slave zum Antworten) in Mikrosekunden + + for(int i = 1; i <= NrOfSlavesToPoll; i++) + blePoll.setDataPollParams(i, 1, 10, 1000); + // Setzen der Parameter beim Datenpolling, für Slaves individuell + // ----- Parameter ---------------------------------------------------------- + // <i> Adresse des Slave (1-..) + // <1> Priorität beim Aufruf, 0 = immer bis max 65535 = sehr selten + // <10> minimale Priorität bei automatischer Prioritätsreduzierung + // im Fall von Störungen (Time-Out) + // <1000> Time-Out (Zeit für Slave zum Antworten) in Mikrosekunden + +#ifdef DebugTerminal + blePoll.stopEP(); // Das Polling muss extra gestartet werden + mon.setInfo(infoThis); // Info-Meldung für Monitor +#endif + + // Initialisierung von serieller Schnittstelle und Ringpuffer + // -------------------------------------------------------------------------- + ttyParams.inst = 0; // Instanzindex der Schnittstelle (0,1) + ttyParams.rxdPort = 1; // Nummer des IO-Port mit RxD-Pin + ttyParams.rxdPin = 10; // Nummer des RxD-Pin am Port + ttyParams.txdPort = 1; // Nummer des IO-Port mit TxD-Pin + ttyParams.txdPin = 3; // Nummer des TxD-Pin am Port + ttyParams.speed = Baud31250; // Enumerator für Bitrate + ttyParams.type = stCur; // Stromschleife + + tty.begin(&ttyParams, (IntrfBuf *) &crb); + // Übergeben von Parametern und Referenz auf Ringpufferverwaltung + // für die Übergabe empfangener Zeichen + + tty.startSend(); // Sendebetrieb aktivieren + + crb.setWriteBuffer(sndBufSize, sndBuffer); + // Speicher an Ringpufferverwaltung übergeben + + crb.begin((IntrfSerial *) &tty); + // Referenz auf Schnittstelle an Ringpufferverwaltung + // für die Übergabe zu sendender Zeichen + + setParM1(); + setParP1(); + midi1.begin(120, nd32, MidiCycle, (IntrfBuf *) &crb); + midi1.setChannel(1); + + setParM2(); + setParP2(); + midi2.begin(120, nd32, MidiCycle, (IntrfBuf *) &crb); + midi2.setChannel(2); + //midi2.stop(); +} + +// ============================================================================ +void loop() +// ============================================================================ +{ + lc.begin(); // Muss am Anfang von LOOP aufgerufen werden + // -------------------------------------------------------------------------- + +#ifdef DebugTerminal + mon.run(); // Der Monitor bekommt bei jedem Durchlauf die CPU +#endif + + // Alle 250 Mikrosekunden erfolgt der Aufruf des Ble-Polling + // + if(lc.timerMicro(lcTimer0, bleCycleTime, 0)) + blePoll.run(); + // ----- Parameter der Software-Timer --------------------------------------- + // <lcTimer0> Id/Nummer des Timer, zur Zeit werden bis 10 Timer unterstützt + // lcTimer0 bis lcTimer9 (einstellbar in LoopCheck.h) + // <bleCycleTime> Ablaufzeit in Einheit des Timer-Typ (Micro/Milli) + // hier in Mikrosekunden (timerMicro) + // <0> Anzahl der Wiederholungen, 0 = unbegrenzt + + // Alle <appCycleTime> Mikrosekunden erfolgt der Aufruf der Anwendung + // + if(lc.timerMicro(lcTimer1, appCycleTime, 0, 10000)) + ap.run(); + + // Alle <MidiCycle> Mikrosekunden erfolgt der Aufruf des Midi-Controller + // + if(lc.timerMicro(lcTimer2, MidiCycle, 0, 1000)) + { + midi1.run(); + midi2.run(); + } + +#ifdef DebugTerminal + // Jede Sekunde erfolgt die Ausgabe einer Versionsmeldung + // das kann über c0 am Terminal abgeschaltet werden + // + if(lc.timerMilli(lcTimer3, 1000, 0)) + { + if(!mon.cFlag[0]) + mon.printcr((char *)"%@TestBleMidiMaster, Version 20221018"); + } + // Die Zeichen %@ am Anfang steuern die Ausgabe bei AndroidMonTerm in ein + // Textfeld (Label) statt auf das Terminal-Display + + // Jede Millisekunde erfolgt der Aufruf der Zustandsmaschine + // + if(lc.timerMilli(lcTimer4, smCycleTime, 0)) + { + sm.run(); + } +#endif + + // -------------------------------------------------------------------------- + lc.end(); // Muss vor dem Ende von LOOP aufgerufen werden +} + +// **************************************************************************** +// Z u s t a n d s m a s c h i n e S O A A P - A n w e n d u n g (ap) +// **************************************************************************** +// +byte apTmpByteArray[256]; // Zwischenspeicher für Zeichenfolgen +int apNrOfMeasBytes; // Anzahl der empfangenen Messwertbytes +byte apMeasByteArray[32]; // Zwischenspeicher für Messwerte +byte apSlaveList[NrOfSlavesToPoll]; // Merker für gepollte Slaves +int apNrOfSlaves; // Aktuelle Anzahl von Slaves +int curListIdx; // Aktueller Index für Slaveliste +int area; // Area des aktuellen Slave +int sMsgLen; // Länge einer SOAAP-Meldung +int slNr; // Slave-Nummer (Adresse) +int txNr; // Anzahl versendeter Zeichen + +PlpType pAppId; // Anwendungs-Id aus Polling-Sicht + +int lastNoteIdxM1 = 0; +int lastNoteIdxM2 = 0; + +#ifdef TEST001 +char testMsgBuf[256]; +#endif +// ---------------------------------------------------------------------------- +// Initialisierungen +// +dword apInitCnt; +void apInit() +{ + apInitCnt++; + + midi1.setNoteType(MidiNotes::nti8); + lastNoteIdxM1 = midi1.addChordNote(MidiNotes::nti8, SchlossC, 10); + midi1.setOpMode(momSequence); + midi2.setNoteType(MidiNotes::nti8); + lastNoteIdxM2 = midi2.addChordNote(MidiNotes::nti8, Kammerton, 10); + midi2.setOpMode(momSequence); + ap.enter(apWaitDE); +} + +// ---------------------------------------------------------------------------- +// Warten, bis Datenaustausch Master/Slave erfolgt +// +dword apWaitDECnt; +void apWaitDE() +{ + apWaitDECnt++; + + if(!blePoll.DataExchange) + return; // Verbleiben in diesem Zustand bis Leerpolling beendet + + apNrOfSlaves = blePoll.getSlaveList(apSlaveList, NrOfSlavesToPoll); + // Ermitteln der angeschlossenen Slaves + + ap.enter(apWaitMeas); +} + +// ---------------------------------------------------------------------------- +// Warten auf neuen Messwert von einem Slave +// +dword apWaitMeasCnt; +void apWaitMeas() +{ + apWaitMeasCnt++; + + // Ermitteln, ob einer der Slaves einen Messwert hat + // + for(curListIdx = 0; curListIdx < apNrOfSlaves; curListIdx++) + { + slNr = apSlaveList[curListIdx]; + if(blePoll.measAvail(slNr)) break; + } + if(curListIdx == apNrOfSlaves) return; + // Wenn kein Slave neue Messwerte hat, + // dann im nächsten Zustandstakt Abfrage wiederholen + + // Slave (curListIdx) hat Messwerte übermittelt + // diese werden mit dem nächsten Takt verarbeitet + ap.enter(apProcMeas); +} + +// ---------------------------------------------------------------------------- +// Verarbeiten der Daten vom Slave +// +dword apProcMeasCnt; +void apProcMeas() +{ + apProcMeasCnt++; + + // Parameter und Daten für die SOAAP-Ausgabe holen + // + slNr = apSlaveList[curListIdx]; + area = blePoll.getArea(slNr); + pAppId = blePoll.getAppId(slNr); + apNrOfMeasBytes = blePoll.getMeas(slNr, apMeasByteArray); + + // Spezifisch je Slave auswerten + // + if(slNr == 1 || slNr == 2) + { + ap.enter(apCheckValues); + return; + } + + // Auf nächsten Messwert von einem Slave warten + // + ap.enter(apWaitMeas); +} + +// ---------------------------------------------------------------------------- +// Daten überprüfen (auswerten) +// +short accXold, accYold, accZold; +float rollOld, pitchOld, yawOld; +dword apCheckValuesCnt; +void apCheckValues() +{ + apCheckValuesCnt++; + + switch (appType) + { + case BlePoll::atSOAAP1: + //bool newData = false; + + accXold = * (short *) &apMeasByteArray[6]; + accYold = * (short *) &apMeasByteArray[8]; + accZold = * (short *) &apMeasByteArray[10]; + + break; + + case BlePoll::atSOAAP2: + rollOld = * (float *) &apMeasByteArray[0]; + pitchOld = * (float *) &apMeasByteArray[4]; + yawOld = * (float *) &apMeasByteArray[8]; + + break; + } + + ap.enter(apCalcResult); +} + +// ---------------------------------------------------------------------------- +// Daten auf Midi-Noten abbilden +// +//short borderLowAz = 100; +//short borderHighAz = 8000; +//short borderLowAy = 100; +//short borderHighAy = 8300; +//short borderLowAx = 100; +//short borderHighAx = 4000; + +//byte lowNote = 23; +//byte highNote = 72; +//byte highNote = 96; + +void setParM1() +{ + val2midArr[1].borderLowAz = 100; + val2midArr[1].borderHighAz = 8000; + val2midArr[1].borderLowAy = 100; + val2midArr[1].borderHighAy = 8300; + val2midArr[1].borderLowAx = 100; + val2midArr[1].borderHighAx = 4000; + val2midArr[1].lowNote = 23; + val2midArr[1].highNote = 96; +} + +void setParM2() +{ + val2midArr[2].borderLowAz = 100; + val2midArr[2].borderHighAz = 8000; + val2midArr[2].borderLowAy = 100; + val2midArr[2].borderHighAy = 8300; + val2midArr[2].borderLowAx = 100; + val2midArr[2].borderHighAx = 4000; + val2midArr[2].lowNote = 23; + val2midArr[2].highNote = 96; +} + +void setParP1() +{ + Posture2MidiPtr pmp = &post2midArr[1]; + + pmp->offsetRoll = 90; + pmp->borderLowRoll = 45; + pmp->borderHighRoll = 170; + pmp->aimRoll = NoteType; + + pmp->offsetPitch = 90; + pmp->borderLowPitch = 45; + pmp->borderHighPitch = 170; + pmp->aimPitch = NoteVal; + + pmp->midiBords[NoteVal].low = 23; + pmp->midiBords[NoteVal].high = 96; + pmp->midiBords[NoteType].low = 2; + pmp->midiBords[NoteType].high = 12; + + pmp->koeffRoll = + (pmp->midiBords[pmp->aimRoll].high - pmp->midiBords[pmp->aimRoll].low) / + (pmp->borderHighRoll - pmp->borderLowRoll); + + pmp->koeffPitch = + (pmp->midiBords[pmp->aimPitch].high - pmp->midiBords[pmp->aimPitch].low) / + (pmp->borderHighPitch - pmp->borderLowPitch); +} + +void setParP2() +{ + Posture2MidiPtr pmp = &post2midArr[2]; + + pmp->offsetRoll = 90; + pmp->borderLowRoll = 45; + pmp->borderHighRoll = 170; + pmp->aimRoll = NoteType; + + pmp->offsetPitch = 90; + pmp->borderLowPitch = 45; + pmp->borderHighPitch = 170; + pmp->aimPitch = NoteVal; + + pmp->midiBords[NoteVal].low = 23; + pmp->midiBords[NoteVal].high = 96; + pmp->midiBords[NoteType].low = 2; + pmp->midiBords[NoteType].high = 12; + + pmp->koeffRoll = + (pmp->midiBords[pmp->aimRoll].high - pmp->midiBords[pmp->aimRoll].low) / + (pmp->borderHighRoll - pmp->borderLowRoll); + + pmp->koeffPitch = + (pmp->midiBords[pmp->aimPitch].high - pmp->midiBords[pmp->aimPitch].low) / + (pmp->borderHighPitch - pmp->borderLowPitch); +} + + +byte resultAz; +byte resultAy; +byte resultAx; + +byte resultNote[3]; + +dword apCalcResultCnt; +void apCalcResult() +{ + short testY; + int result; + float rollVal, pitchVal, yawVal; + Meas2Midi meas2midi; + + apCalcResultCnt++; + + switch (appType) + { + case BlePoll::atSOAAP1: + if((accZold < val2midArr[slNr].borderLowAz) && (accXold < val2midArr[slNr].borderLowAx)) + { + ap.enter(apWaitMeas); + return; + } + + testY = accZold + accYold / 4; + result = val2midArr[slNr].lowNote + + (val2midArr[slNr].highNote * testY) / val2midArr[slNr].borderHighAz; + if(result > val2midArr[slNr].highNote) + resultAz = val2midArr[slNr].highNote; + else if (result < val2midArr[slNr].lowNote) + resultAz = val2midArr[slNr].lowNote; + else + resultAz = result; + + testY = accXold + accYold / 4; + result = (MidiNotes::nti32 * testY) / val2midArr[slNr].borderHighAz; + if(result < MidiNotes::nti2) result = MidiNotes::nti2; + if(result > MidiNotes::nti32) result = MidiNotes::nti32; + resultAx = result; + break; + + case BlePoll::atSOAAP2: + rollVal = rollOld + post2midArr[slNr].offsetRoll; // Rollwinkel in positiven Bereich verschieben + if(rollVal < post2midArr[slNr].borderLowRoll) + { + rollVal = post2midArr[slNr].borderLowRoll; // Inhalt ggf. auf Minimalwert begrenzen + } + else if(rollVal > post2midArr[slNr].borderHighRoll) + { + rollVal = post2midArr[slNr].borderHighRoll; // Inhalt ggf. auf Maximalwert begrenzen + } + meas2midi = post2midArr[slNr].aimRoll; + resultNote[meas2midi] = + post2midArr[slNr].midiBords[meas2midi].low + + (byte) ((rollVal - post2midArr[slNr].borderLowRoll) * post2midArr[slNr].koeffRoll); + + pitchVal = pitchOld + post2midArr[slNr].offsetPitch; // Pitchwinkel in positiven Bereich verschieben + if(pitchVal < post2midArr[slNr].borderLowPitch) + { + pitchVal = post2midArr[slNr].borderLowPitch; // Inhalt ggf. auf Minimalwert begrenzen + } + else if(pitchVal > post2midArr[slNr].borderHighPitch) + { + pitchVal = post2midArr[slNr].borderHighPitch; // Inhalt ggf. auf Maximalwert begrenzen + } + meas2midi = post2midArr[slNr].aimPitch; + resultNote[meas2midi] = + post2midArr[slNr].midiBords[meas2midi].low + + (byte) ((pitchVal - post2midArr[slNr].borderLowPitch) * post2midArr[slNr].koeffPitch); + resultNote[NoteVel] = 100; + break; + } + + ap.enter(apSetResult); +} + +// ---------------------------------------------------------------------------- +// Bedienen des Midi-Controller +// +dword apSetResultCnt; +void apSetResult() +{ + apSetResultCnt++; + + switch (appType) + { + case BlePoll::atSOAAP1: + if(slNr == 1) + midi1.setChordNote(lastNoteIdxM1, (MidiNotes::NoteTypeIdx) resultAx, resultAz, 100); + else if(slNr == 2) + midi2.setChordNote(lastNoteIdxM2, (MidiNotes::NoteTypeIdx) resultAx, resultAz, 100); + break; + + case BlePoll::atSOAAP2: + if(slNr == 1) + midi1.setChordNote + ( + lastNoteIdxM1, + (MidiNotes::NoteTypeIdx) resultNote[NoteType], + resultNote[NoteVal], + resultNote[NoteVel] + ); + else if(slNr == 2) + midi2.setChordNote + ( + lastNoteIdxM1, + (MidiNotes::NoteTypeIdx) resultNote[NoteType], + resultNote[NoteVal], + resultNote[NoteVel] + ); + break; + } + + ap.enter(apWaitMeas); +} + +byte testValue = 22; + +void apTestController() +{ + midi1.setChordNote(lastNoteIdxM1, MidiNotes::nti4, testValue, 60); + testValue++; + if(testValue > 96) + testValue = 22; + ap.setDelay(100); +} + + + +#ifdef DebugTerminal +// **************************************************************************** +// Z u s t a n d s m a s c h i n e z u m D e b u g g e n (sm) +// **************************************************************************** +// +dword debDword; +byte tmpByteArray[256]; + + +void smInit() +{ + sm.enter(smCheckJobs); +} + +// ---------------------------------------------------------------------------- +// Abfrage der Monitorschalter +// ---------------------------------------------------------------------------- +// + +void smCheckJobs() +{ + if(mon.cFlag[1] && !mon.busy) + sm.enter(smDebDword); + else if(mon.cFlag[2] && !mon.busy) + sm.enter(smCtrlPolling); + else if(mon.cFlag[3] && !mon.busy) + sm.enter(smReadPollValues); + else if(mon.cFlag[4] && !mon.busy) + sm.enter(smCheckApp); + else if(mon.cFlag[5] && !mon.busy) + sm.enter(smMode4Slave); +} + +// ---------------------------------------------------------------------------- +// Debug-Informationen +// ---------------------------------------------------------------------------- +// + +void smDebDword() +{ + int idx; + + if(sm.firstEnter()) + { + mon.print((char *) "DebDword["); + mon.lastKeyIn = ':'; + } + + if(mon.lastKeyIn == ':') return; + + if(mon.lastKeyIn >= 0x30 && mon.lastKeyIn <= 0x39) + { + idx = mon.lastKeyIn & 0x0F; + mon.print(idx); + mon.print((char *) "]="); + debDword = blePoll.debGetDword(idx); + mon.println(debDword); + sm.resetEnter(); + } + else + { + if(mon.lastKeyIn == ' ') + { + mon.cFlag[1] = false; + mon.print((char *) "-- Schleifenabbruch - drücke Enter"); + sm.enter(smCheckJobs); + } + } +} + +// ---------------------------------------------------------------------------- +// Steuern des Polling-Prozesses +// ---------------------------------------------------------------------------- +// + +char *smPollHelp = +{ + "C Pollzähler zurücksetzen\r\n" + "L Liste der Slaves anzeigen\r\n" + "P Polling starten/stoppen/fortsetzen\r\n" + "R Radiopuffer auslesen (16 Zeichen)\r\n" + "S Sendepuffer auslesen (16 Zeichen)\r\n" + "T Übertragungsstatistik und Daten anzeigen\r\n" + "0...9 Slave-Umgebung\r\n" +}; + +TxStatistics txStatistics; + +void smCtrlPolling() +{ + dword tmpDw; + short tmpShort; + int i; + + PlpMeas6Ptr resPtr; + + if(sm.firstEnter()) + { + mon.print((char *) "polling "); + mon.lastKeyIn = ':'; + } + + if(mon.lastKeyIn == ':') return; + + if(mon.lastKeyIn == 'H' || mon.lastKeyIn == 'h') + { + mon.println(); + mon.print(smPollHelp); + sm.resetEnter(); + } + + // -------------------------------------------------------------------------- + else if(mon.lastKeyIn == 'P' || mon.lastKeyIn == 'p') + { + if(blePoll.stoppedEP()) + { + blePoll.resumeEP(); + mon.println((char *) "fortgesetzt"); + sm.resetEnter(); + } + else + { + blePoll.stopEP(); + sm.enter(smWaitPolling); + } + } + + // -------------------------------------------------------------------------- + else if(mon.lastKeyIn == 'C' || mon.lastKeyIn == 'c') + { + blePoll.resetPollCounters(); + mon.println((char *) "Zähler zurückgesetzt"); + sm.resetEnter(); + } + + + // -------------------------------------------------------------------------- + else if(mon.lastKeyIn == 'R' || mon.lastKeyIn == 'r') + { + mon.print((char *) "Radiopuffer = "); + bleCom.getPduMem(tmpByteArray, 0, 16); + mon.println(tmpByteArray, 16, ' '); + sm.resetEnter(); + } + + + // -------------------------------------------------------------------------- + else if(mon.lastKeyIn == 'S' || mon.lastKeyIn == 's') + { + mon.print((char *) "Sendepuffer = "); + bleCom.getPduSentS(tmpByteArray, 0, 16); + mon.println(tmpByteArray, 16, ' '); + sm.resetEnter(); + } + + // -------------------------------------------------------------------------- + else if(mon.lastKeyIn == 'L' || mon.lastKeyIn == 'l') + { + mon.print((char *) "Slave-Liste: "); + int nrOfSlaves = blePoll.getSlaveList(tmpByteArray, 255); + mon.println(tmpByteArray, nrOfSlaves, ','); + sm.resetEnter(); + } + + // -------------------------------------------------------------------------- + else if(mon.lastKeyIn == 'T' || mon.lastKeyIn == 't') + { + mon.print((char *) "TxStat ["); + dword bleStat = blePoll.getStatistics(&txStatistics); + mon.print(bleStat); + mon.print((char *) "] "); + mon.print(txStatistics.mode); mon.cprint(' '); + mon.print(txStatistics.interrupts); mon.cprint(' '); + mon.print(txStatistics.recs); mon.cprint(' '); + mon.print(txStatistics.sendings); mon.cprint(' '); + mon.print(txStatistics.aliens); mon.cprint(' '); + mon.print(txStatistics.wrongs); mon.cprint(' '); + mon.print(txStatistics.pollAcks); mon.cprint(' '); + mon.print(txStatistics.pollNaks); mon.cprint(' '); + mon.print(txStatistics.crcErrors); mon.print(" s[ "); + mon.print(txStatistics.memDumpSnd,8,' '); mon.print("] r[ "); + mon.print(txStatistics.memDumpRec,16,' '); mon.cprintln(']'); + sm.resetEnter(); + } + + // -------------------------------------------------------------------------- + else if(mon.lastKeyIn >= '0' && mon.lastKeyIn <= '9') + { + int idx = mon.lastKeyIn & 0x0F; + SlavePtr slPtr = blePoll.getSlavePtr(idx); + PollStatePtr pPtr = blePoll.getPollPtr(slPtr->pIdx); + + mon.print((char *) "Slave["); + mon.print(idx); + mon.print((char *) "] "); + mon.print(slPtr->cntTo); mon.cprint(' '); + mon.print(slPtr->cntNakEP); mon.cprint(' '); + mon.print(slPtr->cntAckDP); mon.cprint(' '); + + if(slPtr->cntAckDP == 0) + { + if(slPtr->cntTo == 0) + tmpDw = slPtr->cntNakEP; + else + tmpDw = slPtr->cntNakEP / slPtr->cntTo; + } + else + { + if(slPtr->cntTo == 0) + tmpDw = slPtr->cntAckDP; + else + tmpDw = slPtr->cntAckDP / slPtr->cntTo; + } + mon.print(tmpDw); mon.cprint(' '); + + resPtr = (PlpMeas6Ptr) &slPtr->result; + + mon.print(slPtr->cntLostPdu); mon.cprint('|'); + mon.print(slPtr->cntErrCrc); mon.cprint('|'); + //mon.print(slPtr->result.measCnt); mon.cprint('|'); + mon.print(resPtr->measCnt); mon.cprint('|'); + mon.print(slPtr->cntLostMeas); mon.cprint(' '); + + for(i = 0; i < 6; i++) + { + //tmpShort = (short) slPtr->result.meas[i]; + tmpShort = (short) resPtr->meas[i]; + mon.prints(tmpShort); mon.cprint(' '); + } + mon.print((char *) " Poll["); + mon.print(slPtr->pIdx); + mon.print((char *) "] "); + mon.print(pPtr->status); mon.cprint(' '); + mon.println(pPtr->slIdx); + sm.resetEnter(); + } + + + + else + { + if(mon.lastKeyIn == ' ') + { + mon.cFlag[2] = false; + mon.print((char *) "-- Schleifenabbruch - drücke Enter"); + sm.enter(smCheckJobs); + } + } +} + +void smWaitPolling() +{ + if(!blePoll.stoppedEP()) return; + + mon.println((char *) "angehalten"); + sm.enter(smCtrlPolling); +} + +// ---------------------------------------------------------------------------- +// Zugriff auf die Sensordaten +// ---------------------------------------------------------------------------- +// + +char *rpValHelp = +{ +"0-9 Sensordaten\r\n" +"Leerzeichen für Abbruch\r\n" +}; + +void smReadPollValues() +{ + PlPduMeasPtr resultPtr; + PlPduMeasPtr ctrlPtr; + byte appId; + float tmpFloat; + char conv[32]; + + if(sm.firstEnter()) + { + mon.print((char *) "Werte vom Sensor "); + mon.lastKeyIn = ':'; + } + + if(mon.lastKeyIn == ':') return; + + if(mon.lastKeyIn == 'H' || mon.lastKeyIn == 'h') + { + mon.println(); + mon.println(rpValHelp); + sm.resetEnter(); + } + // -------------------------------------------------------------------------- + else if(mon.lastKeyIn >= '0' && mon.lastKeyIn <= '9') + { + int idx = mon.lastKeyIn & 0x0F; + SlavePtr slPtr = blePoll.getSlavePtr(idx); + PollStatePtr pPtr = blePoll.getPollPtr(slPtr->pIdx); + resultPtr = (PlPduMeasPtr) &slPtr->result; + ctrlPtr = (PlPduMeasPtr) &slPtr->control; + appId = resultPtr->appId; + + mon.print((char *) "Slave["); + mon.print(idx); + mon.print((char *) "] pduCnt="); + mon.print(resultPtr->counter); + mon.print((char *) " pduType="); + mon.print(resultPtr->type); + mon.print((char *) " appId="); + mon.print(resultPtr->appId); + mon.print((char *) " measCnt="); + mon.println(resultPtr->measCnt); + + mon.println(resultPtr->plData,27,' '); + + switch (appId) + { + case plptIMU3F4Ctrl4: + mon.print("AppId: plptIMU3F4Ctrl4"); + mon.print(" Roll="); + tmpFloat = ((PlpI3S4C4Ptr) resultPtr)->meas[0]; + sprintf(conv,"%f",tmpFloat); + mon.print(conv); + mon.print(" Pitch="); + tmpFloat = ((PlpI3S4C4Ptr) resultPtr)->meas[1]; + sprintf(conv,"%f",tmpFloat); + mon.print(conv); + break; + + default: + mon.print(" Unbekannte AppId"); + break; + } + mon.println(); + sm.resetEnter(); + } + else + { + if(mon.lastKeyIn == ' ') + { + mon.cFlag[3] = false; + mon.print((char *) "-- Schleifenabbruch - drücke Enter"); + sm.enter(smCheckJobs); + } + } + +} + +// ---------------------------------------------------------------------------- +// Analysieren der Anwendung +// ---------------------------------------------------------------------------- +// +char *caHelp = +{ +"c Zyklen der Zustandsmaschine\r\n" +"m Ausgabe Midiwerte\r\n" +"Leerzeichen für Abbruch\r\n" +}; + +void smCheckApp() +{ + if(sm.firstEnter()) + { + mon.print((char *) "Check App "); + mon.lastKeyIn = ':'; + } + + if(mon.lastKeyIn == ':') return; + + if(mon.lastKeyIn == 'H' || mon.lastKeyIn == 'h') + { + mon.println(); + mon.println(caHelp); + sm.resetEnter(); + } + else if(mon.lastKeyIn == 'C' || mon.lastKeyIn == 'c') + { + mon.cprintln('c'); + mon.print(apInitCnt); mon.cprint(' '); + mon.print(apWaitDECnt); mon.cprint(' '); + mon.print(apWaitMeasCnt); mon.cprint(' '); + mon.print(apProcMeasCnt); mon.cprint(' '); + mon.print(apCheckValuesCnt); mon.cprint(' '); + mon.print(apCalcResultCnt); mon.cprint(' '); + mon.println(apSetResultCnt); + sm.resetEnter(); + } + else if(mon.lastKeyIn == 'M' || mon.lastKeyIn == 'm') + { + mon.cprintln('m'); + mon.print(slNr); mon.cprint(' '); + mon.print(resultNote[NoteType]); mon.cprint(' '); + mon.print(resultNote[NoteVal]); mon.cprint(' '); + mon.println(resultNote[NoteVel]); + sm.resetEnter(); + } + + else if(mon.lastKeyIn == ' ') + { + mon.cFlag[4] = false; + mon.print((char *) "-- Schleifenabbruch - drücke Enter"); + sm.enter(smCheckJobs); + } +} + +// ---------------------------------------------------------------------------- +// Modus (Polling-Info, Steuerung) an einen Slave +// ---------------------------------------------------------------------------- +// ACHTUNG! +// Diese Testfunktion ist allgemein gehalten. Tatsächlich wird zur Zeit noch +// nicht der Datentyp ausgewertet und immer die ersten zwei Zeichen Inhalt +// zum Slave übertragen +// +char *msHelp = +{ +"1. 1..5 Slaveadresse\r\n" +"2. 0..9 Modustyp oder A für Antwort\r\n" +" xyz Modus, Senden mit TAB\r\n" +"Leerzeichen für Abbruch\r\n" +}; + +int inIdx = 0; +int msSlaveNr = 0; +int msModeType = 0; + +CtrlResp2 ctrlResp; +byte oldProcCnt = 0; + +void smMode4Slave() +{ + //CtrlData2Ptr ctrlDataPtr; + + if(sm.firstEnter()) + { + mon.print((char *) "Meldung an Slave["); + mon.lastKeyIn = ':'; + inIdx = 0; + } + + if(mon.lastKeyIn == ':') return; + + if(mon.lastKeyIn == 'H' || mon.lastKeyIn == 'h') + { + mon.println(); + mon.println(msHelp); + sm.resetEnter(); + } + else if(mon.lastKeyIn >= '1' && mon.lastKeyIn <= '5' && inIdx == 0) + { + mon.cprint(mon.lastKeyIn); + msSlaveNr = mon.lastKeyIn & 0x0F; + mon.print("] Typ = "); + inIdx = 1; + mon.lastKeyIn = ':'; + } + else if(mon.lastKeyIn >= '0' && mon.lastKeyIn <= '9' && inIdx == 1) + { + mon.cprint(mon.lastKeyIn); + msModeType = mon.lastKeyIn & 0x0F; + sm.enter(smMode4SlaveIn); + } + else if((mon.lastKeyIn == 'A' || mon.lastKeyIn == 'a') && inIdx == 1) + { + mon.print("Antwort: {"); + blePoll.getCtrlResp(msSlaveNr, &ctrlResp); + + if(ctrlResp.procCnt != oldProcCnt) + { + oldProcCnt = ctrlResp.procCnt; + mon.cprint(ctrlResp.ctrl[0]); + mon.cprint(ctrlResp.ctrl[1]); + } + mon.cprintln('}'); + sm.resetEnter(); + } + + else if(mon.lastKeyIn == ' ') + { + mon.cFlag[5] = false; + mon.print((char *) "-- Schleifenabbruch - drücke Enter"); + sm.enter(smCheckJobs); + } +} + +char mode2Snd[8]; + +void smMode4SlaveIn() +{ + if(sm.firstEnter()) + { + mon.print((char *) " {"); + mon.lastKeyIn = ':'; + inIdx = 0; + } + + if(mon.lastKeyIn == ':') return; + + if(mon.lastKeyIn == ' ') + { + mon.cFlag[5] = false; + mon.print((char *) "-- Schleifenabbruch - drücke Enter"); + sm.enter(smCheckJobs); + } + + else if(mon.lastKeyIn == '\t' || inIdx > 5) + { + blePoll.updControl(msSlaveNr, (byte *) mode2Snd, 2); + mon.println("} gesendet"); + sm.enter(smMode4Slave); + } + + else + { + mode2Snd[inIdx] = mon.lastKeyIn; + mon.cprint(mon.lastKeyIn); + mon.lastKeyIn = ':'; + inIdx++; + } + +} + +// ---------------------------------------------------------------------------- +// Debug-Informationen +// ---------------------------------------------------------------------------- +// + +#endif // DebugTerminal + diff --git a/sketches/_PIO_Sketches/Karger/22_11_11_1_BLE_Master_Soaap/test/README b/sketches/_PIO_Sketches/Karger/22_11_11_1_BLE_Master_Soaap/test/README new file mode 100644 index 0000000000000000000000000000000000000000..9b1e87bc67c90e7f09a92a3e855444b085c655a6 --- /dev/null +++ b/sketches/_PIO_Sketches/Karger/22_11_11_1_BLE_Master_Soaap/test/README @@ -0,0 +1,11 @@ + +This directory is intended for PlatformIO Test Runner and project tests. + +Unit Testing is a software testing method by which individual units of +source code, sets of one or more MCU program modules together with associated +control data, usage procedures, and operating procedures, are tested to +determine whether they are fit for use. Unit testing finds problems early +in the development cycle. + +More information about PlatformIO Unit Testing: +- https://docs.platformio.org/en/latest/advanced/unit-testing/index.html diff --git a/sketches/_PIO_Sketches/Karger/BLE_Master_Test_1/.gitignore b/sketches/_PIO_Sketches/Karger/BLE_Master_Test_1/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..d7c90c91edbd8584ab713f39dcdbbaa149059e5d --- /dev/null +++ b/sketches/_PIO_Sketches/Karger/BLE_Master_Test_1/.gitignore @@ -0,0 +1,7 @@ +.pio +.vscode/.browse.c_cpp.db* +.vscode/c_cpp_properties.json +.vscode/launch.json +.vscode/ipch +*.log +*.ini \ No newline at end of file diff --git a/sketches/_PIO_Sketches/Karger/BLE_Master_Test_1/.pio/build/nano33ble/idedata.json b/sketches/_PIO_Sketches/Karger/BLE_Master_Test_1/.pio/build/nano33ble/idedata.json new file mode 100644 index 0000000000000000000000000000000000000000..df0afb763a300d300f146a268654bce90035aa03 --- /dev/null +++ b/sketches/_PIO_Sketches/Karger/BLE_Master_Test_1/.pio/build/nano33ble/idedata.json @@ -0,0 +1 @@ +{"env_name": "nano33ble", "libsource_dirs": ["c:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\sketches\\_PIO_Sketches\\Karger\\BLE_Master_Test_1\\lib", "c:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\sketches\\_PIO_Sketches\\Karger\\BLE_Master_Test_1\\.pio\\libdeps\\nano33ble", "C:\\Users\\lenna\\.platformio\\lib", "C:\\Users\\lenna\\.platformio\\packages\\framework-arduino-mbed\\libraries"], "defines": ["PLATFORMIO=60104", "ARDUINO_ARDUINO_NANO33BLE", "ARDUINO_ARCH_NRF52840", "smnDEFBYBUILD", "smnNANOBLE33", "smnDEBUG", "ARM_MATH_CM4", "BOARD_PCA10056", "__CMSIS_RTOS", "CMSIS_VECTAB_VIRTUAL", "CMSIS_VECTAB_VIRTUAL_HEADER_FILE=\"cmsis_nvic.h\"", "COMPONENT_FLASHIAP=1", "CONFIG_GPIO_AS_PINRESET", "__CORTEX_M4", "DEVICE_ANALOGIN=1", "DEVICE_FLASH=1", "DEVICE_I2C=1", "DEVICE_I2C_ASYNCH=1", "DEVICE_I2CSLAVE=1", "DEVICE_INTERRUPTIN=1", "DEVICE_LPTICKER=1", "DEVICE_PORTIN=1", "DEVICE_PORTINOUT=1", "DEVICE_PORTOUT=1", "DEVICE_PWMOUT=1", "DEVICE_SERIAL=1", "DEVICE_SERIAL_ASYNCH=1", "DEVICE_SERIAL_FC=1", "DEVICE_SLEEP=1", "DEVICE_SPI=1", "DEVICE_SPI_ASYNCH=1", "DEVICE_SYSTICK_CLK_OFF_DURING_SLEEP=1", "DEVICE_TRNG=1", "DEVICE_USBDEVICE=1", "DEVICE_USTICKER=1", "DEVICE_WATCHDOG=1", "FEATURE_BLE=1", "FEATURE_CRYPTOCELL310=1", "FEATURE_STORAGE=1", "__FPU_PRESENT=1", "__MBED__=1", "MBED_BUILD_TIMESTAMP=1652255892.88627", "__MBED_CMSIS_RTOS_CM", "MBED_MPU_CUSTOM", "MBED_TICKLESS", "MBEDTLS_CONFIG_HW_SUPPORT", "NRF52840_XXAA", "NRF52_PAN_20", "SWI_DISABLE0", "TARGET_ARDUINO_NANO33BLE", "TARGET_CORDIO", "TARGET_CORDIO_LL", "TARGET_CORTEX", "TARGET_CORTEX_M", "TARGET_LIKE_CORTEX_M4", "TARGET_LIKE_MBED", "TARGET_M4", "TARGET_MCU_NRF52840", "TARGET_NAME=ARDUINO_NANO33BLE", "TARGET_NORDIC", "TARGET_NORDIC_CORDIO", "TARGET_NRF52", "TARGET_NRF52840", "TARGET_NRF5x", "TARGET_RELEASE", "TARGET_RTOS_M4_M7", "TARGET_SDK_15_0", "TARGET_SOFTDEVICE_NONE", "TOOLCHAIN_GCC", "TOOLCHAIN_GCC_ARM", "WSF_MAX_HANDLERS=10", "MBED_NO_GLOBAL_USING_DIRECTIVE=1", "CORE_MAJOR=3", "CORE_MINOR=1", "CORE_PATCH=1", "USE_ARDUINO_PINOUT", "ARDUINO=10810", "ARDUINO_ARCH_MBED"], "includes": {"build": ["c:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\sketches\\_PIO_Sketches\\Karger\\BLE_Master_Test_1\\include", "c:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\sketches\\_PIO_Sketches\\Karger\\BLE_Master_Test_1\\src", "c:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\sketches\\_PIO_Sketches\\Karger\\BLE_Master_Test_1\\include", "c:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\sketches\\_PIO_Sketches\\Karger\\BLE_Master_Test_1\\src", "C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\libraries\\SensorLSM9DS1", "C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\libraries\\nRF52840Twi", "C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\libraries\\nRF52840Gpio", "C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\libraries\\MidiNotes", "C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\libraries\\nRF52840Radio", "C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\libraries\\Monitor", "C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\libraries\\LoopCheck", "C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\libraries\\BlePoll", "C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\libraries\\StateMachine", "C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\libraries\\SoaapMsg", "C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\libraries\\nRF52840Ser", "C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\libraries\\ComRingBuf", "C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\libraries\\environment", "C:\\Users\\lenna\\.platformio\\packages\\framework-arduino-mbed\\cores\\arduino", "C:\\Users\\lenna\\.platformio\\packages\\framework-arduino-mbed\\cores\\arduino\\api\\deprecated", "C:\\Users\\lenna\\.platformio\\packages\\framework-arduino-mbed\\cores\\arduino\\api\\deprecated-avr-comp", "C:\\Users\\lenna\\.platformio\\packages\\framework-arduino-mbed\\variants\\ARDUINO_NANO33BLE"], "compatlib": ["C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\libraries\\BlePoll", "C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\libraries\\nRF52840Radio", "C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\libraries\\Monitor", "C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\libraries\\LoopCheck", "C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\libraries\\BlePoll", "C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\libraries\\StateMachine", "C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\libraries\\SoaapMsg", "C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\libraries\\nRF52840Ser", "C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\libraries\\ComRingBuf", "C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\libraries\\environment", "C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\libraries\\ComRingBuf", "C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\libraries\\nRF52840Radio", "C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\libraries\\Monitor", "C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\libraries\\LoopCheck", "C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\libraries\\BlePoll", "C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\libraries\\StateMachine", "C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\libraries\\SoaapMsg", "C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\libraries\\nRF52840Ser", "C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\libraries\\ComRingBuf", "C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\libraries\\environment", "C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\libraries\\LoopCheck", "C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\libraries\\nRF52840Radio", "C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\libraries\\Monitor", "C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\libraries\\LoopCheck", "C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\libraries\\BlePoll", "C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\libraries\\StateMachine", "C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\libraries\\SoaapMsg", "C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\libraries\\nRF52840Ser", "C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\libraries\\ComRingBuf", "C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\libraries\\environment", "C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\libraries\\MidiNotes", "C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\libraries\\MidiNotes", "C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\libraries\\nRF52840Radio", "C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\libraries\\Monitor", "C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\libraries\\LoopCheck", "C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\libraries\\BlePoll", "C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\libraries\\StateMachine", "C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\libraries\\SoaapMsg", "C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\libraries\\nRF52840Ser", "C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\libraries\\ComRingBuf", "C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\libraries\\environment", "C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\libraries\\Monitor", "C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\libraries\\nRF52840Radio", "C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\libraries\\Monitor", "C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\libraries\\LoopCheck", "C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\libraries\\BlePoll", "C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\libraries\\StateMachine", "C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\libraries\\SoaapMsg", "C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\libraries\\nRF52840Ser", "C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\libraries\\ComRingBuf", "C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\libraries\\environment", "C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\libraries\\SensorLSM9DS1", "C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\libraries\\SensorLSM9DS1", "C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\libraries\\nRF52840Radio", "C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\libraries\\Monitor", "C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\libraries\\LoopCheck", "C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\libraries\\BlePoll", "C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\libraries\\StateMachine", "C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\libraries\\SoaapMsg", "C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\libraries\\nRF52840Ser", "C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\libraries\\ComRingBuf", "C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\libraries\\environment", "C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\libraries\\SoaapMsg", "C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\libraries\\nRF52840Radio", "C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\libraries\\Monitor", "C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\libraries\\LoopCheck", "C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\libraries\\BlePoll", "C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\libraries\\StateMachine", "C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\libraries\\SoaapMsg", "C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\libraries\\nRF52840Ser", "C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\libraries\\ComRingBuf", "C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\libraries\\environment", "C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\libraries\\StateMachine", "C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\libraries\\StateMachine", "C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\libraries\\environment", "C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\libraries\\nRF52840Radio", "C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\libraries\\Monitor", "C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\libraries\\LoopCheck", "C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\libraries\\BlePoll", "C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\libraries\\StateMachine", "C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\libraries\\SoaapMsg", "C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\libraries\\nRF52840Ser", "C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\libraries\\ComRingBuf", "C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\libraries\\environment", "C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\libraries\\nRF52840Gpio", "C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\libraries\\nRF52840Gpio", "C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\libraries\\nRF52840Radio", "C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\libraries\\Monitor", "C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\libraries\\LoopCheck", "C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\libraries\\BlePoll", "C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\libraries\\StateMachine", "C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\libraries\\SoaapMsg", "C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\libraries\\nRF52840Ser", "C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\libraries\\ComRingBuf", "C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\libraries\\environment", "C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\libraries\\nRF52840Radio", "C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\libraries\\nRF52840Radio", "C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\libraries\\Monitor", "C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\libraries\\LoopCheck", "C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\libraries\\BlePoll", "C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\libraries\\StateMachine", "C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\libraries\\SoaapMsg", "C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\libraries\\nRF52840Ser", "C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\libraries\\ComRingBuf", "C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\libraries\\environment", "C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\libraries\\nRF52840Ser", "C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\libraries\\nRF52840Radio", "C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\libraries\\Monitor", "C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\libraries\\LoopCheck", "C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\libraries\\BlePoll", "C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\libraries\\StateMachine", "C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\libraries\\SoaapMsg", "C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\libraries\\nRF52840Ser", "C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\libraries\\ComRingBuf", "C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\libraries\\environment", "C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\libraries\\nRF52840Twi", "C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\libraries\\nRF52840Twi", "C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\libraries\\nRF52840Radio", "C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\libraries\\Monitor", "C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\libraries\\LoopCheck", "C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\libraries\\BlePoll", "C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\libraries\\StateMachine", "C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\libraries\\SoaapMsg", "C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\libraries\\nRF52840Ser", "C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\libraries\\ComRingBuf", "C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\libraries\\environment", "C:\\Users\\lenna\\.platformio\\packages\\framework-arduino-mbed\\libraries\\Camera\\src", "C:\\Users\\lenna\\.platformio\\packages\\framework-arduino-mbed\\libraries\\Ethernet\\src", "C:\\Users\\lenna\\.platformio\\packages\\framework-arduino-mbed\\libraries\\GC2145", "C:\\Users\\lenna\\.platformio\\packages\\framework-arduino-mbed\\libraries\\GPS\\src", "C:\\Users\\lenna\\.platformio\\packages\\framework-arduino-mbed\\libraries\\GSM\\src", "C:\\Users\\lenna\\.platformio\\packages\\framework-arduino-mbed\\libraries\\Himax_HM01B0", "C:\\Users\\lenna\\.platformio\\packages\\framework-arduino-mbed\\libraries\\KernelDebug\\src", "C:\\Users\\lenna\\.platformio\\packages\\framework-arduino-mbed\\libraries\\MCUboot\\src", "C:\\Users\\lenna\\.platformio\\packages\\framework-arduino-mbed\\libraries\\MLC\\src", "C:\\Users\\lenna\\.platformio\\packages\\framework-arduino-mbed\\libraries\\MRI\\src", "C:\\Users\\lenna\\.platformio\\packages\\framework-arduino-mbed\\libraries\\Nano33BLE_System\\src", "C:\\Users\\lenna\\.platformio\\packages\\framework-arduino-mbed\\libraries\\Nicla_System\\src", "C:\\Users\\lenna\\.platformio\\packages\\framework-arduino-mbed\\libraries\\PDM\\src", "C:\\Users\\lenna\\.platformio\\packages\\framework-arduino-mbed\\libraries\\Portenta_Audio\\src", "C:\\Users\\lenna\\.platformio\\packages\\framework-arduino-mbed\\libraries\\Portenta_SDCARD\\src", "C:\\Users\\lenna\\.platformio\\packages\\framework-arduino-mbed\\libraries\\Portenta_SDRAM\\src", "C:\\Users\\lenna\\.platformio\\packages\\framework-arduino-mbed\\libraries\\Portenta_Video\\src", "C:\\Users\\lenna\\.platformio\\packages\\framework-arduino-mbed\\libraries\\Portenta_lvgl\\src", "C:\\Users\\lenna\\.platformio\\packages\\framework-arduino-mbed\\libraries\\RPC\\src", "C:\\Users\\lenna\\.platformio\\packages\\framework-arduino-mbed\\libraries\\SE05X\\src", "C:\\Users\\lenna\\.platformio\\packages\\framework-arduino-mbed\\libraries\\SFU\\src", "C:\\Users\\lenna\\.platformio\\packages\\framework-arduino-mbed\\libraries\\SPI", "C:\\Users\\lenna\\.platformio\\packages\\framework-arduino-mbed\\libraries\\STM32H747_System\\src", "C:\\Users\\lenna\\.platformio\\packages\\framework-arduino-mbed\\libraries\\Scheduler\\src", "C:\\Users\\lenna\\.platformio\\packages\\framework-arduino-mbed\\libraries\\SocketWrapper\\src", "C:\\Users\\lenna\\.platformio\\packages\\framework-arduino-mbed\\libraries\\ThreadDebug\\src", "C:\\Users\\lenna\\.platformio\\packages\\framework-arduino-mbed\\libraries\\USBAudio", "C:\\Users\\lenna\\.platformio\\packages\\framework-arduino-mbed\\libraries\\USBHID\\src", "C:\\Users\\lenna\\.platformio\\packages\\framework-arduino-mbed\\libraries\\USBHOST\\src", "C:\\Users\\lenna\\.platformio\\packages\\framework-arduino-mbed\\libraries\\USBMSD\\src", "C:\\Users\\lenna\\.platformio\\packages\\framework-arduino-mbed\\libraries\\WiFi\\src", "C:\\Users\\lenna\\.platformio\\packages\\framework-arduino-mbed\\libraries\\Wire", "C:\\Users\\lenna\\.platformio\\packages\\framework-arduino-mbed\\libraries\\doom\\src", "C:\\Users\\lenna\\.platformio\\packages\\framework-arduino-mbed\\libraries\\ea_malloc", "C:\\Users\\lenna\\.platformio\\packages\\framework-arduino-mbed\\libraries\\mbed-memory-status", "C:\\Users\\lenna\\.platformio\\packages\\framework-arduino-mbed\\libraries\\openamp_arduino\\src", "C:\\Users\\lenna\\.platformio\\packages\\framework-arduino-mbed\\libraries\\rpclib\\src"], "toolchain": ["C:\\Users\\lenna\\.platformio\\packages\\toolchain-gccarmnoneeabi\\arm-none-eabi\\include\\c++\\8.2.1", "C:\\Users\\lenna\\.platformio\\packages\\toolchain-gccarmnoneeabi\\arm-none-eabi\\include\\c++\\8.2.1\\arm-none-eabi", "C:\\Users\\lenna\\.platformio\\packages\\toolchain-gccarmnoneeabi\\lib\\gcc\\arm-none-eabi\\8.2.1\\include", "C:\\Users\\lenna\\.platformio\\packages\\toolchain-gccarmnoneeabi\\lib\\gcc\\arm-none-eabi\\8.2.1\\include-fixed", "C:\\Users\\lenna\\.platformio\\packages\\toolchain-gccarmnoneeabi\\arm-none-eabi\\include"]}, "cc_flags": "-std=gnu11 -DAPPLICATION_ADDR=0x10000 -DAPPLICATION_SIZE=0xf0000 -DMBED_RAM_SIZE=0x40000 -DMBED_RAM_START=0x20000000 -DMBED_ROM_SIZE=0x100000 -DMBED_ROM_START=0x0 -DMBED_TRAP_ERRORS_ENABLED=1 -Os -Wall -Wextra -Wno-missing-field-initializers -Wno-unused-parameter -c -fdata-sections -ffunction-sections -fmessage-length=0 -fno-exceptions -fomit-frame-pointer -funsigned-char -mcpu=cortex-m4 -mfloat-abi=softfp -mfpu=fpv4-sp-d16 -mthumb -iprefixC:\\Users\\lenna\\.platformio\\packages\\framework-arduino-mbed\\cores\\arduino @C:\\Users\\lenna\\.platformio\\packages\\framework-arduino-mbed\\variants\\ARDUINO_NANO33BLE\\includes.txt -nostdlib", "cxx_flags": "-Wvla -fno-rtti -std=gnu++14 -DAPPLICATION_ADDR=0x10000 -DAPPLICATION_SIZE=0xf0000 -DMBED_RAM_SIZE=0x40000 -DMBED_RAM_START=0x20000000 -DMBED_ROM_SIZE=0x100000 -DMBED_ROM_START=0x0 -DMBED_TRAP_ERRORS_ENABLED=1 -Os -Wall -Wextra -Wno-missing-field-initializers -Wno-unused-parameter -c -fdata-sections -ffunction-sections -fmessage-length=0 -fno-exceptions -fomit-frame-pointer -funsigned-char -mcpu=cortex-m4 -mfloat-abi=softfp -mfpu=fpv4-sp-d16 -mthumb -iprefixC:\\Users\\lenna\\.platformio\\packages\\framework-arduino-mbed\\cores\\arduino @C:\\Users\\lenna\\.platformio\\packages\\framework-arduino-mbed\\variants\\ARDUINO_NANO33BLE\\includes.txt -nostdlib", "cc_path": "C:\\Users\\lenna\\.platformio\\packages\\toolchain-gccarmnoneeabi\\bin\\arm-none-eabi-gcc.exe", "cxx_path": "C:\\Users\\lenna\\.platformio\\packages\\toolchain-gccarmnoneeabi\\bin\\arm-none-eabi-g++.exe", "gdb_path": "C:\\Users\\lenna\\.platformio\\packages\\toolchain-gccarmnoneeabi\\bin\\arm-none-eabi-gdb.exe", "prog_path": "c:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\sketches\\_PIO_Sketches\\Karger\\BLE_Master_Test_1\\.pio\\build\\nano33ble\\firmware.elf", "svd_path": "C:\\Users\\lenna\\.platformio\\platforms\\nordicnrf52\\misc\\svd\\nrf52840.svd", "compiler_type": "gcc", "targets": [{"name": "size", "title": "Program Size", "description": "Calculate program size", "group": "Platform"}, {"name": "upload", "title": "Upload", "description": null, "group": "Platform"}, {"name": "erase", "title": "Erase Flash", "description": null, "group": "Platform"}], "extra": {"flash_images": []}} \ No newline at end of file diff --git a/sketches/_PIO_Sketches/Karger/BLE_Master_Test_1/.pio/build/project.checksum b/sketches/_PIO_Sketches/Karger/BLE_Master_Test_1/.pio/build/project.checksum new file mode 100644 index 0000000000000000000000000000000000000000..3c2961d85e9ba1031c76f84d3102bcb4f64b73cc --- /dev/null +++ b/sketches/_PIO_Sketches/Karger/BLE_Master_Test_1/.pio/build/project.checksum @@ -0,0 +1 @@ +6107bbcff6a5f2b9e99a6c32ff252bb709c950ae \ No newline at end of file diff --git a/sketches/_PIO_Sketches/Karger/BLE_Master_Test_1/.pio/libdeps/nano33ble/BlePoll.pio-link b/sketches/_PIO_Sketches/Karger/BLE_Master_Test_1/.pio/libdeps/nano33ble/BlePoll.pio-link new file mode 100644 index 0000000000000000000000000000000000000000..28e17bc7ae86c00b35723fe8330bad0ca9a97a93 --- /dev/null +++ b/sketches/_PIO_Sketches/Karger/BLE_Master_Test_1/.pio/libdeps/nano33ble/BlePoll.pio-link @@ -0,0 +1 @@ +{"cwd": "c:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\sketches\\_PIO_Sketches\\Karger\\BLE_Master_Test_1", "spec": {"owner": null, "id": null, "name": "BlePoll", "requirements": null, "uri": "symlink://C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\libraries\\BlePoll"}} \ No newline at end of file diff --git a/sketches/_PIO_Sketches/Karger/BLE_Master_Test_1/.pio/libdeps/nano33ble/ComRingBuf.pio-link b/sketches/_PIO_Sketches/Karger/BLE_Master_Test_1/.pio/libdeps/nano33ble/ComRingBuf.pio-link new file mode 100644 index 0000000000000000000000000000000000000000..56126438430e9280d1ac92cda5e3c9e43fd2d2c5 --- /dev/null +++ b/sketches/_PIO_Sketches/Karger/BLE_Master_Test_1/.pio/libdeps/nano33ble/ComRingBuf.pio-link @@ -0,0 +1 @@ +{"cwd": "c:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\sketches\\_PIO_Sketches\\Karger\\BLE_Master_Test_1", "spec": {"owner": null, "id": null, "name": "ComRingBuf", "requirements": null, "uri": "symlink://C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\libraries\\ComRingBuf"}} \ No newline at end of file diff --git a/sketches/_PIO_Sketches/Karger/BLE_Master_Test_1/.pio/libdeps/nano33ble/LoopCheck.pio-link b/sketches/_PIO_Sketches/Karger/BLE_Master_Test_1/.pio/libdeps/nano33ble/LoopCheck.pio-link new file mode 100644 index 0000000000000000000000000000000000000000..e32a4fb766d160e6337a3565c9bd6ea0029deae7 --- /dev/null +++ b/sketches/_PIO_Sketches/Karger/BLE_Master_Test_1/.pio/libdeps/nano33ble/LoopCheck.pio-link @@ -0,0 +1 @@ +{"cwd": "c:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\sketches\\_PIO_Sketches\\Karger\\BLE_Master_Test_1", "spec": {"owner": null, "id": null, "name": "LoopCheck", "requirements": null, "uri": "symlink://C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\libraries\\LoopCheck"}} \ No newline at end of file diff --git a/sketches/_PIO_Sketches/Karger/BLE_Master_Test_1/.pio/libdeps/nano33ble/MidiNotes.pio-link b/sketches/_PIO_Sketches/Karger/BLE_Master_Test_1/.pio/libdeps/nano33ble/MidiNotes.pio-link new file mode 100644 index 0000000000000000000000000000000000000000..41e3a9906f26be2ff46316bba3179b1d0bd4be05 --- /dev/null +++ b/sketches/_PIO_Sketches/Karger/BLE_Master_Test_1/.pio/libdeps/nano33ble/MidiNotes.pio-link @@ -0,0 +1 @@ +{"cwd": "c:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\sketches\\_PIO_Sketches\\Karger\\BLE_Master_Test_1", "spec": {"owner": null, "id": null, "name": "MidiNotes", "requirements": null, "uri": "symlink://C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\libraries\\MidiNotes"}} \ No newline at end of file diff --git a/sketches/_PIO_Sketches/Karger/BLE_Master_Test_1/.pio/libdeps/nano33ble/Monitor.pio-link b/sketches/_PIO_Sketches/Karger/BLE_Master_Test_1/.pio/libdeps/nano33ble/Monitor.pio-link new file mode 100644 index 0000000000000000000000000000000000000000..4c502e2a44fc82ee0fbcbd201665542e2f1d6b1c --- /dev/null +++ b/sketches/_PIO_Sketches/Karger/BLE_Master_Test_1/.pio/libdeps/nano33ble/Monitor.pio-link @@ -0,0 +1 @@ +{"cwd": "c:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\sketches\\_PIO_Sketches\\Karger\\BLE_Master_Test_1", "spec": {"owner": null, "id": null, "name": "Monitor", "requirements": null, "uri": "symlink://C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\libraries\\Monitor"}} \ No newline at end of file diff --git a/sketches/_PIO_Sketches/Karger/BLE_Master_Test_1/.pio/libdeps/nano33ble/SensorLSM9DS1.pio-link b/sketches/_PIO_Sketches/Karger/BLE_Master_Test_1/.pio/libdeps/nano33ble/SensorLSM9DS1.pio-link new file mode 100644 index 0000000000000000000000000000000000000000..bdec87c63a7998807f54ebc393fa2b8e18c424b3 --- /dev/null +++ b/sketches/_PIO_Sketches/Karger/BLE_Master_Test_1/.pio/libdeps/nano33ble/SensorLSM9DS1.pio-link @@ -0,0 +1 @@ +{"cwd": "c:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\sketches\\_PIO_Sketches\\Karger\\BLE_Master_Test_1", "spec": {"owner": null, "id": null, "name": "SensorLSM9DS1", "requirements": null, "uri": "symlink://C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\libraries\\SensorLSM9DS1"}} \ No newline at end of file diff --git a/sketches/_PIO_Sketches/Karger/BLE_Master_Test_1/.pio/libdeps/nano33ble/SoaapMsg.pio-link b/sketches/_PIO_Sketches/Karger/BLE_Master_Test_1/.pio/libdeps/nano33ble/SoaapMsg.pio-link new file mode 100644 index 0000000000000000000000000000000000000000..fc05abe269f0169f2afbcf2759de824f5b893f88 --- /dev/null +++ b/sketches/_PIO_Sketches/Karger/BLE_Master_Test_1/.pio/libdeps/nano33ble/SoaapMsg.pio-link @@ -0,0 +1 @@ +{"cwd": "c:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\sketches\\_PIO_Sketches\\Karger\\BLE_Master_Test_1", "spec": {"owner": null, "id": null, "name": "SoaapMsg", "requirements": null, "uri": "symlink://C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\libraries\\SoaapMsg"}} \ No newline at end of file diff --git a/sketches/_PIO_Sketches/Karger/BLE_Master_Test_1/.pio/libdeps/nano33ble/StateMachine.pio-link b/sketches/_PIO_Sketches/Karger/BLE_Master_Test_1/.pio/libdeps/nano33ble/StateMachine.pio-link new file mode 100644 index 0000000000000000000000000000000000000000..e0ce3a058ae2760279eb131fe5f7a428a8f01e1c --- /dev/null +++ b/sketches/_PIO_Sketches/Karger/BLE_Master_Test_1/.pio/libdeps/nano33ble/StateMachine.pio-link @@ -0,0 +1 @@ +{"cwd": "c:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\sketches\\_PIO_Sketches\\Karger\\BLE_Master_Test_1", "spec": {"owner": null, "id": null, "name": "StateMachine", "requirements": null, "uri": "symlink://C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\libraries\\StateMachine"}} \ No newline at end of file diff --git a/sketches/_PIO_Sketches/Karger/BLE_Master_Test_1/.pio/libdeps/nano33ble/environment.pio-link b/sketches/_PIO_Sketches/Karger/BLE_Master_Test_1/.pio/libdeps/nano33ble/environment.pio-link new file mode 100644 index 0000000000000000000000000000000000000000..58b10673feffeae43ce8bc157878aa3287bc7f56 --- /dev/null +++ b/sketches/_PIO_Sketches/Karger/BLE_Master_Test_1/.pio/libdeps/nano33ble/environment.pio-link @@ -0,0 +1 @@ +{"cwd": "c:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\sketches\\_PIO_Sketches\\Karger\\BLE_Master_Test_1", "spec": {"owner": null, "id": null, "name": "environment", "requirements": null, "uri": "symlink://C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\libraries\\environment"}} \ No newline at end of file diff --git a/sketches/_PIO_Sketches/Karger/BLE_Master_Test_1/.pio/libdeps/nano33ble/integrity.dat b/sketches/_PIO_Sketches/Karger/BLE_Master_Test_1/.pio/libdeps/nano33ble/integrity.dat new file mode 100644 index 0000000000000000000000000000000000000000..eb48d1334c2ebd5faafe31fd0022200f84692be8 --- /dev/null +++ b/sketches/_PIO_Sketches/Karger/BLE_Master_Test_1/.pio/libdeps/nano33ble/integrity.dat @@ -0,0 +1,13 @@ +symlink://C:\Users\lenna\OneDrive\Dokumente\Git\SOAAP\libraries\nRF52840Ser +symlink://C:\Users\lenna\OneDrive\Dokumente\Git\SOAAP\libraries\nRF52840Radio +symlink://C:\Users\lenna\OneDrive\Dokumente\Git\SOAAP\libraries\Monitor +symlink://C:\Users\lenna\OneDrive\Dokumente\Git\SOAAP\libraries\nRF52840Twi +symlink://C:\Users\lenna\OneDrive\Dokumente\Git\SOAAP\libraries\SensorLSM9DS1 +symlink://C:\Users\lenna\OneDrive\Dokumente\Git\SOAAP\libraries\nRF52840Gpio +symlink://C:\Users\lenna\OneDrive\Dokumente\Git\SOAAP\libraries\environment +symlink://C:\Users\lenna\OneDrive\Dokumente\Git\SOAAP\libraries\LoopCheck +symlink://C:\Users\lenna\OneDrive\Dokumente\Git\SOAAP\libraries\MidiNotes +symlink://C:\Users\lenna\OneDrive\Dokumente\Git\SOAAP\libraries\ComRingBuf +symlink://C:\Users\lenna\OneDrive\Dokumente\Git\SOAAP\libraries\BlePoll +symlink://C:\Users\lenna\OneDrive\Dokumente\Git\SOAAP\libraries\SoaapMsg +symlink://C:\Users\lenna\OneDrive\Dokumente\Git\SOAAP\libraries\StateMachine \ No newline at end of file diff --git a/sketches/_PIO_Sketches/Karger/BLE_Master_Test_1/.pio/libdeps/nano33ble/nRF52840Gpio.pio-link b/sketches/_PIO_Sketches/Karger/BLE_Master_Test_1/.pio/libdeps/nano33ble/nRF52840Gpio.pio-link new file mode 100644 index 0000000000000000000000000000000000000000..3073b4f1bc60606bb097a21dc7cf3986074598e0 --- /dev/null +++ b/sketches/_PIO_Sketches/Karger/BLE_Master_Test_1/.pio/libdeps/nano33ble/nRF52840Gpio.pio-link @@ -0,0 +1 @@ +{"cwd": "c:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\sketches\\_PIO_Sketches\\Karger\\BLE_Master_Test_1", "spec": {"owner": null, "id": null, "name": "nRF52840Gpio", "requirements": null, "uri": "symlink://C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\libraries\\nRF52840Gpio"}} \ No newline at end of file diff --git a/sketches/_PIO_Sketches/Karger/BLE_Master_Test_1/.pio/libdeps/nano33ble/nRF52840Radio.pio-link b/sketches/_PIO_Sketches/Karger/BLE_Master_Test_1/.pio/libdeps/nano33ble/nRF52840Radio.pio-link new file mode 100644 index 0000000000000000000000000000000000000000..fd40a8f98d13dcda2abe778b810adc2a1ac35fca --- /dev/null +++ b/sketches/_PIO_Sketches/Karger/BLE_Master_Test_1/.pio/libdeps/nano33ble/nRF52840Radio.pio-link @@ -0,0 +1 @@ +{"cwd": "c:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\sketches\\_PIO_Sketches\\Karger\\BLE_Master_Test_1", "spec": {"owner": null, "id": null, "name": "nRF52840Radio", "requirements": null, "uri": "symlink://C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\libraries\\nRF52840Radio"}} \ No newline at end of file diff --git a/sketches/_PIO_Sketches/Karger/BLE_Master_Test_1/.pio/libdeps/nano33ble/nRF52840Ser.pio-link b/sketches/_PIO_Sketches/Karger/BLE_Master_Test_1/.pio/libdeps/nano33ble/nRF52840Ser.pio-link new file mode 100644 index 0000000000000000000000000000000000000000..e57534b75b96899080d89827a24e57eb7c5f224f --- /dev/null +++ b/sketches/_PIO_Sketches/Karger/BLE_Master_Test_1/.pio/libdeps/nano33ble/nRF52840Ser.pio-link @@ -0,0 +1 @@ +{"cwd": "c:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\sketches\\_PIO_Sketches\\Karger\\BLE_Master_Test_1", "spec": {"owner": null, "id": null, "name": "nRF52840Ser", "requirements": null, "uri": "symlink://C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\libraries\\nRF52840Ser"}} \ No newline at end of file diff --git a/sketches/_PIO_Sketches/Karger/BLE_Master_Test_1/.pio/libdeps/nano33ble/nRF52840Twi.pio-link b/sketches/_PIO_Sketches/Karger/BLE_Master_Test_1/.pio/libdeps/nano33ble/nRF52840Twi.pio-link new file mode 100644 index 0000000000000000000000000000000000000000..3eb0cf1371ad6143871c0af57bb2bf1f1ca41cc5 --- /dev/null +++ b/sketches/_PIO_Sketches/Karger/BLE_Master_Test_1/.pio/libdeps/nano33ble/nRF52840Twi.pio-link @@ -0,0 +1 @@ +{"cwd": "c:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\sketches\\_PIO_Sketches\\Karger\\BLE_Master_Test_1", "spec": {"owner": null, "id": null, "name": "nRF52840Twi", "requirements": null, "uri": "symlink://C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\libraries\\nRF52840Twi"}} \ No newline at end of file diff --git a/sketches/_PIO_Sketches/Karger/BLE_Master_Test_1/.vscode/extensions.json b/sketches/_PIO_Sketches/Karger/BLE_Master_Test_1/.vscode/extensions.json new file mode 100644 index 0000000000000000000000000000000000000000..080e70d08b9811fa743afe5094658dba0ed6b7c2 --- /dev/null +++ b/sketches/_PIO_Sketches/Karger/BLE_Master_Test_1/.vscode/extensions.json @@ -0,0 +1,10 @@ +{ + // See http://go.microsoft.com/fwlink/?LinkId=827846 + // for the documentation about the extensions.json format + "recommendations": [ + "platformio.platformio-ide" + ], + "unwantedRecommendations": [ + "ms-vscode.cpptools-extension-pack" + ] +} diff --git a/sketches/_PIO_Sketches/Karger/BLE_Master_Test_1/include/README b/sketches/_PIO_Sketches/Karger/BLE_Master_Test_1/include/README new file mode 100644 index 0000000000000000000000000000000000000000..194dcd43252dcbeb2044ee38510415041a0e7b47 --- /dev/null +++ b/sketches/_PIO_Sketches/Karger/BLE_Master_Test_1/include/README @@ -0,0 +1,39 @@ + +This directory is intended for project header files. + +A header file is a file containing C declarations and macro definitions +to be shared between several project source files. You request the use of a +header file in your project source file (C, C++, etc) located in `src` folder +by including it, with the C preprocessing directive `#include'. + +```src/main.c + +#include "header.h" + +int main (void) +{ + ... +} +``` + +Including a header file produces the same results as copying the header file +into each source file that needs it. Such copying would be time-consuming +and error-prone. With a header file, the related declarations appear +in only one place. If they need to be changed, they can be changed in one +place, and programs that include the header file will automatically use the +new version when next recompiled. The header file eliminates the labor of +finding and changing all the copies as well as the risk that a failure to +find one copy will result in inconsistencies within a program. + +In C, the usual convention is to give header files names that end with `.h'. +It is most portable to use only letters, digits, dashes, and underscores in +header file names, and at most one dot. + +Read more about using header files in official GCC documentation: + +* Include Syntax +* Include Operation +* Once-Only Headers +* Computed Includes + +https://gcc.gnu.org/onlinedocs/cpp/Header-Files.html diff --git a/sketches/_PIO_Sketches/Karger/BLE_Master_Test_1/lib/README b/sketches/_PIO_Sketches/Karger/BLE_Master_Test_1/lib/README new file mode 100644 index 0000000000000000000000000000000000000000..6debab1e8b4c3faa0d06f4ff44bce343ce2cdcbf --- /dev/null +++ b/sketches/_PIO_Sketches/Karger/BLE_Master_Test_1/lib/README @@ -0,0 +1,46 @@ + +This directory is intended for project specific (private) libraries. +PlatformIO will compile them to static libraries and link into executable file. + +The source code of each library should be placed in a an own separate directory +("lib/your_library_name/[here are source files]"). + +For example, see a structure of the following two libraries `Foo` and `Bar`: + +|--lib +| | +| |--Bar +| | |--docs +| | |--examples +| | |--src +| | |- Bar.c +| | |- Bar.h +| | |- library.json (optional, custom build options, etc) https://docs.platformio.org/page/librarymanager/config.html +| | +| |--Foo +| | |- Foo.c +| | |- Foo.h +| | +| |- README --> THIS FILE +| +|- platformio.ini +|--src + |- main.c + +and a contents of `src/main.c`: +``` +#include <Foo.h> +#include <Bar.h> + +int main (void) +{ + ... +} + +``` + +PlatformIO Library Dependency Finder will find automatically dependent +libraries scanning project source files. + +More information about PlatformIO Library Dependency Finder +- https://docs.platformio.org/page/librarymanager/ldf.html diff --git a/sketches/_PIO_Sketches/Karger/BLE_Master_Test_1/platformio.ini b/sketches/_PIO_Sketches/Karger/BLE_Master_Test_1/platformio.ini new file mode 100644 index 0000000000000000000000000000000000000000..ccfbefb1b29fcf9743c184f15a2115cd9a82015d --- /dev/null +++ b/sketches/_PIO_Sketches/Karger/BLE_Master_Test_1/platformio.ini @@ -0,0 +1,60 @@ +; PlatformIO Project Configuration File +; +; Build options: build flags, source filter +; Upload options: custom upload port, speed and extra flags +; Library options: dependencies, extra library storages +; Advanced options: extra scripting +; +; Please visit documentation for the other options and examples +; https://docs.platformio.org/page/projectconf.html + +[env:nano33ble] +platform = nordicnrf52 +board = nano33ble +framework = arduino +upload_port = COM3 +build_flags = + -DsmnDEFBYBUILD -DsmnNANOBLE33 -DsmnDEBUG +lib_deps = + symlink://C:\Users\lenna\OneDrive\Dokumente\Git\SOAAP\libraries\BlePoll + symlink://C:\Users\lenna\OneDrive\Dokumente\Git\SOAAP\libraries\environment + symlink://C:\Users\lenna\OneDrive\Dokumente\Git\SOAAP\libraries\ComRingBuf + symlink://C:\Users\lenna\OneDrive\Dokumente\Git\SOAAP\libraries\LoopCheck + symlink://C:\Users\lenna\OneDrive\Dokumente\Git\SOAAP\libraries\MidiNotes + symlink://C:\Users\lenna\OneDrive\Dokumente\Git\SOAAP\libraries\Monitor + symlink://C:\Users\lenna\OneDrive\Dokumente\Git\SOAAP\libraries\nRF52840Gpio + symlink://C:\Users\lenna\OneDrive\Dokumente\Git\SOAAP\libraries\nRF52840Radio + symlink://C:\Users\lenna\OneDrive\Dokumente\Git\SOAAP\libraries\nRF52840Ser + symlink://C:\Users\lenna\OneDrive\Dokumente\Git\SOAAP\libraries\nRF52840Twi + symlink://C:\Users\lenna\OneDrive\Dokumente\Git\SOAAP\libraries\SensorLSM9DS1 + symlink://C:\Users\lenna\OneDrive\Dokumente\Git\SOAAP\libraries\SoaapMsg + symlink://C:\Users\lenna\OneDrive\Dokumente\Git\SOAAP\libraries\StateMachine + ;symlink://C:\Users\lenna\OneDrive\Dokumente\Git\SOAAP\libraries\SoaapComDue + +[env:Logging] +platform = nordicnrf52 +board = nano33ble +framework = arduino +upload_port = COM3 +build_flags = + -DsmnDEFBYBUILD -DsmnNANOBLE33 -DsmnDEBUG +lib_deps = + symlink://C:\Users\lenna\OneDrive\Dokumente\Git\SOAAP\libraries\BlePoll + symlink://C:\Users\lenna\OneDrive\Dokumente\Git\SOAAP\libraries\environment + symlink://C:\Users\lenna\OneDrive\Dokumente\Git\SOAAP\libraries\ComRingBuf + symlink://C:\Users\lenna\OneDrive\Dokumente\Git\SOAAP\libraries\LoopCheck + symlink://C:\Users\lenna\OneDrive\Dokumente\Git\SOAAP\libraries\MidiNotes + symlink://C:\Users\lenna\OneDrive\Dokumente\Git\SOAAP\libraries\Monitor + symlink://C:\Users\lenna\OneDrive\Dokumente\Git\SOAAP\libraries\nRF52840Gpio + symlink://C:\Users\lenna\OneDrive\Dokumente\Git\SOAAP\libraries\nRF52840Radio + symlink://C:\Users\lenna\OneDrive\Dokumente\Git\SOAAP\libraries\nRF52840Ser + symlink://C:\Users\lenna\OneDrive\Dokumente\Git\SOAAP\libraries\nRF52840Twi + symlink://C:\Users\lenna\OneDrive\Dokumente\Git\SOAAP\libraries\SensorLSM9DS1 + symlink://C:\Users\lenna\OneDrive\Dokumente\Git\SOAAP\libraries\SoaapMsg + symlink://C:\Users\lenna\OneDrive\Dokumente\Git\SOAAP\libraries\StateMachine + ;symlink://C:\Users\lenna\OneDrive\Dokumente\Git\SOAAP\libraries\SoaapComDue +monitor_filters = + default ; Remove typical terminal control codes from input + time ; Add timestamp with milliseconds for each new line + log2file ; Log data to a file “platformio-device-monitor-*.log” located in the current working directory + diff --git a/sketches/_PIO_Sketches/Karger/BLE_Master_Test_1/src/main.cpp b/sketches/_PIO_Sketches/Karger/BLE_Master_Test_1/src/main.cpp new file mode 100644 index 0000000000000000000000000000000000000000..7669201242f9aee1636d388890138095ae1d6aa2 --- /dev/null +++ b/sketches/_PIO_Sketches/Karger/BLE_Master_Test_1/src/main.cpp @@ -0,0 +1,438 @@ +// ---------------------------------------------------------------------------- +// SoaapBleMaster.ino +// Beispielhafte Anwendung SOAAP / Steuerung optischer und akustischer Ausgaben +// Kommunikation über BLE-Funkanäle mit Bewerbungstelegrammen +// P o l l i n g - M a s t e r +// ---------------------------------------------------------------------------- +// Editor: Robert Patzke +// URI/URL: www.mfp-portal.de +//----------------------------------------------------------------------------- +// Lizenz: CC-BY-SA (wikipedia: Creative Commons) +// Datum: 1. November 2021 +// Letzte Bearbeitung: 1. November 2021 +// +#include "Arduino.h" + +#include "LoopCheck.h" +#include "StateMachine.h" +#include "nRF52840Radio.h" +#include "BlePoll.h" +#include "Monitor.h" +#include "SoaapBleMaster.h" //Eingefügt + +#define DebugTerminal +// Mit dieser Definition werden die Klasse Monitor und weitere Testmethoden +// eingebunden, womit ein anwendungsorientiertes Debugging möglich ist + +LoopCheck lc; +// Eine statische Instanz der Klasse LoopCheck +// Darüber wird das Zeitverhalten gesteuert (Software-Timer) und geprüft + +#ifdef DebugTerminal +Monitor mon(modeEcho | modeNl,0,&lc); +byte tmpByteArray[256]; +// Eine statische Instanz (mit Konstruktordaten) der Klasse Monitor +// Darüber wird mit (direkten) Terminals (z.B. VT100) kommuniziert +// Unter Linux werden hier GtkTerm (siehe Internet) und +// ArduinoMonTerm (eigene Entwicklung mit grafischen Wertanzeigen) eingesetzt. +// Das in den IDEs integrierte Terminal ist dafür meistens nicht geeigent, +// weil damit keine direkte Kommunikation (getipptes Zeichen sofort gesendet) +// möglich ist. +// ----- Parameter ------------------------------------------------------------ +// <mode Echo> Alle eintreffenden Zeichen werden sofort zurückgesendet +// <mode NL> Vor der Ausgabe des Prompt (M>) erfolgt CR/LF +// <0> Für Speicherzugriffe wird von 32 Bit ARM ausgegangen +// <&lc> Für Zeitüberwachungen und entsprechende statisctische Daten +// greift die Monitor-Klasse auf die LoopCheck-Klasse zu +#endif + +nRF52840Radio bleCom; +// Eine statische Instanz der Klasse nRF52840Radio +// Darüber wird direkt die CPU (nRF52840) auf dem Arduino-Board zum Senden und +// Empfangen von BLE-Beacons angesprochen. + + +#define bleCycleTime 150 +BlePoll blePoll((IntrfRadio *) &bleCom, micros); +// Eine statische Instanz der Klasse BlePoll +// Darüber werden das Polling des Masters als auch die Antworten der Slaves +// gesteuert. Es können Geräte entwickelt werden, die nur Master oder Slave +// sind und solche mit Doppelfunktion, wenn kein expliziter Master +// eingesetzt und das Netzwerk über Spontan-Master quasi dezentral +// betrieben werden soll. +// ----- Parameter ------------------------------------------------------------ +// <&bleCom> Die Klasse (vom angenommenen Typ IntrfRadio), die die Daten- +// übertragung abwickelt. Hier wird eine Instanz von nRF52840Radio +// angebunden. Für andere Hardware kann eine entsprechende Klasse +// verwendet werden, die von IntrfRadio abgeleitet wurde. +// <micros> Eine Funktion, die die verstrichene Zeit in Mikrosekunden gibt. +// Damit werden Zeiten (z.B. Time-Out) berechnet. +// Wird hier der Wert NULL übergeben, dann werden die Zeiten aus +// dem Aufrufzyklus (bleCycleTime) in Mikrosekunden berechnet, +// was hier einer Auflösung von 500 Mikrosekunden entspricht. + +#ifdef DebugTerminal +#define smCycleTime 5 +void smInit(); // Vorwärtsreferenz auf die weiter unten definierte Funktion +StateMachine sm(smInit, NULL, smCycleTime); +// Eine statische Instanz für die Zustandsmaschine, die hier für allgemeine +// Steuerungen, Überwachungen und zum Debugging verwendet wird +// ----- Parameter ------------------------------------------------------------ +// <smInit> Der zuerst aufgerufene Zustand (Funktion). Weitere Zustände +// werden in den weiteren Zustandsfunktionen eingesetzt. +// <NULL> Hier kann eine weitere Zustandsfunktion angegeben werden, +// die dann grundsätzlich vor dem Verzweigen in einen Zustand +// aufgerufen wird. +// <smCycleTime> Die Zukluszeit (Takt) der Zustandsmaschine in Millisekunden +#endif + +#define NrOfSlavesToPoll 5 +// Die Anzahl der Slaves, die der Master aufrufen soll (Polling). +// Es wird grundsätzlich mit der Adresse 1 begonnen und nach dem Aufruf die +// Adresse inkrementiert, also immer die Slaves Adr = 1 bis +// Adr = NrOfSlavesToPoll+1 aufgerufen. +// ACHTUNG! +// Diese Zahl muss kleiner/gleich der in BlePoll.h definierten maximalen +// Anzahl der Slaves (MAXSLAVE) sein, weil die Ressourcen darüber statisch +// festgelegt werden. + +// ============================================================================ +int durchlaufe=0; //hinzugefügt +void setup() +{ + + pinMode(LED_BUILTIN,OUTPUT); + bleCom.begin(); // Initialisierung der Datenübertragung + //bleCom.setPower(0x08); // Maximale Sendeleistung bei nRF52840 + // TEST + bleCom.setPower(0x0FC); // Reduzierte Sendeleistung beim Schreibtisch-Test + + blePoll.begin(BlePoll::ctMASTER, NrOfSlavesToPoll, BlePoll::atSOAAP, 1000000); + // Initialisierung des Polling mit folgenden Parametern: + // <BlePoll::ctMASTER> Es wird ein Master eingerichtet + // <NrOfSlavesToPoll> Anzahl gepollter Slaves (s.o.) + // <BlePoll::atSOAAP> Spezielle Anwendung SOAAP + // <10000> INT-Watchdog-Timeout beim Lesen in Mikrosekunden + + blePoll.setEmptyPollParams(2000, 500, 2000); + // Setzen der Parameter für das leere Polling zur Feststellung der + // vorhandenen Slaves und Aufbau einer Poll-Liste für den Datenaustausch + // ----- Parameter ---------------------------------------------------------- + // <2000> Anzahl der Poll-Durchläufe, solange kein Slave gefunden wird + // <500> Anzahl weiterer Durchläufe, nachdem wenigstens ein Slave gefunden ist + // <2000> Time-Out (Zeit für Slave zum Antworten) in Mikrosekunden + + for(int i = 1; i <= NrOfSlavesToPoll; i++) + blePoll.setDataPollParams(i, 1, 10, 1000); + // Setzen der Parameter beim Datenpolling, für Slaves individuell + // ----- Parameter ---------------------------------------------------------- + // <i> Adresse des Slave (1-..) + // <1> Priorität beim Aufruf, 0 = immer bis max 65535 = sehr selten + // <10> minimale Priorität bei automatischer Prioritätsreduzierung + // im Fall von Störungen (Time-Out) + // <1500> Time-Out (Zeit für Slave zum Antworten) in Mikrosekunden + + // TEST + blePoll.stopEP(); // Das Polling muss extra gestartet werden +} + +// ============================================================================ +void loop() +{ + lc.begin(); // Muss am Anfang von LOOP aufgerufen werden + // -------------------------------------------------------------------------- + +#ifdef DebugTerminal + mon.run(); // Der Monitor bekommt bei jedem Durchlauf die CPU + +#endif + + // Alle 500 Mikrosekunden erfolgt der Aufruf des Ble-Polling + // + if(lc.timerMicro(lcTimer0, bleCycleTime, 0)){ + blePoll.run(); + } + + // ----- Parameter der Software-Timer --------------------------------------- + // <lcTimer0> Id/Nummer des Timer, zur Zeit werden bis 10 Timer unterstützt + // lcTimer0 bis lcTimer9 (einstellbar in LoopCheck.h) + // <bleCycleTime> Ablaufzeit in Einheit des Timer-Typ (Micro/Milli) + // hier in Mikrosekunden (timerMicro) + // <0> Anzahl der Wiederholungen, 0 = unbegrenzt + +#ifdef DebugTerminal + // Jede Sekunde erfolgt die Ausgabe einer Versionsmeldung + // das kann über c0 am Terminal abgeschaltet werden + // + if(lc.timerMilli(lcTimer1, 1000, 0)) + { + if(!mon.cFlag[0]){ + durchlaufe++; //hinzugefügt + //mon.printcr((char *)"%@TestBleMaster (ttyACM0), Version 20211104\n"); + //mon.println(durchlaufe); //hinzugefügt + smWaitPolling(); + } + + } + // Die Zeichen %@ am Anfang steuern die Ausgabe bei AndroidMonTerm in ein + // Textfeld (Label) statt auf das Terminal-Display + + // Alle 5 Millisekunden erfolgt der Aufruf der Zustandsmaschine + // + if(lc.timerMilli(lcTimer2, smCycleTime, 0)) + { + sm.run(); + } +#endif + + + // -------------------------------------------------------------------------- + lc.end(); // Muss vor dem Ende von LOOP aufgerufen werden +} + +#ifdef DebugTerminal +// **************************************************************************** +// Z u s t a n d s m a s c h i n e +// **************************************************************************** +// +dword debDword; + + + +void smInit() +{ + sm.enter(smCheckJobs); +} + +// ---------------------------------------------------------------------------- +// Abfrage der Monitorschalter +// ---------------------------------------------------------------------------- +// + +void smCheckJobs() +{ + if(mon.cFlag[1] && !mon.busy) + sm.enter(smDebDword); + else if(mon.cFlag[2] && !mon.busy) + sm.enter(smCtrlPolling); + else if(mon.cFlag[3] && !mon.busy) + sm.enter(smReadPollValues); + /* + else if(mon.cFlag[4] && !mon.busy) + sm.enter(smCheckSens); + */ +} + +// ---------------------------------------------------------------------------- +// Debug-Informationen +// ---------------------------------------------------------------------------- +// + +void smDebDword() +{ + int idx; + + if(sm.firstEnter()) + { + mon.print((char *) "DebDword["); + mon.lastKeyIn = ':'; + } + + if(mon.lastKeyIn == ':') return; + + if(mon.lastKeyIn >= 0x30 && mon.lastKeyIn <= 0x39) + { + idx = mon.lastKeyIn & 0x0F; + mon.print(idx); + mon.print((char *) "]="); + debDword = blePoll.debGetDword(idx); + mon.println(debDword); + sm.resetEnter(); + } + else + { + if(mon.lastKeyIn == ' ') + { + mon.cFlag[1] = false; + mon.print((char *) "-- Schleifenabbruch - drücke Enter"); + sm.enter(smCheckJobs); + } + } +} + +// ---------------------------------------------------------------------------- +// Steuern des Polling-Prozesses +// ---------------------------------------------------------------------------- +// + +TxStatistics txStatistics; + +void smCtrlPolling() +{ + dword tmpDw; + short tmpShort; + int i; + + if(sm.firstEnter()) + { + mon.print((char *) "polling "); + mon.lastKeyIn = ':'; + } + + if(mon.lastKeyIn == ':') return; + + // -------------------------------------------------------------------------- + if(mon.lastKeyIn == 'P' || mon.lastKeyIn == 'p') + { + if(blePoll.stoppedEP()) + { + blePoll.resumeEP(); + mon.println((char *) "fortgesetzt"); + sm.resetEnter(); + } + else + { + blePoll.stopEP(); + sm.enter(smWaitPolling); + } + } + + // -------------------------------------------------------------------------- + else if(mon.lastKeyIn == 'C' || mon.lastKeyIn == 'c') + { + blePoll.resetPollCounters(); + mon.println((char *) "Zähler zurückgesetzt"); + sm.resetEnter(); + } + + + // -------------------------------------------------------------------------- + else if(mon.lastKeyIn == 'R' || mon.lastKeyIn == 'r') + { + mon.print((char *) "Radiopuffer = "); + bleCom.getPduMem(tmpByteArray, 0, 10); + mon.println(tmpByteArray, 10, ' '); + sm.resetEnter(); + } + + + // -------------------------------------------------------------------------- + else if(mon.lastKeyIn == 'S' || mon.lastKeyIn == 's') + { + mon.print((char *) "Sendepuffer = "); + bleCom.getPduSent(tmpByteArray, 0, 10); + mon.println(tmpByteArray, 10, ' '); + sm.resetEnter(); + } + + // -------------------------------------------------------------------------- + else if(mon.lastKeyIn == 'L' || mon.lastKeyIn == 'l') + { + mon.print((char *) "Slave-Liste: "); + int nrOfSlaves = blePoll.getSlaveList(tmpByteArray, 255); + mon.println(tmpByteArray, nrOfSlaves, ','); + sm.resetEnter(); + } + + // -------------------------------------------------------------------------- + else if(mon.lastKeyIn == 'T' || mon.lastKeyIn == 't') + { + mon.print((char *) "TxStat ["); + dword bleStat = blePoll.getStatistics(&txStatistics); + mon.print(bleStat); + mon.print((char *) "] "); + mon.print(txStatistics.mode); mon.cprint(' '); + mon.print(txStatistics.interrupts); mon.cprint(' '); + mon.print(txStatistics.recs); mon.cprint(' '); + mon.print(txStatistics.sendings); mon.cprint(' '); + mon.print(txStatistics.aliens); mon.cprint(' '); + mon.print(txStatistics.wrongs); mon.cprint(' '); + mon.print(txStatistics.pollAcks); mon.cprint(' '); + mon.print(txStatistics.pollNaks); mon.cprint(' '); + mon.print(txStatistics.crcErrors); mon.print(" s[ "); + mon.print(txStatistics.memDumpSnd,8,' '); mon.print("] r[ "); + mon.print(txStatistics.memDumpRec,16,' '); mon.cprintln(']'); + sm.resetEnter(); + } + + // -------------------------------------------------------------------------- + else if(mon.lastKeyIn >= '0' && mon.lastKeyIn <= '9') + { + int idx = mon.lastKeyIn & 0x0F; + SlavePtr slPtr = blePoll.getSlavePtr(idx); + PollStatePtr pPtr = blePoll.getPollPtr(slPtr->pIdx); + + mon.print((char *) "Slave["); + mon.print(idx); + mon.print((char *) "] "); + mon.print(slPtr->cntTo); mon.cprint(' '); + mon.print(slPtr->cntNakEP); mon.cprint(' '); + mon.print(slPtr->cntAckDP); mon.cprint(' '); + + if(slPtr->cntAckDP == 0) + { + if(slPtr->cntTo == 0) + tmpDw = slPtr->cntNakEP; + else + tmpDw = slPtr->cntNakEP / slPtr->cntTo; + } + else + { + if(slPtr->cntTo == 0) + tmpDw = slPtr->cntAckDP; + else + tmpDw = slPtr->cntAckDP / slPtr->cntTo; + } + mon.print(tmpDw); mon.cprint(' '); + + mon.print(slPtr->cntLostPdu); mon.cprint('|'); + mon.print(slPtr->cntErrCrc); mon.cprint('|'); + mon.print(slPtr->result.measCnt); mon.cprint('|'); + mon.print(slPtr->cntLostMeas); mon.cprint(' '); + + for(i = 0; i < 6; i++) + { + tmpShort = (short) slPtr->result.meas[i]; + mon.prints(tmpShort); mon.cprint(' '); + } + mon.print((char *) " Poll["); + mon.print(slPtr->pIdx); + mon.print((char *) "] "); + mon.print(pPtr->status); mon.cprint(' '); + mon.println(pPtr->slIdx); + sm.resetEnter(); + } + + + + else + { + if(mon.lastKeyIn == ' ') + { + mon.cFlag[2] = false; + mon.print((char *) "-- Schleifenabbruch - drücke Enter"); + sm.enter(smCheckJobs); + } + } +} + +void smWaitPolling() +{ + if(!blePoll.stoppedEP()) return; + + mon.println((char *) "angehalten"); + sm.enter(smCtrlPolling); +} + +// ---------------------------------------------------------------------------- +// Debug-Informationen +// ---------------------------------------------------------------------------- +// + +void smReadPollValues() +{ + +} + +#endif // DebugTerminal + diff --git a/sketches/_PIO_Sketches/Karger/BLE_Master_Test_1/template_platformio.txt b/sketches/_PIO_Sketches/Karger/BLE_Master_Test_1/template_platformio.txt new file mode 100644 index 0000000000000000000000000000000000000000..00fcc504ed42a1ed10054916dbc0a611c5bc2c2c --- /dev/null +++ b/sketches/_PIO_Sketches/Karger/BLE_Master_Test_1/template_platformio.txt @@ -0,0 +1,60 @@ +; PlatformIO Project Configuration File +; +; Build options: build flags, source filter +; Upload options: custom upload port, speed and extra flags +; Library options: dependencies, extra library storages +; Advanced options: extra scripting +; +; Please visit documentation for the other options and examples +; https://docs.platformio.org/page/projectconf.html + +[env:nano33ble] +platform = nordicnrf52 +board = nano33ble +framework = arduino +upload_port = COM3 +build_flags = + -DsmnDEFBYBUILD -DsmnNANOBLE33 -DsmnDEBUG +lib_deps = + symlink://[Pfad_Repository]\libraries\BlePoll + symlink://[Pfad_Repository]\libraries\environment + symlink://[Pfad_Repository]\libraries\ComRingBuf + symlink://[Pfad_Repository]\libraries\LoopCheck + symlink://[Pfad_Repository]\libraries\MidiNotes + symlink://[Pfad_Repository]\libraries\Monitor + symlink://[Pfad_Repository]\libraries\nRF52840Gpio + symlink://[Pfad_Repository]\libraries\nRF52840Radio + symlink://[Pfad_Repository]\libraries\nRF52840Ser + symlink://[Pfad_Repository]\libraries\nRF52840Twi + symlink://[Pfad_Repository]\libraries\SensorLSM9DS1 + symlink://[Pfad_Repository]\libraries\SoaapMsg + symlink://[Pfad_Repository]\libraries\StateMachine + ;symlink://[Pfad_Repository]\libraries\SoaapComDue + +[env:Logging] +platform = nordicnrf52 +board = nano33ble +framework = arduino +upload_port = COM3 +build_flags = + -DsmnDEFBYBUILD -DsmnNANOBLE33 -DsmnDEBUG +lib_deps = + symlink://[Pfad_Repository]\libraries\BlePoll + symlink://[Pfad_Repository]\libraries\environment + symlink://[Pfad_Repository]\libraries\ComRingBuf + symlink://[Pfad_Repository]\libraries\LoopCheck + symlink://[Pfad_Repository]\libraries\MidiNotes + symlink://[Pfad_Repository]\libraries\Monitor + symlink://[Pfad_Repository]\libraries\nRF52840Gpio + symlink://[Pfad_Repository]\libraries\nRF52840Radio + symlink://[Pfad_Repository]\libraries\nRF52840Ser + symlink://[Pfad_Repository]\libraries\nRF52840Twi + symlink://[Pfad_Repository]\libraries\SensorLSM9DS1 + symlink://[Pfad_Repository]\libraries\SoaapMsg + symlink://[Pfad_Repository]\libraries\StateMachine + ;symlink://[Pfad_Repository]\libraries\SoaapComDue +monitor_filters = + default ; Remove typical terminal control codes from input + time ; Add timestamp with milliseconds for each new line + log2file ; Log data to a file “platformio-device-monitor-*.log” located in the current working directory + diff --git a/sketches/_PIO_Sketches/Karger/BLE_Master_Test_1/test/README b/sketches/_PIO_Sketches/Karger/BLE_Master_Test_1/test/README new file mode 100644 index 0000000000000000000000000000000000000000..9b1e87bc67c90e7f09a92a3e855444b085c655a6 --- /dev/null +++ b/sketches/_PIO_Sketches/Karger/BLE_Master_Test_1/test/README @@ -0,0 +1,11 @@ + +This directory is intended for PlatformIO Test Runner and project tests. + +Unit Testing is a software testing method by which individual units of +source code, sets of one or more MCU program modules together with associated +control data, usage procedures, and operating procedures, are tested to +determine whether they are fit for use. Unit testing finds problems early +in the development cycle. + +More information about PlatformIO Unit Testing: +- https://docs.platformio.org/en/latest/advanced/unit-testing/index.html diff --git a/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.gitignore b/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.gitignore new file mode 100644 index 0000000000000000000000000000000000000000..672308dcd458c0250233374dcfe709c33b67c2ed --- /dev/null +++ b/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.gitignore @@ -0,0 +1,6 @@ +.pio +.vscode/.browse.c_cpp.db* +.vscode/c_cpp_properties.json +.vscode/launch.json +.vscode/ipch +*.ini \ No newline at end of file diff --git a/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.pio/build/nano33ble/.sconsign39.dblite b/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.pio/build/nano33ble/.sconsign39.dblite new file mode 100644 index 0000000000000000000000000000000000000000..63be4bed358c427195e49cbc722e90e30b853826 Binary files /dev/null and b/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.pio/build/nano33ble/.sconsign39.dblite differ diff --git a/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.pio/build/nano33ble/FrameworkArduino/Interrupts.cpp.o b/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.pio/build/nano33ble/FrameworkArduino/Interrupts.cpp.o new file mode 100644 index 0000000000000000000000000000000000000000..6c9841f8b79d3c0544c1fa7f0782759e1af2a51a Binary files /dev/null and b/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.pio/build/nano33ble/FrameworkArduino/Interrupts.cpp.o differ diff --git a/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.pio/build/nano33ble/FrameworkArduino/Serial.cpp.o b/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.pio/build/nano33ble/FrameworkArduino/Serial.cpp.o new file mode 100644 index 0000000000000000000000000000000000000000..295926d8825b590173829774b4a40d9ff4adc8f2 Binary files /dev/null and b/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.pio/build/nano33ble/FrameworkArduino/Serial.cpp.o differ diff --git a/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.pio/build/nano33ble/FrameworkArduino/Tone.cpp.o b/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.pio/build/nano33ble/FrameworkArduino/Tone.cpp.o new file mode 100644 index 0000000000000000000000000000000000000000..825be7302b203c09976878f2d5cb1ea2a99a811f Binary files /dev/null and b/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.pio/build/nano33ble/FrameworkArduino/Tone.cpp.o differ diff --git a/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.pio/build/nano33ble/FrameworkArduino/USB/PluggableUSBDevice.cpp.o b/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.pio/build/nano33ble/FrameworkArduino/USB/PluggableUSBDevice.cpp.o new file mode 100644 index 0000000000000000000000000000000000000000..9c886ba269a45e35f34d0be3a619b9968b716ebe Binary files /dev/null and b/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.pio/build/nano33ble/FrameworkArduino/USB/PluggableUSBDevice.cpp.o differ diff --git a/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.pio/build/nano33ble/FrameworkArduino/USB/USBCDC.cpp.o b/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.pio/build/nano33ble/FrameworkArduino/USB/USBCDC.cpp.o new file mode 100644 index 0000000000000000000000000000000000000000..dcf1160ab607cd05205e3c07a0fd61328b46547a Binary files /dev/null and b/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.pio/build/nano33ble/FrameworkArduino/USB/USBCDC.cpp.o differ diff --git a/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.pio/build/nano33ble/FrameworkArduino/USB/USBSerial.cpp.o b/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.pio/build/nano33ble/FrameworkArduino/USB/USBSerial.cpp.o new file mode 100644 index 0000000000000000000000000000000000000000..d534c1fb5f0eaa501367e8bb3e1662dec1048b8c Binary files /dev/null and b/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.pio/build/nano33ble/FrameworkArduino/USB/USBSerial.cpp.o differ diff --git a/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.pio/build/nano33ble/FrameworkArduino/WMath.cpp.o b/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.pio/build/nano33ble/FrameworkArduino/WMath.cpp.o new file mode 100644 index 0000000000000000000000000000000000000000..f5fe8e0142d91ebbda5fd43bbe00d139bf127965 Binary files /dev/null and b/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.pio/build/nano33ble/FrameworkArduino/WMath.cpp.o differ diff --git a/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.pio/build/nano33ble/FrameworkArduino/abi.cpp.o b/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.pio/build/nano33ble/FrameworkArduino/abi.cpp.o new file mode 100644 index 0000000000000000000000000000000000000000..049d127a2b6877f29effc011deaa6de622879609 Binary files /dev/null and b/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.pio/build/nano33ble/FrameworkArduino/abi.cpp.o differ diff --git a/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.pio/build/nano33ble/FrameworkArduino/api/Common.cpp.o b/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.pio/build/nano33ble/FrameworkArduino/api/Common.cpp.o new file mode 100644 index 0000000000000000000000000000000000000000..f21ab7233894b4513fb2f0668c037bfa8bf66c02 Binary files /dev/null and b/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.pio/build/nano33ble/FrameworkArduino/api/Common.cpp.o differ diff --git a/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.pio/build/nano33ble/FrameworkArduino/api/IPAddress.cpp.o b/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.pio/build/nano33ble/FrameworkArduino/api/IPAddress.cpp.o new file mode 100644 index 0000000000000000000000000000000000000000..dc96c7f7bccf38b66142457b0acb07d37be84da5 Binary files /dev/null and b/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.pio/build/nano33ble/FrameworkArduino/api/IPAddress.cpp.o differ diff --git a/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.pio/build/nano33ble/FrameworkArduino/api/PluggableUSB.cpp.o b/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.pio/build/nano33ble/FrameworkArduino/api/PluggableUSB.cpp.o new file mode 100644 index 0000000000000000000000000000000000000000..f628d930d9813b86b018b3bc22e85baf8e66a221 Binary files /dev/null and b/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.pio/build/nano33ble/FrameworkArduino/api/PluggableUSB.cpp.o differ diff --git a/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.pio/build/nano33ble/FrameworkArduino/api/Print.cpp.o b/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.pio/build/nano33ble/FrameworkArduino/api/Print.cpp.o new file mode 100644 index 0000000000000000000000000000000000000000..5bd90a4ee9b90ac62540faf8d3521665638734bd Binary files /dev/null and b/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.pio/build/nano33ble/FrameworkArduino/api/Print.cpp.o differ diff --git a/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.pio/build/nano33ble/FrameworkArduino/api/Stream.cpp.o b/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.pio/build/nano33ble/FrameworkArduino/api/Stream.cpp.o new file mode 100644 index 0000000000000000000000000000000000000000..5c8d3573fcd97236448846b55d6b9d0ed84f8345 Binary files /dev/null and b/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.pio/build/nano33ble/FrameworkArduino/api/Stream.cpp.o differ diff --git a/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.pio/build/nano33ble/FrameworkArduino/api/String.cpp.o b/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.pio/build/nano33ble/FrameworkArduino/api/String.cpp.o new file mode 100644 index 0000000000000000000000000000000000000000..0cdddeaba9f1703c59d385e5b676691e25935f8a Binary files /dev/null and b/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.pio/build/nano33ble/FrameworkArduino/api/String.cpp.o differ diff --git a/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.pio/build/nano33ble/FrameworkArduino/arm_hal_random.c.o b/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.pio/build/nano33ble/FrameworkArduino/arm_hal_random.c.o new file mode 100644 index 0000000000000000000000000000000000000000..5c07ffc730e4924f3bb8d7cdd06145c8c458258b Binary files /dev/null and b/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.pio/build/nano33ble/FrameworkArduino/arm_hal_random.c.o differ diff --git a/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.pio/build/nano33ble/FrameworkArduino/as_mbed_library/variant.cpp.o b/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.pio/build/nano33ble/FrameworkArduino/as_mbed_library/variant.cpp.o new file mode 100644 index 0000000000000000000000000000000000000000..6dc884556ee35c888abba3919c31ca6cad8f3658 Binary files /dev/null and b/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.pio/build/nano33ble/FrameworkArduino/as_mbed_library/variant.cpp.o differ diff --git a/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.pio/build/nano33ble/FrameworkArduino/itoa.c.o b/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.pio/build/nano33ble/FrameworkArduino/itoa.c.o new file mode 100644 index 0000000000000000000000000000000000000000..b5450562e4d2e10fc21017817830502019ef2c1b Binary files /dev/null and b/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.pio/build/nano33ble/FrameworkArduino/itoa.c.o differ diff --git a/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.pio/build/nano33ble/FrameworkArduino/main.cpp.o b/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.pio/build/nano33ble/FrameworkArduino/main.cpp.o new file mode 100644 index 0000000000000000000000000000000000000000..b7bfb5e9fcba4b2e72fa0ecf2ddfc6ace9fa8065 Binary files /dev/null and b/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.pio/build/nano33ble/FrameworkArduino/main.cpp.o differ diff --git a/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.pio/build/nano33ble/FrameworkArduino/mbed/platform/cxxsupport/mstd_mutex.cpp.o b/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.pio/build/nano33ble/FrameworkArduino/mbed/platform/cxxsupport/mstd_mutex.cpp.o new file mode 100644 index 0000000000000000000000000000000000000000..48e49b2cdd0621c400b5f36049fe85671435ca24 Binary files /dev/null and b/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.pio/build/nano33ble/FrameworkArduino/mbed/platform/cxxsupport/mstd_mutex.cpp.o differ diff --git a/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.pio/build/nano33ble/FrameworkArduino/pinToIndex.cpp.o b/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.pio/build/nano33ble/FrameworkArduino/pinToIndex.cpp.o new file mode 100644 index 0000000000000000000000000000000000000000..525e981af7ea3239cdd358e2a6486b9eeb225144 Binary files /dev/null and b/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.pio/build/nano33ble/FrameworkArduino/pinToIndex.cpp.o differ diff --git a/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.pio/build/nano33ble/FrameworkArduino/random_seed.cpp.o b/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.pio/build/nano33ble/FrameworkArduino/random_seed.cpp.o new file mode 100644 index 0000000000000000000000000000000000000000..8e99f7b1103595b3159ff904a315fe4db6ed81b7 Binary files /dev/null and b/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.pio/build/nano33ble/FrameworkArduino/random_seed.cpp.o differ diff --git a/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.pio/build/nano33ble/FrameworkArduino/timer.cpp.o b/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.pio/build/nano33ble/FrameworkArduino/timer.cpp.o new file mode 100644 index 0000000000000000000000000000000000000000..e460418560d0eb3a7980b20a5e957aea1aecb9d7 Binary files /dev/null and b/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.pio/build/nano33ble/FrameworkArduino/timer.cpp.o differ diff --git a/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.pio/build/nano33ble/FrameworkArduino/wiring.cpp.o b/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.pio/build/nano33ble/FrameworkArduino/wiring.cpp.o new file mode 100644 index 0000000000000000000000000000000000000000..ae2e00bf06b2fa683f79d8be394f9b72b435d270 Binary files /dev/null and b/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.pio/build/nano33ble/FrameworkArduino/wiring.cpp.o differ diff --git a/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.pio/build/nano33ble/FrameworkArduino/wiring_analog.cpp.o b/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.pio/build/nano33ble/FrameworkArduino/wiring_analog.cpp.o new file mode 100644 index 0000000000000000000000000000000000000000..d2b5bdf05cb72760f512a40ee7f4182752d93bb7 Binary files /dev/null and b/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.pio/build/nano33ble/FrameworkArduino/wiring_analog.cpp.o differ diff --git a/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.pio/build/nano33ble/FrameworkArduino/wiring_digital.cpp.o b/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.pio/build/nano33ble/FrameworkArduino/wiring_digital.cpp.o new file mode 100644 index 0000000000000000000000000000000000000000..8c3db1e4556a973001c1e21daa19bd0065fbff5e Binary files /dev/null and b/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.pio/build/nano33ble/FrameworkArduino/wiring_digital.cpp.o differ diff --git a/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.pio/build/nano33ble/FrameworkArduino/wiring_pulse.cpp.o b/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.pio/build/nano33ble/FrameworkArduino/wiring_pulse.cpp.o new file mode 100644 index 0000000000000000000000000000000000000000..8b83c5a8e757f2b0cac1f54ce315e988332709ac Binary files /dev/null and b/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.pio/build/nano33ble/FrameworkArduino/wiring_pulse.cpp.o differ diff --git a/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.pio/build/nano33ble/FrameworkArduino/wiring_shift.cpp.o b/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.pio/build/nano33ble/FrameworkArduino/wiring_shift.cpp.o new file mode 100644 index 0000000000000000000000000000000000000000..673fcf8f7cd8073cf7d745e87e2a830e4335863b Binary files /dev/null and b/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.pio/build/nano33ble/FrameworkArduino/wiring_shift.cpp.o differ diff --git a/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.pio/build/nano33ble/FrameworkArduinoVariant/variant.cpp.o b/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.pio/build/nano33ble/FrameworkArduinoVariant/variant.cpp.o new file mode 100644 index 0000000000000000000000000000000000000000..86cce2e8a92084743f3356451fc72df9865bd794 Binary files /dev/null and b/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.pio/build/nano33ble/FrameworkArduinoVariant/variant.cpp.o differ diff --git a/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.pio/build/nano33ble/cpp.linker_script.ld b/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.pio/build/nano33ble/cpp.linker_script.ld new file mode 100644 index 0000000000000000000000000000000000000000..270da6c4371ee1182fb0253c37c7c543b92ccc48 --- /dev/null +++ b/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.pio/build/nano33ble/cpp.linker_script.ld @@ -0,0 +1,154 @@ +MEMORY +{ + FLASH (rx) : ORIGIN = 0x10000, LENGTH = 0xf0000 + RAM_NVIC (rwx) : ORIGIN = 0x20000000, LENGTH = 0x100 + RAM_CRASH_DATA (rwx) : ORIGIN = (0x20000000 + 0x100), LENGTH = 0x100 + RAM (rwx) : ORIGIN = ((0x20000000 + 0x100) + 0x100), LENGTH = (0x40000 - (0x100 + 0x100)) +} +OUTPUT_FORMAT ("elf32-littlearm", "elf32-bigarm", "elf32-littlearm") +ENTRY(Reset_Handler) +SECTIONS +{ + .text : + { + KEEP(*(.Vectors)) + *(.text*) + KEEP(*(.init)) + KEEP(*(.fini)) + *crtbegin.o(.ctors) + *crtbegin?.o(.ctors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors) + *(SORT(.ctors.*)) + *(.ctors) + *crtbegin.o(.dtors) + *crtbegin?.o(.dtors) + *(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors) + *(SORT(.dtors.*)) + *(.dtors) + *(.rodata*) + KEEP(*(.eh_frame*)) + } > FLASH + .sdh_soc_observers : + { + PROVIDE(__start_sdh_soc_observers = .); + KEEP(*(SORT(.sdh_soc_observers*))) + PROVIDE(__stop_sdh_soc_observers = .); + } > FLASH + .sdh_stack_observers : + { + PROVIDE(__start_sdh_stack_observers = .); + KEEP(*(SORT(.sdh_stack_observers*))) + PROVIDE(__stop_sdh_stack_observers = .); + } > FLASH + .sdh_req_observers : + { + PROVIDE(__start_sdh_req_observers = .); + KEEP(*(SORT(.sdh_req_observers*))) + PROVIDE(__stop_sdh_req_observers = .); + } > FLASH + .sdh_state_observers : + { + PROVIDE(__start_sdh_state_observers = .); + KEEP(*(SORT(.sdh_state_observers*))) + PROVIDE(__stop_sdh_state_observers = .); + } > FLASH + .sdh_ble_observers : + { + PROVIDE(__start_sdh_ble_observers = .); + KEEP(*(SORT(.sdh_ble_observers*))) + PROVIDE(__stop_sdh_ble_observers = .); + } > FLASH + .ARM.extab : + { + *(.ARM.extab* .gnu.linkonce.armextab.*) + } > FLASH + __exidx_start = .; + .ARM.exidx : + { + *(.ARM.exidx* .gnu.linkonce.armexidx.*) + } > FLASH + __exidx_end = .; + __etext = .; + .data : AT (__etext) + { + __data_start__ = .; + *(vtable) + *(.data*) + . = ALIGN(8); + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP(*(.preinit_array)) + PROVIDE_HIDDEN (__preinit_array_end = .); + . = ALIGN(8); + PROVIDE_HIDDEN (__init_array_start = .); + KEEP(*(SORT(.init_array.*))) + KEEP(*(.init_array)) + PROVIDE_HIDDEN (__init_array_end = .); + . = ALIGN(8); + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP(*(SORT(.fini_array.*))) + KEEP(*(.fini_array)) + PROVIDE_HIDDEN (__fini_array_end = .); + . = ALIGN(8); + PROVIDE(__start_fs_data = .); + KEEP(*(.fs_data)) + PROVIDE(__stop_fs_data = .); + *(.jcr) + . = ALIGN(8); + __data_end__ = .; + } > RAM + __edata = .; + .nvictable (NOLOAD) : + { + PROVIDE(__start_nvictable = .); + KEEP(*(.nvictable)) + PROVIDE(__stop_nvictable = .); + } > RAM_NVIC + .crash_data_ram : + { + . = ALIGN(8); + __CRASH_DATA_RAM__ = .; + __CRASH_DATA_RAM_START__ = .; + KEEP(*(.keep.crash_data_ram)) + *(.m_crash_data_ram) + . += 0x100; + . = ALIGN(8); + __CRASH_DATA_RAM_END__ = .; + } > RAM_CRASH_DATA + .noinit (NOLOAD) : + { + PROVIDE(__start_noinit = .); + KEEP(*(.noinit)) + PROVIDE(__stop_noinit = .); + } > RAM + .bss : + { + . = ALIGN(8); + __bss_start__ = .; + *(.bss*) + *(COMMON) + . = ALIGN(8); + __bss_end__ = .; + } > RAM + .heap (NOLOAD): + { + __end__ = .; + end = __end__; + *(.heap*); + ASSERT(. <= (ORIGIN(RAM) + LENGTH(RAM) - 0x400), "heap region overflowed into stack"); + . = ORIGIN(RAM) + LENGTH(RAM) - 0x400; + __HeapLimit = .; + } > RAM + PROVIDE(__heap_start = ADDR(.heap)); + PROVIDE(__heap_size = SIZEOF(.heap)); + PROVIDE(__mbed_sbrk_start = ADDR(.heap)); + PROVIDE(__mbed_krbs_start = ADDR(.heap) + SIZEOF(.heap)); + .stack (NOLOAD): + { + __StackLimit = .; + *(.stack*) + . = ORIGIN(RAM) + LENGTH(RAM); + } > RAM + __StackTop = ORIGIN(RAM) + LENGTH(RAM); + __StackLimit = __StackTop - 0x400; + PROVIDE(__stack = __StackTop); +} diff --git a/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.pio/build/nano33ble/firmware.bin b/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.pio/build/nano33ble/firmware.bin new file mode 100644 index 0000000000000000000000000000000000000000..e8b770e854d101303736c4415e4167c53af54fe3 Binary files /dev/null and b/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.pio/build/nano33ble/firmware.bin differ diff --git a/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.pio/build/nano33ble/firmware.elf b/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.pio/build/nano33ble/firmware.elf new file mode 100644 index 0000000000000000000000000000000000000000..9b44d63b332fbc4bdf28f9376350878dd58ce517 Binary files /dev/null and b/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.pio/build/nano33ble/firmware.elf differ diff --git a/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.pio/build/nano33ble/idedata.json b/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.pio/build/nano33ble/idedata.json new file mode 100644 index 0000000000000000000000000000000000000000..9727ec372d5cf2dca51a525457e3d016ca9311ff --- /dev/null +++ b/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.pio/build/nano33ble/idedata.json @@ -0,0 +1 @@ +{"env_name": "nano33ble", "libsource_dirs": ["c:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\sketches\\_PIO_Sketches\\Karger\\BLE_Slae_Test\\lib", "c:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\sketches\\_PIO_Sketches\\Karger\\BLE_Slae_Test\\.pio\\libdeps\\nano33ble", "C:\\Users\\lenna\\.platformio\\lib", "C:\\Users\\lenna\\.platformio\\packages\\framework-arduino-mbed\\libraries"], "defines": ["PLATFORMIO=60104", "ARDUINO_ARDUINO_NANO33BLE", "ARDUINO_ARCH_NRF52840", "smnDEFBYBUILD", "smnNANOBLE33", "smnDEBUG", "ARM_MATH_CM4", "BOARD_PCA10056", "__CMSIS_RTOS", "CMSIS_VECTAB_VIRTUAL", "CMSIS_VECTAB_VIRTUAL_HEADER_FILE=\"cmsis_nvic.h\"", "COMPONENT_FLASHIAP=1", "CONFIG_GPIO_AS_PINRESET", "__CORTEX_M4", "DEVICE_ANALOGIN=1", "DEVICE_FLASH=1", "DEVICE_I2C=1", "DEVICE_I2C_ASYNCH=1", "DEVICE_I2CSLAVE=1", "DEVICE_INTERRUPTIN=1", "DEVICE_LPTICKER=1", "DEVICE_PORTIN=1", "DEVICE_PORTINOUT=1", "DEVICE_PORTOUT=1", "DEVICE_PWMOUT=1", "DEVICE_SERIAL=1", "DEVICE_SERIAL_ASYNCH=1", "DEVICE_SERIAL_FC=1", "DEVICE_SLEEP=1", "DEVICE_SPI=1", "DEVICE_SPI_ASYNCH=1", "DEVICE_SYSTICK_CLK_OFF_DURING_SLEEP=1", "DEVICE_TRNG=1", "DEVICE_USBDEVICE=1", "DEVICE_USTICKER=1", "DEVICE_WATCHDOG=1", "FEATURE_BLE=1", "FEATURE_CRYPTOCELL310=1", "FEATURE_STORAGE=1", "__FPU_PRESENT=1", "__MBED__=1", "MBED_BUILD_TIMESTAMP=1652255892.88627", "__MBED_CMSIS_RTOS_CM", "MBED_MPU_CUSTOM", "MBED_TICKLESS", "MBEDTLS_CONFIG_HW_SUPPORT", "NRF52840_XXAA", "NRF52_PAN_20", "SWI_DISABLE0", "TARGET_ARDUINO_NANO33BLE", "TARGET_CORDIO", "TARGET_CORDIO_LL", "TARGET_CORTEX", "TARGET_CORTEX_M", "TARGET_LIKE_CORTEX_M4", "TARGET_LIKE_MBED", "TARGET_M4", "TARGET_MCU_NRF52840", "TARGET_NAME=ARDUINO_NANO33BLE", "TARGET_NORDIC", "TARGET_NORDIC_CORDIO", "TARGET_NRF52", "TARGET_NRF52840", "TARGET_NRF5x", "TARGET_RELEASE", "TARGET_RTOS_M4_M7", "TARGET_SDK_15_0", "TARGET_SOFTDEVICE_NONE", "TOOLCHAIN_GCC", "TOOLCHAIN_GCC_ARM", "WSF_MAX_HANDLERS=10", "MBED_NO_GLOBAL_USING_DIRECTIVE=1", "CORE_MAJOR=3", "CORE_MINOR=1", "CORE_PATCH=1", "USE_ARDUINO_PINOUT", "ARDUINO=10810", "ARDUINO_ARCH_MBED"], "includes": {"build": ["c:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\sketches\\_PIO_Sketches\\Karger\\BLE_Slae_Test\\include", "c:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\sketches\\_PIO_Sketches\\Karger\\BLE_Slae_Test\\src", "c:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\sketches\\_PIO_Sketches\\Karger\\BLE_Slae_Test\\include", "c:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\sketches\\_PIO_Sketches\\Karger\\BLE_Slae_Test\\src", "C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\libraries\\StateMachine", "C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\libraries\\SensorLSM9DS1", "C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\libraries\\nRF52840Twi", "C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\libraries\\nRF52840Ser", "C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\libraries\\nRF52840Radio", "C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\libraries\\nRF52840Gpio", "C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\libraries\\Monitor", "C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\libraries\\MidiNotes", "C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\libraries\\LoopCheck", "C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\libraries\\ComRingBuf", "C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\libraries\\BlePoll", "C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\libraries\\environment", "C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\libraries\\SoaapMsg", "C:\\Users\\lenna\\.platformio\\packages\\framework-arduino-mbed\\cores\\arduino", "C:\\Users\\lenna\\.platformio\\packages\\framework-arduino-mbed\\cores\\arduino\\api\\deprecated", "C:\\Users\\lenna\\.platformio\\packages\\framework-arduino-mbed\\cores\\arduino\\api\\deprecated-avr-comp", "C:\\Users\\lenna\\.platformio\\packages\\framework-arduino-mbed\\variants\\ARDUINO_NANO33BLE"], "compatlib": ["C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\libraries\\BlePoll", "C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\libraries\\BlePoll", "C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\libraries\\environment", "C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\libraries\\SoaapMsg", "C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\libraries\\ComRingBuf", "C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\libraries\\ComRingBuf", "C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\libraries\\environment", "C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\libraries\\SoaapMsg", "C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\libraries\\LoopCheck", "C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\libraries\\LoopCheck", "C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\libraries\\environment", "C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\libraries\\SoaapMsg", "C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\libraries\\MidiNotes", "C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\libraries\\MidiNotes", "C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\libraries\\ComRingBuf", "C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\libraries\\environment", "C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\libraries\\SoaapMsg", "C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\libraries\\Monitor", "C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\libraries\\Monitor", "C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\libraries\\LoopCheck", "C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\libraries\\environment", "C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\libraries\\SoaapMsg", "C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\libraries\\SensorLSM9DS1", "C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\libraries\\SensorLSM9DS1", "C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\libraries\\environment", "C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\libraries\\SoaapMsg", "C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\libraries\\SoaapMsg", "C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\libraries\\SoaapMsg", "C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\libraries\\StateMachine", "C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\libraries\\StateMachine", "C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\libraries\\environment", "C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\libraries\\environment", "C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\libraries\\SoaapMsg", "C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\libraries\\nRF52840Gpio", "C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\libraries\\nRF52840Gpio", "C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\libraries\\environment", "C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\libraries\\SoaapMsg", "C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\libraries\\nRF52840Radio", "C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\libraries\\nRF52840Radio", "C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\libraries\\environment", "C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\libraries\\SoaapMsg", "C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\libraries\\nRF52840Ser", "C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\libraries\\nRF52840Ser", "C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\libraries\\environment", "C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\libraries\\SoaapMsg", "C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\libraries\\nRF52840Twi", "C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\libraries\\nRF52840Twi", "C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\libraries\\environment", "C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\libraries\\SoaapMsg", "C:\\Users\\lenna\\.platformio\\packages\\framework-arduino-mbed\\libraries\\Camera\\src", "C:\\Users\\lenna\\.platformio\\packages\\framework-arduino-mbed\\libraries\\Ethernet\\src", "C:\\Users\\lenna\\.platformio\\packages\\framework-arduino-mbed\\libraries\\GC2145", "C:\\Users\\lenna\\.platformio\\packages\\framework-arduino-mbed\\libraries\\GPS\\src", "C:\\Users\\lenna\\.platformio\\packages\\framework-arduino-mbed\\libraries\\GSM\\src", "C:\\Users\\lenna\\.platformio\\packages\\framework-arduino-mbed\\libraries\\Himax_HM01B0", "C:\\Users\\lenna\\.platformio\\packages\\framework-arduino-mbed\\libraries\\KernelDebug\\src", "C:\\Users\\lenna\\.platformio\\packages\\framework-arduino-mbed\\libraries\\MCUboot\\src", "C:\\Users\\lenna\\.platformio\\packages\\framework-arduino-mbed\\libraries\\MLC\\src", "C:\\Users\\lenna\\.platformio\\packages\\framework-arduino-mbed\\libraries\\MRI\\src", "C:\\Users\\lenna\\.platformio\\packages\\framework-arduino-mbed\\libraries\\Nano33BLE_System\\src", "C:\\Users\\lenna\\.platformio\\packages\\framework-arduino-mbed\\libraries\\Nicla_System\\src", "C:\\Users\\lenna\\.platformio\\packages\\framework-arduino-mbed\\libraries\\PDM\\src", "C:\\Users\\lenna\\.platformio\\packages\\framework-arduino-mbed\\libraries\\Portenta_Audio\\src", "C:\\Users\\lenna\\.platformio\\packages\\framework-arduino-mbed\\libraries\\Portenta_SDCARD\\src", "C:\\Users\\lenna\\.platformio\\packages\\framework-arduino-mbed\\libraries\\Portenta_SDRAM\\src", "C:\\Users\\lenna\\.platformio\\packages\\framework-arduino-mbed\\libraries\\Portenta_Video\\src", "C:\\Users\\lenna\\.platformio\\packages\\framework-arduino-mbed\\libraries\\Portenta_lvgl\\src", "C:\\Users\\lenna\\.platformio\\packages\\framework-arduino-mbed\\libraries\\RPC\\src", "C:\\Users\\lenna\\.platformio\\packages\\framework-arduino-mbed\\libraries\\SE05X\\src", "C:\\Users\\lenna\\.platformio\\packages\\framework-arduino-mbed\\libraries\\SFU\\src", "C:\\Users\\lenna\\.platformio\\packages\\framework-arduino-mbed\\libraries\\SPI", "C:\\Users\\lenna\\.platformio\\packages\\framework-arduino-mbed\\libraries\\STM32H747_System\\src", "C:\\Users\\lenna\\.platformio\\packages\\framework-arduino-mbed\\libraries\\Scheduler\\src", "C:\\Users\\lenna\\.platformio\\packages\\framework-arduino-mbed\\libraries\\SocketWrapper\\src", "C:\\Users\\lenna\\.platformio\\packages\\framework-arduino-mbed\\libraries\\ThreadDebug\\src", "C:\\Users\\lenna\\.platformio\\packages\\framework-arduino-mbed\\libraries\\USBAudio", "C:\\Users\\lenna\\.platformio\\packages\\framework-arduino-mbed\\libraries\\USBHID\\src", "C:\\Users\\lenna\\.platformio\\packages\\framework-arduino-mbed\\libraries\\USBHOST\\src", "C:\\Users\\lenna\\.platformio\\packages\\framework-arduino-mbed\\libraries\\USBMSD\\src", "C:\\Users\\lenna\\.platformio\\packages\\framework-arduino-mbed\\libraries\\WiFi\\src", "C:\\Users\\lenna\\.platformio\\packages\\framework-arduino-mbed\\libraries\\Wire", "C:\\Users\\lenna\\.platformio\\packages\\framework-arduino-mbed\\libraries\\doom\\src", "C:\\Users\\lenna\\.platformio\\packages\\framework-arduino-mbed\\libraries\\ea_malloc", "C:\\Users\\lenna\\.platformio\\packages\\framework-arduino-mbed\\libraries\\mbed-memory-status", "C:\\Users\\lenna\\.platformio\\packages\\framework-arduino-mbed\\libraries\\openamp_arduino\\src", "C:\\Users\\lenna\\.platformio\\packages\\framework-arduino-mbed\\libraries\\rpclib\\src"], "toolchain": ["C:\\Users\\lenna\\.platformio\\packages\\toolchain-gccarmnoneeabi\\arm-none-eabi\\include\\c++\\8.2.1", "C:\\Users\\lenna\\.platformio\\packages\\toolchain-gccarmnoneeabi\\arm-none-eabi\\include\\c++\\8.2.1\\arm-none-eabi", "C:\\Users\\lenna\\.platformio\\packages\\toolchain-gccarmnoneeabi\\lib\\gcc\\arm-none-eabi\\8.2.1\\include", "C:\\Users\\lenna\\.platformio\\packages\\toolchain-gccarmnoneeabi\\lib\\gcc\\arm-none-eabi\\8.2.1\\include-fixed", "C:\\Users\\lenna\\.platformio\\packages\\toolchain-gccarmnoneeabi\\arm-none-eabi\\include"]}, "cc_flags": "-std=gnu11 -DAPPLICATION_ADDR=0x10000 -DAPPLICATION_SIZE=0xf0000 -DMBED_RAM_SIZE=0x40000 -DMBED_RAM_START=0x20000000 -DMBED_ROM_SIZE=0x100000 -DMBED_ROM_START=0x0 -DMBED_TRAP_ERRORS_ENABLED=1 -Os -Wall -Wextra -Wno-missing-field-initializers -Wno-unused-parameter -c -fdata-sections -ffunction-sections -fmessage-length=0 -fno-exceptions -fomit-frame-pointer -funsigned-char -mcpu=cortex-m4 -mfloat-abi=softfp -mfpu=fpv4-sp-d16 -mthumb -iprefixC:\\Users\\lenna\\.platformio\\packages\\framework-arduino-mbed\\cores\\arduino @C:\\Users\\lenna\\.platformio\\packages\\framework-arduino-mbed\\variants\\ARDUINO_NANO33BLE\\includes.txt -nostdlib", "cxx_flags": "-Wvla -fno-rtti -std=gnu++14 -DAPPLICATION_ADDR=0x10000 -DAPPLICATION_SIZE=0xf0000 -DMBED_RAM_SIZE=0x40000 -DMBED_RAM_START=0x20000000 -DMBED_ROM_SIZE=0x100000 -DMBED_ROM_START=0x0 -DMBED_TRAP_ERRORS_ENABLED=1 -Os -Wall -Wextra -Wno-missing-field-initializers -Wno-unused-parameter -c -fdata-sections -ffunction-sections -fmessage-length=0 -fno-exceptions -fomit-frame-pointer -funsigned-char -mcpu=cortex-m4 -mfloat-abi=softfp -mfpu=fpv4-sp-d16 -mthumb -iprefixC:\\Users\\lenna\\.platformio\\packages\\framework-arduino-mbed\\cores\\arduino @C:\\Users\\lenna\\.platformio\\packages\\framework-arduino-mbed\\variants\\ARDUINO_NANO33BLE\\includes.txt -nostdlib", "cc_path": "C:\\Users\\lenna\\.platformio\\packages\\toolchain-gccarmnoneeabi\\bin\\arm-none-eabi-gcc.exe", "cxx_path": "C:\\Users\\lenna\\.platformio\\packages\\toolchain-gccarmnoneeabi\\bin\\arm-none-eabi-g++.exe", "gdb_path": "C:\\Users\\lenna\\.platformio\\packages\\toolchain-gccarmnoneeabi\\bin\\arm-none-eabi-gdb.exe", "prog_path": "c:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\sketches\\_PIO_Sketches\\Karger\\BLE_Slae_Test\\.pio\\build\\nano33ble\\firmware.elf", "svd_path": "C:\\Users\\lenna\\.platformio\\platforms\\nordicnrf52\\misc\\svd\\nrf52840.svd", "compiler_type": "gcc", "targets": [{"name": "size", "title": "Program Size", "description": "Calculate program size", "group": "Platform"}, {"name": "upload", "title": "Upload", "description": null, "group": "Platform"}, {"name": "erase", "title": "Erase Flash", "description": null, "group": "Platform"}], "extra": {"flash_images": []}} \ No newline at end of file diff --git a/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.pio/build/nano33ble/lib035/MidiNotes/MidiNotes.cpp.o b/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.pio/build/nano33ble/lib035/MidiNotes/MidiNotes.cpp.o new file mode 100644 index 0000000000000000000000000000000000000000..b7e8e7587bb8f1e33eac5b6410be298f562c849a Binary files /dev/null and b/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.pio/build/nano33ble/lib035/MidiNotes/MidiNotes.cpp.o differ diff --git a/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.pio/build/nano33ble/lib035/libMidiNotes.a b/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.pio/build/nano33ble/lib035/libMidiNotes.a new file mode 100644 index 0000000000000000000000000000000000000000..12e4eef541f153641c53a8ead88eb3aabb74041d Binary files /dev/null and b/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.pio/build/nano33ble/lib035/libMidiNotes.a differ diff --git a/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.pio/build/nano33ble/lib22a/libnRF52840Gpio.a b/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.pio/build/nano33ble/lib22a/libnRF52840Gpio.a new file mode 100644 index 0000000000000000000000000000000000000000..0260a18e13883332f0f0b17bd5f1291e500ad56e Binary files /dev/null and b/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.pio/build/nano33ble/lib22a/libnRF52840Gpio.a differ diff --git a/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.pio/build/nano33ble/lib22a/nRF52840Gpio/nRF52840Gpio.cpp.o b/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.pio/build/nano33ble/lib22a/nRF52840Gpio/nRF52840Gpio.cpp.o new file mode 100644 index 0000000000000000000000000000000000000000..fd51005553425053a45b5ee49d5fc534b45f1b8e Binary files /dev/null and b/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.pio/build/nano33ble/lib22a/nRF52840Gpio/nRF52840Gpio.cpp.o differ diff --git a/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.pio/build/nano33ble/lib298/libnRF52840Radio.a b/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.pio/build/nano33ble/lib298/libnRF52840Radio.a new file mode 100644 index 0000000000000000000000000000000000000000..9497d3bc5474b1fbbc8026ca1051673676249643 Binary files /dev/null and b/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.pio/build/nano33ble/lib298/libnRF52840Radio.a differ diff --git a/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.pio/build/nano33ble/lib298/nRF52840Radio/nRF52840Radio.cpp.o b/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.pio/build/nano33ble/lib298/nRF52840Radio/nRF52840Radio.cpp.o new file mode 100644 index 0000000000000000000000000000000000000000..00da6f15ccde22943daa6b76cddc86c58ade2a75 Binary files /dev/null and b/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.pio/build/nano33ble/lib298/nRF52840Radio/nRF52840Radio.cpp.o differ diff --git a/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.pio/build/nano33ble/lib489/SoaapMsg/SoaapMsg.cpp.o b/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.pio/build/nano33ble/lib489/SoaapMsg/SoaapMsg.cpp.o new file mode 100644 index 0000000000000000000000000000000000000000..f07bc27cfddbf1a1f59b9261c65e55ce37fdd4f3 Binary files /dev/null and b/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.pio/build/nano33ble/lib489/SoaapMsg/SoaapMsg.cpp.o differ diff --git a/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.pio/build/nano33ble/lib489/libSoaapMsg.a b/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.pio/build/nano33ble/lib489/libSoaapMsg.a new file mode 100644 index 0000000000000000000000000000000000000000..0f5f101a4bf192983d3af48841d8b3da90269375 Binary files /dev/null and b/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.pio/build/nano33ble/lib489/libSoaapMsg.a differ diff --git a/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.pio/build/nano33ble/lib55b/SensorLSM9DS1/SensorLSM9DS1.cpp.o b/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.pio/build/nano33ble/lib55b/SensorLSM9DS1/SensorLSM9DS1.cpp.o new file mode 100644 index 0000000000000000000000000000000000000000..e10942dc0ae0610df61e126a056ac77dd4ebfd4a Binary files /dev/null and b/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.pio/build/nano33ble/lib55b/SensorLSM9DS1/SensorLSM9DS1.cpp.o differ diff --git a/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.pio/build/nano33ble/lib55b/libSensorLSM9DS1.a b/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.pio/build/nano33ble/lib55b/libSensorLSM9DS1.a new file mode 100644 index 0000000000000000000000000000000000000000..d2703d36923b2cd37a54ef94b9ac71c1f01ff0b4 Binary files /dev/null and b/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.pio/build/nano33ble/lib55b/libSensorLSM9DS1.a differ diff --git a/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.pio/build/nano33ble/lib672/LoopCheck/LoopCheck.cpp.o b/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.pio/build/nano33ble/lib672/LoopCheck/LoopCheck.cpp.o new file mode 100644 index 0000000000000000000000000000000000000000..049d5d7b31ea41acfccbf2e2a40ef279ba598ee1 Binary files /dev/null and b/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.pio/build/nano33ble/lib672/LoopCheck/LoopCheck.cpp.o differ diff --git a/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.pio/build/nano33ble/lib672/libLoopCheck.a b/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.pio/build/nano33ble/lib672/libLoopCheck.a new file mode 100644 index 0000000000000000000000000000000000000000..940940d39109c3b8b0ac88b172812c5e29604fcc Binary files /dev/null and b/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.pio/build/nano33ble/lib672/libLoopCheck.a differ diff --git a/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.pio/build/nano33ble/lib743/StateMachine/StateMachine.cpp.o b/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.pio/build/nano33ble/lib743/StateMachine/StateMachine.cpp.o new file mode 100644 index 0000000000000000000000000000000000000000..62c1425dd0556265397bb8c4c0246b0162526a1e Binary files /dev/null and b/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.pio/build/nano33ble/lib743/StateMachine/StateMachine.cpp.o differ diff --git a/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.pio/build/nano33ble/lib743/libStateMachine.a b/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.pio/build/nano33ble/lib743/libStateMachine.a new file mode 100644 index 0000000000000000000000000000000000000000..c5274ccd04ec4c8e5f706da07e33669bcf1ac309 Binary files /dev/null and b/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.pio/build/nano33ble/lib743/libStateMachine.a differ diff --git a/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.pio/build/nano33ble/lib854/libnRF52840Twi.a b/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.pio/build/nano33ble/lib854/libnRF52840Twi.a new file mode 100644 index 0000000000000000000000000000000000000000..d4289901abb5ac14c0b8e04dddc33a6ac52bcd5d Binary files /dev/null and b/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.pio/build/nano33ble/lib854/libnRF52840Twi.a differ diff --git a/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.pio/build/nano33ble/lib854/nRF52840Twi/nRF52840Twi.cpp.o b/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.pio/build/nano33ble/lib854/nRF52840Twi/nRF52840Twi.cpp.o new file mode 100644 index 0000000000000000000000000000000000000000..a8a48b75ceedf1ad8792df3f61889aee1b50e744 Binary files /dev/null and b/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.pio/build/nano33ble/lib854/nRF52840Twi/nRF52840Twi.cpp.o differ diff --git a/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.pio/build/nano33ble/lib88d/libnRF52840Ser.a b/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.pio/build/nano33ble/lib88d/libnRF52840Ser.a new file mode 100644 index 0000000000000000000000000000000000000000..d11cdf828d1270375730e8eef52a55aacd1e7c3a Binary files /dev/null and b/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.pio/build/nano33ble/lib88d/libnRF52840Ser.a differ diff --git a/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.pio/build/nano33ble/lib88d/nRF52840Ser/nRF52840Ser.cpp.o b/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.pio/build/nano33ble/lib88d/nRF52840Ser/nRF52840Ser.cpp.o new file mode 100644 index 0000000000000000000000000000000000000000..dc3e164731ae73159f5aa5c47867805cc62334fb Binary files /dev/null and b/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.pio/build/nano33ble/lib88d/nRF52840Ser/nRF52840Ser.cpp.o differ diff --git a/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.pio/build/nano33ble/libFrameworkArduino.a b/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.pio/build/nano33ble/libFrameworkArduino.a new file mode 100644 index 0000000000000000000000000000000000000000..bc4887205d4d5a70cd946c4ebe247b9a43c614e9 Binary files /dev/null and b/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.pio/build/nano33ble/libFrameworkArduino.a differ diff --git a/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.pio/build/nano33ble/libFrameworkArduinoVariant.a b/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.pio/build/nano33ble/libFrameworkArduinoVariant.a new file mode 100644 index 0000000000000000000000000000000000000000..cb9d1f91879fb9d2ee13cbe8b942140a6dd85b55 Binary files /dev/null and b/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.pio/build/nano33ble/libFrameworkArduinoVariant.a differ diff --git a/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.pio/build/nano33ble/liba91/Monitor/Monitor.cpp.o b/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.pio/build/nano33ble/liba91/Monitor/Monitor.cpp.o new file mode 100644 index 0000000000000000000000000000000000000000..deb5d277562414e9db8131c21fcb720298a91541 Binary files /dev/null and b/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.pio/build/nano33ble/liba91/Monitor/Monitor.cpp.o differ diff --git a/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.pio/build/nano33ble/liba91/libMonitor.a b/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.pio/build/nano33ble/liba91/libMonitor.a new file mode 100644 index 0000000000000000000000000000000000000000..6fa045a8eb02d6c5cc91d3b4e9dd20fb0186d567 Binary files /dev/null and b/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.pio/build/nano33ble/liba91/libMonitor.a differ diff --git a/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.pio/build/nano33ble/libae7/ComRingBuf/ComRingBuf.cpp.o b/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.pio/build/nano33ble/libae7/ComRingBuf/ComRingBuf.cpp.o new file mode 100644 index 0000000000000000000000000000000000000000..687546aae3a7f3cd71ff00b9260c0f44e484dfa4 Binary files /dev/null and b/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.pio/build/nano33ble/libae7/ComRingBuf/ComRingBuf.cpp.o differ diff --git a/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.pio/build/nano33ble/libae7/libComRingBuf.a b/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.pio/build/nano33ble/libae7/libComRingBuf.a new file mode 100644 index 0000000000000000000000000000000000000000..98dc83f798e0db8bc846946bdc31be05eea26b64 Binary files /dev/null and b/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.pio/build/nano33ble/libae7/libComRingBuf.a differ diff --git a/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.pio/build/nano33ble/libcb6/BlePoll/BlePoll.cpp.o b/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.pio/build/nano33ble/libcb6/BlePoll/BlePoll.cpp.o new file mode 100644 index 0000000000000000000000000000000000000000..859eb2f9d034e4f0ff59fa79e15ff573d669fef6 Binary files /dev/null and b/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.pio/build/nano33ble/libcb6/BlePoll/BlePoll.cpp.o differ diff --git a/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.pio/build/nano33ble/libcb6/libBlePoll.a b/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.pio/build/nano33ble/libcb6/libBlePoll.a new file mode 100644 index 0000000000000000000000000000000000000000..8479c8dac4a068e351977eb33afbe01a62e2d5af Binary files /dev/null and b/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.pio/build/nano33ble/libcb6/libBlePoll.a differ diff --git a/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.pio/build/nano33ble/src/main.cpp.o b/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.pio/build/nano33ble/src/main.cpp.o new file mode 100644 index 0000000000000000000000000000000000000000..e9f3e33ee37679f1555db71d936567d0a702f89f Binary files /dev/null and b/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.pio/build/nano33ble/src/main.cpp.o differ diff --git a/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.pio/build/project.checksum b/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.pio/build/project.checksum new file mode 100644 index 0000000000000000000000000000000000000000..8de1c7c752ebc08953959170fb7b0d8484f9df7a --- /dev/null +++ b/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.pio/build/project.checksum @@ -0,0 +1 @@ +8949507b04c84791d764325d3c0e910241474dde \ No newline at end of file diff --git a/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.pio/libdeps/nano33ble/BlePoll.pio-link b/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.pio/libdeps/nano33ble/BlePoll.pio-link new file mode 100644 index 0000000000000000000000000000000000000000..978477bae18199005bf305ebb4df3ac7c1191808 --- /dev/null +++ b/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.pio/libdeps/nano33ble/BlePoll.pio-link @@ -0,0 +1 @@ +{"cwd": "C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\sketches\\_PIO_Sketches\\Karger\\BLE_Slae_Test", "spec": {"owner": null, "id": null, "name": "BlePoll", "requirements": null, "uri": "symlink://C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\libraries\\BlePoll"}} \ No newline at end of file diff --git a/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.pio/libdeps/nano33ble/ComRingBuf.pio-link b/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.pio/libdeps/nano33ble/ComRingBuf.pio-link new file mode 100644 index 0000000000000000000000000000000000000000..e04c4d7c552ba69f044c93cf7b6358317e29219f --- /dev/null +++ b/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.pio/libdeps/nano33ble/ComRingBuf.pio-link @@ -0,0 +1 @@ +{"cwd": "C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\sketches\\_PIO_Sketches\\Karger\\BLE_Slae_Test", "spec": {"owner": null, "id": null, "name": "ComRingBuf", "requirements": null, "uri": "symlink://C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\libraries\\ComRingBuf"}} \ No newline at end of file diff --git a/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.pio/libdeps/nano33ble/LoopCheck.pio-link b/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.pio/libdeps/nano33ble/LoopCheck.pio-link new file mode 100644 index 0000000000000000000000000000000000000000..e1ac5a053fe51f9c88e8a0170bc0c60e56758be0 --- /dev/null +++ b/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.pio/libdeps/nano33ble/LoopCheck.pio-link @@ -0,0 +1 @@ +{"cwd": "C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\sketches\\_PIO_Sketches\\Karger\\BLE_Slae_Test", "spec": {"owner": null, "id": null, "name": "LoopCheck", "requirements": null, "uri": "symlink://C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\libraries\\LoopCheck"}} \ No newline at end of file diff --git a/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.pio/libdeps/nano33ble/MidiNotes.pio-link b/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.pio/libdeps/nano33ble/MidiNotes.pio-link new file mode 100644 index 0000000000000000000000000000000000000000..2a8ec94b3947b495f78670ce1aca031da327ef0e --- /dev/null +++ b/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.pio/libdeps/nano33ble/MidiNotes.pio-link @@ -0,0 +1 @@ +{"cwd": "C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\sketches\\_PIO_Sketches\\Karger\\BLE_Slae_Test", "spec": {"owner": null, "id": null, "name": "MidiNotes", "requirements": null, "uri": "symlink://C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\libraries\\MidiNotes"}} \ No newline at end of file diff --git a/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.pio/libdeps/nano33ble/Monitor.pio-link b/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.pio/libdeps/nano33ble/Monitor.pio-link new file mode 100644 index 0000000000000000000000000000000000000000..8724c6e004489a40959c837ea6794f40cb63c38f --- /dev/null +++ b/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.pio/libdeps/nano33ble/Monitor.pio-link @@ -0,0 +1 @@ +{"cwd": "C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\sketches\\_PIO_Sketches\\Karger\\BLE_Slae_Test", "spec": {"owner": null, "id": null, "name": "Monitor", "requirements": null, "uri": "symlink://C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\libraries\\Monitor"}} \ No newline at end of file diff --git a/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.pio/libdeps/nano33ble/SensorLSM9DS1.pio-link b/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.pio/libdeps/nano33ble/SensorLSM9DS1.pio-link new file mode 100644 index 0000000000000000000000000000000000000000..74b4363313704966664ad157112409dc4155826f --- /dev/null +++ b/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.pio/libdeps/nano33ble/SensorLSM9DS1.pio-link @@ -0,0 +1 @@ +{"cwd": "C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\sketches\\_PIO_Sketches\\Karger\\BLE_Slae_Test", "spec": {"owner": null, "id": null, "name": "SensorLSM9DS1", "requirements": null, "uri": "symlink://C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\libraries\\SensorLSM9DS1"}} \ No newline at end of file diff --git a/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.pio/libdeps/nano33ble/SoaapMsg.pio-link b/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.pio/libdeps/nano33ble/SoaapMsg.pio-link new file mode 100644 index 0000000000000000000000000000000000000000..63ab581b52c0a74a1872336c6d82ba54b60241d3 --- /dev/null +++ b/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.pio/libdeps/nano33ble/SoaapMsg.pio-link @@ -0,0 +1 @@ +{"cwd": "C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\sketches\\_PIO_Sketches\\Karger\\BLE_Slae_Test", "spec": {"owner": null, "id": null, "name": "SoaapMsg", "requirements": null, "uri": "symlink://C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\libraries\\SoaapMsg"}} \ No newline at end of file diff --git a/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.pio/libdeps/nano33ble/StateMachine.pio-link b/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.pio/libdeps/nano33ble/StateMachine.pio-link new file mode 100644 index 0000000000000000000000000000000000000000..6e215a70373300c36c4bd0c4e9f0464487c97f70 --- /dev/null +++ b/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.pio/libdeps/nano33ble/StateMachine.pio-link @@ -0,0 +1 @@ +{"cwd": "C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\sketches\\_PIO_Sketches\\Karger\\BLE_Slae_Test", "spec": {"owner": null, "id": null, "name": "StateMachine", "requirements": null, "uri": "symlink://C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\libraries\\StateMachine"}} \ No newline at end of file diff --git a/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.pio/libdeps/nano33ble/environment.pio-link b/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.pio/libdeps/nano33ble/environment.pio-link new file mode 100644 index 0000000000000000000000000000000000000000..a9b1f84a21edb89e615510bb2fb23e7445b9eccc --- /dev/null +++ b/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.pio/libdeps/nano33ble/environment.pio-link @@ -0,0 +1 @@ +{"cwd": "C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\sketches\\_PIO_Sketches\\Karger\\BLE_Slae_Test", "spec": {"owner": null, "id": null, "name": "environment", "requirements": null, "uri": "symlink://C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\libraries\\environment"}} \ No newline at end of file diff --git a/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.pio/libdeps/nano33ble/integrity.dat b/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.pio/libdeps/nano33ble/integrity.dat new file mode 100644 index 0000000000000000000000000000000000000000..6ad1ace54354516865687e4e038f9a0c96a596f1 --- /dev/null +++ b/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.pio/libdeps/nano33ble/integrity.dat @@ -0,0 +1,13 @@ +symlink://C:\Users\lenna\OneDrive\Dokumente\Git\SOAAP\libraries\nRF52840Ser +symlink://C:\Users\lenna\OneDrive\Dokumente\Git\SOAAP\libraries\MidiNotes +symlink://C:\Users\lenna\OneDrive\Dokumente\Git\SOAAP\libraries\nRF52840Radio +symlink://C:\Users\lenna\OneDrive\Dokumente\Git\SOAAP\libraries\BlePoll +symlink://C:\Users\lenna\OneDrive\Dokumente\Git\SOAAP\libraries\SoaapMsg +symlink://C:\Users\lenna\OneDrive\Dokumente\Git\SOAAP\libraries\SensorLSM9DS1 +symlink://C:\Users\lenna\OneDrive\Dokumente\Git\SOAAP\libraries\LoopCheck +symlink://C:\Users\lenna\OneDrive\Dokumente\Git\SOAAP\libraries\StateMachine +symlink://C:\Users\lenna\OneDrive\Dokumente\Git\SOAAP\libraries\ComRingBuf +symlink://C:\Users\lenna\OneDrive\Dokumente\Git\SOAAP\libraries\nRF52840Gpio +symlink://C:\Users\lenna\OneDrive\Dokumente\Git\SOAAP\libraries\environment +symlink://C:\Users\lenna\OneDrive\Dokumente\Git\SOAAP\libraries\Monitor +symlink://C:\Users\lenna\OneDrive\Dokumente\Git\SOAAP\libraries\nRF52840Twi \ No newline at end of file diff --git a/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.pio/libdeps/nano33ble/nRF52840Gpio.pio-link b/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.pio/libdeps/nano33ble/nRF52840Gpio.pio-link new file mode 100644 index 0000000000000000000000000000000000000000..15616b399f47d5c991efaf3829880a630e0f710d --- /dev/null +++ b/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.pio/libdeps/nano33ble/nRF52840Gpio.pio-link @@ -0,0 +1 @@ +{"cwd": "C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\sketches\\_PIO_Sketches\\Karger\\BLE_Slae_Test", "spec": {"owner": null, "id": null, "name": "nRF52840Gpio", "requirements": null, "uri": "symlink://C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\libraries\\nRF52840Gpio"}} \ No newline at end of file diff --git a/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.pio/libdeps/nano33ble/nRF52840Radio.pio-link b/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.pio/libdeps/nano33ble/nRF52840Radio.pio-link new file mode 100644 index 0000000000000000000000000000000000000000..daf4ba5b7188463cab8add7ba82e0ec2197233e8 --- /dev/null +++ b/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.pio/libdeps/nano33ble/nRF52840Radio.pio-link @@ -0,0 +1 @@ +{"cwd": "C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\sketches\\_PIO_Sketches\\Karger\\BLE_Slae_Test", "spec": {"owner": null, "id": null, "name": "nRF52840Radio", "requirements": null, "uri": "symlink://C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\libraries\\nRF52840Radio"}} \ No newline at end of file diff --git a/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.pio/libdeps/nano33ble/nRF52840Ser.pio-link b/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.pio/libdeps/nano33ble/nRF52840Ser.pio-link new file mode 100644 index 0000000000000000000000000000000000000000..6138f45ed8a830ddf37c11bccb690ba38e6e2596 --- /dev/null +++ b/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.pio/libdeps/nano33ble/nRF52840Ser.pio-link @@ -0,0 +1 @@ +{"cwd": "C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\sketches\\_PIO_Sketches\\Karger\\BLE_Slae_Test", "spec": {"owner": null, "id": null, "name": "nRF52840Ser", "requirements": null, "uri": "symlink://C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\libraries\\nRF52840Ser"}} \ No newline at end of file diff --git a/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.pio/libdeps/nano33ble/nRF52840Twi.pio-link b/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.pio/libdeps/nano33ble/nRF52840Twi.pio-link new file mode 100644 index 0000000000000000000000000000000000000000..fd14e5670e139b046a6ce30d9bd18db2b58f13c2 --- /dev/null +++ b/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.pio/libdeps/nano33ble/nRF52840Twi.pio-link @@ -0,0 +1 @@ +{"cwd": "C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\sketches\\_PIO_Sketches\\Karger\\BLE_Slae_Test", "spec": {"owner": null, "id": null, "name": "nRF52840Twi", "requirements": null, "uri": "symlink://C:\\Users\\lenna\\OneDrive\\Dokumente\\Git\\SOAAP\\libraries\\nRF52840Twi"}} \ No newline at end of file diff --git a/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.vscode/c_cpp_properties.json b/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.vscode/c_cpp_properties.json new file mode 100644 index 0000000000000000000000000000000000000000..da5d72a3c7ed5877585eb88a016c649a897272ed --- /dev/null +++ b/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.vscode/c_cpp_properties.json @@ -0,0 +1,227 @@ +// +// !!! WARNING !!! AUTO-GENERATED FILE! +// PLEASE DO NOT MODIFY IT AND USE "platformio.ini": +// https://docs.platformio.org/page/projectconf/section_env_build.html#build-flags +// +{ + "configurations": [ + { + "name": "PlatformIO", + "includePath": [ + "c:/Users/lenna/OneDrive/Dokumente/Git/SOAAP/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/include", + "c:/Users/lenna/OneDrive/Dokumente/Git/SOAAP/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/src", + "C:/Users/lenna/OneDrive/Dokumente/Git/SOAAP/libraries/StateMachine", + "C:/Users/lenna/OneDrive/Dokumente/Git/SOAAP/libraries/SensorLSM9DS1", + "C:/Users/lenna/OneDrive/Dokumente/Git/SOAAP/libraries/nRF52840Twi", + "C:/Users/lenna/OneDrive/Dokumente/Git/SOAAP/libraries/nRF52840Ser", + "C:/Users/lenna/OneDrive/Dokumente/Git/SOAAP/libraries/nRF52840Radio", + "C:/Users/lenna/OneDrive/Dokumente/Git/SOAAP/libraries/nRF52840Gpio", + "C:/Users/lenna/OneDrive/Dokumente/Git/SOAAP/libraries/Monitor", + "C:/Users/lenna/OneDrive/Dokumente/Git/SOAAP/libraries/MidiNotes", + "C:/Users/lenna/OneDrive/Dokumente/Git/SOAAP/libraries/LoopCheck", + "C:/Users/lenna/OneDrive/Dokumente/Git/SOAAP/libraries/ComRingBuf", + "C:/Users/lenna/OneDrive/Dokumente/Git/SOAAP/libraries/BlePoll", + "C:/Users/lenna/OneDrive/Dokumente/Git/SOAAP/libraries/environment", + "C:/Users/lenna/OneDrive/Dokumente/Git/SOAAP/libraries/SoaapMsg", + "C:/Users/lenna/.platformio/packages/framework-arduino-mbed/cores/arduino", + "C:/Users/lenna/.platformio/packages/framework-arduino-mbed/cores/arduino/api/deprecated", + "C:/Users/lenna/.platformio/packages/framework-arduino-mbed/cores/arduino/api/deprecated-avr-comp", + "C:/Users/lenna/.platformio/packages/framework-arduino-mbed/variants/ARDUINO_NANO33BLE", + "C:/Users/lenna/.platformio/packages/framework-arduino-mbed/libraries/Camera/src", + "C:/Users/lenna/.platformio/packages/framework-arduino-mbed/libraries/Ethernet/src", + "C:/Users/lenna/.platformio/packages/framework-arduino-mbed/libraries/GC2145", + "C:/Users/lenna/.platformio/packages/framework-arduino-mbed/libraries/GPS/src", + "C:/Users/lenna/.platformio/packages/framework-arduino-mbed/libraries/GSM/src", + "C:/Users/lenna/.platformio/packages/framework-arduino-mbed/libraries/Himax_HM01B0", + "C:/Users/lenna/.platformio/packages/framework-arduino-mbed/libraries/KernelDebug/src", + "C:/Users/lenna/.platformio/packages/framework-arduino-mbed/libraries/MCUboot/src", + "C:/Users/lenna/.platformio/packages/framework-arduino-mbed/libraries/MLC/src", + "C:/Users/lenna/.platformio/packages/framework-arduino-mbed/libraries/MRI/src", + "C:/Users/lenna/.platformio/packages/framework-arduino-mbed/libraries/Nano33BLE_System/src", + "C:/Users/lenna/.platformio/packages/framework-arduino-mbed/libraries/Nicla_System/src", + "C:/Users/lenna/.platformio/packages/framework-arduino-mbed/libraries/PDM/src", + "C:/Users/lenna/.platformio/packages/framework-arduino-mbed/libraries/Portenta_Audio/src", + "C:/Users/lenna/.platformio/packages/framework-arduino-mbed/libraries/Portenta_SDCARD/src", + "C:/Users/lenna/.platformio/packages/framework-arduino-mbed/libraries/Portenta_SDRAM/src", + "C:/Users/lenna/.platformio/packages/framework-arduino-mbed/libraries/Portenta_Video/src", + "C:/Users/lenna/.platformio/packages/framework-arduino-mbed/libraries/Portenta_lvgl/src", + "C:/Users/lenna/.platformio/packages/framework-arduino-mbed/libraries/RPC/src", + "C:/Users/lenna/.platformio/packages/framework-arduino-mbed/libraries/SE05X/src", + "C:/Users/lenna/.platformio/packages/framework-arduino-mbed/libraries/SFU/src", + "C:/Users/lenna/.platformio/packages/framework-arduino-mbed/libraries/SPI", + "C:/Users/lenna/.platformio/packages/framework-arduino-mbed/libraries/STM32H747_System/src", + "C:/Users/lenna/.platformio/packages/framework-arduino-mbed/libraries/Scheduler/src", + "C:/Users/lenna/.platformio/packages/framework-arduino-mbed/libraries/SocketWrapper/src", + "C:/Users/lenna/.platformio/packages/framework-arduino-mbed/libraries/ThreadDebug/src", + "C:/Users/lenna/.platformio/packages/framework-arduino-mbed/libraries/USBAudio", + "C:/Users/lenna/.platformio/packages/framework-arduino-mbed/libraries/USBHID/src", + "C:/Users/lenna/.platformio/packages/framework-arduino-mbed/libraries/USBHOST/src", + "C:/Users/lenna/.platformio/packages/framework-arduino-mbed/libraries/USBMSD/src", + "C:/Users/lenna/.platformio/packages/framework-arduino-mbed/libraries/WiFi/src", + "C:/Users/lenna/.platformio/packages/framework-arduino-mbed/libraries/Wire", + "C:/Users/lenna/.platformio/packages/framework-arduino-mbed/libraries/doom/src", + "C:/Users/lenna/.platformio/packages/framework-arduino-mbed/libraries/ea_malloc", + "C:/Users/lenna/.platformio/packages/framework-arduino-mbed/libraries/mbed-memory-status", + "C:/Users/lenna/.platformio/packages/framework-arduino-mbed/libraries/openamp_arduino/src", + "C:/Users/lenna/.platformio/packages/framework-arduino-mbed/libraries/rpclib/src", + "" + ], + "browse": { + "limitSymbolsToIncludedHeaders": true, + "path": [ + "c:/Users/lenna/OneDrive/Dokumente/Git/SOAAP/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/include", + "c:/Users/lenna/OneDrive/Dokumente/Git/SOAAP/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/src", + "C:/Users/lenna/OneDrive/Dokumente/Git/SOAAP/libraries/StateMachine", + "C:/Users/lenna/OneDrive/Dokumente/Git/SOAAP/libraries/SensorLSM9DS1", + "C:/Users/lenna/OneDrive/Dokumente/Git/SOAAP/libraries/nRF52840Twi", + "C:/Users/lenna/OneDrive/Dokumente/Git/SOAAP/libraries/nRF52840Ser", + "C:/Users/lenna/OneDrive/Dokumente/Git/SOAAP/libraries/nRF52840Radio", + "C:/Users/lenna/OneDrive/Dokumente/Git/SOAAP/libraries/nRF52840Gpio", + "C:/Users/lenna/OneDrive/Dokumente/Git/SOAAP/libraries/Monitor", + "C:/Users/lenna/OneDrive/Dokumente/Git/SOAAP/libraries/MidiNotes", + "C:/Users/lenna/OneDrive/Dokumente/Git/SOAAP/libraries/LoopCheck", + "C:/Users/lenna/OneDrive/Dokumente/Git/SOAAP/libraries/ComRingBuf", + "C:/Users/lenna/OneDrive/Dokumente/Git/SOAAP/libraries/BlePoll", + "C:/Users/lenna/OneDrive/Dokumente/Git/SOAAP/libraries/environment", + "C:/Users/lenna/OneDrive/Dokumente/Git/SOAAP/libraries/SoaapMsg", + "C:/Users/lenna/.platformio/packages/framework-arduino-mbed/cores/arduino", + "C:/Users/lenna/.platformio/packages/framework-arduino-mbed/cores/arduino/api/deprecated", + "C:/Users/lenna/.platformio/packages/framework-arduino-mbed/cores/arduino/api/deprecated-avr-comp", + "C:/Users/lenna/.platformio/packages/framework-arduino-mbed/variants/ARDUINO_NANO33BLE", + "C:/Users/lenna/.platformio/packages/framework-arduino-mbed/libraries/Camera/src", + "C:/Users/lenna/.platformio/packages/framework-arduino-mbed/libraries/Ethernet/src", + "C:/Users/lenna/.platformio/packages/framework-arduino-mbed/libraries/GC2145", + "C:/Users/lenna/.platformio/packages/framework-arduino-mbed/libraries/GPS/src", + "C:/Users/lenna/.platformio/packages/framework-arduino-mbed/libraries/GSM/src", + "C:/Users/lenna/.platformio/packages/framework-arduino-mbed/libraries/Himax_HM01B0", + "C:/Users/lenna/.platformio/packages/framework-arduino-mbed/libraries/KernelDebug/src", + "C:/Users/lenna/.platformio/packages/framework-arduino-mbed/libraries/MCUboot/src", + "C:/Users/lenna/.platformio/packages/framework-arduino-mbed/libraries/MLC/src", + "C:/Users/lenna/.platformio/packages/framework-arduino-mbed/libraries/MRI/src", + "C:/Users/lenna/.platformio/packages/framework-arduino-mbed/libraries/Nano33BLE_System/src", + "C:/Users/lenna/.platformio/packages/framework-arduino-mbed/libraries/Nicla_System/src", + "C:/Users/lenna/.platformio/packages/framework-arduino-mbed/libraries/PDM/src", + "C:/Users/lenna/.platformio/packages/framework-arduino-mbed/libraries/Portenta_Audio/src", + "C:/Users/lenna/.platformio/packages/framework-arduino-mbed/libraries/Portenta_SDCARD/src", + "C:/Users/lenna/.platformio/packages/framework-arduino-mbed/libraries/Portenta_SDRAM/src", + "C:/Users/lenna/.platformio/packages/framework-arduino-mbed/libraries/Portenta_Video/src", + "C:/Users/lenna/.platformio/packages/framework-arduino-mbed/libraries/Portenta_lvgl/src", + "C:/Users/lenna/.platformio/packages/framework-arduino-mbed/libraries/RPC/src", + "C:/Users/lenna/.platformio/packages/framework-arduino-mbed/libraries/SE05X/src", + "C:/Users/lenna/.platformio/packages/framework-arduino-mbed/libraries/SFU/src", + "C:/Users/lenna/.platformio/packages/framework-arduino-mbed/libraries/SPI", + "C:/Users/lenna/.platformio/packages/framework-arduino-mbed/libraries/STM32H747_System/src", + "C:/Users/lenna/.platformio/packages/framework-arduino-mbed/libraries/Scheduler/src", + "C:/Users/lenna/.platformio/packages/framework-arduino-mbed/libraries/SocketWrapper/src", + "C:/Users/lenna/.platformio/packages/framework-arduino-mbed/libraries/ThreadDebug/src", + "C:/Users/lenna/.platformio/packages/framework-arduino-mbed/libraries/USBAudio", + "C:/Users/lenna/.platformio/packages/framework-arduino-mbed/libraries/USBHID/src", + "C:/Users/lenna/.platformio/packages/framework-arduino-mbed/libraries/USBHOST/src", + "C:/Users/lenna/.platformio/packages/framework-arduino-mbed/libraries/USBMSD/src", + "C:/Users/lenna/.platformio/packages/framework-arduino-mbed/libraries/WiFi/src", + "C:/Users/lenna/.platformio/packages/framework-arduino-mbed/libraries/Wire", + "C:/Users/lenna/.platformio/packages/framework-arduino-mbed/libraries/doom/src", + "C:/Users/lenna/.platformio/packages/framework-arduino-mbed/libraries/ea_malloc", + "C:/Users/lenna/.platformio/packages/framework-arduino-mbed/libraries/mbed-memory-status", + "C:/Users/lenna/.platformio/packages/framework-arduino-mbed/libraries/openamp_arduino/src", + "C:/Users/lenna/.platformio/packages/framework-arduino-mbed/libraries/rpclib/src", + "" + ] + }, + "defines": [ + "PLATFORMIO=60104", + "ARDUINO_ARDUINO_NANO33BLE", + "ARDUINO_ARCH_NRF52840", + "smnDEFBYBUILD", + "smnNANOBLE33", + "smnDEBUG", + "ARM_MATH_CM4", + "BOARD_PCA10056", + "__CMSIS_RTOS", + "CMSIS_VECTAB_VIRTUAL", + "CMSIS_VECTAB_VIRTUAL_HEADER_FILE=\"cmsis_nvic.h\"", + "COMPONENT_FLASHIAP=1", + "CONFIG_GPIO_AS_PINRESET", + "__CORTEX_M4", + "DEVICE_ANALOGIN=1", + "DEVICE_FLASH=1", + "DEVICE_I2C=1", + "DEVICE_I2C_ASYNCH=1", + "DEVICE_I2CSLAVE=1", + "DEVICE_INTERRUPTIN=1", + "DEVICE_LPTICKER=1", + "DEVICE_PORTIN=1", + "DEVICE_PORTINOUT=1", + "DEVICE_PORTOUT=1", + "DEVICE_PWMOUT=1", + "DEVICE_SERIAL=1", + "DEVICE_SERIAL_ASYNCH=1", + "DEVICE_SERIAL_FC=1", + "DEVICE_SLEEP=1", + "DEVICE_SPI=1", + "DEVICE_SPI_ASYNCH=1", + "DEVICE_SYSTICK_CLK_OFF_DURING_SLEEP=1", + "DEVICE_TRNG=1", + "DEVICE_USBDEVICE=1", + "DEVICE_USTICKER=1", + "DEVICE_WATCHDOG=1", + "FEATURE_BLE=1", + "FEATURE_CRYPTOCELL310=1", + "FEATURE_STORAGE=1", + "__FPU_PRESENT=1", + "__MBED__=1", + "MBED_BUILD_TIMESTAMP=1652255892.88627", + "__MBED_CMSIS_RTOS_CM", + "MBED_MPU_CUSTOM", + "MBED_TICKLESS", + "MBEDTLS_CONFIG_HW_SUPPORT", + "NRF52840_XXAA", + "NRF52_PAN_20", + "SWI_DISABLE0", + "TARGET_ARDUINO_NANO33BLE", + "TARGET_CORDIO", + "TARGET_CORDIO_LL", + "TARGET_CORTEX", + "TARGET_CORTEX_M", + "TARGET_LIKE_CORTEX_M4", + "TARGET_LIKE_MBED", + "TARGET_M4", + "TARGET_MCU_NRF52840", + "TARGET_NAME=ARDUINO_NANO33BLE", + "TARGET_NORDIC", + "TARGET_NORDIC_CORDIO", + "TARGET_NRF52", + "TARGET_NRF52840", + "TARGET_NRF5x", + "TARGET_RELEASE", + "TARGET_RTOS_M4_M7", + "TARGET_SDK_15_0", + "TARGET_SOFTDEVICE_NONE", + "TOOLCHAIN_GCC", + "TOOLCHAIN_GCC_ARM", + "WSF_MAX_HANDLERS=10", + "MBED_NO_GLOBAL_USING_DIRECTIVE=1", + "CORE_MAJOR=3", + "CORE_MINOR=1", + "CORE_PATCH=1", + "USE_ARDUINO_PINOUT", + "ARDUINO=10810", + "ARDUINO_ARCH_MBED", + "" + ], + "cStandard": "c11", + "cppStandard": "c++14", + "compilerPath": "C:/Users/lenna/.platformio/packages/toolchain-gccarmnoneeabi/bin/arm-none-eabi-gcc.exe", + "compilerArgs": [ + "-mcpu=cortex-m4", + "-mfloat-abi=softfp", + "-mfpu=fpv4-sp-d16", + "-mthumb", + "-iprefixC:/Users/lenna/.platformio/packages/framework-arduino-mbed/cores/arduino", + "@C:/Users/lenna/.platformio/packages/framework-arduino-mbed/variants/ARDUINO_NANO33BLE/includes.txt", + "" + ] + } + ], + "version": 4 +} diff --git a/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.vscode/extensions.json b/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.vscode/extensions.json new file mode 100644 index 0000000000000000000000000000000000000000..080e70d08b9811fa743afe5094658dba0ed6b7c2 --- /dev/null +++ b/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.vscode/extensions.json @@ -0,0 +1,10 @@ +{ + // See http://go.microsoft.com/fwlink/?LinkId=827846 + // for the documentation about the extensions.json format + "recommendations": [ + "platformio.platformio-ide" + ], + "unwantedRecommendations": [ + "ms-vscode.cpptools-extension-pack" + ] +} diff --git a/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.vscode/launch.json b/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.vscode/launch.json new file mode 100644 index 0000000000000000000000000000000000000000..7a67a423076ee1431832c657907ced496eb0ba1a --- /dev/null +++ b/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.vscode/launch.json @@ -0,0 +1,47 @@ +// AUTOMATICALLY GENERATED FILE. PLEASE DO NOT MODIFY IT MANUALLY +// +// PIO Unified Debugger +// +// Documentation: https://docs.platformio.org/page/plus/debugging.html +// Configuration: https://docs.platformio.org/page/projectconf/section_env_debug.html + +{ + "version": "0.2.0", + "configurations": [ + { + "type": "platformio-debug", + "request": "launch", + "name": "PIO Debug", + "executable": "c:/Users/lenna/OneDrive/Dokumente/Git/SOAAP/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.pio/build/nano33ble/firmware.elf", + "projectEnvName": "nano33ble", + "toolchainBinDir": "C:/Users/lenna/.platformio/packages/toolchain-gccarmnoneeabi/bin", + "internalConsoleOptions": "openOnSessionStart", + "svdPath": "C:/Users/lenna/.platformio/platforms/nordicnrf52/misc/svd/nrf52840.svd", + "preLaunchTask": { + "type": "PlatformIO", + "task": "Pre-Debug" + } + }, + { + "type": "platformio-debug", + "request": "launch", + "name": "PIO Debug (skip Pre-Debug)", + "executable": "c:/Users/lenna/OneDrive/Dokumente/Git/SOAAP/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.pio/build/nano33ble/firmware.elf", + "projectEnvName": "nano33ble", + "toolchainBinDir": "C:/Users/lenna/.platformio/packages/toolchain-gccarmnoneeabi/bin", + "internalConsoleOptions": "openOnSessionStart", + "svdPath": "C:/Users/lenna/.platformio/platforms/nordicnrf52/misc/svd/nrf52840.svd" + }, + { + "type": "platformio-debug", + "request": "launch", + "name": "PIO Debug (without uploading)", + "executable": "c:/Users/lenna/OneDrive/Dokumente/Git/SOAAP/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/.pio/build/nano33ble/firmware.elf", + "projectEnvName": "nano33ble", + "toolchainBinDir": "C:/Users/lenna/.platformio/packages/toolchain-gccarmnoneeabi/bin", + "internalConsoleOptions": "openOnSessionStart", + "svdPath": "C:/Users/lenna/.platformio/platforms/nordicnrf52/misc/svd/nrf52840.svd", + "loadMode": "manual" + } + ] +} diff --git a/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/include/README b/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/include/README new file mode 100644 index 0000000000000000000000000000000000000000..194dcd43252dcbeb2044ee38510415041a0e7b47 --- /dev/null +++ b/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/include/README @@ -0,0 +1,39 @@ + +This directory is intended for project header files. + +A header file is a file containing C declarations and macro definitions +to be shared between several project source files. You request the use of a +header file in your project source file (C, C++, etc) located in `src` folder +by including it, with the C preprocessing directive `#include'. + +```src/main.c + +#include "header.h" + +int main (void) +{ + ... +} +``` + +Including a header file produces the same results as copying the header file +into each source file that needs it. Such copying would be time-consuming +and error-prone. With a header file, the related declarations appear +in only one place. If they need to be changed, they can be changed in one +place, and programs that include the header file will automatically use the +new version when next recompiled. The header file eliminates the labor of +finding and changing all the copies as well as the risk that a failure to +find one copy will result in inconsistencies within a program. + +In C, the usual convention is to give header files names that end with `.h'. +It is most portable to use only letters, digits, dashes, and underscores in +header file names, and at most one dot. + +Read more about using header files in official GCC documentation: + +* Include Syntax +* Include Operation +* Once-Only Headers +* Computed Includes + +https://gcc.gnu.org/onlinedocs/cpp/Header-Files.html diff --git a/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/lib/README b/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/lib/README new file mode 100644 index 0000000000000000000000000000000000000000..6debab1e8b4c3faa0d06f4ff44bce343ce2cdcbf --- /dev/null +++ b/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/lib/README @@ -0,0 +1,46 @@ + +This directory is intended for project specific (private) libraries. +PlatformIO will compile them to static libraries and link into executable file. + +The source code of each library should be placed in a an own separate directory +("lib/your_library_name/[here are source files]"). + +For example, see a structure of the following two libraries `Foo` and `Bar`: + +|--lib +| | +| |--Bar +| | |--docs +| | |--examples +| | |--src +| | |- Bar.c +| | |- Bar.h +| | |- library.json (optional, custom build options, etc) https://docs.platformio.org/page/librarymanager/config.html +| | +| |--Foo +| | |- Foo.c +| | |- Foo.h +| | +| |- README --> THIS FILE +| +|- platformio.ini +|--src + |- main.c + +and a contents of `src/main.c`: +``` +#include <Foo.h> +#include <Bar.h> + +int main (void) +{ + ... +} + +``` + +PlatformIO Library Dependency Finder will find automatically dependent +libraries scanning project source files. + +More information about PlatformIO Library Dependency Finder +- https://docs.platformio.org/page/librarymanager/ldf.html diff --git a/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/platformio.ini b/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/platformio.ini new file mode 100644 index 0000000000000000000000000000000000000000..bfec98771c70ca94f7c7c7198cb894d6330c8a09 --- /dev/null +++ b/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/platformio.ini @@ -0,0 +1,32 @@ +; PlatformIO Project Configuration File +; +; Build options: build flags, source filter +; Upload options: custom upload port, speed and extra flags +; Library options: dependencies, extra library storages +; Advanced options: extra scripting +; +; Please visit documentation for the other options and examples +; https://docs.platformio.org/page/projectconf.html + +[env:nano33ble] +platform = nordicnrf52 +board = nano33ble +framework = arduino +upload_port = COM5 +build_flags = + -DsmnDEFBYBUILD -DsmnNANOBLE33 -DsmnDEBUG ;-DSlaveACM3 +lib_deps = + symlink://C:\Users\lenna\OneDrive\Dokumente\Git\SOAAP\libraries\BlePoll + symlink://C:\Users\lenna\OneDrive\Dokumente\Git\SOAAP\libraries\environment + symlink://C:\Users\lenna\OneDrive\Dokumente\Git\SOAAP\libraries\ComRingBuf + symlink://C:\Users\lenna\OneDrive\Dokumente\Git\SOAAP\libraries\LoopCheck + symlink://C:\Users\lenna\OneDrive\Dokumente\Git\SOAAP\libraries\MidiNotes + symlink://C:\Users\lenna\OneDrive\Dokumente\Git\SOAAP\libraries\Monitor + symlink://C:\Users\lenna\OneDrive\Dokumente\Git\SOAAP\libraries\nRF52840Gpio + symlink://C:\Users\lenna\OneDrive\Dokumente\Git\SOAAP\libraries\nRF52840Radio + symlink://C:\Users\lenna\OneDrive\Dokumente\Git\SOAAP\libraries\nRF52840Ser + symlink://C:\Users\lenna\OneDrive\Dokumente\Git\SOAAP\libraries\nRF52840Twi + symlink://C:\Users\lenna\OneDrive\Dokumente\Git\SOAAP\libraries\SensorLSM9DS1 + symlink://C:\Users\lenna\OneDrive\Dokumente\Git\SOAAP\libraries\SoaapMsg + symlink://C:\Users\lenna\OneDrive\Dokumente\Git\SOAAP\libraries\StateMachine + ;symlink://C:\Users\lenna\OneDrive\Dokumente\Git\SOAAP\libraries\SoaapComDue diff --git a/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/src/main.cpp b/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/src/main.cpp new file mode 100644 index 0000000000000000000000000000000000000000..01e687692afe5efc29fe53f7ca2b3a5df088695e --- /dev/null +++ b/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/src/main.cpp @@ -0,0 +1,840 @@ +// ---------------------------------------------------------------------------- +// SoaapBleSlave.ino +// Beispielhafte Anwendung SOAAP / Steuerung optischer und akustischer Ausgaben +// Kommunikation über BLE-Funkanäle mit Bewerbungstelegrammen +// P o l l i n g - S l a v e +// ---------------------------------------------------------------------------- +// Editor: Robert Patzke +// URI/URL: www.mfp-portal.de +//----------------------------------------------------------------------------- +// Lizenz: CC-BY-SA (wikipedia: Creative Commons) +// Datum: 1. November 2021 +// Letzte Bearbeitung: 1. November 2021 +// +#include "Arduino.h" + +#include <LoopCheck.h> +#include "StateMachine.h" + +#include "nRF52840Twi.h" +#include "SensorLSM9DS1.h" + +#include "nRF52840Radio.h" +#include <BlePoll.h> +#include "Monitor.h" + +#include "SoaapBleSlave.h" // Eingefügt + + +#define DebugTerminal +// Mit dieser Definition werden die Klasse Monitor und weitere Testmethoden +// eingebunden, womit ein anwendungsorientiertes Debugging möglich ist + +#define SlaveACM2 +/* +#ifdef SlaveACM1 +#define SlaveADR 1 +#define StartMsg "%@TestBleSlave (Adr=1, ttyACM1), Version 20211108 " +#endif +*/ +#ifdef SlaveACM2 +#define SlaveADR 2 +#define StartMsg "%@TestBleSlave (Adr=4, ttyACM2), Version 20211108 " +#endif + +#ifdef SlaveACM3 +#define SlaveADR 5 +#define StartMsg "%@TestBleSlave (Adr=5, ttyACM3), Version 20211108" +#endif + +LoopCheck lc; +// Eine statische Instanz der Klasse LoopCheck +// Darüber wird das Zeitverhalten gesteuert (Software-Timer) und geprüft + +#ifdef DebugTerminal +Monitor mon(modeEcho | modeNl,0,&lc); +// Eine statische Instanz (mit Konstruktordaten) der Klasse Monitor +// Darüber wird mit (direkten) Terminals (z.B. VT100) kommuniziert +// Unter Linux werden hier GtkTerm (siehe Internet) und +// ArduinoMonTerm (eigene Entwicklung mit grafischen Wertanzeigen) eingesetzt. +// Das in den IDEs integrierte Terminal ist dafür meistens nicht geeigent, +// weil damit keine direkte Kommunikation (getipptes Zeichen sofort gesendet) +// möglich ist. +// ----- Parameter ------------------------------------------------------------ +// <mode Echo> Alle eintreffenden Zeichen werden sofort zurückgesendet +// <mode NL> Vor der Ausgabe des Prompt (M>) erfolgt CR/LF +// <0> Für Speicherzugriffe wird von 32 Bit ARM ausgegangen +// <&lc> Für Zeitüberwachungen und entsprechende statisctische Daten +// greift die Monitor-Klasse auf die LoopCheck-Klasse zu +#endif + +nRF52840Radio bleCom; +// Eine statische Instanz der Klasse nRF52840Radio +// Darüber wird direkt die CPU (nRF52840) auf dem Arduino-Board zum Senden und +// Empfangen von BLE-Beacons angesprochen. + +#define bleCycle 150 +BlePoll blePoll((IntrfRadio *) &bleCom, micros); +// Eine statische Instanz der Klasse BlePoll +// Darüber werden das Polling des Masters als auch die Antworten der Slaves +// gesteuert. Es können Geräte entwickelt werden, die nur Master oder Slave +// sind und solche mit Doppelfunktion, wenn kein expliziter Master +// eingesetzt und das Netzwerk über Spontan-Master quasi dezentral +// betrieben werden soll. +// ----- Parameter ------------------------------------------------------------ +// <&bleCom> Die Klasse (vom angenommenen Typ IntrfRadio), die die Daten- +// übertragung abwickelt. Hier wird eine Instanz von nRF52840Radio +// angebunden. Für andere Hardware kann eine entsprechende Klasse +// verwendet werden, die von IntrfRadio abgeleitet wurde. +// <micros> Eine Funktion, die die verstrichene Zeit in Mikrosekunden gibt. +// Damit werden Zeiten (z.B. Time-Out) berechnet. +// Wird hier der Wert NULL übergeben, dann werden die Zeiten aus +// dem Aufrufzyklus (bleCycleTime) in Mikrosekunden berechnet, +// was hier einer Auflösung von 500 Mikrosekunden entspricht. + +#ifdef DebugTerminal +#define smCycleTime 5 +void smInit(); // Vorwärtsreferenz auf die weiter unten definierte Funktion +StateMachine sm(smInit, NULL, smCycleTime); +// Eine statische Instanz für die Zustandsmaschine, die hier für allgemeine +// Steuerungen, Überwachungen und zum Debugging verwendet wird +// ----- Parameter ------------------------------------------------------------ +// <smInit> Der zuerst aufgerufene Zustand (Funktion). Weitere Zustände +// werden in den weiteren Zustandsfunktionen eingesetzt. +// <NULL> Hier kann eine weitere Zustandsfunktion angegeben werden, +// die dann grundsätzlich vor dem Verzweigen in einen Zustand +// aufgerufen wird. +// <smCycleTime> Die Zukluszeit (Takt) der Zustandsmaschine in Millisekunden +#endif + +nRF52840Twi twi; +// Eine statische Instanz der Klasse nRF52840Twi +// Darüber wird direkt die CPU (nRF52840) auf dem Arduino-Board zum Senden und +// Empfangen von I2C (TWI) Botschaften aufgerufen. + +int durchlaufe=0; //hinzugefügt +#define SensorCycle 500 +SensorLSM9DS1 sens((IntrfTw *) &twi, SensorCycle); +// Eine statische Instanz der Klasse SensorLSM9DS1 zum Zugriff +// auf den Sensor LSM9DS1 über den I2C-Bus (TWI) +// ----- Parameter ------------------------------------------------------------ +// <&twi> Die Klasse (vom angenommenen Typ IntrfTw), die die Datenüber- +// tragung auf I2C abwickelt. Hier wird eine Instanz von nRF52840Twi +// angebunden. Für andere Hardware kann eine entsprechende Klasse +// verwendet werden, die von IntrfTw abgeleitet wurde. +// +// <SensorCycle> Der Zugriff auf den Sensor erfolgt mit einer Zustands- +// maschine, deren Takt über die Periodenzeit SensorCycle +// in Mikrosekunden definiert ist. Siehe dazu entsprechenden +// Timeraufruf in LOOP. + +bool getValues(PlpType plpType, byte *dest); // Vorwärtsreferenz für Datenübergabe + +void setup() +{ + TwiParams twiPar; // Parameter für den I2C-Bus + +#ifdef DebugTerminal + mon.config(6); // 6 Anzeigekanäle, die von ArduinoMonTerm aufgebaut werden + + for(int i = 0; i < 6; i++) + { + if(i < 3) + mon.config(i+1,'C',16000,-16000,NULL); // Kanalnummer, Typ, Maxwert, Minwert + else + mon.config(i+1,'C',4000,-4000,NULL); + } +#endif + + bleCom.begin(); // Initialisierung der Datenübertragung + //bleCom.setPower(0x008); // Maximale Sendeleistung bei nRF52840 + bleCom.setPower(0x0FC); // Reduzierte Sendeleistung beim Schreibtisch-Test + + blePoll.begin(BlePoll::ctSLAVE, SlaveADR, BlePoll::atSOAAP, 10000); + // Initialisierung des Polling mit folgenden Parametern: + // <BlePoll::ctSLAVE> Es wird ein Slave eingerichtet + // <SlaveADR> Adresse (Nummer) des Slave + // <BlePoll::atSOAAP> Spezielle Anwendung SOAAP + // <10000> INT-Watchdog-Timeout in Mikrosekunden + blePoll.setCbDataPtr(sendData); + //blePoll.setCbDataPtr(getValues); + // Callback für Datenübergabe setzen + + // Spezifische Parameter für den I2C-Bus am Arduino Nano 33 BLE + // + twiPar.inst = 0; // 1. Instanz der I2C + twiPar.type = TwiMaster; // Auswahl Master/slave + twiPar.clkPort = 0; // Takt über Port 0 (P0) + twiPar.clkPin = 15; // Takt an Pin 15 (P0.15) + twiPar.dataPort = 0; // Daten über Port 0 (P0) + twiPar.dataPin = 14; // Daten an Pin 14 (P0.14) + twiPar.speed = Twi100k; // Taktfrequenz + + twi.begin(&twiPar); // Initialisierung des I2C-Bus + + sens.begin(FreqAG119, 12, MaxAcc4g, MaxGyro2000dps, FreqM_OFF, 0, MaxMag4G); + // Initialisierung der Sensorabfrage mit folgenden Parametern + // + // <FreqAG119> Beschleunigungssensoren und Gyroskop mit 119 Hz abgefragt + // + // <12> Vor der Wertübergabe wird der Mittelwert über 12 Messungen + // gebildet. Die Messfrequenz beträgt daher ca. 10 Hz. + // + // <MaxAcc4g> Der Maximalausschlag der Beschleunigung ist 4g + // + // <MaxGyro2000dps> Maximalausschlag des Gyro ist 2000 Grad/s + // + // <FreqM_OFF> Der Magnetfeldsensor ist AUS (funktioniert noch nicht) + // + // <0> Keine Mittelwertbildung der Magnetfeldmessung + // + // <MaxMag4G> Der Maximalwert entspricht 4 Gauss + + sens.syncValuesAG(); + // Rücksetzen des Ready-Bit für Messwertübergabe +} + +#ifdef DebugTerminal +char runView[4] = {'|','/','-','\\'}; +int runViewIdx = 0; +#endif + +void loop() +{ + lc.begin(); + // -------------------------------------------------------------------------- + +#ifdef DebugTerminal + // Der Monitor wird ständig aufgerufen und stellt damit eine grundsätzliche + // Belastung dar. Das ist für die Entwicklung auch vorgesehen. + // Es entsteht dadurch eine Reserve für den produktiven Einsatz. + // + mon.run(); +#endif + + // Alle 500 Mikrosekunden erfolgt der Aufruf des Ble-Polling + // + if(lc.timerMicro(lcTimer0, bleCycle, 0)) + blePoll.run(); + // ----- Parameter der Software-Timer --------------------------------------- + // <lcTimer0> Id/Nummer des Timer, zur Zeit werden bis 10 Timer unterstützt + // lcTimer0 bis lcTimer9 (einstellbar in LoopCheck.h) + // <bleCycleTime> Ablaufzeit in Einheit des Timer-Typ (Micro/Milli) + // hier in Mikrosekunden (timerMicro) + // <0> Anzahl der Wiederholungen, 0 = unbegrenzt + + // Alle 500 Mikrosekunden erfolgt der Aufruf der Sensorzustandsmaschine + // + if(lc.timerMicro(lcTimer1, SensorCycle, 0)) + sens.run(); + +#ifdef DebugTerminal + // Alle 5 Millisekunden wird die Zustandsmaschine für + // betriebliche Abläufe aufgerufen + // + if(lc.timerMilli(lcTimer2, smCycleTime, 0)) + { + sm.run(); + } + + // Jede halbe Sekunde erfolgt die Ausgabe der Version + // + if(lc.timerMilli(lcTimer3, 500, 0)) + { + if(!mon.cFlag[0]) + { + /* + mon.print((char *) StartMsg); + mon.cprintcr(runView[runViewIdx]); + runViewIdx++; + if(runViewIdx > 3) runViewIdx = 0; + */ + smCtrlPolling(); + } + } +#endif + // -------------------------------------------------------------------------- + lc.end(); +} + +// ---------------------------------------------------------------------------- +// Übergabe der Daten an die BLE-Kommunikation +// ---------------------------------------------------------------------------- +// +RawDataAG rawData; +bool sendData(PlpType plpType, byte *dest){ + short i; + for (i=0;i<12;i++){ + //i%2!=0?rawData.byteArray[i]=0:rawData.byteArray[i]=i; + if(i==0 || i==2 || i == 4 || i == 6 || i ==8 || i== 10 || i== 12){ + dest[i]=i; + }else{ + dest[i]=i; + } + } + return true; +} + +bool getValues(PlpType plpType, byte *dest) +{ + bool newData; + short i; + + memset(rawData.byteArray,0,12); + + newData = sens.getValuesAG(&rawData); + //Debug: Messdaten überschreiben + /* + for (i=0;i<12;i++){ + i%2!=0?rawData.byteArray[i]=1:rawData.byteArray[i]=i; + } + */ + //Ende Lennard + if(newData) + { + switch(plpType) + { + case plptMeas6: + for(i = 0; i < 12; i++) + dest[i] = rawData.byteArray[i]; + break; + } + } + return(newData); + +} + + +#ifdef DebugTerminal +// **************************************************************************** +// Z u s t a n d s m a s c h i n e +// **************************************************************************** +// + +dword debDword; +byte tmpByteArray[256]; +CalValueAG calData; +CalValue calValue; + + +void smInit() +{ + sm.enter(smCheckJobs); +} + +// ---------------------------------------------------------------------------- +// Abfrage der Monitorschalter +// ---------------------------------------------------------------------------- +// + +void smCheckJobs() +{ + if(mon.cFlag[1] && !mon.busy) + sm.enter(smDebDword); + else if(mon.cFlag[2] && !mon.busy) + sm.enter(smCtrlPolling); + else if(mon.cFlag[3] && !mon.busy) + sm.enter(smCheckSens); + /* + else if(mon.cFlag[4] && !mon.busy) + sm.enter(smCheckSens); + */ +} + + +// ---------------------------------------------------------------------------- +// Debug-Informationen +// ---------------------------------------------------------------------------- +// + +void smDebDword() +{ + int idx; + + if(sm.firstEnter()) + { + mon.print((char *) "DebDword["); + mon.lastKeyIn = ':'; + } + + if(mon.lastKeyIn == ':') return; + + if(mon.lastKeyIn >= 0x30 && mon.lastKeyIn <= 0x39) + { + idx = mon.lastKeyIn & 0x0F; + mon.print(idx); + mon.print((char *) "]="); + debDword = blePoll.debGetDword(idx); + mon.println(debDword); + sm.resetEnter(); + } + else + { + if(mon.lastKeyIn == ' ') + { + mon.cFlag[1] = false; + mon.print((char *) "-- Schleifenabbruch - drücke Enter"); + sm.enter(smCheckJobs); + } + } +} + +// ---------------------------------------------------------------------------- +// Steuern des Polling-Prozesses +// ---------------------------------------------------------------------------- +// Es ist sowohl die Master- als auch die Slave-Funktion vorgesehen +// + +TxStatistics txStatistics; + +void smCtrlPolling() +{ + if(sm.firstEnter()) + { + mon.print((char *) "polling "); + mon.lastKeyIn = ':'; + } + + if(mon.lastKeyIn == ':') return; + + // -------------------------------------------------------------------------- + if(mon.lastKeyIn == 'P' || mon.lastKeyIn == 'p') + { + if(blePoll.stoppedEP()) + { + blePoll.resumeEP(); + mon.println((char *) "fortgesetzt"); + sm.resetEnter(); + } + else + { + blePoll.stopEP(); + sm.enter(smWaitPolling); + } + } + + // -------------------------------------------------------------------------- + else if(mon.lastKeyIn == 'S' || mon.lastKeyIn == 's') + { + mon.print((char *) "Sendepuffer = "); + bleCom.getPduSent(tmpByteArray, 0, 10); + mon.println(tmpByteArray, 10, ' '); + sm.resetEnter(); + } + + // -------------------------------------------------------------------------- + else if(mon.lastKeyIn == 'R' || mon.lastKeyIn == 'r') + { + mon.print((char *) "Radiopuffer = "); + bleCom.getPduMem(tmpByteArray, 0, 10); + mon.println(tmpByteArray, 10, ' '); + sm.resetEnter(); + } + + // -------------------------------------------------------------------------- + else if(mon.lastKeyIn == 'T' || mon.lastKeyIn == 't') + { + mon.print((char *) "TxStat ["); + dword bleStat = blePoll.getStatistics(&txStatistics); + mon.print(bleStat); + mon.print((char *) "] "); + mon.print(txStatistics.mode); mon.cprint(' '); + mon.print(txStatistics.interrupts); mon.cprint(' '); + mon.print(txStatistics.recs); mon.cprint(' '); + mon.print(txStatistics.sendings); mon.cprint(' '); + mon.print(txStatistics.aliens); mon.cprint(' '); + mon.print(txStatistics.wrongs); mon.cprint(' '); + mon.print(txStatistics.pollAcks); mon.cprint(' '); + mon.print(txStatistics.pollNaks); mon.cprint(' '); + mon.print(txStatistics.crcErrors); mon.print(" r[ "); + mon.print(txStatistics.memDumpRec,8,' '); mon.print("] s[ "); + mon.print(txStatistics.memDumpSnd,16,' '); mon.cprintln(']'); + sm.resetEnter(); + } + + + else + { + if(mon.lastKeyIn == ' ') + { + mon.cFlag[2] = false; + mon.print((char *) "-- Schleifenabbruch - drücke Enter"); + sm.enter(smCheckJobs); + } + } +} + +void smWaitPolling() +{ + if(!blePoll.stoppedEP()) return; + + mon.println((char *) "angehalten"); + sm.enter(smCtrlPolling); +} + +// ---------------------------------------------------------------------------- +// (4) Testen der Sensorzugriffe +// ---------------------------------------------------------------------------- +// + +char charOut[2]; + +void smCheckSens() +{ + if(sm.firstEnter()) + { + mon.print((char *) "Sensorzugriff "); + mon.lastKeyIn = ':'; + } + + if(mon.lastKeyIn == ':') return; + + charOut[0] = mon.lastKeyIn; + charOut[1] = '\0'; + mon.println(charOut); + + if(mon.lastKeyIn == '0' || mon.lastKeyIn == ' ') + { + mon.cFlag[3] = false; + mon.print((char *) "-- Schleifenabbruch - drücke Enter"); + sm.enter(smCheckJobs); + } + else if(mon.lastKeyIn == '1') + sm.enter(smSensReset1); + else if(mon.lastKeyIn == '2') + sm.enter(smSensReset2); + else if(mon.lastKeyIn == '3') + sm.enter(smSensGetValues1); + else if(mon.lastKeyIn == '4') + sm.enter(smSensGetValues2); + else if(mon.lastKeyIn == '5') + sm.enter(smSensGetValues3); + else if(mon.lastKeyIn == '6') + sm.enter(smSensGetValues4); + else if(mon.lastKeyIn == '7') + sm.enter(smSensGetValues5); + else if(mon.lastKeyIn == '8') + sm.enter(smSensGetValues6); + else if(mon.lastKeyIn == 'c') + sm.enter(smSensDebugValues); + else if(mon.lastKeyIn == 'e') + sm.enter(smSensGetErrors); + else if(mon.lastKeyIn == 'r') + sm.enter(smSensGetRunCounts); + else if(mon.lastKeyIn == 's') + sm.enter(smSensGetSoaapValues); + else if(mon.lastKeyIn == 't') + sm.enter(smSensGetTimeOuts); + else + sm.resetEnter(); + mon.lastKeyIn = ':'; +} + +void smSensReset1() +{ + int retv = sens.resetAG(); + //int retv = twi.writeByteReg(0x6B, 0x22, 0x05); + mon.print((char *) "resetAG = "); + mon.println(retv); + sm.enter(smCheckSens); +} + +void smSensReset2() +{ + int retv = sens.resetM(); + //int retv = twi.writeByteReg(0x1E, 0x21, 0x0C); + mon.print((char *) "resetM = "); + mon.println(retv); + sm.enter(smCheckSens); +} + +void smSensGetValues1() +{ + if(sm.firstEnter()) + sens.syncValuesAG(); + + if(!sens.getValuesAG(&rawData)) return; + + mon.print((char *) "ValueA = "); + mon.print(rawData.valueAG.A.x); + mon.print((char *) " "); + mon.print(rawData.valueAG.A.y); + mon.print((char *) " "); + mon.println(rawData.valueAG.A.z); + sm.enter(smCheckSens); +} + +char outValue[64]; + +void smSensGetValues2() +{ + if(sm.firstEnter()) + sens.syncValuesAG(); + + if(!sens.getValuesAG(&calData)) return; + + mon.print((char *) "ValueA = "); + sprintf(outValue,"%f ",calData.A.x); + mon.print(outValue); + sprintf(outValue,"%f ",calData.A.y); + mon.print(outValue); + sprintf(outValue,"%f ",calData.A.z); + mon.println(outValue); + sm.enter(smCheckSens); +} + +void smSensGetValues3() +{ + if(sm.firstEnter()) + { + sens.syncValuesAG(); + mon.lastKeyIn = ':'; + } + + if(!sens.getValuesAG(&calData)) return; + + mon.print((char *) "Values A = "); + sprintf(outValue,"%+5.3f ",calData.A.x); + mon.print(outValue); + sprintf(outValue,"%+5.3f ",calData.A.y); + mon.print(outValue); + sprintf(outValue,"%+5.3f ",calData.A.z); + mon.println(outValue); + + if(mon.lastKeyIn == ' ') + sm.enter(smCheckSens); +} + +void smSensGetValues4() +{ + if(sm.firstEnter()) + { + sens.syncValuesAG(); + mon.lastKeyIn = ':'; + } + + if(!sens.getValuesAG(&calData)) return; + + mon.print((char *) "Values AG = "); + sprintf(outValue,"%+5.3f ",calData.A.x); + mon.print(outValue); + sprintf(outValue,"%+5.3f ",calData.A.y); + mon.print(outValue); + sprintf(outValue,"%+5.3f ",calData.A.z); + mon.print(outValue); + + sprintf(outValue,"%+5.1f ",calData.G.x); + mon.print(outValue); + sprintf(outValue,"%+5.1f ",calData.G.y); + mon.print(outValue); + sprintf(outValue,"%+5.1f ",calData.G.z); + mon.println(outValue); + + + if(mon.lastKeyIn == ' ') + sm.enter(smCheckSens); +} + +void smSensGetValues5() +{ + if(sm.firstEnter()) + { + sens.syncValuesAG(); + mon.lastKeyIn = ':'; + sm.setTimeOut(1000); + } + + if(sm.timeOut()) + { + mon.println((char *) " Time Out"); + sm.enter(smCheckSens); + return; + } + + if(!sens.getValuesAG(&calData)) return; + sm.setTimeOut(1000); + + mon.print((char *) "Values AGM = "); + + sprintf(outValue,"%+5.3f ",calData.A.x); + mon.print(outValue); + sprintf(outValue,"%+5.3f ",calData.A.y); + mon.print(outValue); + sprintf(outValue,"%+5.3f ",calData.A.z); + mon.print(outValue); + + sprintf(outValue,"%+5.1f ",calData.G.x); + mon.print(outValue); + sprintf(outValue,"%+5.1f ",calData.G.y); + mon.print(outValue); + sprintf(outValue,"%+5.1f ",calData.G.z); + mon.print(outValue); + + sens.getValuesM(&calValue); + + sprintf(outValue,"%+5.3f ",calValue.x); + mon.print(outValue); + sprintf(outValue,"%+5.3f ",calValue.y); + mon.print(outValue); + sprintf(outValue,"%+5.3f ",calValue.z); + mon.println(outValue); + + if(mon.lastKeyIn == ' ') + sm.enter(smCheckSens); +} + +void smSensGetValues6() +{ + if(sm.firstEnter()) + { + sens.syncValuesAG(); + mon.lastKeyIn = ':'; + sm.setTimeOut(1000); + } + + if(sm.timeOut()) + { + mon.println((char *) " Time Out"); + sm.enter(smCheckSens); + return; + } + + if(!sens.getValuesAG(&rawData)) return; + sm.setTimeOut(1000); + + mon.print((char *) "Values AGM = "); + + sprintf(outValue,"%4X ",(unsigned short) rawData.valueAG.A.x); + mon.print(outValue); + sprintf(outValue,"%4X ",(unsigned short) rawData.valueAG.A.y); + mon.print(outValue); + sprintf(outValue,"%4X ",(unsigned short) rawData.valueAG.A.z); + mon.print(outValue); + + sprintf(outValue,"%4X ",(unsigned short) rawData.valueAG.G.x); + mon.print(outValue); + sprintf(outValue,"%4X ",(unsigned short) rawData.valueAG.G.y); + mon.print(outValue); + sprintf(outValue,"%4X ",(unsigned short) rawData.valueAG.G.z); + mon.println(outValue); + + /* + sens.getValuesM(&calValue); + + sprintf(outValue,"%+5.3f ",calValue.x); + mon.print(outValue); + sprintf(outValue,"%+5.3f ",calValue.y); + mon.print(outValue); + sprintf(outValue,"%+5.3f ",calValue.z); + mon.println(outValue); + */ + if(mon.lastKeyIn == ' ') + sm.enter(smCheckSens); +} + + +void smSensGetValues7() +{ + if(sm.firstEnter()) + { + sens.syncValuesAG(); + mon.lastKeyIn = ':'; + sm.setTimeOut(1000); + } + + if(sm.timeOut()) + { + mon.println((char *) " Time Out"); + sm.enter(smCheckSens); + return; + } + + if(!sens.getValuesAG(&rawData)) return; + sm.setTimeOut(1000); + + mon.print((char *) "%~Values AGM = $"); + + sprintf(outValue,"#@%04X$",(unsigned short) rawData.valueAG.A.x); + mon.print(outValue); + sprintf(outValue,"#A%04X$",(unsigned short) rawData.valueAG.A.y); + mon.print(outValue); + sprintf(outValue,"#B%04X$",(unsigned short) rawData.valueAG.A.z); + mon.print(outValue); + + sprintf(outValue,"#C%04X$",(unsigned short) rawData.valueAG.G.x); + mon.print(outValue); + sprintf(outValue,"#D%04X$",(unsigned short) rawData.valueAG.G.y); + mon.print(outValue); + sprintf(outValue,"#E%04X$",(unsigned short) rawData.valueAG.G.z); + mon.print(outValue); + + if(mon.lastKeyIn == ' ') + sm.enter(smCheckSens); +} + + +void smSensGetSoaapValues() +{ + sm.enter(smSensGetValues7); +} + +void smSensDebugValues() +{ + mon.print((char *) "Werte: toValueStatusAG="); + mon.print(sens.debGetDword(1)); + mon.print((char *) " toValueStatusM="); + mon.println(sens.debGetDword(2)); + sm.enter(smCheckSens); +} + + +void smSensGetErrors() +{ + mon.print((char *) "Errors AG: AdrNak="); + mon.print(sens.errorCntAdrNakAG); + mon.print((char *) " DataNak="); + mon.print(sens.errorCntDataNakAG); + mon.print((char *) " Overrun="); + mon.print(sens.errorCntOverAG); + + mon.print((char *) " M: AdrNak="); + mon.print(sens.errorCntAdrNakM); + mon.print((char *) " DataNak="); + mon.print(sens.errorCntDataNakM); + mon.print((char *) " Overrun="); + mon.println(sens.errorCntOverM); + sm.enter(smCheckSens); +} + +void smSensGetTimeOuts() +{ + mon.print((char *) "TimeOuts AG: TwiStat="); + mon.print(sens.toCntTwiStatusAG); + mon.print((char *) " TwiData="); + mon.print(sens.toCntTwiDataAG); + mon.print((char *) " Status="); + mon.print(sens.toCntStatusAG); + + mon.print((char *) " M: TwiStat="); + mon.print(sens.toCntTwiStatusM); + mon.print((char *) " TwiData="); + mon.print(sens.toCntTwiDataM); + mon.print((char *) " Status="); + mon.println(sens.toCntStatusM); + sm.enter(smCheckSens); +} + +void smSensGetRunCounts() +{ + mon.print((char *) "RunCounts: "); + for(int i = 0; i < NrOfRunStates; i++) + { + mon.print((char *) " "); + mon.print(sens.runStateCntArray[i]); + } + mon.print((char *) " Total="); + mon.println(sens.runStateCntTotal); + sm.enter(smCheckSens); +} +#endif // DebugTerminal + diff --git a/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/template_platformio.txt b/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/template_platformio.txt new file mode 100644 index 0000000000000000000000000000000000000000..b87a0a9c91e3731b6e71725de1178b3651d42b5a --- /dev/null +++ b/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/template_platformio.txt @@ -0,0 +1,32 @@ +; PlatformIO Project Configuration File +; +; Build options: build flags, source filter +; Upload options: custom upload port, speed and extra flags +; Library options: dependencies, extra library storages +; Advanced options: extra scripting +; +; Please visit documentation for the other options and examples +; https://docs.platformio.org/page/projectconf.html + +[env:nano33ble] +platform = nordicnrf52 +board = nano33ble +framework = arduino +upload_port = COM5 +build_flags = + -DsmnDEFBYBUILD -DsmnNANOBLE33 -DsmnDEBUG ;-DSlaveACM3 +lib_deps = + symlink://[Pfad_Repository]\libraries\BlePoll + symlink://[Pfad_Repository]\libraries\environment + symlink://[Pfad_Repository]\libraries\ComRingBuf + symlink://[Pfad_Repository]\libraries\LoopCheck + symlink://[Pfad_Repository]\libraries\MidiNotes + symlink://[Pfad_Repository]\libraries\Monitor + symlink://[Pfad_Repository]\libraries\nRF52840Gpio + symlink://[Pfad_Repository]\libraries\nRF52840Radio + symlink://[Pfad_Repository]\libraries\nRF52840Ser + symlink://[Pfad_Repository]\libraries\nRF52840Twi + symlink://[Pfad_Repository]\libraries\SensorLSM9DS1 + symlink://[Pfad_Repository]\libraries\SoaapMsg + symlink://[Pfad_Repository]\libraries\StateMachine + ;symlink://[Pfad_Repository]\libraries\SoaapComDue diff --git a/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/test/README b/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/test/README new file mode 100644 index 0000000000000000000000000000000000000000..9b1e87bc67c90e7f09a92a3e855444b085c655a6 --- /dev/null +++ b/sketches/_PIO_Sketches/Karger/BLE_Slae_Test/test/README @@ -0,0 +1,11 @@ + +This directory is intended for PlatformIO Test Runner and project tests. + +Unit Testing is a software testing method by which individual units of +source code, sets of one or more MCU program modules together with associated +control data, usage procedures, and operating procedures, are tested to +determine whether they are fit for use. Unit testing finds problems early +in the development cycle. + +More information about PlatformIO Unit Testing: +- https://docs.platformio.org/en/latest/advanced/unit-testing/index.html diff --git a/sketches/_PIO_Sketches/Karger/SoaapBleMasterMessdatenAusgabe/.vscode/extensions.json b/sketches/_PIO_Sketches/Karger/SoaapBleMasterMessdatenAusgabe/.vscode/extensions.json new file mode 100644 index 0000000000000000000000000000000000000000..080e70d08b9811fa743afe5094658dba0ed6b7c2 --- /dev/null +++ b/sketches/_PIO_Sketches/Karger/SoaapBleMasterMessdatenAusgabe/.vscode/extensions.json @@ -0,0 +1,10 @@ +{ + // See http://go.microsoft.com/fwlink/?LinkId=827846 + // for the documentation about the extensions.json format + "recommendations": [ + "platformio.platformio-ide" + ], + "unwantedRecommendations": [ + "ms-vscode.cpptools-extension-pack" + ] +} diff --git a/sketches/_PIO_Sketches/Karger/SoaapBleMasterMessdatenAusgabe/include/README b/sketches/_PIO_Sketches/Karger/SoaapBleMasterMessdatenAusgabe/include/README new file mode 100644 index 0000000000000000000000000000000000000000..194dcd43252dcbeb2044ee38510415041a0e7b47 --- /dev/null +++ b/sketches/_PIO_Sketches/Karger/SoaapBleMasterMessdatenAusgabe/include/README @@ -0,0 +1,39 @@ + +This directory is intended for project header files. + +A header file is a file containing C declarations and macro definitions +to be shared between several project source files. You request the use of a +header file in your project source file (C, C++, etc) located in `src` folder +by including it, with the C preprocessing directive `#include'. + +```src/main.c + +#include "header.h" + +int main (void) +{ + ... +} +``` + +Including a header file produces the same results as copying the header file +into each source file that needs it. Such copying would be time-consuming +and error-prone. With a header file, the related declarations appear +in only one place. If they need to be changed, they can be changed in one +place, and programs that include the header file will automatically use the +new version when next recompiled. The header file eliminates the labor of +finding and changing all the copies as well as the risk that a failure to +find one copy will result in inconsistencies within a program. + +In C, the usual convention is to give header files names that end with `.h'. +It is most portable to use only letters, digits, dashes, and underscores in +header file names, and at most one dot. + +Read more about using header files in official GCC documentation: + +* Include Syntax +* Include Operation +* Once-Only Headers +* Computed Includes + +https://gcc.gnu.org/onlinedocs/cpp/Header-Files.html diff --git a/sketches/_PIO_Sketches/Karger/SoaapBleMasterMessdatenAusgabe/lib/README b/sketches/_PIO_Sketches/Karger/SoaapBleMasterMessdatenAusgabe/lib/README new file mode 100644 index 0000000000000000000000000000000000000000..6debab1e8b4c3faa0d06f4ff44bce343ce2cdcbf --- /dev/null +++ b/sketches/_PIO_Sketches/Karger/SoaapBleMasterMessdatenAusgabe/lib/README @@ -0,0 +1,46 @@ + +This directory is intended for project specific (private) libraries. +PlatformIO will compile them to static libraries and link into executable file. + +The source code of each library should be placed in a an own separate directory +("lib/your_library_name/[here are source files]"). + +For example, see a structure of the following two libraries `Foo` and `Bar`: + +|--lib +| | +| |--Bar +| | |--docs +| | |--examples +| | |--src +| | |- Bar.c +| | |- Bar.h +| | |- library.json (optional, custom build options, etc) https://docs.platformio.org/page/librarymanager/config.html +| | +| |--Foo +| | |- Foo.c +| | |- Foo.h +| | +| |- README --> THIS FILE +| +|- platformio.ini +|--src + |- main.c + +and a contents of `src/main.c`: +``` +#include <Foo.h> +#include <Bar.h> + +int main (void) +{ + ... +} + +``` + +PlatformIO Library Dependency Finder will find automatically dependent +libraries scanning project source files. + +More information about PlatformIO Library Dependency Finder +- https://docs.platformio.org/page/librarymanager/ldf.html diff --git a/sketches/_PIO_Sketches/Karger/SoaapBleMasterMessdatenAusgabe/platformio.ini b/sketches/_PIO_Sketches/Karger/SoaapBleMasterMessdatenAusgabe/platformio.ini new file mode 100644 index 0000000000000000000000000000000000000000..441ea1198fe389208a3e3e603d50c6418189de19 --- /dev/null +++ b/sketches/_PIO_Sketches/Karger/SoaapBleMasterMessdatenAusgabe/platformio.ini @@ -0,0 +1,59 @@ +; PlatformIO Project Configuration File +; +; Build options: build flags, source filter +; Upload options: custom upload port, speed and extra flags +; Library options: dependencies, extra library storages +; Advanced options: extra scripting +; +; Please visit documentation for the other options and examples +; https://docs.platformio.org/page/projectconf.html + +[env:nano33ble] +platform = nordicnrf52 +board = nano33ble +framework = arduino +upload_port = COM3 +build_flags = + -DsmnDEFBYBUILD -DsmnNANOBLE33 -DsmnDEBUG +lib_deps = + symlink://C:\Users\Lennard\Documents\Git_local\REP_STR\libraries\BlePoll + symlink://C:\Users\Lennard\Documents\Git_local\REP_STR\libraries\environment + symlink://C:\Users\Lennard\Documents\Git_local\REP_STR\libraries\ComRingBuf + symlink://C:\Users\Lennard\Documents\Git_local\REP_STR\libraries\LoopCheck + symlink://C:\Users\Lennard\Documents\Git_local\REP_STR\libraries\MidiNotes + symlink://C:\Users\Lennard\Documents\Git_local\REP_STR\libraries\Monitor + symlink://C:\Users\Lennard\Documents\Git_local\REP_STR\libraries\nRF52840Gpio + symlink://C:\Users\Lennard\Documents\Git_local\REP_STR\libraries\nRF52840Radio + symlink://C:\Users\Lennard\Documents\Git_local\REP_STR\libraries\nRF52840Ser + symlink://C:\Users\Lennard\Documents\Git_local\REP_STR\libraries\nRF52840Twi + symlink://C:\Users\Lennard\Documents\Git_local\REP_STR\libraries\SensorLSM9DS1 + symlink://C:\Users\Lennard\Documents\Git_local\REP_STR\libraries\SoaapMsg + symlink://C:\Users\Lennard\Documents\Git_local\REP_STR\libraries\StateMachine + ;symlink://C:\Users\lenna\OneDrive\Dokumente\Git\SOAAP\libraries\SoaapComDue + +[env:Logging] +platform = nordicnrf52 +board = nano33ble +framework = arduino +upload_port = COM3 +build_flags = + -DsmnDEFBYBUILD -DsmnNANOBLE33 -DsmnDEBUG +lib_deps = + symlink://C:\Users\Lennard\Documents\Git_local\REP_STR\libraries\BlePoll + symlink://C:\Users\Lennard\Documents\Git_local\REP_STR\libraries\environment + symlink://C:\Users\Lennard\Documents\Git_local\REP_STR\libraries\ComRingBuf + symlink://C:\Users\Lennard\Documents\Git_local\REP_STR\libraries\LoopCheck + symlink://C:\Users\Lennard\Documents\Git_local\REP_STR\libraries\MidiNotes + symlink://C:\Users\Lennard\Documents\Git_local\REP_STR\libraries\Monitor + symlink://C:\Users\Lennard\Documents\Git_local\REP_STR\libraries\nRF52840Gpio + symlink://C:\Users\Lennard\Documents\Git_local\REP_STR\libraries\nRF52840Radio + symlink://C:\Users\Lennard\Documents\Git_local\REP_STR\libraries\nRF52840Ser + symlink://C:\Users\Lennard\Documents\Git_local\REP_STR\libraries\nRF52840Twi + symlink://C:\Users\Lennard\Documents\Git_local\REP_STR\libraries\SensorLSM9DS1 + symlink://C:\Users\Lennard\Documents\Git_local\REP_STR\libraries\SoaapMsg + symlink://C:\Users\Lennard\Documents\Git_local\REP_STR\libraries\StateMachine + ;symlink://C:\Users\lenna\OneDrive\Dokumente\Git\SOAAP\libraries\SoaapComDue +monitor_filters = + default ; Remove typical terminal control codes from input + time ; Add timestamp with milliseconds for each new line + log2file ; Log data to a file “platformio-device-monitor-*.log” located in the current working directory \ No newline at end of file diff --git a/sketches/_PIO_Sketches/Karger/SoaapBleMasterMessdatenAusgabe/src/main.cpp b/sketches/_PIO_Sketches/Karger/SoaapBleMasterMessdatenAusgabe/src/main.cpp new file mode 100644 index 0000000000000000000000000000000000000000..816104a6c86541ac768c4828b1796d148cf00045 --- /dev/null +++ b/sketches/_PIO_Sketches/Karger/SoaapBleMasterMessdatenAusgabe/src/main.cpp @@ -0,0 +1,707 @@ +// ---------------------------------------------------------------------------- +// SoaapBleMaster.ino +// Beispielhafte Anwendung SOAAP / Steuerung optischer und akustischer Ausgaben +// Kommunikation über BLE-Funkanäle mit Bewerbungstelegrammen +// P o l l i n g - M a s t e r +// ---------------------------------------------------------------------------- +// Editor: Robert Patzke +// URI/URL: www.hs-hannover.de +//----------------------------------------------------------------------------- +// Lizenz: CC-BY-SA (wikipedia: Creative Commons) +// Datum: 1. November 2021 +// Letzte Bearbeitung: 4. Februar 2022 +// +// +//Läuft nicht mit den aktuellen Versionen der Bibliotheken. Dateien sind im Projekt SoaapBleMaster_Test_2 zu finden + +#include "Arduino.h" +#include "SoaapBleMaster.h" + + +void devSendDataML(void); +// ---------------------------------------------------------------------------- +LoopCheck lc; +// ---------------------------------------------------------------------------- +// Eine statische Instanz der Klasse LoopCheck +// Darüber wird das Zeitverhalten gesteuert (Software-Timer) und geprüft + +// ---------------------------------------------------------------------------- +nRF52840Radio bleCom; +// ---------------------------------------------------------------------------- +// Eine statische Instanz der Klasse nRF52840Radio +// Darüber wird direkt die CPU (nRF52840) auf dem Arduino-Board zum Senden und +// Empfangen von BLE-Beacons angesprochen. + + +#define bleCycleTime 250 +// ---------------------------------------------------------------------------- +BlePoll blePoll((IntrfRadio *) &bleCom, micros); +// ---------------------------------------------------------------------------- +// Eine statische Instanz der Klasse BlePoll +// Darüber werden das Polling des Masters als auch die Antworten der Slaves +// gesteuert. Es können Geräte entwickelt werden, die nur Master oder Slave +// sind und solche mit Doppelfunktion, wenn kein expliziter Master +// eingesetzt und das Netzwerk über Spontan-Master quasi dezentral +// betrieben werden soll. +// ----- Parameter ------------------------------------------------------------ +// <&bleCom> Die Klasse (vom angenommenen Typ IntrfRadio), die die Daten- +// übertragung abwickelt. Hier wird eine Instanz von nRF52840Radio +// angebunden. Für andere Hardware kann eine entsprechende Klasse +// verwendet werden, die von IntrfRadio abgeleitet wurde. +// <micros> Eine Funktion, die die verstrichene Zeit in Mikrosekunden gibt. +// Damit werden Zeiten (z.B. Time-Out) berechnet. +// Wird hier der Wert NULL übergeben, dann werden die Zeiten aus +// dem Aufrufzyklus (bleCycleTime) in Mikrosekunden berechnet, +// was hier einer Auflösung von 250 Mikrosekunden entspricht. + +#define NrOfSlavesToPoll 5 +// Die Anzahl der Slaves, die der Master aufrufen soll (Polling). +// Es wird grundsätzlich mit der Adresse 1 begonnen und nach dem Aufruf die +// Adresse inkrementiert, also immer die Slaves Adr = 1 bis +// Adr = NrOfSlavesToPoll+1 aufgerufen. +// ACHTUNG! +// Diese Zahl muss kleiner/gleich der in BlePoll.h definierten maximalen +// Anzahl der Slaves (MAXSLAVE) sein, weil die Ressourcen darüber statisch +// festgelegt werden. + +SerParams ttyParams; +// ---------------------------------------------------------------------------- +nRF52840Ser tty; +// ---------------------------------------------------------------------------- +// Eine statische Instanz der Klasse nRF52840Ser (UART) +// Darüber werden die seriellen Schnittstellen (UARTE0 und UARTE1) des +// nRF52840 bedient. +// Die Parameter werden in einer Struktur <SerParams> über die Funktion +// <begin(...)> gesetzt. + +#define sndBufSize 256 +byte sndBuffer[sndBufSize]; +// ---------------------------------------------------------------------------- +ComRingBuf crb; +// ---------------------------------------------------------------------------- +// Eine statische Instanz der Klasse <ComRingBuf> +// Damit wird ein Ringpuffer aufgebaut, der eine serielle Schnittstelle bedient. +// Der Speicher muss extra eingerichtet und mit der Funktion +// <setWriteBuffer(sndBufSize, sndBuffer)> übergeben werden. +// Die Klasse für die serielle Schnittstelle muss von <IntrfSerial> abgeleitet +// sein, die Instanz wird mit der Funktion <begin(...)> übergeben. + +#define appCycleTime 500 +StateMachine ap(apInit, NULL, appCycleTime); +// Eine statische Instanz für die Zustandsmaschine, die hier für die +// Anwendung (App) von SOAAP eingesetzt wird +// ----- Parameter ------------------------------------------------------------ +// <smInit> Der zuerst aufgerufene Zustand (Funktion). Weitere Zustände +// werden in den weiteren Zustandsfunktionen eingesetzt. +// <NULL> Hier kann eine weitere Zustandsfunktion angegeben werden, +// die dann grundsätzlich vor dem Verzweigen in einen Zustand +// aufgerufen wird. +// <smCycleTime> Die Zukluszeit (Takt) der Zustandsmaschine in Mikrosekunden + + +// ---------------------------------------------------------------------------- +SoaapMsg sMsg; +// ---------------------------------------------------------------------------- +// Eine statische Instanz der Klasse <SoaapMsg> +// Damit werden SOAAP-spezifische Meldungen/Telegramme generiert und ausgewertet +// und SOAAP-spezifische Datentypen und Parameter definiert. + +#ifdef DebugTerminal +// ---------------------------------------------------------------------------- +// Zum Debuggen und weitere Analysen der Programmumgebung und Funktionstests +// Es ist ein (richtiges) Terminal erforderlich, mit dem einzelnen Zeichen +// direkt abgeschickt und die eintreffenden direkt angezeigt werden. +// ---------------------------------------------------------------------------- +#define smCycleTime 5 +StateMachine sm(smInit, NULL, smCycleTime); +// Eine statische Instanz für die Zustandsmaschine, die hier für allgemeine +// Steuerungen, Überwachungen und zum Debugging verwendet wird +// ----- Parameter ------------------------------------------------------------ +// <smInit> Der zuerst aufgerufene Zustand (Funktion). Weitere Zustände +// werden in den weiteren Zustandsfunktionen eingesetzt. +// <NULL> Hier kann eine weitere Zustandsfunktion angegeben werden, +// die dann grundsätzlich vor dem Verzweigen in einen Zustand +// aufgerufen wird. +// <smCycleTime> Die Zukluszeit (Takt) der Zustandsmaschine in Millisekunden + +Monitor mon(modeEcho | modeNl,0,&lc); +// Eine statische Instanz (mit Konstruktordaten) der Klasse Monitor +// Darüber wird mit (direkten) Terminals (z.B. VT100) kommuniziert +// Unter Linux werden hier GtkTerm (siehe Internet) und +// ArduinoMonTerm (eigene Entwicklung mit grafischen Wertanzeigen) eingesetzt. +// Das in den IDEs integrierte Terminal ist dafür meistens nicht geeigent, +// weil damit keine direkte Kommunikation (getipptes Zeichen sofort gesendet) +// möglich ist. +// ----- Parameter ------------------------------------------------------------ +// <mode Echo> Alle eintreffenden Zeichen werden sofort zurückgesendet +// <mode NL> Vor der Ausgabe des Prompt (M>) erfolgt CR/LF +// <0> Für Speicherzugriffe wird von 32 Bit ARM ausgegangen +// <&lc> Für Zeitüberwachungen und entsprechende statisctische Daten +// greift die Monitor-Klasse auf die LoopCheck-Klasse zu +// ---------------------------------------------------------------------------- +#endif + + +// ============================================================================ +void setup() +// ============================================================================ +{ + bleCom.begin(); // Initialisierung der Datenübertragung + //bleCom.setPower(0x08); // Maximale Sendeleistung bei nRF52840 + // TEST + bleCom.setPower(0x0FC); // Reduzierte Sendeleistung beim Schreibtisch-Test + + blePoll.begin(BlePoll::ctMASTER, NrOfSlavesToPoll, BlePoll::atDevSOAAP, 10000); + // Initialisierung des Polling mit folgenden Parametern: + // <BlePoll::ctMASTER> Es wird ein Master eingerichtet + // <NrOfSlavesToPoll> Anzahl gepollter Slaves (s.o.) + // <BlePoll::atSOAAP> Spezielle Anwendung SOAAP + // <10000> INT-Watchdog-Timeout beim Lesen in Mikrosekunden + + blePoll.setEmptyPollParams(2000, 500, 2000); + // Setzen der Parameter für das leere Polling zur Feststellung der + // vorhandenen Slaves und Aufbau einer Poll-Liste für den Datenaustausch + // ----- Parameter ---------------------------------------------------------- + // <2000> Anzahl der Poll-Durchläufe, solange kein Slave gefunden wird + // <500> Anzahl weiterer Durchläufe, nachdem wenigstens ein Slave gefunden ist + // <2000> Time-Out (Zeit für Slave zum Antworten) in Mikrosekunden + + for(int i = 1; i <= NrOfSlavesToPoll; i++) + blePoll.setDataPollParams(i, 1, 10, 1000); + // Setzen der Parameter beim Datenpolling, für Slaves individuell + // ----- Parameter ---------------------------------------------------------- + // <i> Adresse des Slave (1-..) + // <1> Priorität beim Aufruf, 0 = immer bis max 65535 = sehr selten + // <10> minimale Priorität bei automatischer Prioritätsreduzierung + // im Fall von Störungen (Time-Out) + // <1000> Time-Out (Zeit für Slave zum Antworten) in Mikrosekunden + +#ifdef DebugTerminal + //blePoll.stopEP(); // Das Polling muss extra gestartet werden + if(blePoll.stoppedEP()) + { + blePoll.resumeEP();} +#endif + + // Initialisierung von serieller Schnittstelle und Ringpuffer + // -------------------------------------------------------------------------- + ttyParams.inst = 0; // Instanzindex der Schnittstelle (0,1) + ttyParams.rxdPort = 1; // Nummer des IO-Port mit RxD-Pin + ttyParams.rxdPin = 10; // Nummer des RxD-Pin am Port + ttyParams.txdPort = 1; // Nummer des IO-Port mit TxD-Pin + ttyParams.txdPin = 3; // Nummer des TxD-Pin am Port + ttyParams.speed = Baud115200; // Enumerator für Bitrate + ttyParams.type = stStd; // Spannungsausgang + + tty.begin(&ttyParams, (IntrfBuf *) &crb); + // Übergeben von Parametern und Referenz auf Ringpufferverwaltung + // für die Übergabe empfangener Zeichen + + tty.startSend(); // Sendebetrieb aktivieren + + crb.setWriteBuffer(sndBufSize, sndBuffer); + // Speicher an Ringpufferverwaltung übergeben + + crb.begin((IntrfSerial *) &tty); + // Referenz auf Schnittstelle an Ringpufferverwaltung + // für die Übergabe zu sendender Zeichen +} + +// ============================================================================ +void loop() +// ============================================================================ +{ + lc.begin(); // Muss am Anfang von LOOP aufgerufen werden + // -------------------------------------------------------------------------- + +#ifdef DebugTerminal + mon.run(); // Der Monitor bekommt bei jedem Durchlauf die CPU +#endif + + // Alle 250 Mikrosekunden erfolgt der Aufruf des Ble-Polling + // + if(lc.timerMicro(lcTimer0, bleCycleTime, 0)) + blePoll.run(); + // ----- Parameter der Software-Timer --------------------------------------- + // <lcTimer0> Id/Nummer des Timer, zur Zeit werden bis 10 Timer unterstützt + // lcTimer0 bis lcTimer9 (einstellbar in LoopCheck.h) + // <bleCycleTime> Ablaufzeit in Einheit des Timer-Typ (Micro/Milli) + // hier in Mikrosekunden (timerMicro) + // <0> Anzahl der Wiederholungen, 0 = unbegrenzt + + // Alle 500 Mikrosekunden erfolgt der Aufruf der Anwendung + // + if(lc.timerMicro(lcTimer1, appCycleTime, 0, 10000)) + ap.run(); + + +#ifdef DebugTerminal + // Jede Sekunde erfolgt die Ausgabe einer Versionsmeldung + // das kann über c0 am Terminal abgeschaltet werden + // + if(lc.timerMilli(lcTimer2, 1000, 0)) + { + //if(!mon.cFlag[0]) + //mon.printcr((char *)"%@TestBleMaster (ttyACM0), Version 20220303"); + //smWaitPolling(); + } + // Die Zeichen %@ am Anfang steuern die Ausgabe bei AndroidMonTerm in ein + // Textfeld (Label) statt auf das Terminal-Display + + // Alle 5 Millisekunden erfolgt der Aufruf der Zustandsmaschine + // + if(lc.timerMilli(lcTimer3, smCycleTime, 0)) + { + sm.run(); + } +#endif + + // -------------------------------------------------------------------------- + lc.end(); // Muss vor dem Ende von LOOP aufgerufen werden +} + +// **************************************************************************** +// Z u s t a n d s m a s c h i n e S O A A P - A n w e n d u n g (ap) +// **************************************************************************** +// +byte apTmpByteArray[256]; // Zwischenspeicher für Zeichenfolgen +int apNrOfMeasBytes; // Anzahl der empfangenen Messwertbytes +int apNrOfCtrlBytes; // Anzahl der empfangenen Steuerbytes inkl count und path +byte apMeasByteArray[32]; // Zwischenspeicher für Messwerte +byte apCtrlByteArray[32]; // Zwischenspeicher für Steuerbytes +byte apSlaveList[NrOfSlavesToPoll]; // Merker für gepollte Slaves +int apNrOfSlaves; // Aktuelle Anzahl von Slaves +int curListIdx; // Aktueller Index für Slaveliste +int area; // Area des aktuellen Slave +int sMsgLen; // Länge einer SOAAP-Meldung +int slNr; // Slave-Nummer (Adresse) +int txNr; // Anzahl versendeter Zeichen + +SoaapApId sAppId; // Anwendungs-Id aus Sicht SOAAP +PlpType pAppId; // Anwendungs-Id aus Polling-Sicht + +#ifdef TEST001 +char testMsgBuf[256]; +#endif +// ---------------------------------------------------------------------------- +// Initialisierungen +// +void apInit() +{ +#ifdef TEST001 + crb.putLine("Initialisierung"); +#endif + + // Eventuelle Initialisierung + ap.enter(apWaitDE); // in nächsten Zustand schalten +} + +// ---------------------------------------------------------------------------- +// Warten, bis Datenaustausch Master/Slave erfolgt +// +void apWaitDE() +{ + if(!blePoll.DataExchange) + return; // Verbleiben in diesem Zustand bis Leerpolling beendet + + apNrOfSlaves = blePoll.getSlaveList(apSlaveList, NrOfSlavesToPoll); + // Ermitteln der angeschlossenen Slaves + +#ifdef TEST001 + crb.putStr("Slaveliste\r\n"); +#endif + + ap.enter(apWaitMeas); +} + +// ---------------------------------------------------------------------------- +// Warten auf neuen Messwert von einem Slave +// +void apWaitMeas() +{ + // Ermitteln, ob einer der Slaves einen Messwert hat + // + for(curListIdx = 0; curListIdx < apNrOfSlaves; curListIdx++) + { + slNr = apSlaveList[curListIdx]; + if(blePoll.measAvail(slNr)) break; + } + if(curListIdx == apNrOfSlaves) return; + // Wenn kein Slave neue Messwerte hat, + // dann im nächsten Zustandstakt Abfrage wiederholen + +#ifdef TEST001 + crb.putStr("Messwerte\r\n"); +#endif + + // Slave (curListIdx) hat Messwerte übermittelt + // diese werden mit dem nächsten Takt verarbeitet + ap.enter(apProcMeas); +} + +// ---------------------------------------------------------------------------- +// Verarbeiten der Daten vom Slave +// +void apProcMeas() +{ +#ifdef TEST001 + if(ap.firstEnter()) + { + slNr = apSlaveList[curListIdx]; + sprintf(testMsgBuf,"Slave-Nr = %d\r\n",slNr); + crb.putStr(testMsgBuf); + } + //ap.enter(apWaitMeas); + //return; +#endif + + // Parameter und Daten für die SOAAP-Meldung holen + // + slNr = apSlaveList[curListIdx]; + area = blePoll.getArea(slNr); + pAppId = blePoll.getAppId(slNr); + apNrOfMeasBytes = blePoll.getMeas(slNr, apMeasByteArray); + apNrOfCtrlBytes = blePoll.getCtrlM(slNr, apCtrlByteArray); + +#ifdef TEST001 + ap.enter(apWaitMeas); + return; +#endif + + // Abbildung des Polling-Telegramm-Typs auf die SOAAP-Anwendungs-Id + // + switch(pAppId) + { + case plptMeas9: + sAppId = saiDefaultMeas; + break; + + case plptMeas13: + sAppId = saiMaximalMeas; + break; + + case plptMeas9Ctrl4: + sAppId = saiDefaultMeasCtrl; + break; + + default: + sAppId = saiDefaultMeas; + break; + } + + // Konstruktion der SOAAP-Meldung + // + //sMsgLen = sMsg.getMsgA(area, slNr, sAppId, (char *) apTmpByteArray, apMeasByteArray); + // Senden des Telegramm über serielle Schnittstelle + // + //txNr = crb.putStr((char *) apTmpByteArray); + // Auf nächsten Messwert von einem Slave warten + // + devSendDataML(); + ap.enter(apWaitMeas); +} + +void devSendDataML(void){ + PlpMeas9Ptr resPtr; + short tmpShort; + SlavePtr slPtr = blePoll.getSlavePtr(1); + resPtr = (PlpMeas9Ptr) &slPtr->result; + for (int i = 0; i < 9; i++) + { + // tmpShort = (short) slPtr->result.meas[i]; + tmpShort = (short)resPtr->meas[i]; + mon.prints(tmpShort); + if(i<8)mon.cprint(' '); + } + mon.print("\n"); +} + +#ifdef DebugTerminal +// **************************************************************************** +// Z u s t a n d s m a s c h i n e z u m D e b u g g e n (sm) +// **************************************************************************** +// +dword debDword; +byte tmpByteArray[256]; + + +void smInit() +{ + sm.enter(smCheckJobs); +} + +// ---------------------------------------------------------------------------- +// Abfrage der Monitorschalter +// ---------------------------------------------------------------------------- +// + +void smCheckJobs() +{ + if(mon.cFlag[1] && !mon.busy) + sm.enter(smDebDword); + else if(mon.cFlag[2] && !mon.busy) + sm.enter(smCtrlPolling); + else if(mon.cFlag[3] && !mon.busy) + sm.enter(smReadPollValues); + else if(mon.cFlag[4] && !mon.busy) + sm.enter(smCheckSer); +} + +// ---------------------------------------------------------------------------- +// Debug-Informationen +// ---------------------------------------------------------------------------- +// + +void smDebDword() +{ + int idx; + + if(sm.firstEnter()) + { + mon.print((char *) "DebDword["); + mon.lastKeyIn = ':'; + } + + if(mon.lastKeyIn == ':') return; + + if(mon.lastKeyIn >= 0x30 && mon.lastKeyIn <= 0x39) + { + idx = mon.lastKeyIn & 0x0F; + mon.print(idx); + mon.print((char *) "]="); + debDword = blePoll.debGetDword(idx); + mon.println(debDword); + sm.resetEnter(); + } + else + { + if(mon.lastKeyIn == ' ') + { + mon.cFlag[1] = false; + mon.print((char *) "-- Schleifenabbruch - drücke Enter"); + sm.enter(smCheckJobs); + } + } +} + +// ---------------------------------------------------------------------------- +// Steuern des Polling-Prozesses +// ---------------------------------------------------------------------------- +// + +TxStatistics txStatistics; + +void smCtrlPolling() +{ + dword tmpDw; + short tmpShort; + int i; + + PlpMeas9Ptr resPtr; + + if(sm.firstEnter()) + { + mon.print((char *) "polling "); + mon.lastKeyIn = ':'; + } + + if(mon.lastKeyIn == ':') return; + + // -------------------------------------------------------------------------- + if(mon.lastKeyIn == 'P' || mon.lastKeyIn == 'p') + { + if(blePoll.stoppedEP()) + { + blePoll.resumeEP(); + mon.println((char *) "fortgesetzt"); + sm.resetEnter(); + } + else + { + blePoll.stopEP(); + sm.enter(smWaitPolling); + } + } + + // -------------------------------------------------------------------------- + else if(mon.lastKeyIn == 'C' || mon.lastKeyIn == 'c') + { + blePoll.resetPollCounters(); + mon.println((char *) "Zähler zurückgesetzt"); + sm.resetEnter(); + } + + + // -------------------------------------------------------------------------- + else if(mon.lastKeyIn == 'R' || mon.lastKeyIn == 'r') + { + mon.print((char *) "Radiopuffer = "); + bleCom.getPduMem(tmpByteArray, 0, 10); + mon.println(tmpByteArray, 10, ' '); + sm.resetEnter(); + } + + + // -------------------------------------------------------------------------- + else if(mon.lastKeyIn == 'S' || mon.lastKeyIn == 's') + { + mon.print((char *) "Sendepuffer = "); + bleCom.getPduSent(tmpByteArray, 0, 10); + mon.println(tmpByteArray, 10, ' '); + sm.resetEnter(); + } + + // -------------------------------------------------------------------------- + else if(mon.lastKeyIn == 'K' || mon.lastKeyIn == 'k') + { + mon.print(slNr); mon.print((char *)"|"); + for(int i= 0; i< apNrOfCtrlBytes; i++){ + mon.print(apCtrlByteArray[i]); + mon.print((char *)" "); + } + mon.print((char *) "\n"); + sm.resetEnter(); + } + // -------------------------------------------------------------------------- + else if(mon.lastKeyIn == 'L' || mon.lastKeyIn == 'l') + { + mon.print((char *) "Slave-Liste: "); + int nrOfSlaves = blePoll.getSlaveList(tmpByteArray, 255); + mon.println(tmpByteArray, nrOfSlaves, ','); + sm.resetEnter(); + } + + // -------------------------------------------------------------------------- + else if(mon.lastKeyIn == 'T' || mon.lastKeyIn == 't') + { + mon.print((char *) "TxStat ["); + dword bleStat = blePoll.getStatistics(&txStatistics); + mon.print(bleStat); + mon.print((char *) "] "); + mon.print(txStatistics.mode); mon.cprint(' '); + mon.print(txStatistics.interrupts); mon.cprint(' '); + mon.print(txStatistics.recs); mon.cprint(' '); + mon.print(txStatistics.sendings); mon.cprint(' '); + mon.print(txStatistics.aliens); mon.cprint(' '); + mon.print(txStatistics.wrongs); mon.cprint(' '); + mon.print(txStatistics.pollAcks); mon.cprint(' '); + mon.print(txStatistics.pollNaks); mon.cprint(' '); + mon.print(txStatistics.crcErrors); mon.print(" s[ "); + mon.print(txStatistics.memDumpSnd,8,' '); mon.print("] r[ "); + mon.print(txStatistics.memDumpRec,16,' '); mon.cprintln(']'); + sm.resetEnter(); + } + + // -------------------------------------------------------------------------- + else if(mon.lastKeyIn >= '0' && mon.lastKeyIn <= '9') + { + int idx = mon.lastKeyIn & 0x0F; + SlavePtr slPtr = blePoll.getSlavePtr(idx); + PollStatePtr pPtr = blePoll.getPollPtr(slPtr->pIdx); + + mon.print((char *) "Slave["); + mon.print(idx); + mon.print((char *) "] "); + mon.print(slPtr->cntTo); mon.cprint(' '); + mon.print(slPtr->cntNakEP); mon.cprint(' '); + mon.print(slPtr->cntAckDP); mon.cprint(' '); + + if(slPtr->cntAckDP == 0) + { + if(slPtr->cntTo == 0) + tmpDw = slPtr->cntNakEP; + else + tmpDw = slPtr->cntNakEP / slPtr->cntTo; + } + else + { + if(slPtr->cntTo == 0) + tmpDw = slPtr->cntAckDP; + else + tmpDw = slPtr->cntAckDP / slPtr->cntTo; + } + mon.print(tmpDw); mon.cprint(' '); + + resPtr = (PlpMeas9Ptr) &slPtr->result; + + mon.print(slPtr->cntLostPdu); mon.cprint('|'); + mon.print(slPtr->cntErrCrc); mon.cprint('|'); + //mon.print(slPtr->result.measCnt); mon.cprint('|'); + mon.print(resPtr->measCnt); mon.cprint('|'); + mon.print(slPtr->cntLostMeas); mon.cprint(' '); + + for(i = 0; i < 9; i++) + { + //tmpShort = (short) slPtr->result.meas[i]; + tmpShort = (short) resPtr->meas[i]; + mon.prints(tmpShort); mon.cprint(' '); + } + mon.print((char *) " Poll["); + mon.print(slPtr->pIdx); + mon.print((char *) "] "); + mon.print(pPtr->status); mon.cprint(' '); + mon.println(pPtr->slIdx); + sm.resetEnter(); + } + + + + else + { + if(mon.lastKeyIn == ' ') + { + mon.cFlag[2] = false; + mon.print((char *) "-- Schleifenabbruch - drücke Enter"); + sm.enter(smCheckJobs); + } + } +} + +void smWaitPolling() +{ + if(!blePoll.stoppedEP()) return; + + mon.println((char *) "angehalten"); + sm.enter(smCtrlPolling); +} + +// ---------------------------------------------------------------------------- +// Testen der seriellen Schnittstelle +// ---------------------------------------------------------------------------- +// +void smCheckSer() +{ + if(sm.firstEnter()) + { + mon.print((char *) "TestSer..."); + mon.lastKeyIn = ':'; + } + + if(mon.lastKeyIn == ':') return; + + if(mon.lastKeyIn == ' ') + { + mon.cFlag[4] = false; + mon.print((char *) "-- Schleifenabbruch - drücke Enter"); + sm.enter(smCheckJobs); + } + else + { + crb.putChr(mon.lastKeyIn); + mon.cprint(mon.lastKeyIn); + mon.lastKeyIn = ':'; + } +} + +// ---------------------------------------------------------------------------- +// Debug-Informationen +// ---------------------------------------------------------------------------- +// + +void smReadPollValues() +{ + +} + +#endif // DebugTerminal + diff --git a/sketches/_PIO_Sketches/Karger/SoaapBleMasterMessdatenAusgabe/template_platformio.txt b/sketches/_PIO_Sketches/Karger/SoaapBleMasterMessdatenAusgabe/template_platformio.txt new file mode 100644 index 0000000000000000000000000000000000000000..15fc69d85e05ee9d499f73ed91bde12711b55562 --- /dev/null +++ b/sketches/_PIO_Sketches/Karger/SoaapBleMasterMessdatenAusgabe/template_platformio.txt @@ -0,0 +1,59 @@ +; PlatformIO Project Configuration File +; +; Build options: build flags, source filter +; Upload options: custom upload port, speed and extra flags +; Library options: dependencies, extra library storages +; Advanced options: extra scripting +; +; Please visit documentation for the other options and examples +; https://docs.platformio.org/page/projectconf.html + +[env:nano33ble] +platform = nordicnrf52 +board = nano33ble +framework = arduino +upload_port = COM3 +build_flags = + -DsmnDEFBYBUILD -DsmnNANOBLE33 -DsmnDEBUG +lib_deps = + symlink://C:\Users\lenna\OneDrive\Dokumente\Git\SOAAP\libraries\BlePoll + symlink://C:\Users\lenna\OneDrive\Dokumente\Git\SOAAP\libraries\environment + symlink://C:\Users\lenna\OneDrive\Dokumente\Git\SOAAP\libraries\ComRingBuf + symlink://C:\Users\lenna\OneDrive\Dokumente\Git\SOAAP\libraries\LoopCheck + symlink://C:\Users\lenna\OneDrive\Dokumente\Git\SOAAP\libraries\MidiNotes + symlink://C:\Users\lenna\OneDrive\Dokumente\Git\SOAAP\libraries\Monitor + symlink://C:\Users\lenna\OneDrive\Dokumente\Git\SOAAP\libraries\nRF52840Gpio + symlink://C:\Users\lenna\OneDrive\Dokumente\Git\SOAAP\libraries\nRF52840Radio + symlink://C:\Users\lenna\OneDrive\Dokumente\Git\SOAAP\libraries\nRF52840Ser + symlink://C:\Users\lenna\OneDrive\Dokumente\Git\SOAAP\libraries\nRF52840Twi + symlink://C:\Users\lenna\OneDrive\Dokumente\Git\SOAAP\libraries\SensorLSM9DS1 + symlink://C:\Users\lenna\OneDrive\Dokumente\Git\SOAAP\libraries\SoaapMsg + symlink://C:\Users\lenna\OneDrive\Dokumente\Git\SOAAP\libraries\StateMachine + ;symlink://C:\Users\lenna\OneDrive\Dokumente\Git\SOAAP\libraries\SoaapComDue + +[env:Logging] +platform = nordicnrf52 +board = nano33ble +framework = arduino +upload_port = COM3 +build_flags = + -DsmnDEFBYBUILD -DsmnNANOBLE33 -DsmnDEBUG +lib_deps = + symlink://C:\Users\lenna\OneDrive\Dokumente\Git\SOAAP\libraries\BlePoll + symlink://C:\Users\lenna\OneDrive\Dokumente\Git\SOAAP\libraries\environment + symlink://C:\Users\lenna\OneDrive\Dokumente\Git\SOAAP\libraries\ComRingBuf + symlink://C:\Users\lenna\OneDrive\Dokumente\Git\SOAAP\libraries\LoopCheck + symlink://C:\Users\lenna\OneDrive\Dokumente\Git\SOAAP\libraries\MidiNotes + symlink://C:\Users\lenna\OneDrive\Dokumente\Git\SOAAP\libraries\Monitor + symlink://C:\Users\lenna\OneDrive\Dokumente\Git\SOAAP\libraries\nRF52840Gpio + symlink://C:\Users\lenna\OneDrive\Dokumente\Git\SOAAP\libraries\nRF52840Radio + symlink://C:\Users\lenna\OneDrive\Dokumente\Git\SOAAP\libraries\nRF52840Ser + symlink://C:\Users\lenna\OneDrive\Dokumente\Git\SOAAP\libraries\nRF52840Twi + symlink://C:\Users\lenna\OneDrive\Dokumente\Git\SOAAP\libraries\SensorLSM9DS1 + symlink://C:\Users\lenna\OneDrive\Dokumente\Git\SOAAP\libraries\SoaapMsg + symlink://C:\Users\lenna\OneDrive\Dokumente\Git\SOAAP\libraries\StateMachine + ;symlink://C:\Users\lenna\OneDrive\Dokumente\Git\SOAAP\libraries\SoaapComDue +monitor_filters = + default ; Remove typical terminal control codes from input + time ; Add timestamp with milliseconds for each new line + log2file ; Log data to a file “platformio-device-monitor-*.log” located in the current working directory \ No newline at end of file diff --git a/sketches/_PIO_Sketches/Karger/SoaapBleMasterMessdatenAusgabe/test/README b/sketches/_PIO_Sketches/Karger/SoaapBleMasterMessdatenAusgabe/test/README new file mode 100644 index 0000000000000000000000000000000000000000..9b1e87bc67c90e7f09a92a3e855444b085c655a6 --- /dev/null +++ b/sketches/_PIO_Sketches/Karger/SoaapBleMasterMessdatenAusgabe/test/README @@ -0,0 +1,11 @@ + +This directory is intended for PlatformIO Test Runner and project tests. + +Unit Testing is a software testing method by which individual units of +source code, sets of one or more MCU program modules together with associated +control data, usage procedures, and operating procedures, are tested to +determine whether they are fit for use. Unit testing finds problems early +in the development cycle. + +More information about PlatformIO Unit Testing: +- https://docs.platformio.org/en/latest/advanced/unit-testing/index.html diff --git a/sketches/_PIO_Sketches/Karger/SoaapBleMaster_Test_2/.vscode/extensions.json b/sketches/_PIO_Sketches/Karger/SoaapBleMaster_Test_2/.vscode/extensions.json new file mode 100644 index 0000000000000000000000000000000000000000..080e70d08b9811fa743afe5094658dba0ed6b7c2 --- /dev/null +++ b/sketches/_PIO_Sketches/Karger/SoaapBleMaster_Test_2/.vscode/extensions.json @@ -0,0 +1,10 @@ +{ + // See http://go.microsoft.com/fwlink/?LinkId=827846 + // for the documentation about the extensions.json format + "recommendations": [ + "platformio.platformio-ide" + ], + "unwantedRecommendations": [ + "ms-vscode.cpptools-extension-pack" + ] +} diff --git a/sketches/_PIO_Sketches/Karger/SoaapBleMaster_Test_2/README.md b/sketches/_PIO_Sketches/Karger/SoaapBleMaster_Test_2/README.md new file mode 100644 index 0000000000000000000000000000000000000000..a38fa89c3f61ca00246497ef2b7ba9e35902a5ed --- /dev/null +++ b/sketches/_PIO_Sketches/Karger/SoaapBleMaster_Test_2/README.md @@ -0,0 +1,12 @@ +Speicherort für PlatformIO projekte. + +Workflow: + -PlatformIO öffnen + -Projekt öffnen -> Projektordner wählen, in dem die platformio.ini liegt. + -platformio.ini anpassen: + Inhalt für die platformio.ini aus der template_platformio.txt kopieren. + Dabei den Pfad für die libraries für den jeweiligen Rechner anpassen. + + +Trotz implementierung in der .gitignore will git nachwievor die platformio.ini synchronisieren, obwohl das eigentlich nicht der Fall sein soll. +Synchronisierung dieser ist aufgrund der unterschiedlichen Dateipfade nicht gewünscht. \ No newline at end of file diff --git a/sketches/_PIO_Sketches/Karger/SoaapBleMaster_Test_2/include/README b/sketches/_PIO_Sketches/Karger/SoaapBleMaster_Test_2/include/README new file mode 100644 index 0000000000000000000000000000000000000000..194dcd43252dcbeb2044ee38510415041a0e7b47 --- /dev/null +++ b/sketches/_PIO_Sketches/Karger/SoaapBleMaster_Test_2/include/README @@ -0,0 +1,39 @@ + +This directory is intended for project header files. + +A header file is a file containing C declarations and macro definitions +to be shared between several project source files. You request the use of a +header file in your project source file (C, C++, etc) located in `src` folder +by including it, with the C preprocessing directive `#include'. + +```src/main.c + +#include "header.h" + +int main (void) +{ + ... +} +``` + +Including a header file produces the same results as copying the header file +into each source file that needs it. Such copying would be time-consuming +and error-prone. With a header file, the related declarations appear +in only one place. If they need to be changed, they can be changed in one +place, and programs that include the header file will automatically use the +new version when next recompiled. The header file eliminates the labor of +finding and changing all the copies as well as the risk that a failure to +find one copy will result in inconsistencies within a program. + +In C, the usual convention is to give header files names that end with `.h'. +It is most portable to use only letters, digits, dashes, and underscores in +header file names, and at most one dot. + +Read more about using header files in official GCC documentation: + +* Include Syntax +* Include Operation +* Once-Only Headers +* Computed Includes + +https://gcc.gnu.org/onlinedocs/cpp/Header-Files.html diff --git a/sketches/_PIO_Sketches/Karger/SoaapBleMaster_Test_2/lib/README b/sketches/_PIO_Sketches/Karger/SoaapBleMaster_Test_2/lib/README new file mode 100644 index 0000000000000000000000000000000000000000..6debab1e8b4c3faa0d06f4ff44bce343ce2cdcbf --- /dev/null +++ b/sketches/_PIO_Sketches/Karger/SoaapBleMaster_Test_2/lib/README @@ -0,0 +1,46 @@ + +This directory is intended for project specific (private) libraries. +PlatformIO will compile them to static libraries and link into executable file. + +The source code of each library should be placed in a an own separate directory +("lib/your_library_name/[here are source files]"). + +For example, see a structure of the following two libraries `Foo` and `Bar`: + +|--lib +| | +| |--Bar +| | |--docs +| | |--examples +| | |--src +| | |- Bar.c +| | |- Bar.h +| | |- library.json (optional, custom build options, etc) https://docs.platformio.org/page/librarymanager/config.html +| | +| |--Foo +| | |- Foo.c +| | |- Foo.h +| | +| |- README --> THIS FILE +| +|- platformio.ini +|--src + |- main.c + +and a contents of `src/main.c`: +``` +#include <Foo.h> +#include <Bar.h> + +int main (void) +{ + ... +} + +``` + +PlatformIO Library Dependency Finder will find automatically dependent +libraries scanning project source files. + +More information about PlatformIO Library Dependency Finder +- https://docs.platformio.org/page/librarymanager/ldf.html diff --git a/sketches/_PIO_Sketches/Karger/SoaapBleMaster_Test_2/platformio.ini b/sketches/_PIO_Sketches/Karger/SoaapBleMaster_Test_2/platformio.ini new file mode 100644 index 0000000000000000000000000000000000000000..e77e37f74cf92af39372d3f9a0c619877b28010b --- /dev/null +++ b/sketches/_PIO_Sketches/Karger/SoaapBleMaster_Test_2/platformio.ini @@ -0,0 +1,59 @@ +; PlatformIO Project Configuration File +; +; Build options: build flags, source filter +; Upload options: custom upload port, speed and extra flags +; Library options: dependencies, extra library storages +; Advanced options: extra scripting +; +; Please visit documentation for the other options and examples +; https://docs.platformio.org/page/projectconf.html + +[env:nano33ble] +platform = nordicnrf52 +board = nano33ble +framework = arduino +upload_port = COM3 +build_flags = + -DsmnDEFBYBUILD -DsmnNANOBLE33 -DsmnDEBUG +lib_deps = + ;symlink://C:\Users\Lennard\Documents\Git_local\REP_STR\libraries\BlePoll + ;symlink://C:\Users\Lennard\Documents\Git_local\REP_STR\libraries\environment + ;symlink://C:\Users\Lennard\Documents\Git_local\REP_STR\libraries\ComRingBuf + ;symlink://C:\Users\Lennard\Documents\Git_local\REP_STR\libraries\LoopCheck + ;symlink://C:\Users\Lennard\Documents\Git_local\REP_STR\libraries\MidiNotes + ;symlink://C:\Users\Lennard\Documents\Git_local\REP_STR\libraries\Monitor + ;symlink://C:\Users\Lennard\Documents\Git_local\REP_STR\libraries\nRF52840Gpio + ;symlink://C:\Users\Lennard\Documents\Git_local\REP_STR\libraries\nRF52840Radio + ;symlink://C:\Users\Lennard\Documents\Git_local\REP_STR\libraries\nRF52840Ser + ;symlink://C:\Users\Lennard\Documents\Git_local\REP_STR\libraries\nRF52840Twi + ;symlink://C:\Users\Lennard\Documents\Git_local\REP_STR\libraries\SensorLSM9DS1 + ;symlink://C:\Users\Lennard\Documents\Git_local\REP_STR\libraries\SoaapMsg + ;symlink://C:\Users\Lennard\Documents\Git_local\REP_STR\libraries\StateMachine + ;symlink://C:\Users\lenna\OneDrive\Dokumente\Git\SOAAP\libraries\SoaapComDue + +[env:Logging] +platform = nordicnrf52 +board = nano33ble +framework = arduino +upload_port = COM3 +build_flags = + -DsmnDEFBYBUILD -DsmnNANOBLE33 -DsmnDEBUG +lib_deps = + ;symlink://C:\Users\Lennard\Documents\Git_local\REP_STR\libraries\BlePoll + ;symlink://C:\Users\Lennard\Documents\Git_local\REP_STR\libraries\environment + ;symlink://C:\Users\Lennard\Documents\Git_local\REP_STR\libraries\ComRingBuf + ;symlink://C:\Users\Lennard\Documents\Git_local\REP_STR\libraries\LoopCheck + ;symlink://C:\Users\Lennard\Documents\Git_local\REP_STR\libraries\MidiNotes + ;symlink://C:\Users\Lennard\Documents\Git_local\REP_STR\libraries\Monitor + ;symlink://C:\Users\Lennard\Documents\Git_local\REP_STR\libraries\nRF52840Gpio + ;symlink://C:\Users\Lennard\Documents\Git_local\REP_STR\libraries\nRF52840Radio + ;symlink://C:\Users\Lennard\Documents\Git_local\REP_STR\libraries\nRF52840Ser + ;symlink://C:\Users\Lennard\Documents\Git_local\REP_STR\libraries\nRF52840Twi + ;symlink://C:\Users\Lennard\Documents\Git_local\REP_STR\libraries\SensorLSM9DS1 + ;symlink://C:\Users\Lennard\Documents\Git_local\REP_STR\libraries\SoaapMsg + ;symlink://C:\Users\Lennard\Documents\Git_local\REP_STR\libraries\StateMachine + ;symlink://C:\Users\lenna\OneDrive\Dokumente\Git\SOAAP\libraries\SoaapComDue +monitor_filters = + default ; Remove typical terminal control codes from input + time ; Add timestamp with milliseconds for each new line + log2file ; Log data to a file “platformio-device-monitor-*.log” located in the current working directory \ No newline at end of file diff --git a/sketches/_PIO_Sketches/Karger/SoaapBleMaster_Test_2/src/BlePoll/BlePoll.cpp b/sketches/_PIO_Sketches/Karger/SoaapBleMaster_Test_2/src/BlePoll/BlePoll.cpp new file mode 100644 index 0000000000000000000000000000000000000000..f2b89ae3d67d527cf753ec12a685ac02e0bde3ae --- /dev/null +++ b/sketches/_PIO_Sketches/Karger/SoaapBleMaster_Test_2/src/BlePoll/BlePoll.cpp @@ -0,0 +1,1624 @@ +//----------------------------------------------------------------------------- +// Thema: Social Manufacturing Network / Development Environment +// Datei: BlePoll.cpp +// Editor: Robert Patzke +// URI/URL: www.mfp-portal.de +//----------------------------------------------------------------------------- +// Lizenz: CC-BY-SA (wikipedia: Creative Commons) +// Datum: 1. September 2021 +// +// Diese Bibliothek (Klassse) enthält diverse Ressourcen zur Kommunikation +// über BLE-Funkmodule auf niedriger Ebene, also dem direkten Telegrammaustausch. +// Darauf aufbauend sollen mehrkanalige Messeinrichtungen mit möglichst +// geringen Latenzzeiten entwickelt werden. +// + +#include "BlePoll.h" + +// -------------------------------------------------------------------------- +// Textmakros zur Vereinfachung der Programmierung +// -------------------------------------------------------------------------- + +#define next(x) nextState = &BlePoll::x + +// -------------------------------------------------------------------------- +// Initialisierungen +// -------------------------------------------------------------------------- + +BlePoll::BlePoll(IntrfRadio *refRadio, dword inCycleMics) +{ + init(refRadio, inCycleMics, NULL); +} + +BlePoll::BlePoll(IntrfRadio *refRadio, MicsecFuPtr inMicroFu) +{ + init(refRadio, 0, inMicroFu); +} + +void BlePoll::init(IntrfRadio *refRadio, dword inCycleMics, MicsecFuPtr inMicroFu) +{ + radio = refRadio; + radio->setPacketParms(bptAdv); + radio->setAccessAddress(AdvAccAddr); + chn = adr = area = 0; + master = nak = eadr = false; + plMode = plmIdle; + plpType = plptEmpty; + micSec = inMicroFu; + cycleMics = inCycleMics; + cycleCnt = 0; + toValue = 0; + toSet = 0; + nextState = NULL; + slaveIdx = 0; + pollIdx = 0; + pollNr = 0; + maxAdr = MAXSLAVE; + curSlave = NULL; + cntAlien = 0; + cntWrong = 0; + cntAllNaks = 0; + cntWaitDisabled = 0; + cntPolling = 0; + cntAllRecs = 0; + cntAllTo = 0; + pollStopped = false; + pollStop = false; + recStopped = false; + recStop = false; + runCounter = 0; + newValue = false; + cbData = NULL; + + for(int i = 1; i <= MAXSLAVE; i++) + { + slaveList[i].cntNakEP = 0; + slaveList[i].cntTo = 0; + slaveList[i].pIdx = 0; + slaveList[i].delayCnt = 5; + slaveList[i].newPdu = false; + slaveList[i].newMeas = false; + pollList[i].prioCnt = 0; + pollList[i].slIdx = 0; + pollList[i].status = 0; + } + + DataExchange = false; +} + +// ---------------------------------------------------------------------------- +void BlePoll::begin(ComType typeIn, int adrIn, AppType appType, dword watchDog) +{ + // TODO + // -------------------------------------------------------------------------- + // Das muss nochmal völlig neu überarbeitet werden. + // Zur Zeit sind viele Redundanzen und teilweise Mehrdeutigkeiten enthalten, + // weil für jede Testanwendung spezifische Vorbereitungen gemacht wurden. + // -------------------------------------------------------------------------- + // + wdTimeOut = watchDog; // WatchDog-Time-Out in Mikrosekunden + + if(typeIn == ctMASTER) + master = true; + else + master = false; void resetPollCounters(); + + + chn = 0; // 1. Bewerbungskanal + area = 0; // Default-Anwendungsbereich + eadr = true; // Start mit leerem Polling + + // -------------------------------------------------------------------------- + plMode = plmEmpty; // Leeres Polling (Adressenliste) + // -------------------------------------------------------------------------- + + if(master) + { + nak = true; // Nak-Bit vom Master forciert leere Antwort + maxAdr = adrIn; + if(maxAdr > MAXSLAVE) + maxAdr = MAXSLAVE; + adr = 1; + slaveIdx = adr; // Reserve für getrennte Verwaltung von adr und slaveIdx + next(smInit); + } + else + { + nak = true; + adr = adrIn; + next(smInit); + } + + if(appType == atSOAAP || appType == atTestSend || appType == atDevSOAAP) + { + pduOut.adr5 = 0x53; + pduOut.adr4 = 0x4F; + pduOut.adr3 = 0x41; + + pduIn.adr5 = 0x53; + pduIn.adr4 = 0x4F; + pduIn.adr3 = 0x41; + } + + if(appType == atTestSend) + plMode = plmTest; + + pduOut.head = HeadS0B; + pduIn.head = HeadS0B; + + pduOut.data[0] = 0; // Pdu-Zähler (CNT) + pduIn.data[0] = 0; + + pduOut.data[1] = appType; // Pdu-Typ (TYPE) + pduIn.data[1] = appType; + + if(appType == atSOAAP) + { + if(master) + { + valuePdu.appId = plptMeas9Ctrl4; + ctrlPdu.appId = plptCtrlX; + plMode = plmSoaapM; + fullCycle = true; + } + else + { + valuePdu.appId = plptMeas9Ctrl4; + ctrlPdu.appId = plptCtrlX; + plMode = plmSoaapS; + } + } + else if (appType == atDevSOAAP) + { + if(master) + { + valuePdu.appId = plptMeas13; + ctrlPdu.appId = plptCtrl2; + plMode = plmSoaapM; + fullCycle = true; + } + else + { + valuePdu.appId = plptMeas13; + ctrlPdu.appId = plptCtrl2; + plMode = plmSoaapS; + } + } + + valuePdu.measCnt = 0; + valuePdu.counter = 0; + valuePdu.type = appType; +} + + +// -------------------------------------------------------------------------- +// Konfiguration +// -------------------------------------------------------------------------- +// +void BlePoll::setPollAddress(int chnIn, int adrIn, int areaIn, bool masterIn, bool eadrIn, bool nakIn) +{ + chn = chnIn; + adr = adrIn; + area = areaIn; + master = masterIn; + eadr = eadrIn; + nak = nakIn; +} + +void BlePoll::setPduAddress() +{ + setPduAddress(&pduOut); +} + +void BlePoll::setPduAddress(bcPduPtr pduPtr) +{ + pduPtr->adr0 = (byte) adr; + pduPtr->adr1 = (byte) (area & 0x3F); + if(nak) pduPtr->adr1 |= 0x40; + if(eadr) pduPtr->adr1 |= 0x80; + pduPtr->adr2 = (byte) chn; + if(master) pduPtr->adr2 |= 0x80; +} + +void BlePoll::setEmptyPollParams(int cycleTotal, int cycleRun, dword timeOut) +{ + epCycleTotal = cycleTotal; + epCycleRun = cycleRun; + epTimeOut = timeOut; +} + +void BlePoll::setDataPollParams(int slAdr, int prio, int minPrio, dword timeOut) +{ + if(slAdr > MAXSLAVE) return; + slaveList[slAdr].prioSet = prio; + slaveList[slAdr].minPrio = minPrio; + slaveList[slAdr].timeOut = timeOut; +} + +void BlePoll::setCbDataPtr(cbDataPtr cbPtr) +{ + cbData = cbPtr; +} + +void BlePoll::setCbCtrlPtr(cbCtrlPtr cbPtr) +{ + cbCtrl = cbPtr; +} + + +dword smStartComESCnt; +bcPdu recBeacon; +int lenBeacon = 0; + +// -------------------------------------------------------------------------- +// Hilfsfunktionen +// -------------------------------------------------------------------------- +// +void BlePoll::setTimeOut(dword value) +{ + if(micSec != NULL) + { + toSet = micSec(); + toValue = value; + } + else + { + if(cycleMics > 1) + cycleCnt = value / cycleMics; + else + cycleCnt = value; + } +} + +bool BlePoll::timeOut() +{ + if(micSec != NULL) + { + if((micSec() - toSet) > toValue) + return(true); + else + return(false); + } + else + { + if(cycleCnt > 0) + return(false); + else + return(true); + } +} + +bool BlePoll::getValues(bcPduPtr pduPtr, PlpType appId) +{ + bool retv = false; + + switch (appId) + { + case plptMeas6: + pduPtr->len = sizeof(PlpMeas6) + 6; + break; + + case plptMeas9Ctrl4: + pduPtr->len = sizeof(PlpM9C4) + 6; + break; + } + pduPtr->data[0]++; // Pdu-Counter + pduPtr->data[1] = valuePdu.type; + pduPtr->data[2] = appId; + + newValue = cbData(appId, &pduPtr->data[4]); + + if(newValue) + { + retv = true; + pduPtr->data[3]++; // measCnt + } + return(retv); +} + + +bool BlePoll::getCtrls(bcPduPtr pduPtr, PlpType appId) +{ + int ctrlLen; + + if(recBeacon.len > 6) + ctrlLen = recBeacon.len - 6; + else + ctrlLen = 4; + + newCtrl = cbCtrl((PlpType) appId, &pduPtr->data[22], &recBeacon.data[0], ctrlLen); + + return(newCtrl); +} + + +// -------------------------------------------------------------------------- +// Steuerung des Polling +// -------------------------------------------------------------------------- +// + +// Aktuellen Betriebszustand einstellen +// +void BlePoll::start(PlMode inPlMode) +{ + oldPlMode = plMode; + plMode = inPlMode; + pollStop = true; +} + +// Anhalten des leeren Polling +// +void BlePoll::stopEP() +{ + pollStop = true; +} + +// Weiterlaufen des leeren Polling +// +void BlePoll::resumeEP() +{ + pollStop = false; + pollStopped = false; +} + +// Abfrage, ob gestoppt +// +bool BlePoll::stoppedEP() +{ + return(pollStopped); +} + +// Anhalten des Empfangs beim Slave +// +void BlePoll::stopSR() +{ + recStop = true; +} + +// Weiterlaufen des Empfangs beim Slave +// +void BlePoll::resumeSR() +{ + recStop = false; + recStopped = false; +} + +// Abfrage, ob Slaveempfang gestoppt +// +bool BlePoll::stoppedSR() +{ + return(recStopped); +} + + +// Eintritt in die Zustandsmaschine +// +void BlePoll::run() +{ + runCounter++; + if(cycleCnt > 0) cycleCnt--; + + if(nextState != NULL) + (this->*nextState)(); +} + +// -------------------------------------------------------------------------- +// Zugriff auf Polling-Informationen +// -------------------------------------------------------------------------- +// +int BlePoll::getSlaveList(byte *dest, int maxByte) +{ + int slIdx; + + for(int i = 1; i <= pollMaxNr; i++) + { + if(i == maxByte) break; + slIdx = pollList[i].slIdx; + dest[i-1] = slaveList[slIdx].adr; + } + return(pollMaxNr); +} + +void BlePoll::resetPollCounters() +{ + int slIdx; + SlavePtr slPtr; + + for(int i = 1; i <= pollMaxNr; i++) + { + slIdx = pollList[i].slIdx; + slPtr = &slaveList[slIdx]; + slPtr->cntAckDP = 0; + slPtr->cntErrCrc = 0; + slPtr->cntLostMeas = 0; + slPtr->cntLostPdu = 0; + slPtr->cntNakEP = 0; + slPtr->cntTo = 0; + } +} + + + + +// **************************************************************************** +// Zustandsmaschine +// **************************************************************************** +// + +// ---------------------------------------------------------------------------- +// Verzweigung nach Anwendung (nach Anlauf) +// ---------------------------------------------------------------------------- +// +dword smInitCnt; + +void BlePoll::smInit() +{ + bleState = 100; + smInitCnt++; + + switch(plMode) + { + case plmIdle: + break; + + case plmTest: + next(smStartTest); + break; + + case plmEmpty: + epCycleTotal = -1; + epCycleRun = -1; + next(smStartEP); + break; + + case plmScan: + break; + + case plmSoaapM: + if(pollStop) + pollStopped = true; + if(!pollStopped) + next(smStartEP); + break; + + case plmSoaapS: + next(smStartComES); + break; + + case plmXchg: + break; + } +} + +// ---------------------------------------------------------------------------- +// Verzweigung nach Anwendung (im Betrieb) +// ---------------------------------------------------------------------------- +// +dword smIdleCnt; + +void BlePoll::smIdle() +{ + bleState = 200; + smIdleCnt++; + + switch(plMode) + { + case plmIdle: + break; + + case plmTest: + next(smStartTest); + break; + + case plmEmpty: + next(smStartEP); + break; + + case plmScan: + if(master) + next(smReqComS); + break; + + case plmXchg: + if(!master) + next(smStartComES); + break; + + case plmSoaapM: + if(!pollStopped) + next(smStartEP); + break; + } +} + +// ---------------------------------------------------------------------------- +// Low Level Tests +// ---------------------------------------------------------------------------- +// +void BlePoll::smStartTest() +{ + bleState = 500; + + if(master) + { + nak = false; + adr = 1; + slaveIdx = adr; + setTimeOut(500000); + } + else + { + nak = true; + } + pduOut.len = 6; + setPduAddress(); + radio->setChannel(chn); + next(smWaitTest); +} + +void BlePoll::smWaitTest() +{ + if(!timeOut()) return; + radio->disable(txmRead); + next(smLoopTest); +} + +void BlePoll::smLoopTest() +{ + pduOut.adr0++; + radio->send(&pduOut, txmRead); + setTimeOut(500000); + next(smWaitTest); +} + + + +// ---------------------------------------------------------------------------- +// L e e r e s P o l l i n g +// ---------------------------------------------------------------------------- +// +void BlePoll::smStartEP() +{ + bleState = 1000; + + pduOut.len = 6; // Nur Adresse + radio->setChannel(chn); + pollMaxNr = 0; + + nak = true; + + if(master) + { + adr = 1; + slaveIdx = adr; // Slave-Array[0] reserviert + pollIdx = 1; // Poll-Array[0] reserviert + pollNr = 0; // Anzahl in der Poll-Liste + next(smReqEadr); + } + else + { + next(smWaitEadr); + } +} + +// ---------------------------------------------------------------------------- +// Leeres Polling M a s t e r +// ---------------------------------------------------------------------------- +// + +void BlePoll::smReqEadr() +{ + bleState = 1100; + + // Datenstruktur für den Slave definieren + // + curSlave = &slaveList[slaveIdx]; // Zeiger auf zu pollenden Slave + curSlave->adr = adr; + curSlave->area = area; + curSlave->chn = chn; + + curPoll = &pollList[pollIdx]; // Zeiger auf freien Platz in Poll-Liste + + setPduAddress(); + setTimeOut(epTimeOut); + + radio->getStatistics(&statistic); + + radio->send(&pduOut, txmPoll); + cntPolling++; + next(smWaitNak); +} + + +void BlePoll::smWaitNak() +{ + bleState = 1110; + + if(timeOut()) + { + // Für die Adresse ist kein Teilnehmer vorhanden, oder die Übertragung ist gestört + // + radio->disable(txmPoll); + + if(curSlave->pIdx != 0) + { + // Wenn der Teilnehmer bereits in die Poll-Liste eingetragen ist + // dann wird darin seine temporäre Abwesenheit markiert + pollList[(int) curSlave->pIdx].status &= ~psSlaveIsPresent; + } + + // Der Time-Out-Zähler macht erkenntlich, wie stark sich Störungen auswirken + // + curSlave->cntTo++; + cntAllTo++; + + // Nächste Adresse und zur Anforderung + // + adr++; + slaveIdx = adr; + if(adr > maxAdr) + next(smEndEP); + else + next(smReqEadr); + return; + } + + + if(radio->fin(txmPoll, &crcError)) + { + // Auf dem Kanal wurde ein Datensatz (BLE-Beacon) empfangen + // und es werden die ersten 8 Byte (Header, Len und Adresse) geholt + // + cntAllRecs++; + radio->getRecData(&pduIn, 8); + + if(pduIn.adr3 != pduOut.adr3 || pduIn.adr4 != pduOut.adr4 || pduIn.adr5 != pduOut.adr5) + { + // Wenn die höherwertigen 3 Byte der Adresse nicht mit der Anwendungskodierung + // übereinstimmen, dann ist es ein Fremd-Beacon. + // Diese werden gezählt und kennzeichnen, wie stark aktiv ein anderes + // BLE-Netzwerk in Reichweite ist. + // + cntAlien++; + + // Nächste Adresse und zur Anforderung, nicht auf Time-Out warten + // + adr++; + slaveIdx = adr; + if(adr > maxAdr) + next(smEndEP); + else + next(smReqEadr); + return; + } + + if(pduIn.adr0 != pduOut.adr0 || (pduIn.adr1 & 0x3F) != (pduOut.adr1 & 0x3F)) + { + // Wenn die Teinehmernummer oder die Gebietsnummer falsch sind, dann ist + // möglicherweise ein weiterer Master aktiv, der fehlerhafterweise denselben + // Kanal verwendet. + // Auch dieses Ereignis wird gezäht. + cntWrong++; + + // Nächste Adresse und zur Anforderung, nicht auf Time-Out warten + // + adr++; + slaveIdx = adr; + if(adr > maxAdr) + next(smEndEP); + else + next(smReqEadr); + return; + } + + // Alles korrekt, der adressierte Teilnehmer hat rechtzeitig geantwortet + // Radio ist abgeschaltet + // + + if(curSlave->pIdx != 0) + { + // Wenn der Teilnehmer bereits in die Poll-Liste eingetragen ist, + // dann wird er darin als aktuell anwesend markiert + // + pollList[(int) curSlave->pIdx].status |= psSlaveIsPresent; + pollNr++; + } + else + { + // Wenn nicht, wird der aktuelle Listeneintrag definiert + // + curPoll->status |= psSlaveIsPresent | psSlaveWasPresent; + curPoll->slIdx = slaveIdx; // Querverweis zur Liste möglicher Teilnehmer + curSlave->pIdx = pollIdx; // Und in der Liste auch ein Verweis zur Poll-Liste + pollIdx++; // Weiter mit nächstem Listenplatz + pollNr++; // Anzahl der beantworteten Pollings + } + + // Die Nak-Antworten werden gezählt + // + curSlave->cntNakEP++; // Teilnehmerspezifisch + cntAllNaks++; // und insgesamt + + // Weiter mit nächstem Teilnehmer und nächster Adresse (TN-Nummer) + // + adr++; + slaveIdx = adr; + + // Wenn die vorgegeben Endadresse erreicht ist + // dann zum Ende des Polldurchgangs über alle möglichen Teilnehmer, + // ansonsten nächsten Teilnehmer pollen + // + if(adr > maxAdr) + next(smEndEP); + else + next(smReqEadr); + } +} + + +void BlePoll::smEndEP() +{ + // Nach jedem vollständigen Polldurchlauf kann das Polling + // abgebrochen werden. + // + if(pollStop || pollStopped) + { + pollStopped = true; + next(smIdle); + return; + } + + // Es werden die Maximalwerte der rechtzeitigen Antworten gebildet + // + if(pollNr > pollMaxNr) + pollMaxNr = pollNr; + + if(pollMaxNr == 0) + { + // Wenn noch kein Teilnehmer angeschlossen ist (oder Kanal total gestört) + // + if(epCycleTotal > 0) + { + // dann wird der Pollvorgang so oft wie vorgegeben wiederholt + // + epCycleTotal--; + pollNr = 0; + pollIdx = 1; + adr = 1; + slaveIdx = adr; + next(smReqEadr); + return; + } + else if(epCycleTotal == 0) + { + // und anschließend der Idle-Zustand angenommen + next(smIdle); + return; + } + } + else + { + // Wenn wenigstens schon ein Teilnehmer geantwortet hat + // + if(epCycleRun > 0) + { + // dann wird der Pollvorgang auch so oft wie anderweitig vorgegeben wiederholt + // + epCycleRun--; + pollNr = 0; + //pollIdx = 1; falsch, pollIdx zeigt auf nächsten freien Platz + adr = 1; + slaveIdx = adr; + next(smReqEadr); + return; + } + else if(epCycleRun == 0) + { + // und anschließend die Datenübertragung gestartet + // oder das Polling ganz beendet + // + if(fullCycle) + next(smStartCom); + else + next(smIdle); + return; + } + } + + // Nächster Poll-Lauf, wenn epCycleXXX noch nicht abgelaufen ist + // oder auf einen wert kleiner 0 gestellt wurde + // + pollNr = 0; + //pollIdx = 1; falsch, pollIdx zeigt auf nächsten freien Platz + adr = 1; + slaveIdx = adr; + next(smReqEadr); +} + +// ---------------------------------------------------------------------------- +// Leeres Polling S l a v e +// ---------------------------------------------------------------------------- +// +void BlePoll::smWaitEadr() +{ + bleState = 1200; + + if(!radio->disabled(txmRespE)) + { + radio->disable(txmRespE); + cntWaitDisabled++; + return; + } + + setPduAddress(); + radio->send(&pduOut, txmRespE); + next(smEvalPoll); +} + +void BlePoll::smEvalPoll() +{ + bleState = 1210; + + radio->getStatistics(&statistic); + if(!radio->fin(txmRespE, &crcError)) return; + next(smWaitEadr); +} + +// ---------------------------------------------------------------------------- +// D a t e n ü b e r t r a g u n g +// ---------------------------------------------------------------------------- +// + +// Vorbereitung der Datenübertragung +// +void BlePoll::smStartCom() +{ + bleState = 2000; + + if(pollStop || pollStopped) // Der Start der Datenübertragung kann + { // verzögert werden + pollStopped = true; + return; + } + + // -------------------------------------------- + // Auswahl des Funkkanals (Frequenz) + // -------------------------------------------- + // + radio->setChannel(chn); + + // -------------------------------------------- + // Voreinstellungen für den Master + // -------------------------------------------- + // + if(master) + { + // Aufbau der Polling-Liste + // + for(int i = 1; i <= pollMaxNr; i++) + { + int slIdx = pollList[i].slIdx; + pollList[i].prioCnt = slaveList[slIdx].prioSet; + } + pollIdx = 1; + + // Vorbereitung der mit dem Polling übermittelten Daten + // + pduOut.len = 13; // Adresse (6) + 7 Byte Steuerung + ctrlPdu.counter = 0; // Zähler im Steuertelegramm + ctrlPdu.appId = plptMeas9Ctrl4; // Info für Slave zur Antwort + + next(smReqComS); + } + // -------------------------------------------- + // Voreinstellungen für den Slave + // -------------------------------------------- + // + else + { + nak = true; + next(smWaitEadr); + } + + DataExchange = true; +} + +// ---------------------------------------------------------------------------- +// Datenübertragung Master S l a v e - > M a s t e r +// ---------------------------------------------------------------------------- +// + +// M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M +// Polling : Anfordern von Daten beim Slave +// ---------------------------------------------------------------------------- +// +void BlePoll::smReqComS() +{ + bleState = 2100; + + if(pollStop || pollStopped) // Das Polling kann + { // angehalten werden + pollStopped = true; + return; + } + + // Es ist von einem vorherigen Funkempfang auszugehen + // Die Hardware muss erst ausgeschaltet werden + // + if(!radio->disabled(txmPoll)) + { + radio->disable(txmPoll); + return; + } + + // Der aufzufordernde Teilnehmer wird der Poll-Liste entnommen + // + curPoll = &pollList[pollIdx]; + + // Ein Aufruf erfolgt nur, wenn der Prioritätszähler auf 0 steht + // ansonsten wird er dekrementiert und der nächste Teilnehmer + // im nächsten Zustandslauf ausgewählt. + // + if(curPoll->prioCnt > 0) + { + curPoll->prioCnt--; + pollIdx++; + if(pollIdx > pollMaxNr) + pollIdx = 1; + return; + } + + // Zugriff auf den Slave aus der Poll-Liste vorbereiten + // + slaveIdx = curPoll->slIdx; + curSlave = &slaveList[slaveIdx]; + + // Slave-spezifische Parameter setzen + // + eadr = false; // Ist true, wenn Daten nur zum Slave übertragen werden + nak = false; // Ist true, wenn keine Daten übertragen werden (empty poll) + adr = curSlave->adr; + area = curSlave->area; + setPduAddress(); + setTimeOut(curSlave->timeOut); + + + // Statistic-Daten einholen für evt. Auswertung + // + radio->getStatistics(&statistic); + + // Aufruf des Slave starten + // + radio->send(&pduOut, txmPoll); + + cntPolling++; + next(smWaitAckComS); +} + +// M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M +// Warten auf die Antwort vom Slave +// ---------------------------------------------------------------------------- +// +void BlePoll::smWaitAckComS() +{ + byte tmpByte; + short tmpShort; + + // Zeiger zur spezifischen Betrachtung von Empfangsdaten + PlPduMeasPtr resPtr; + + bleState = 2110; + + if(timeOut()) + { + // Wenn der Slave nicht antwortet (kann auch eine Störung sein), + // dann wird seine Priorität heruntergesetzt (Zählwert erhöht) + // und der nächste Slave aus der Poll-Liste angefragt + // byte oldPduCount; + + curSlave->prioSet++; + if(curSlave->prioSet > curSlave->minPrio) + curSlave->prioSet = curSlave->minPrio; + + curPoll->prioCnt = curSlave->prioSet; + + curSlave->cntTo++; + pollIdx++; + if(pollIdx > pollMaxNr) + pollIdx = 1; + + radio->disable(txmPoll); + next(smReqComS); + return; + } + + if(radio->fin(txmPoll, &crcError)) + { + cntAllRecs++; + + // Wenn (irgend-) ein Beacon eingegangen ist, + // wird die maximale (BLE-Standard) Anzahl von Bytes kopiert + // + radio->getRecData(&pduIn, 39); + + if(pduIn.adr3 != pduOut.adr3 || pduIn.adr4 != pduOut.adr4 || pduIn.adr5 != pduOut.adr5) + { + // Beacons aus fremdem Netzen werden nur gezählt und es wird weiter gewartet + // + cntAlien++; + pollIdx++; + if(pollIdx > pollMaxNr) + pollIdx = 1; + + next(smReqComS); + return; + } + + if(pduIn.adr0 != pduOut.adr0 || (pduIn.adr1 & 0x3F) != (pduOut.adr1 & 0x3F)) + { + // Beacons mit falscher Slaveadresse werden ebenfalls nur gezählt + // Hier wird später die Rundrufübertragung implementiert + // + cntWrong++; + pollIdx++; + if(pollIdx > pollMaxNr) + pollIdx = 1; + + next(smReqComS); + return; + } + + // Antwort vom richtigen Teilnehmer ist eingegangen + // + + if(crcError) + { + // Die Daten werden bei einem CRC-Fehler verworfen. + // Der Fehler wird gezählt und ist ein Hinweis auf fremde + // Funkaktivitäten + // + curSlave->cntErrCrc++; + pollIdx++; + if(pollIdx > pollMaxNr) + pollIdx = 1; + + next(smReqComS); + return; + } + + // Die Daten werden in der Slave-Struktur abgelegt + // + resPtr = (PlPduMeasPtr) &curSlave->result; + + resPtr->counter = pduIn.data[0]; + resPtr->type = pduIn.data[1]; + resPtr->appId = pduIn.data[2]; + resPtr->measCnt = pduIn.data[3]; + + // Die Inhalte sind abhängig von der <appId> + // + switch(resPtr->appId) + { + case plptMeas9Ctrl4: + ((PlpM9C4Ptr) resPtr)->meas[0] = *(word *) &pduIn.data[4]; + ((PlpM9C4Ptr) resPtr)->meas[1] = *(word *) &pduIn.data[6]; + ((PlpM9C4Ptr) resPtr)->meas[2] = *(word *) &pduIn.data[8]; + ((PlpM9C4Ptr) resPtr)->meas[3] = *(word *) &pduIn.data[10]; + ((PlpM9C4Ptr) resPtr)->meas[4] = *(word *) &pduIn.data[12]; + ((PlpM9C4Ptr) resPtr)->meas[5] = *(word *) &pduIn.data[14]; + ((PlpM9C4Ptr) resPtr)->meas[6] = *(word *) &pduIn.data[16]; + ((PlpM9C4Ptr) resPtr)->meas[7] = *(word *) &pduIn.data[18]; + ((PlpM9C4Ptr) resPtr)->meas[8] = *(word *) &pduIn.data[20]; + ((PlpM9C4Ptr) resPtr)->ctrlPath = pduIn.data[22]; + ((PlpM9C4Ptr) resPtr)->procCnt = pduIn.data[23]; + ((PlpM9C4Ptr) resPtr)->ctrl[0] = pduIn.data[24]; + ((PlpM9C4Ptr) resPtr)->ctrl[1] = pduIn.data[25]; + break; + + case plptMeas6: + ((PlpM9C4Ptr) resPtr)->meas[0] = *(word *) &pduIn.data[4]; + ((PlpM9C4Ptr) resPtr)->meas[1] = *(word *) &pduIn.data[6]; + ((PlpM9C4Ptr) resPtr)->meas[2] = *(word *) &pduIn.data[8]; + ((PlpM9C4Ptr) resPtr)->meas[3] = *(word *) &pduIn.data[10]; + ((PlpM9C4Ptr) resPtr)->meas[4] = *(word *) &pduIn.data[12]; + ((PlpM9C4Ptr) resPtr)->meas[5] = *(word *) &pduIn.data[14]; + ((PlpM9C4Ptr) resPtr)->meas[6] = *(word *) &pduIn.data[16]; + break; + } + + + // Zählen der verlorenen Telegramme und Messwerte + // beginnt um <delayCnt> Pollzyklen verzögert + // + if(curSlave->delayCnt == 0) + { + tmpByte = curSlave->result.counter - curSlave->oldPduCount; + if(tmpByte > 1) + curSlave->cntLostPdu += tmpByte - 1; + + tmpByte = resPtr->measCnt - curSlave->oldMeasCount; + if(tmpByte != 0) + curSlave->newMeas = true; + if(tmpByte > 1) + curSlave->cntLostMeas += tmpByte - 1; + } + else curSlave->delayCnt--; + + curSlave->oldPduCount = curSlave->result.counter; + curSlave->oldMeasCount = resPtr->measCnt; + + curSlave->newPdu = true; + curSlave->cntAckDP++; + curPoll->prioCnt = curSlave->prioSet; + + pollIdx++; + if(pollIdx > pollMaxNr) + pollIdx = 1; + + next(smReqComS); + return; + } +} + +void BlePoll::smEndComS() +{ + if(pollStop || pollStopped) + { + pollStopped = true; + return; + } + // Von vorne (zur Zeit, Test) + // + adr = 1; + slaveIdx = adr; + next(smReqEadr); +} + +// ---------------------------------------------------------------------------- +// Datenübertragung Master M a s t e r - > S l a v e +// ---------------------------------------------------------------------------- +// +void BlePoll::smReqComE() +{ + bleState = 4100; + + if(!radio->disabled(txmRead)) + { + radio->disable(txmRead); + return; + } + + curSlave = &slaveList[slaveIdx]; + curSlave->adr = adr; + curSlave->area = area; + curSlave->chn = chn; + + setPduAddress(); + //setTimeOut(2000); + // Test + setTimeOut(1000000); + radio->send(&pduOut, txmRead); + radio->getStatistics(&statistic); + cntPolling++; + next(smWaitNak); +} + +void BlePoll::smWaitAckComE() +{ + bleState = 4110; + + if(timeOut()) + { + radio->disable(txmRead); + curSlave->cntTo++; + adr++; + slaveIdx = adr; + if(adr > maxAdr) + next(smEndEP); + else + next(smReqEadr); + return; + } + + + if(radio->fin(txmRead, &crcError)) + { + radio->getRecData(&pduIn, 8); + + if(pduIn.adr3 != pduOut.adr3 || pduIn.adr4 != pduOut.adr4 || pduIn.adr5 != pduOut.adr5) + { + cntAlien++; + radio->cont(txmRead); + return; + } + + if(pduIn.adr0 != pduOut.adr0 || (pduIn.adr1 & 0x3F) != (pduOut.adr1 & 0x3F)) + { + cntWrong++; + radio->cont(txmRead); + return; + } + + radio->disable(txmRead); + curSlave->cntNakEP++; + cntAllNaks++; + adr++; + slaveIdx = adr; + if(adr > maxAdr) + next(smEndEP); + else + next(smReqEadr); + } + radio->getStatistics(&statistic); +} + +void BlePoll::smEndComE() +{ + if(pollStop || pollStopped) + { + pollStopped = true; + return; + } + // Von vorne (zur Zeit, Test) + // + adr = 1; + slaveIdx = adr; + next(smReqEadr); +} + + +// S S S S S S S S S S S S S S S S S S S S S S S S S S S S S S S S S S S S S S +// ---------------------------------------------------------------------------- +// Datenübertragung Slave M a s t e r < - > S l a v e +// ---------------------------------------------------------------------------- +// + +// S S S S S S S S S S S S S S S S S S S S S S S S S S S S S S S S S S S S S S +// Vorbereitungen für den Empfang (Polling durch Master) +// ---------------------------------------------------------------------------- +// +void BlePoll::smStartComES() +{ + bool newValues; + bool newCtrl; + byte lenValues; + byte appId; + + bleState = 1310; + smStartComESCnt++; + + if(recStop || recStopped) + { + recStopped = true; + return; + } + + // Wenn keine Daten von der Anwendung zur Verfügung gestellt werden, + // dann macht der Betrieb hier keinen Sinn und der Slave geht in IDLE + // + if(cbData == NULL) + { + next(smIdle); + return; + } + + // Falls der Sender noch nicht ausgeschaltet ist, muss gewartet werden + // + if(!radio->disabled(txmResp)) + { + radio->disable(txmResp); + cntWaitDisabled++; + return; + } + + // Vorbereiten des erwarteten Inhalts beim Polling durch den Master + // + nak = true; + eadr = true; + setPduAddress(&pduIn); + pduIn.len = 6; + + + // Vorbereiten des zu sendenden Inhalts als Antwort auf das Polling + // + nak = false; + eadr = false; + setPduAddress(&pduOut); + + // Eintragen der Messwerte in das Sendetelegramm + // + if(lenBeacon == 0) // Wenn noch kein Empfangszyklus vorliegt + appId = valuePdu.appId; // dann wird der voreingestellte Satz gewählt + else + appId = recBeacon.data[2]; // ansonsten der speziell angeforderte + + newValues = getValues(&pduOut, (PlpType) appId); + + if((appId == plptMeas9Ctrl4) && (cbCtrl != NULL)) + getCtrls(&pduOut, (PlpType) appId); + + radio->setChannel(chn); + radio->send(&pduIn, &pduOut, txmResp, newValues); + + setTimeOut(wdTimeOut); + next(smWaitComES); +} + +// S S S S S S S S S S S S S S S S S S S S S S S S S S S S S S S S S S S S S S +void BlePoll::smWaitComES() +{ + bleState = 1320; + + radio->getStatistics(&statistic); + if(timeOut()) + { + next(smStartComES); + return; + } + + if(!radio->fin(txmResp, &crcError)) return; + // + // Übertragung beendet, Daten empfangen (polling) und versendet (response) + // + //lenBeacon = radio->getRecData(&recBeacon, txmResp, sizeof(recBeacon)); + next(smStartComES); +} + +// -------------------------------------------------------------------------- +// Anwenderfunktionen +// -------------------------------------------------------------------------- +// + +// neue Steuerungsdaten für einen Slave + +void BlePoll::updControl(int adr, byte *ctrlList, int nr) +{ + if(adr <= 0) return; + if(adr >= MAXSLAVE) return; + if(nr <= 1) return; + if(nr > 27) return; + + SlavePtr slavePtr = &slaveList[adr]; + PlpCtrl27Ptr ctrlPtr = (PlpCtrl27Ptr) &slavePtr->control; + for(int i = 0; i < nr; i++) + ctrlPtr->ctrl[i] = ctrlList[i]; + ctrlPtr->ctrlCnt++; + slavePtr->rspOk = false; +} + +// Feststellenn, ob Übertragung der Steuerungsdaten erfolgt ist + +bool BlePoll::ackTrans(int adr) +{ + if(adr <= 0) return(false); + if(adr >= MAXSLAVE) return(false); + + SlavePtr slavePtr = &slaveList[adr]; + return(slavePtr->rspOk); +} + +// Feststellen, ob Steuerungsdaten beim Slave verarbeitet sind + +bool BlePoll::ackControl(int adr) +{ + if(adr <= 0) return(false); + if(adr >= MAXSLAVE) return(false); + + SlavePtr slavePtr = &slaveList[adr]; + PlpCtrl27Ptr ctrlPtr = (PlpCtrl27Ptr) &slavePtr->control; + if(ctrlPtr->ctrlCnt == slavePtr->rspCtrlCount) + return(true); + else + return(false); +} + +// ---------------------------------------------------------------------------- +// Zugriff auf Slavedaten über die Adresse +// ---------------------------------------------------------------------------- +// + +// Feststellen, ob ein Slave neue Messwerte hat +// +bool BlePoll::measAvail(int slAdr) +{ + if(slAdr < 1) return(false); + if(slAdr >= MAXSLAVE) return(false); + + SlavePtr slavePtr = &slaveList[slAdr]; + + if(!slavePtr->newMeas) + return(false); + + slavePtr->newMeas = false; + return(true); +} + +// Auslesen der Netzwerk-Area +// +int BlePoll::getArea(int slAdr) +{ + if(slAdr < 1) return(false); + if(slAdr >= MAXSLAVE) return(false); + + SlavePtr slavePtr = &slaveList[slAdr]; + + return(slavePtr->area); +} + +// Auslesen der AppId aus Sicht der Klasse BlePoll +// +PlpType BlePoll::getAppId(int slAdr) +{ + if(slAdr < 1) return(plptError); + if(slAdr >= MAXSLAVE) return(plptError); + + SlavePtr slavePtr = &slaveList[slAdr]; + + return((PlpType) slavePtr->result.plData[0]); +} + +// Auslesen der Messwerte +// +int BlePoll::getMeas(int slAdr, byte *dest) +{ + int anzByte; + PlpType appId; + + if(slAdr < 1) return(false); + if(slAdr >= MAXSLAVE) return(false); + + SlavePtr slavePtr = &slaveList[slAdr]; + + appId = (PlpType) slavePtr->result.plData[0]; + + switch(appId) + { + case plptMeas6: + anzByte = 12; + break; + + case plptMeas9: + anzByte = 18; + break; + + case plptMeas9Ctrl4: + anzByte = 22; + break; + + case plptMeas13: + anzByte = 26; + break; + + default: + anzByte = 18; + break; + } + + for (int i = 0; i < anzByte; i++) + { + dest[i] = slavePtr->result.plData[i+2]; + } + + return(anzByte); +} + +int BlePoll::getCtrlM(int slAdr, byte *dest){ + int anzByte; + PlpType appId; + + if(slAdr < 1) return(false); + if(slAdr >= MAXSLAVE) return(false); + + + SlavePtr slavePtr = &slaveList[slAdr]; + appId = (PlpType) slavePtr->result.plData[0]; + + switch(appId) + { + case plptMeas6: + anzByte = 0; + break; + + case plptMeas9: + anzByte = 0; + break; + + case plptMeas9Ctrl4: + anzByte = 4; + break; + + case plptMeas13: + anzByte = 0; + break; + + default: + anzByte = 0; + break; + } + + for (int i = 0; i < anzByte; i++) + { + dest[i] = slavePtr->result.plData[i+20]; + } + + return(anzByte); +} + + +// -------------------------------------------------------------------------- +// Debugging +// -------------------------------------------------------------------------- +// +dword BlePoll::debGetDword(int idx) +{ + dword retv = 0; + + switch(idx) + { + case 0: + retv = plMode; + break; + + case 1: + retv = cntAllRecs; + break; + + case 2: + retv = cntAllNaks; + break; + + case 3: + retv = cntAllTo; + break; + + case 4: + retv = cntAlien; + break; + + case 5: + retv = cntWrong; + break; + + case 6: + retv = statistic.pollAcks; + break; + + case 7: + retv = statistic.pollNaks; + break; + + case 8: + retv = bleState; + break; + + case 9: + retv = radio->getState(); + break; + } + + return(retv); +} + +dword BlePoll::getStatistics(TxStatisticsPtr dest) +{ + *dest = statistic; + return(bleState); +} + + +SlavePtr BlePoll::getSlavePtr(int idx) +{ + return(&slaveList[idx]); +} + +PollStatePtr BlePoll::getPollPtr(int idx) +{ + return(&pollList[idx]); +} + + + + + + + diff --git a/sketches/_PIO_Sketches/Karger/SoaapBleMaster_Test_2/src/BlePoll/BlePoll.h b/sketches/_PIO_Sketches/Karger/SoaapBleMaster_Test_2/src/BlePoll/BlePoll.h new file mode 100644 index 0000000000000000000000000000000000000000..721d22c5c1b2fd65fc1415d7707fb2d93383e036 --- /dev/null +++ b/sketches/_PIO_Sketches/Karger/SoaapBleMaster_Test_2/src/BlePoll/BlePoll.h @@ -0,0 +1,513 @@ +//----------------------------------------------------------------------------- +// Thema: Social Manufacturing Network / Development Environment +// Datei: BlePoll.h +// Editor: Robert Patzke +// URI/URL: www.mfp-portal.de +//----------------------------------------------------------------------------- +// Lizenz: CC-BY-SA (wikipedia: Creative Commons) +// Datum: 1. September 2021 +// +// Diese Bibliothek (Klassse) enthält diverse Ressourcen zur Kommunikation +// über BLE-Funkmodule auf niedriger Ebene, also dem direkten Telegrammaustausch. +// Darauf aufbauend sollen mehrkanalige Messeinrichtungen mit möglichst +// geringen Latenzzeiten entwickelt werden. +// + +#ifndef BlePoll_h +#define BlePoll_h +// ---------------------------------------------------------------------------- + +#include "stddef.h" +#include "string.h" +#include "arduinoDefs.h" +#include "bleSpec.h" +#include "IntrfRadio.h" + +#define MAXSLAVE 100 + +// Betriebsmodus (Polling und Slave) +// +typedef enum _PlMode +{ + plmIdle, // Ruhezustand, Gerät nicht im Netz aktiv + plmTest, // Low Level Tests + plmEmpty, // Leeres Polling (Aufbau Adressliste) + plmScan, // Daten aller aktiven Teilnehmer holen (Master) + plmSoaapM, // Vollständiger Betrieb SOAAP (Master) + plmSoaapS, // Vollständiger Betrieb SOAAP (Slave) + plmXchg // Daten übertragen (Slave, beide Richtungen) +} PlMode; + +// Grundsätzliche Datenstruktur für die Nutzdaten (ohne 6 Bytes Adresse) +// +typedef struct _PlPduBase // maximale Länge Beacon = 31 Bytes +{ + byte counter; // zyklischer Telegrammmzähler + byte type; // Kennzeichnung der Datenstruktur (AppType) + byte plData[29]; // weitere spezifische Nutzdaten +} PlPduBase, *PlPduBasePtr; + +// Grundsätzliche Datenstruktur für Messwerte (ohne 6 Bytes Adresse) +// +typedef struct _PlPduMeas // maximale Länge Beacon = 31 Bytes +{ + byte counter; // zyklischer Telegrammmzähler + byte type; // Kennzeichnung der Datenstruktur (AppType) + byte appId; // Kennzeichnung für Dateninhalte (PlpType) + byte measCnt; // Zähler für Messwertaktualisierung + byte plData[27]; // weitere spezifische Nutzdaten +} PlPduMeas, *PlPduMeasPtr; + +// Erweiterte Datenstruktur für die Nutzdaten (ohne 6 Bytes Adresse) +// zur Zeit noch nicht genutzt +// +typedef struct _PlPduExtd // grundsätzliche maximale Länge = 249 Bytes +{ + byte counter; // zyklischer Telegrammmzähler + byte type; // Kennzeichnung der Datenstruktur (AppType) + byte plData[247]; // weitere spezifische Nutzdaten +} PlPduExtd, *PlPduExtdPtr; + +// Datentypen (appId in plPduBase) +// +typedef enum _PlpType +{ + plptError, // Fehler erkannt + plptEmpty, // Leeres Telegramm (nur adresse) + plptBasic, // Grundlegende Bytestruktur + plptFullMeas, // Maximale Belegung mit 16-Bit Messwerten (word) + plptMeas3, // 3 Messwerte (1 Raumsensor) + plptMeas6, // 6 Messwerte (2 Raumsensoren) + plptMeas9, // 9 Messwerte (3 Raumsensoren) + plptMeas9Ctrl4, // 9 Messwerte + 4 Byte Steuerung + plptMeas10Ctrl4, // 10 Messwerte + 4 Byte Steuerung + plptMeas12, // 12 Messwerte (9 + 6 Byte Extradaten) + plptMeas13, // 13 Messwerte (9 + 8 Byte Extradaten) + plptMeasX, // Variable Anzahl Messwerte + plptCtrl0, // Keine Steuerung + plptCtrl2, // 2 Byte Steuerung + plptCtrl27, // 27 Byte Steuerung + plptCtrlX, // Variable Anzahl Steuerbytes + plptMsg // (Quittierte) Meldung an Slave +} PlpType, *PlpTypePtr; + +// Spezifische Datenstrukturen +// +typedef struct _PlpFullMeas // Ausnahme für vordefinierte Spezialfälle +{ + byte counter; // zyklischer Telegrammmzähler + byte type; // Kennzeichnung der Datenstruktur (AppType) + word meas[14]; // Liste von 14 Messwerten + byte appId; // Kennzeichnung für Dateninhalte (PlpType) + byte align; // Wird nicht gesendet, kennzeichnet Alignement +} PlpFullMeas, *PlpFullMeasPtr; + +typedef struct _PlpMeas3 // Länge 10 (+ 6 Bytes Adresse) +{ + byte counter; // zyklischer Telegrammmzähler + byte type; // Kennzeichnung der Datenstruktur (AppType) + byte appId; // Kennzeichnung für Dateninhalte (PlpType) + byte measCnt; // Zähler für Messwertaktualisierung + word meas[3]; // Liste von 3 Messwerten +} PlpMeas3, *PlpMeas3Ptr; + +typedef struct _PlpMeas6 // Länge 16 (+ 6 Bytes Adresse) +{ + byte counter; // zyklischer Telegrammmzähler + byte type; // Kennzeichnung der Datenstruktur (AppType) + byte appId; // Kennzeichnung für Dateninhalte (PlpType) + byte measCnt; // Zähler für Messwertaktualisierung + word meas[6]; // Liste von 6 Messwerten +} PlpMeas6, *PlpMeas6Ptr; + +typedef struct _PlpMeas9 // Länge 22 (+ 6 Bytes Adresse) +{ + byte counter; // zyklischer Telegrammmzähler + byte type; // Kennzeichnung der Datenstruktur (AppType) + byte appId; // Kennzeichnung für Dateninhalte (PlpType) + byte measCnt; // Zähler für Messwertaktualisierung + word meas[9]; // Liste von 9 Messwerten +} PlpMeas9, *PlpMeas9Ptr; + +typedef struct _PlpM9C4 // Länge 26 (+ 6 Bytes Adresse) +{ + byte counter; // zyklischer Telegrammmzähler + byte type; // Kennzeichnung der Datenstruktur (AppType) + byte appId; // Kennzeichnung für Dateninhalte (PlpType) + byte measCnt; // Zähler für Messwertaktualisierung + word meas[9]; // Liste von 9 Messwerten + byte ctrlPath; // Steuerungspfad (für Verzweigungen/Funktionen) + byte procCnt; // Prozesszähler + byte ctrl[2]; // Steuerungsdaten +} PlpM9C4, *PlpM9C4Ptr; + +typedef struct _PlpMeas12 // Länge 28 (+ 6 Bytes Adresse) +{ + byte counter; // zyklischer Telegrammmzähler + byte type; // Kennzeichnung der Datenstruktur (AppType) + byte appId; // Kennzeichnung für Dateninhalte (PlpType) + byte measCnt; // Zähler für Messwertaktualisierung + word meas[12]; // Liste von 12 Messwerten +} PlpMeas12, *PlpMeas12Ptr; + +typedef struct _PlpMeas13 // Länge 30 (+ 6 Bytes Adresse) +{ + byte counter; // zyklischer Telegrammmzähler + byte type; // Kennzeichnung der Datenstruktur (AppType) + byte appId; // Kennzeichnung für Dateninhalte (PlpType) + byte measCnt; // Zähler für Messwertaktualisierung + word meas[13]; // Liste von 13 Messwerten +} PlpMeas13, *PlpMeas13Ptr; + +typedef struct _PlpCtrl2 // Länge 7 (+ 6 Bytes Adresse) +{ + byte counter; // zyklischer Telegrammmzähler + byte type; // Kennzeichnung der Datenstruktur (AppType) + byte appId; // Kennzeichnung für Dateninhalte (PlpType) + byte ctrlCnt; // Zähler für Kommandoaktualisierung + byte procCnt; // Zähler für Prozessaktualisierung + byte ctrl[2]; // Liste von 2 Steuerbytes +} PlpCtrl2, *PlpCtrl2Ptr; + +typedef struct _PlpCtrl27 // Länge 31 (+ 6 Bytes Adresse) +{ + byte counter; // zyklischer Telegrammmzähler + byte type; // Kennzeichnung der Datenstruktur (AppType) + byte appId; // Kennzeichnung für Dateninhalte (PlpType) + byte ctrlCnt; // Zähler für Kommandoaktualisierung + byte procCnt; // Zähler für Prozessaktualisierung + byte ctrl[26]; // Liste von bis zu 26 Steuerbytes +} PlpCtrl27, *PlpCtrl27Ptr; + +// Identifikator für die Art der Daten +// +typedef enum _MeasId +{ + app // Gestaltung/Bedeutung der Daten aus Anwendung +} MeasId, *MeasIdPtr; + +typedef struct _Slave +{ + dword timeOut; // Wartezeit beim Polling in Mikrosekunden + dword cntTo; // Zähler für ausbleibende Antworten + dword cntErrCrc; // Zähler für CRC-Fehler bei der Übertragung + dword cntNakEP; // Zähler für NAK-Antworten beim Empty-Polling + dword cntAckDP; // Zähler für ACK-Antworten beim Data-Polling + dword cntLostPdu; // Zähler für verlorene Telegramme + dword cntLostMeas; // Zähler für verlorene Messwerte + dword delayCnt; // Verzögerung (Polldurchläufe) vor Fehlerzählung + byte adr; // Adresse (Nummer) des Slave (1-255) + byte area; // Einsatzgebiet des Slave (Adresserweiterung) + byte chn; // Aktueller Übertragungskanal (0-39) + byte pIdx; // Index in der aktuellen Pollingliste + word prioSet; // Anfangspriorität (rel. Häufigkeit) beim Polling + word minPrio; // Minimale Priorität (maximale Prioritätszahl) + PlPduBase result; // Daten vom Slave + PlPduBase control; // Daten zum Slave + bool newPdu; // Kennzeichnung für neues Telegramm + bool rspOk; // Rücksetz-Kennnzeichnung für neues Telegramm + bool newMeas; // Kennzeichnung für neuen Messwert + byte oldPduCount; // Merker für die Telegrammüberwachung + byte oldMeasCount; // Merker für die Messwertüberwachung + byte rspCtrlCount; // Merker für Steuerungsüberwachung +} Slave, *SlavePtr; + + +typedef struct _PollInfo +{ + dword aliens; // Anzahl der netzfremden Aktivitäten + dword wrongs; // Anzahl ungewünschter Netzaktivitäten +} PollInfo, *PollInfoPtr; + + +typedef struct _PollState +{ + byte slIdx; // Index in der Slave-Liste + byte status; // Zustand + word prioCnt; // Prioritätszähler +} PollState, *PollStatePtr; + +typedef bool (*cbDataPtr)(PlpType dataType, byte *dest); +typedef bool (*cbCtrlPtr)(PlpType plpType, byte *dest, byte *src, int sSize); + +#define psSlaveWasPresent 0x01 +#define psSlaveIsPresent 0x02 + +// ---------------------------------------------------------------------------- +// B l e P o l l +// ---------------------------------------------------------------------------- +class BlePoll +{ +public: + // ------------------------------------------------------------------------- + // Öffentliche Datentypen + // ------------------------------------------------------------------------- + // + typedef enum _ComType + { + ctMASTER, + ctSLAVE, + ctHybrid + } ComType; + + // Identifikator für die Anwendung + // + typedef enum _AppType + { + atDefault, // Standard-Default-Anwendung + atTestSend, // einfacher Sendetest (Soaap) + atSOAAP, // Steuerung optischer und akustischer Ausgaben für Performance-Künstler + atDevSOAAP, // Entwicklerbetrieb für SOAAP + atDHA // Dezentrale Hausautomatisierung + } AppType; + + // -------------------------------------------------------------------------- + // Öffentliche Daten + // -------------------------------------------------------------------------- + // + bool DataExchange; + +private: + // ------------------------------------------------------------------------- + // Private Datentypen + // ------------------------------------------------------------------------- + // + + typedef void (BlePoll::*cbVector)(void); + typedef dword (*MicsecFuPtr)(void); + + // -------------------------------------------------------------------------- + // Lokale Daten + // -------------------------------------------------------------------------- + // + IntrfRadio *radio; + bcPdu pduOut; + bcPdu pduIn; + cbVector nextState; + MicsecFuPtr micSec; + cbDataPtr cbData; + cbCtrlPtr cbCtrl; + dword toSet; + dword toValue; + dword cycleMics; + dword cycleCnt; + dword wdTimeOut; + + int chn; + int adr; + int area; + bool master; + bool eadr; + bool nak; + bool crcError; + + PlMode plMode; + PlMode oldPlMode; + PlpType plpType; + + Slave slaveList[MAXSLAVE+1]; + SlavePtr curSlave; + int slaveIdx; // ist z.Zt. identisch mit Slaveadresse adr + PollState pollList[MAXSLAVE+1]; + PollStatePtr curPoll; + int pollIdx; + int pollNr; + int pollMaxNr; + + int maxAdr; + dword cntPolling; + dword cntAllRecs; + dword cntAllTo; + bool pollStop; + bool pollStopped; + + dword cntAllNaks; + dword cntAlien; + dword cntWrong; + dword cntWaitDisabled; + + dword bleState; + dword runCounter; + bool recStop; + bool recStopped; + + TxStatistics statistic; + PlPduMeas valuePdu; + PlpCtrl27 ctrlPdu; + bool newValue; + bool newCtrl; + + // Einstellungen für den Anwendungsbetrieb + // + bool fullCycle; // Vollständige Anwendung (EP & Data) + int epCycleTotal; // Anzahl der leeren Pollings gesamt + int epCycleRun; // Anzahl der leeren Pollings nach Kontakt + dword epTimeOut; // Time-Out in Mikrosekunden + + + // -------------------------------------------------------------------------- + // Lokale Funktionen + // -------------------------------------------------------------------------- + // + void setPduAddress(); + void setPduAddress(bcPduPtr pduPtr); + void setTimeOut(dword value); + bool timeOut(); + bool getValues(bcPduPtr pduPtr, PlpType appId); + bool getCtrls(bcPduPtr pduPtr, PlpType appId); + + + // Zustandsmaschine + // ----------------------------- + void smInit(); + void smIdle(); + + // Leeres Polling Master + // + void smStartEP(); + void smReqEadr(); + void smWaitNak(); + void smEndEP(); + + // Leeres Polling Slave + // + void smWaitEadr(); + void smEvalPoll(); + + // Datenübertragung + // + void smStartCom(); + + // Master: Master -> Slave + // + void smReqComE(); + void smWaitAckComE(); + void smEndComE(); + + // Master: Slave -> Master + // + void smReqComS(); + void smWaitAckComS(); + void smEndComS(); + + // Slave: Master <-> Slave + // + void smStartComES(); + void smWaitComES(); + void smEvalComES(); + + // Test + // + void smStartTest(); + void smWaitTest(); + void smLoopTest(); + + +public: + // -------------------------------------------------------------------------- + // Initialisierungen + // -------------------------------------------------------------------------- + BlePoll(IntrfRadio *refRadio, dword inCycleMics); + BlePoll(IntrfRadio *refRadio, MicsecFuPtr inMicroFu); + void init(IntrfRadio *refRadio, dword inCycleMics, MicsecFuPtr inMicroFu); + + void begin(ComType typeIn, int adrIn, AppType appType, dword watchDog); + void setCbDataPtr(cbDataPtr cbPtr); + void setCbCtrlPtr(cbCtrlPtr cbPtr); + + // -------------------------------------------------------------------------- + // Konfiguration + // -------------------------------------------------------------------------- + // + void setPollAddress(int chnIn, int adrIn, int areaIn, bool masterIn, bool eadrIn, bool nakIn); + void setEmptyPollParams(int cycleTotal, int cycleRun, dword timeOut); + void setDataPollParams(int slAdr, int prio, int minPrio, dword timeOut); + + // -------------------------------------------------------------------------- + // Steuerung des Telegrammaustausches (Polling) + // -------------------------------------------------------------------------- + // + void run(); // Ablaufsteuerung (CPU-Übergabe) dieses Moduls +/** + * @brief Sendet neue Steuerungsdaten an einen Slave + * + * @param adr Addresse d. zu Steuernden Slaves + * @param ctrlList Liste mit Bytes zum Austausch der Steuerbytes + * @param nr Anzahl d. Steuerbytes + */ + void updControl(int adr, byte *ctrlList, int nr); // neue Steuerungsdaten + // +/** + * @brief Prüft ob Steuerungsdaten übertragen wurden + * + * @param adr Adresse d. Slaves + * @return true Erfolgreiche übertragung + * @return false Fehler in Übertragung / Falsche Adresse + */ + bool ackTrans(int adr); // Bestätigung Steuerungsdaten übertragen + /** + * @brief Überprüft ob Steuerungsdaten korrekt übertragen wurden + * + * @param adr Adresse d. Slavrs + * @return true Daten erfolgreich verarbeitet + * @return false Fehler in Übertragung + */ + bool ackControl(int adr); // Bestätigung Steuerung ausgeführt + + + // Test + // + + // Leeres Polling + // + void stopEP(); + void resumeEP(); + bool stoppedEP(); + + // Empfangsbetrieb beim Slave + // + void stopSR(); + void resumeSR(); + bool stoppedSR(); + + // Laufender Betrieb + // + void start(PlMode inPlMode); + + + + // -------------------------------------------------------------------------- + // Zugriff auf Polling-Informationen + // -------------------------------------------------------------------------- + // + int getSlaveList(byte *dest, int maxByte); + void resetPollCounters(); + + // -------------------------------------------------------------------------- + // Zugriff auf Slavedaten + // -------------------------------------------------------------------------- + // Der Index wird von 0 an ausgewertet. Allerdings ist [0] in der Slave-Liste + // auf den Index [1] abzubilden, weil Slave[0] für besondere Aufgaben + // reserviert und für den Anwender nicht zugänglich ist. + // + bool measAvail(int slIdx); // Feststellen, ob neue Messwerte da sind + int getArea(int slIdx); // Wert der Area auslesen + PlpType getAppId(int slIdx); // Wert der AppId (BlePoll) auslesen + int getMeas(int slIdx, byte *dest); // Messwerte übergeben + int getCtrlM(int slIdx, byte *dest); + + + // -------------------------------------------------------------------------- + // Debugging + // -------------------------------------------------------------------------- + // + dword debGetDword(int idx); + dword getStatistics(TxStatisticsPtr dest); + + SlavePtr getSlavePtr(int idx); + PollStatePtr getPollPtr(int idx); +}; + + +// ---------------------------------------------------------------------------- +#endif // BlePoll_h diff --git a/sketches/_PIO_Sketches/Karger/SoaapBleMaster_Test_2/src/BlePoll/library.json b/sketches/_PIO_Sketches/Karger/SoaapBleMaster_Test_2/src/BlePoll/library.json new file mode 100644 index 0000000000000000000000000000000000000000..477225b9ff50f19fdf4a1ffb19f791f80efa4870 --- /dev/null +++ b/sketches/_PIO_Sketches/Karger/SoaapBleMaster_Test_2/src/BlePoll/library.json @@ -0,0 +1,4 @@ +{ + "name": "BlePoll", + "version": "0.0.0+20220804174235" + } \ No newline at end of file diff --git a/sketches/_PIO_Sketches/Karger/SoaapBleMaster_Test_2/src/ComRingBuf/ComRingBuf.cpp b/sketches/_PIO_Sketches/Karger/SoaapBleMaster_Test_2/src/ComRingBuf/ComRingBuf.cpp new file mode 100644 index 0000000000000000000000000000000000000000..66a9784b5507d680cc700b0f7fe5e68379da7e3e --- /dev/null +++ b/sketches/_PIO_Sketches/Karger/SoaapBleMaster_Test_2/src/ComRingBuf/ComRingBuf.cpp @@ -0,0 +1,782 @@ +//----------------------------------------------------------------------------- +// Thema: Social Manufacturing Network / Development Environment +// Datei: ComRingBuf.cpp +// Editor: Robert Patzke +// URI/URL: www.mfp-portal.de +//----------------------------------------------------------------------------- +// Lizenz: CC-BY-SA (wikipedia: Creative Commons) +// Datum: 21. November 2021 +// +// Der Inhalt dieser Datei sind Festlegungen zur Gestaltung eines Ringpuffers. +// + +#include "ComRingBuf.h" + + // -------------------------------------------------------------------------- + // Initialisierungen + // -------------------------------------------------------------------------- + + ComRingBuf::ComRingBuf() + { + rbReadIdx = 0; + rbWriteIdx = 0; + sbReadIdx = 0; + sbWriteIdx = 0; + newLineMode = NewLineModeNL; + } + + void ComRingBuf::begin(IntrfSerial *ser) + { + serIf = ser; + } + + // -------------------------------------------------------------------------- + // Konfiguration + // -------------------------------------------------------------------------- + // + void ComRingBuf::setNewLineMode(byte nlMode) + { + newLineMode = nlMode; + } + + + // -------------------------------------------------------------------------- + // Schnittstellen + // -------------------------------------------------------------------------- + // + // Byte aus dem Sendepuffer lesen + // + bool ComRingBuf::getByteSnd(byte *dest) + { + if(sbReadIdx == sbWriteIdx) return(false); + + *dest = sndBuffer[sbReadIdx]; + sbReadIdx++; + if(sbReadIdx >= sbSize) + sbReadIdx = 0; + return(true); + } + + // Byte in den Empfangspuffer schreiben + // + void ComRingBuf::putByteRec(byte b) + { + int space = rbReadIdx - rbWriteIdx - 1; + if(space == 0) return; + } + + +// ---------------------------------------------------------------------------- +// Writing and reading data via circular buffer (default usage) +// ---------------------------------------------------------------------------- +// + +// ---------------------------------------------------------------------------- +// Lesen (Empfangsvorgänge) +// ---------------------------------------------------------------------------- + +void ComRingBuf::setReadBuffer(int size, byte *bufPtr) +{ + recBuffer = bufPtr; + rbSize = size; + rbReadIdx = 0; + rbWriteIdx = 0; +} + +int ComRingBuf::getChr() +{ + int retv; + + if(rbReadIdx == rbWriteIdx) + return(EOF); + + retv = recBuffer[rbReadIdx]; + rbReadIdx++; + if(rbReadIdx >= rbSize) + rbReadIdx = 0; + return(retv); +} + +void ComRingBuf::clrRecBuf() +{ + rbReadIdx = 0; + rbWriteIdx = 0; +} + +int ComRingBuf::getAll(byte *buffer) +{ + int count, i; + int tmpInt; + + if(rbReadIdx == rbWriteIdx) + return(EOF); + + tmpInt = rbWriteIdx - rbReadIdx; + if(tmpInt < 0) + count = tmpInt + rbSize; + else + count = tmpInt; + + for(i = 0; i < count; i++) + { + buffer[i] = recBuffer[rbReadIdx]; + rbReadIdx++; + if(rbReadIdx >= rbSize) + rbReadIdx = 0; + } + + return(count); +} + +int ComRingBuf::getCount(int len, byte *buffer) +{ + int count, i; + int tmpInt; + + if(rbReadIdx == rbWriteIdx) + return(0); + + tmpInt = rbWriteIdx - rbReadIdx; + if(tmpInt < 0) + count = tmpInt + rbSize; + else + count = tmpInt; + + if(len > count) + len = count; + + for(i = 0; i < len; i++) + { + buffer[i] = recBuffer[rbReadIdx]; + rbReadIdx++; + if(rbReadIdx >= rbSize) + rbReadIdx = 0; + } + + return(len); +} + +int ComRingBuf::getCountStr(int len, char *buffer) +{ + int nrChar; + + nrChar = getCount(len, (uint8_t *) buffer); + if(nrChar == EOF) return(EOF); + + buffer[nrChar] = 0; + return(nrChar); +} + +int ComRingBuf::getLine(char *buffer) +{ + bool eol; + int count, i; + int tmpInt; + + if(rbReadIdx == rbWriteIdx) + return(0); + + tmpInt = rbWriteIdx - rbReadIdx; + if(tmpInt < 0) + count = tmpInt + rbSize; + else + count = tmpInt; + + eol = false; + + for(i = 0; i < count; i++) + { + buffer[i] = recBuffer[rbReadIdx]; + if(!eol) + { + if(buffer[i] == '\r' || buffer[i] == '\n') + eol = true; + } + else + { + if(buffer[i] != '\r' && buffer[i] != '\n') + break; + } + rbReadIdx++; + if(rbReadIdx >= rbSize) + rbReadIdx = 0; + } + + if(!eol) return(0); + + buffer[i] = 0; + return(i); +} + +int ComRingBuf::getLineDec(int *intValue) +{ + bool eol, inVal; + int count, i, j; + int tmpInt; + char c; + char buffer[32]; + + if(rbReadIdx == rbWriteIdx) + return(0); + + tmpInt = rbWriteIdx - rbReadIdx; + if(tmpInt < 0) + count = tmpInt + rbSize; + else + count = tmpInt; + + if(count > 30) + count = 30; + + eol = false; + + j = 0; + inVal = false; + + for(i = 0; i < count; i++) + { + c = recBuffer[rbReadIdx]; + if(!inVal) + { + if(c > '9') + { + rbReadIdx++; + if(rbReadIdx >= rbSize) + rbReadIdx = 0; + continue; + } + inVal = true; + } + + if(!eol) + { + if(c == '\r' || c == '\n') + eol = true; + } + else + { + if(c != '\r' && c != '\n') + break; + } + rbReadIdx++; + if(rbReadIdx >= rbSize) + rbReadIdx = 0; + buffer[j++] = c; + } + + if(!eol) return(0); + + buffer[j] = 0; + *intValue = atoi(buffer); + return(i); +} + +char ComRingBuf::getC() +{ + char retC; + + if(rbReadIdx == rbWriteIdx) + return(0); + + retC = recBuffer[rbReadIdx]; + rbReadIdx++; + if(rbReadIdx >= rbSize) + rbReadIdx = 0; + + return(retC); +} + + +int ComRingBuf::waitLine(int waitLoop, char *buffer) +{ + char inChar; + bool eol; + + if(loopCount == 0) + { + tmpIdx = 0; + } + + tmpVal = inCount(); + if(tmpVal < 1) + { + loopCount++; + if(loopCount < waitLoop) + return(0); + else + { + loopCount = 0; + return(EOF); + } + } + + eol = false; + + for(int i = 0; i < tmpVal; i++) + { + inChar = getC(); + buffer[tmpIdx++] = inChar; + if(inChar == '\r' || inChar == '\n') + { + eol = true; + break; + } + } + + if(eol) + { + buffer[tmpIdx] = 0; + loopCount = 0; + return(tmpIdx); + } + + return(0); +} + +//int ComRingBuf::waitLineDec(int waitLoop, int *intValue) +//{ +//}; + +int ComRingBuf::chkLine(char *rsp) +{ + int i,chkVal; + char chkChar; + + chkVal = inCount(); + if(chkVal <= strlen(rsp)) + return(0); + + chkVal = 0; + + for(i = 0; i < strlen(rsp); i++) + { + chkChar = getC(); + if(rsp[i] != chkChar) + { + chkVal = -100000; + break; + } + else + chkVal++; + } + + if(chkVal < 0) chkVal = EOF; + + while( (recBuffer[rbReadIdx] == '\r' || recBuffer[rbReadIdx] == '\n' ) + && (rbReadIdx != rbWriteIdx)) + { + rbReadIdx++; + if(rbReadIdx >= rbSize) + rbReadIdx = 0; + } + + return(chkVal); +} + +int ComRingBuf::chkBuf(char *rsp) +{ + int i,chkVal; + char chkChar; + + chkVal = inCount(); + if(chkVal < strlen(rsp)) + return(0); + + chkVal = 0; + + for(i = 0; i < strlen(rsp); i++) + { + chkChar = getC(); + if(rsp[i] != chkChar) + chkVal = -100; + else + chkVal++; + } + + return(chkVal); +} + +int ComRingBuf::waitAll(int waitLoop, byte *buffer) +{ +} + +int ComRingBuf::waitChkBuf(int waitLoop, char *rsp) +{ + int i; + int chkVal; + char chkChar; + + if(loopCount == 0) + { + tmpVal = strlen(rsp); + } + + chkVal = inCount(); + if(chkVal < tmpVal) + { + loopCount++; + if(loopCount < waitLoop) + return(0); + else + { + loopCount = 0; + return(-10); + } + } + + chkChar = getC(); + + if(rsp[0] != chkChar) + return(0); + + if(tmpVal == 1) + { + loopCount = 0; + return(1); + } + + chkVal = 1; + + for(i = 1; i < tmpVal; i++) + { + chkChar = getC(); + if(rsp[i] != chkChar) + return(0); + else + chkVal++; + } + + loopCount = 0; + return(chkVal); +} + +int ComRingBuf::inCount(void) +{ + int count = rbWriteIdx - rbReadIdx; + if(count < 0) + count += rbSize; + return(count); +} + +int ComRingBuf::getRestChar(byte tagChr, int len, byte *buffer) +{ + int count, i, j; + byte inChr; + int tmpInt; + bool tagged; + + if(rbReadIdx == rbWriteIdx) + return(0); + + tmpInt = rbWriteIdx - rbReadIdx; + if(tmpInt < 0) + count = tmpInt + rbSize; + else + count = tmpInt; + + if(len > count) + len = count; + + tagged = false; + j = 0; + + for(i = 0; i < len; i++) + { + inChr = recBuffer[rbReadIdx]; + rbReadIdx++; + if(rbReadIdx >= rbSize) + rbReadIdx = 0; + + if(!tagged) + { + if(inChr != tagChr) + continue; + + tagged = true; + continue; + } + + buffer[j++] = inChr; + } + + if(!tagged) j = -1; + + return(j); +} + +int ComRingBuf::getRestStr(char *tagStr, int len, byte *buffer) +{ + int count, i, j, tmpIdx; + byte inChr; + int tmpInt; + bool tagged; + int tagLen; + int tagIdx; + + if(rbReadIdx == rbWriteIdx) + return(0); + + tmpIdx = rbReadIdx; + tmpInt = rbWriteIdx - tmpIdx; + + if(tmpInt < 0) + count = tmpInt + rbSize; + else + count = tmpInt; + + if(len > count) + len = count; + + tagged = false; + j = 0; + + tagLen = (int) strlen(tagStr); + tagIdx = 0; + + if(len < tagLen) + return(0); + + for(i = 0; i < len; i++) + { + inChr = recBuffer[tmpIdx]; + tmpIdx++; + if(tmpIdx >= rbSize) + tmpIdx = 0; + + if(!tagged) + { + if(inChr != tagStr[tagIdx]) + { + tagIdx = 0; + continue; + } + + tagIdx++; + + if(tagIdx == tagLen) + tagged = true; + continue; + } + + buffer[j++] = inChr; + } + + if(!tagged) return(EOF); + else + { + rbReadIdx = tmpIdx; + return(j); + } +} + +int ComRingBuf::reqChkLine(char *req, char *rsp) +{ + int i; + int chkVal; + char chkChar; + + switch(reqChkState) + { + case 0: + rbReadIdx = 0; + rbWriteIdx = 0; + chkVal = putLine(req); + if(chkVal <= 0) + return(EOF); + tmpVal = strlen(rsp); + reqChkState = 1; + return(0); + + case 1: + chkVal = inCount(); + if(chkVal <= tmpVal) + return(0); + chkVal = 0; + + for(i = 0; i < tmpVal; i++) + { + chkChar = getC(); + if(rsp[i] != chkChar) + chkVal = -100; + else + chkVal++; + } + + while( (recBuffer[rbReadIdx] == '\r' || recBuffer[rbReadIdx] == '\n') + && (rbReadIdx != rbWriteIdx) ) + { + rbReadIdx++; + if(rbReadIdx >= rbSize) + rbReadIdx = 0; + } + + reqChkState = 0; + return(chkVal); + } + + return(-1000); // internal error with <reqChkState> +} + +// ---------------------------------------------------------------------------- +// Schreiben (Sendevorgänge) +// ---------------------------------------------------------------------------- + +void ComRingBuf::setWriteBuffer(int size, byte *bufPtr) +{ + sndBuffer = bufPtr; + sbSize = size; + sbReadIdx = 0; + sbWriteIdx = 0; +} + +int ComRingBuf::putChr(int chr) +{ + int space; + bool txDone; + + if(sndBuffer == NULL) return(EOF); + if(serIf == NULL) return(EOF); + + space = getSpace(); + + if(space == 0) + { + // Wenn der Sendepuffer voll ist, dann kann der Entlader feststecken + serIf->resuSend(); + return(EOF); + } + + if(sbReadIdx == sbWriteIdx) + { + // Wenn der Sendepuffer leer ist, dann kann das Zeichen evt. + // direkt gesendet werden. + txDone = serIf->condSend(chr); + if(txDone) return(chr); + } + + putBufB(chr); + return(chr); +} + +int ComRingBuf::putStr(char *msg) +{ + int sIdx = 0; + + if(sndBuffer == NULL) return(EOF); + if(serIf == NULL) return(EOF); + + int space = getSpace(); + int len = strlen(msg); + if(space < len) + { + serIf->resuSend(); + return(EOF); + } + + if(sbReadIdx == sbWriteIdx) + { + // Wenn der Sendepuffer leer ist, dann kann das erste Zeichen evt. + // direkt gesendet werden. + if(serIf->condSend(msg[0])) + sIdx = 1; + } + + for (int i = sIdx; i < len; i++) + { + sndBuffer[sbWriteIdx] = msg[i]; + sbWriteIdx++; + if(sbWriteIdx >= sbSize) + sbWriteIdx = 0; + } + + return(len); +} + +int ComRingBuf::putSeq(byte *msg, int n) +{ + int sIdx = 0; + + if(sndBuffer == NULL) return(EOF); + if(serIf == NULL) return(EOF); + + int space = getSpace(); + + if(space < n) + { + serIf->resuSend(); + return(EOF); + } + + if(sbReadIdx == sbWriteIdx) + { + // Wenn der Sendepuffer leer ist, dann kann das erste Zeichen evt. + // direkt gesendet werden. + if(serIf->condSend(msg[0])) + sIdx = 1; + } + + for (int i = sIdx; i < n; i++) + { + sndBuffer[sbWriteIdx] = msg[i]; + sbWriteIdx++; + if(sbWriteIdx >= sbSize) + sbWriteIdx = 0; + } + + return(n); + +} + +int ComRingBuf::putNL() +{ + int retv = 0; + + if(newLineMode & NewLineModeCR) + { + putBufB('\r'); + retv++; + } + + if(newLineMode & NewLineModeNL) + { + putBufB('\n'); + retv++; + } + + return(retv); +} + +int ComRingBuf::putLine(char *msg) +{ + int retv, nl; + + retv = putStr(msg); + if(retv < 0) + return(retv); + + nl = putNL(); + return(retv); +} + +//int ComRingBuf::putLine(char *msg, char c) +//{ +//} + +//int ComRingBuf::putLine(char *msg, int n) +//{ +//} + + + // -------------------------------------------------------------------------- + // Debugging + // -------------------------------------------------------------------------- + // + + + + + + + + + diff --git a/sketches/_PIO_Sketches/Karger/SoaapBleMaster_Test_2/src/ComRingBuf/ComRingBuf.h b/sketches/_PIO_Sketches/Karger/SoaapBleMaster_Test_2/src/ComRingBuf/ComRingBuf.h new file mode 100644 index 0000000000000000000000000000000000000000..bd8ee0c8e604ac8ca5a6c344ca9966bb856f365b --- /dev/null +++ b/sketches/_PIO_Sketches/Karger/SoaapBleMaster_Test_2/src/ComRingBuf/ComRingBuf.h @@ -0,0 +1,227 @@ +//----------------------------------------------------------------------------- +// Thema: Social Manufacturing Network / Development Environment +// Datei: ComRingBuf.h +// Editor: Robert Patzke +// URI/URL: www.mfp-portal.de +//----------------------------------------------------------------------------- +// Lizenz: CC-BY-SA (wikipedia: Creative Commons) +// Datum: 21. November 2021 +// +// Der Inhalt dieser Datei sind Festlegungen zur Gestaltung eines Ringpuffers. +// + +#ifndef ComRingBuf_h +#define ComRingBuf_h +// ---------------------------------------------------------------------------- + +#include "stddef.h" +#include "stdio.h" +#include "stdlib.h" +#include "string.h" +#include "arduinoDefs.h" +#include "IntrfBuf.h" +#include "IntrfSerial.h" + +#define NewLineModeCR 0x01 +#define NewLineModeNL 0x02 + +// ---------------------------------------------------------------------------- +// C o m R i n g B u f +// ---------------------------------------------------------------------------- +class ComRingBuf : IntrfBuf +{ +private: + // -------------------------------------------------------------------------- + // Lokale Daten + // -------------------------------------------------------------------------- + // + // Zugang zur Peripherie + // + IntrfSerial *serIf; + + // Lesen und Schreiben von Zeichen (Bytes) + // + byte *ptrSend; // Der (veraenderliche) Sendezeiger + byte *ptrRec; // Der (veraenderliche) Empfangszeiger + int maxRec; // Maximale Anzahl zu empfangender Bytes + byte endChrRec; // Abschlusszeichen beim Empfang + byte condMaskCom; // Bedingungen fuer den Datenaustausch + byte newLineMode; // Art für eine neue Zeile (CR/LF) + + byte *recBuffer; // Receive ring buffer start address + word rbReadIdx; // Read index + word rbWriteIdx; // Write index + word rbSize; // Buffer size + + byte *sndBuffer; // Transmit ring buffer start address + word sbReadIdx; // Read index + word sbWriteIdx; // Write index + word sbSize; // Buffer size + + int loopCount; // For internal time out checking + int reqChkState; // State of request/check procedure + int tmpVal; // Variable for temporary data storage + int tmpIdx; // Variable for temporary array index + + + // -------------------------------------------------------------------------- + // Lokale Funktionen + // -------------------------------------------------------------------------- + // + char getC(); + int putNL(); + + // -------------------------------------------------------------------------- + // Inline-Funktionen + // -------------------------------------------------------------------------- + // + void putBufB(byte b) + { + sndBuffer[sbWriteIdx] = b; + sbWriteIdx++; + if(sbWriteIdx >= sbSize) + sbWriteIdx = 0; + } + + int getSpace() + { + int space = sbReadIdx - sbWriteIdx - 1; + if(space < 0) space += sbSize; + return(space); + } + + +public: + // -------------------------------------------------------------------------- + // Initialisierungen + // -------------------------------------------------------------------------- + ComRingBuf(); + + void begin(IntrfSerial *ser); + + // -------------------------------------------------------------------------- + // Konfiguration + // -------------------------------------------------------------------------- + // + void setNewLineMode(byte nlMode); + + // -------------------------------------------------------------------------- + // Schnittstellen + // -------------------------------------------------------------------------- + // + bool getByteSnd(byte *dest); + void putByteRec(byte b); // Byte vom Empfang an Puffer geben + + + // Zuweisen eines Speichers (*bufPtr) der Größe size für den Lesepuffer + // + void setReadBuffer(int size, byte *bufPtr); + + + // -------------------------------------------------------------------------- + // Steuerung + // -------------------------------------------------------------------------- + // + + // ---------------------------------------------- + // Ein einzelnes Zeichen aus dem Ringpuffer lesen + // ---------------------------------------------- + // Rückgabe EOF (-1), wenn kein Zeichen vorhanden + // sonst das älteste Zeichen aus dem Ringpuffer + // + int getChr(); + + // ---------------------------------------------- + // Löschen des Emmpfangspuffers + // ---------------------------------------------- + // + void clrRecBuf(); + + // -------------------------------------------------- + // Alle empfangenen Zeichen aus dem Ringpuffer lesen + // -------------------------------------------------- + // Rückgabe EOF (-1), wenn kein Zeichen vorhanden + // sonst die Anzahl der empfangenen Zeichen + // + int getAll(byte *buffer); + + // ---------------------------------------------------------- + // Begrenzte Anzahl empfangener Zeichen aus Ringpuffer lesen + // ---------------------------------------------------------- + // Rückgabe EOF (-1), wenn kein Zeichen vorhanden + // sonst die Anzahl der ausgelesenen Zeichen + // + int getCount(int count, byte *buffer); + + // ------------------------------------------------------------------------ + // Begrenzte Anzahl Zeichen als 0-terminierten String aus Ringpuffer lesen + // ------------------------------------------------------------------------ + // Rückgabe EOF (-1), wenn kein Zeichen vorhanden + // sonst die Anzahl der ausgelesenen Zeichen + // + int getCountStr(int count, char *buffer); + + // --------------------------------------------------------- + // Die nächste Zeile (Zeichen bis CR und/oder LF) als String + // --------------------------------------------------------- + // Rückgabe EOF (-1), wenn kein Zeichen vorhanden + // sonst die Anzahl der ausgelesenen Zeichen + // + int getLine(char *buffer); + + // ----------------------------------------------- + // Die nächste im Puffer enthaltene Zeile auslesen + // und die darin enthaltene Dezimalzahl übergeben + // ----------------------------------------------- + // Rückgabe EOF (-1), wenn kein Zeichen vorhanden + // sonst die Anzahl der ausgelesenen Zeichen + // oder 0, wenn keine Dezimalzahl enthalten war + // + int getLineDec(int *intValue); + + // --------------------------------------------------------- + // Warten auf Zeile (Zeichen bis CR und/oder LF) als String + // --------------------------------------------------------- + // Rückgabe EOF (-1), wenn Wartezyklen verstrichen + // Rückgabe 0, solange kein Zeilenende gelesen + // sonst die Anzahl der ausgelesenen Zeichen + // + int waitLine(int waitLoop, char *buffer); + + //int waitLineDec(int waitLoop, int *intValue); + + // --------------------------------------------------------- + // Testen der Zeile im Puffer + // --------------------------------------------------------- + // Rückgabe 0, wenn Teststring (noch) nicht enthalten + // sonst die Länge des Teststring + // EOF, wenn Zeile im Puffer (gelöscht) nicht passte + // + int chkLine(char *rsp); + + int chkBuf(char *rsp); + int waitAll(int waitLoop, byte *buffer); + int waitChkBuf(int waitLoop, char *rsp); + int inCount(void); + int getRestChar(byte tagChr, int len, byte *buffer); + int getRestStr(char *tagStr, int len, byte *buffer); + int reqChkLine(char *req, char *rsp); + + void setWriteBuffer(int size, byte *bufPtr); + int putChr(int chr); + int putStr(char *msg); + int putSeq(byte *msg, int n); + int putLine(char *msg); + //int putLine(char *msg, char c); + //int putLine(char *msg, int n); + + // -------------------------------------------------------------------------- + // Debugging + // -------------------------------------------------------------------------- + // + +}; + + +// ---------------------------------------------------------------------------- +#endif // beacon_h diff --git a/sketches/_PIO_Sketches/Karger/SoaapBleMaster_Test_2/src/ComRingBuf/library.json b/sketches/_PIO_Sketches/Karger/SoaapBleMaster_Test_2/src/ComRingBuf/library.json new file mode 100644 index 0000000000000000000000000000000000000000..054f2c8c3093791dc7ce4f7de879b26a019e900b --- /dev/null +++ b/sketches/_PIO_Sketches/Karger/SoaapBleMaster_Test_2/src/ComRingBuf/library.json @@ -0,0 +1,4 @@ +{ + "name": "BlePoll", + "version": "0.0.0+20220804174235" +} \ No newline at end of file diff --git a/sketches/_PIO_Sketches/Karger/SoaapBleMaster_Test_2/src/LoopCheck/LoopCheck.cpp b/sketches/_PIO_Sketches/Karger/SoaapBleMaster_Test_2/src/LoopCheck/LoopCheck.cpp new file mode 100644 index 0000000000000000000000000000000000000000..b01795b4f033ebb0286340840a3b1507c6ef0302 --- /dev/null +++ b/sketches/_PIO_Sketches/Karger/SoaapBleMaster_Test_2/src/LoopCheck/LoopCheck.cpp @@ -0,0 +1,838 @@ +//----------------------------------------------------------------------------- +// Thema: Social Manufacturing Network / Software Loop Checking and Timing +// Datei: LoopCheck.cpp +// Editor: Robert Patzke +// URI/URL: www.mfp-portal.de +//----------------------------------------------------------------------------- +// Lizenz: CC-BY-SA (siehe Wikipedia: Creative Commons) +// + +#include "LoopCheck.h" + + + // ------------------------------------------------------------------------- + // Konstruktoren und Initialisierungen + // ------------------------------------------------------------------------- + // + LoopCheck::LoopCheck() + { + firstLoop = true; + taskHappened = false; + toggleMilli = true; + + initStatistics(); + initTasks(); + initClock(); + } + + void LoopCheck::initStatistics() + { + backgroundMicros = 0; + loopMicros = 0; + loopStartMicros = 0; + loopEndMicros = 0; + backgroundMaxMicros = 0; + backgroundMinMicros = (unsigned long) -1; + backgroundAvgMicros = 0; + loopMaxMicros = 0; + loopMinMicros = (unsigned long) -1; + loopAvgMicros = 0; + loopCounter = 0; + periodFailCount = 0; + periodMaxMicros = 0; + periodMinMicros = (unsigned int) -1; + periodMicros = 0; + periodFailAlarm = false; + + year = 0; + day = 0; + hour = 0; + min = 0; + sec = 0; + msec = 0; + + measureRuntime = 0; + + calcAvgCounter = 0; + } + + void LoopCheck::initTasks() + { + for (int i = 0; i < NrOfTimerTasks; i++) + { + timerTaskList[i].counterStarted = false; + timerTaskList[i].finished = false; + timerTaskList[i].firstRun = true; + timerTaskList[i].runCounter = 0; + } + + for( int i = 0; i < NrOfOnceTasks; i++) + { + onceTaskList[i].finished = false; + onceTaskList[i].firstRun = true; + onceTaskList[i].waitCounter = 0; + } + } + + void LoopCheck::initClock() + { + strcpy(dateTimeStr,"2017-12-07T17:11:35.456+00:00"); + dtYear = 2017; + dtMonth = 12; + dtDay = 7; + dtHour = 17; + dtMin = 11; + dtSec = 35; + dtmSec = 456; + } + + // ------------------------------------------------------------------------- + // Anwenderfunktionen + // ------------------------------------------------------------------------- + // + + void LoopCheck::begin() + { + unsigned int cycleMillis; + unsigned int restMicros; + unsigned int tmpInt; + unsigned int tmpInt100, tmpInt10, tmpInt1; + div_t divResult; + + loopStartMicros = SYSMICSEC; + clockCycleMicros = loopStartMicros - lastClockMicros + lastRestMicros; + // + // Zeit seit dem letzten Aufruf von begin() + + + // + if(firstLoop == true) + { + clockCycleMicros = 0; + lastClockMicros = loopStartMicros; + } + + // Aufteilen in Millisekunden und Mikrosekunden + // + divResult = DIV((int) clockCycleMicros, 1000); + + restMicros = divResult.rem; + cycleMillis = divResult.quot; + + if(cycleMillis > 0) + { + lastRestMicros = restMicros; + lastClockMicros = loopStartMicros; + msec += cycleMillis; + dtmSec += cycleMillis; + + // Betriebsstundenzähler + // + if(msec >= 1000) + { + msec -= 1000; + sec++; + measureRuntime++; + + if(sec == 60) + { + sec = 0; + min++; + if(min == 60) + { + min = 0; + hour++; + if(hour == 24) + { + hour = 0; + day++; + if(day == 365) + { + day = 0; + year++; + } + } + } + } + } + + // Software-Uhr + // + if(dtmSec >= 1000) + { + dtmSec -= 1000; + + dtSec++; + dateTimeStr[20] = '0'; + dateTimeStr[21] = '0'; + dateTimeStr[22] = '0'; + + if(dtSec == 60) + { + dtSec = 0; + dtMin++; + dateTimeStr[17] = '0'; + dateTimeStr[18] = '0'; + + if(dtMin == 60) + { + dtMin = 0; + dtHour++; + dateTimeStr[14] = '0'; + dateTimeStr[15] = '0'; + + if(dtHour == 24) + { + dtHour = 0; + dtDay++; + dateTimeStr[11] = '0'; + dateTimeStr[12] = '0'; + + if ( + (dtDay == (febLen + 1) && dtMonth == 2) + || (dtDay == 31 && (dtMonth == 4 || + dtMonth == 6 || + dtMonth == 9 || + dtMonth == 11)) + || dtDay == 32 + ) + { + dtDay = 1; + dtMonth++; + dateTimeStr[8] = '0'; + dateTimeStr[9] = '1'; + + if(dtMonth == 13) + { + dtMonth = 1; + dtYear++; + tmpInt = dtYear - 2000; + if((tmpInt % 4) == 0) + febLen = 29; + else + febLen = 28; + dateTimeStr[5] = '0'; + dateTimeStr[6] = '1'; + + divResult = DIV(tmpInt,100); + tmpInt100 = divResult.quot; + tmpInt = divResult.rem; + + divResult = DIV(tmpInt,10); + tmpInt10 = divResult.quot; + tmpInt1 = divResult.rem; + + dateTimeStr[1] = (char) (tmpInt100 | 0x30); + dateTimeStr[2] = (char) (tmpInt10 | 0x30); + dateTimeStr[3] = (char) (tmpInt1 | 0x30); + } + else + { + divResult = DIV(dtMonth,10); + dateTimeStr[5] = (char) (divResult.quot | 0x30); + dateTimeStr[6] = (char) (divResult.rem | 0x30); + } + } + else + { + divResult = DIV(dtDay,10); + dateTimeStr[8] = (char) (divResult.quot | 0x30); + dateTimeStr[9] = (char) (divResult.rem | 0x30); + } + } + else + { + divResult = DIV(dtHour,10); + dateTimeStr[11] = (char) (divResult.quot | 0x30); + dateTimeStr[12] = (char) (divResult.rem | 0x30); + } + } + else + { + divResult = DIV(dtMin,10); + dateTimeStr[14] = (char) (divResult.quot | 0x30); + dateTimeStr[15] = (char) (divResult.rem | 0x30); + } + } + else + { + divResult = DIV(dtSec,10); + dateTimeStr[17] = (char) (divResult.quot | 0x30); + dateTimeStr[18] = (char) (divResult.rem | 0x30); + } + } + else + { + divResult = DIV(dtmSec,100); + tmpInt100 = divResult.quot; + tmpInt = divResult.rem; + + divResult = DIV(tmpInt,10); + tmpInt10 = divResult.quot; + tmpInt1 = divResult.rem; + + dateTimeStr[20] = (char) (tmpInt100 | 0x30); + dateTimeStr[21] = (char) (tmpInt10 | 0x30); + dateTimeStr[22] = (char) (tmpInt1 | 0x30); + } + + } + + if(firstLoop == false) + { + backgroundMicros = loopStartMicros - loopEndMicros; + if(backgroundMicros > backgroundMaxMicros) + backgroundMaxMicros = backgroundMicros; + if(backgroundMicros < backgroundMinMicros) + backgroundMinMicros = backgroundMicros; + periodMicros = loopStartMicros - lastStartMicros; + if(periodMicros > periodMaxMicros) + periodMaxMicros = periodMicros; + periodSumMicros += periodMicros; + if(periodMicros < periodMinMicros) + periodMinMicros = periodMicros; + if(periodMicros > PeriodMinTime) + { + periodFailAlarm = true; + periodFailCount++; + } + + divResult = DIV(periodMicros, 1000); + if(divResult.quot > 0) + { + if(divResult.quot >= LoopScreeningGrades) + ++loopScreening[LoopScreeningGrades - 1]; + else + ++loopScreening[divResult.quot -1]; + } + } // if() + + lastStartMicros = loopStartMicros; + + } + + + unsigned int LoopCheck::done() + { + return(SYSMICSEC - loopStartMicros); + } + + void LoopCheck::end() + { + loopEndMicros = SYSMICSEC; + loopMicros = loopEndMicros - loopStartMicros; + if(loopMicros > loopMaxMicros) + loopMaxMicros = loopMicros; + if(loopMicros < loopMinMicros) + loopMinMicros = loopMicros; + + if(firstLoop == false) + { + loopSumMicros += loopMicros; + backgroundSumMicros += backgroundMicros; + calcAvgCounter++; + if(calcAvgCounter == CalcAverageDepth) + { + loopAvgMicros = loopSumMicros / CalcAverageDepth; + backgroundAvgMicros = backgroundSumMicros / CalcAverageDepth; + periodAvgMicros = periodSumMicros / CalcAverageDepth; + calcAvgCounter = 0; + loopSumMicros = 0; + backgroundSumMicros = 0; + periodSumMicros = 0; + } + } + else + { + loopAvgMicros = loopMicros; + backgroundAvgMicros = backgroundMicros; + } + + loopCounter++; + firstLoop = false; + taskHappened = false; + } + + bool LoopCheck::timerMicro + (int taskIdx, unsigned long repeatTime, unsigned int repetitions, unsigned long delay) + { + TimerTask *ctrlPtr; + unsigned long calcMics; + + // Test the limit of enabled timers + // + if(taskIdx < 0) return(false); + if(taskIdx >= NrOfTimerTasks) return(false); + + // Get the reference to timer data for the selected timer + // + ctrlPtr = &timerTaskList[taskIdx]; + + // If the timer task has finished, we are ready here + // + if(ctrlPtr->finished == true) return(false); + + // If it is the first run (initialisation 1) + // + if(ctrlPtr->firstRun == true) + { + ctrlPtr->firstRun = false; + ctrlPtr->repCounter = repetitions; + ctrlPtr->delayCounter = delay; + } + + // If counting is not started yet (initialisation 2) + // + if(ctrlPtr->counterStarted == false) + { + ctrlPtr->startCount = loopStartMicros; + ctrlPtr->counterStarted = true; + return(false); + } + + // If another count task has happened in this loop, we have to wait + // + if(taskHappened == true) return(false); + + // Calculate the number of microseconds since the start of the counter + // + calcMics = loopStartMicros - ctrlPtr->startCount; + ctrlPtr->ticks = calcMics; + + // If there is a delay, wait the delay time + // + if(ctrlPtr->delayCounter > 0) + { + if(calcMics < ctrlPtr->delayCounter) + return(false); + else + { + ctrlPtr->delayCounter = 0; // delay finished + ctrlPtr->startCount = loopStartMicros; // reset counter + } + return(false); + } + + // There is no delay (or delay is finished) + // If repeatTime is not passed, leave with FALSE + // + if(calcMics < repeatTime) + { + return(false); + } + + // One counter period finished + // + taskHappened = true; // disable other timers in this loop + ctrlPtr->counterStarted = false; // prepare resetting the counter + ctrlPtr->runCounter++; // count the timer events + + // If the number of periods is limited finish in time + // + if(ctrlPtr->repCounter > 0) + { + ctrlPtr->repCounter--; + if(ctrlPtr->repCounter == 0) + ctrlPtr->finished = true; + } + + return(true); + } + + bool LoopCheck::timerMicro + (int taskIdx, unsigned long repeatTime, unsigned int repetitions) + { + return(timerMicro(taskIdx, repeatTime, repetitions, 0)); + } + + + bool LoopCheck::timerMilli + (int taskIdx, unsigned long repeatTime, unsigned int repetitions, unsigned long delay) + { + return(timerMicro(taskIdx, repeatTime * 1000, repetitions, delay * 1000)); + } + + bool LoopCheck::timerMilli + (int taskIdx, unsigned long repeatTime, unsigned int repetitions) + { + return(timerMicro(taskIdx,repeatTime * 1000,repetitions,0)); + } + + bool LoopCheck::once(int taskIdx) + { + if(taskIdx < 0) return(false); + if(taskIdx >= NrOfOnceTasks) return(false); + + if(onceTaskList[taskIdx].finished == true) return(false); + onceTaskList[taskIdx].finished = true; + return(true); + } + + bool LoopCheck::once(int taskIdx, unsigned int nrOfLoops) + { + if(taskIdx < 0) return(false); + if(taskIdx >= NrOfOnceTasks) return(false); + + if(onceTaskList[taskIdx].finished == true) return(false); + if(nrOfLoops <= 1) + { + onceTaskList[taskIdx].finished = true; + return(true); + } + + if(onceTaskList[taskIdx].firstRun == true) + { + onceTaskList[taskIdx].firstRun = false; + onceTaskList[taskIdx].waitCounter = nrOfLoops; + } + + onceTaskList[taskIdx].waitCounter--; + if(onceTaskList[taskIdx].waitCounter > 0) + return(false); + + onceTaskList[taskIdx].finished = true; + return(true); + } + + bool LoopCheck::onceDelayed(int taskIdx, unsigned long delay) + { + if(taskIdx < 0) return(false); + if(taskIdx >= NrOfOnceTasks) return(false); + + if(onceTaskList[taskIdx].finished == true) return(false); + + if(onceTaskList[taskIdx].firstRun == true) + { + onceTaskList[taskIdx].firstRun = false; + onceTaskList[taskIdx].startCount = loopStartMicros; + } + + if(loopStartMicros - onceTaskList[taskIdx].startCount < delay) + return(false); + + onceTaskList[taskIdx].finished = true; + return(true); + } + + bool LoopCheck::toggle(int taskIdx) + { + bool toggleBit; + + if(taskIdx < 0) return(false); + if(taskIdx >= NrOfToggleTasks) return(false); + toggleBit = toggleTaskList[taskIdx]; + toggleTaskList[taskIdx] = !toggleBit; + return(toggleBit); + } + + unsigned long LoopCheck::timerCycle(int taskIdx) + { + if(taskIdx < 0) return(0); + if(taskIdx >= NrOfTimerTasks) return(0); + return(timerTaskList[taskIdx].runCounter); + } + + bool LoopCheck::timerCycleMod(int taskIdx, int modulo) + { + div_t divResult; + + if(taskIdx < 0) return(0); + if(taskIdx >= NrOfTimerTasks) return(0); + divResult = DIV(timerTaskList[taskIdx].runCounter,modulo); + if(divResult.rem == 0) + return(true); + else + return(false); + } + + unsigned long LoopCheck::tick(int taskIdx) + { + if(taskIdx < 0) return(0); + if(taskIdx >= NrOfTimerTasks) return(0); + return(timerTaskList[taskIdx].ticks); + } + + unsigned long LoopCheck::operationTime(OpHourMeter *opHourMeter) + { + opHourMeter->Milliseconds = msec; + opHourMeter->Seconds = sec; + opHourMeter->Minutes = min; + opHourMeter->Hours = hour; + opHourMeter->Days = day; + opHourMeter->Years = year; + return(loopStartMicros); + } + + unsigned long LoopCheck::getStatistics(LoopStatistics *statistics) + { + statistics->loopTime = (unsigned int) loopMicros; + statistics->loopMaxTime = (unsigned int) loopMaxMicros; + statistics->loopMinTime = (unsigned int) loopMinMicros; + statistics->loopAvgTime = (unsigned int) loopAvgMicros; + + statistics->bgTime = (unsigned int) backgroundMicros; + statistics->bgMaxTime = (unsigned int) backgroundMaxMicros; + statistics->bgMinTime = (unsigned int) backgroundMinMicros; + statistics->bgAvgTime = (unsigned int) backgroundAvgMicros; + + statistics->alarmCount = periodFailCount; + statistics->periodAlarm = periodFailAlarm; + periodFailAlarm = false; + + statistics->loopPeriod = periodMicros; + statistics->maxPeriod = periodMaxMicros; + statistics->minPeriod = periodMinMicros; + statistics->avgPeriod = periodAvgMicros; + + for (int i = 0; i < LoopScreeningGrades; i++) + statistics->rtScreening[i] = loopScreening[i]; + + return(loopCounter); + } + + void LoopCheck::resetStatistics() + { + backgroundMicros = 0; + loopMicros = 0; + + backgroundMaxMicros = 0; + backgroundMinMicros = (unsigned long) -1; + backgroundAvgMicros = 0; + + loopMaxMicros = 0; + loopMinMicros = (unsigned long) -1; + loopAvgMicros = 0; + loopCounter = 0; + + periodFailCount = 0; + periodMaxMicros = 0; + periodMinMicros = (unsigned int) -1; + periodAvgMicros = 0; + periodMicros = 0; + periodFailAlarm = false; + + for (int i = 0; i < LoopScreeningGrades; i++) + loopScreening[i] = 0; + + calcAvgCounter = 0; + } + + bool LoopCheck::setDateTime(const char *dtStr) + { + int tmpInt; + + if(strlen(dtStr) < 23) return(false); + strcpy(dateTimeStr,dtStr); + dtYear = (dateTimeStr[0] & 0x0F) * 1000 + + (dateTimeStr[1] & 0x0F) * 100 + + (dateTimeStr[2] & 0x0F) * 10 + + (dateTimeStr[3] & 0x0F); + + tmpInt = dtYear - 2000; + if((tmpInt % 4) == 0) + febLen = 29; + else + febLen = 28; + + + dtMonth = (dateTimeStr[5] & 0x0F) * 10 + + (dateTimeStr[6] & 0x0F); + + dtDay = (dateTimeStr[8] & 0x0F) * 10 + + (dateTimeStr[9] & 0x0F); + + dtHour = (dateTimeStr[11] & 0x0F) * 10 + + (dateTimeStr[12] & 0x0F); + + dtMin = (dateTimeStr[14] & 0x0F) * 10 + + (dateTimeStr[15] & 0x0F); + + dtSec = (dateTimeStr[17] & 0x0F) * 10 + + (dateTimeStr[18] & 0x0F); + + dtmSec = (dateTimeStr[20] & 0x0F) * 10 + + (dateTimeStr[21] & 0x0F) * 10 + + (dateTimeStr[22] & 0x0F); + + return(true); + } + + bool LoopCheck::setDateTime(lcDateTime dt) + { + div_t divResult; + int tmpInt; + + dtYear = dt.Year; + + tmpInt = dtYear - 2000; + if((tmpInt % 4) == 0) + febLen = 29; + else + febLen = 28; + + + divResult = DIV(dtYear,1000); + dateTimeStr[0] = (char) (0x30 + divResult.quot); + + divResult = DIV(divResult.rem,100); + dateTimeStr[1] = (char) (0x30 + divResult.quot); + + divResult = DIV(divResult.rem,10); + dateTimeStr[2] = (char) (0x30 + divResult.quot); + dateTimeStr[3] = (char) (0x30 + divResult.rem); + + dtMonth = dt.Month; + divResult = DIV(dtMonth,10); + dateTimeStr[5] = (char) (0x30 + divResult.quot); + dateTimeStr[6] = (char) (0x30 + divResult.rem); + + dtDay = dt.Day; + divResult = DIV(dtDay,10); + dateTimeStr[8] = (char) (0x30 + divResult.quot); + dateTimeStr[9] = (char) (0x30 + divResult.rem); + + dtHour = dt.Hour; + divResult = DIV(dtHour,10); + dateTimeStr[11] = (char) (0x30 + divResult.quot); + dateTimeStr[12] = (char) (0x30 + divResult.rem); + + dtMin = dt.Minute; + divResult = DIV(dtMin,10); + dateTimeStr[14] = (char) (0x30 + divResult.quot); + dateTimeStr[15] = (char) (0x30 + divResult.rem); + + dtSec = dt.Second; + divResult = DIV(dtSec,10); + dateTimeStr[17] = (char) (0x30 + divResult.quot); + dateTimeStr[18] = (char) (0x30 + divResult.rem); + + dtmSec = dt.Millisecond; + divResult = DIV(dtmSec, 100); + dateTimeStr[20] = (char) (0x30 + divResult.quot); + divResult = DIV(divResult.rem, 10); + dateTimeStr[21] = (char) (0x30 + divResult.quot); + dateTimeStr[22] = (char) (0x30 + divResult.rem); + + return(true); + } + + bool LoopCheck::getDateTime(lcDateTime *dt) + { + dt->Year = dtYear; + dt->Month = dtMonth; + dt->Day = dtDay; + dt->Hour = dtHour; + dt->Minute = dtMin; + dt->Second = dtSec; + dt->Millisecond = dtmSec; + return(true); + } + + const char * LoopCheck::refDateTime() + { + return(dateTimeStr); + } + + unsigned long LoopCheck::locMicros() + { +#ifdef smnSimLinux + struct timespec clockTime; + unsigned long retv; + + clock_gettime(CLOCK_MONOTONIC, &clockTime); + retv = clockTime.tv_nsec / 1000; + return(retv); +#endif + +#ifdef smnSimWindows + LARGE_INTEGER countValue, frequency, result; + + QueryPerformanceCounter(&countValue); + QueryPerformanceFrequency(&frequency); + + result.QuadPart = (countValue.QuadPart * 1000000) / frequency.QuadPart; + return((unsigned long) result.QuadPart); +#endif + +#ifdef smnSloeber + return(micros()); +#endif + } + +#ifdef smnESP8266 + div_t LoopCheck::locDiv(int numer, int denom) + { + div_t retv; + + retv.quot = numer / denom; + retv.rem = numer % denom; + + return(retv); + } +#endif + + void LoopCheck::startTimeMeasure() + { + measureTimeSet = SYSMICSEC; + } + + unsigned long LoopCheck::getTimeMeasure() + { + return(SYSMICSEC - measureTimeSet); + } + + unsigned long LoopCheck::getRuntime() + { + return(measureRuntime); + } + + void LoopCheck::hexAsc(char * dest, byte val) + { + char cv; + + cv = val >> 4; + if(cv < 10) + cv += 0x30; + else + cv += 0x37; + dest[0] = cv; + + cv = val & 0x0F; + if(cv < 10) + cv += 0x30; + else + cv += 0x37; + dest[1] = cv; + + dest[2] = '\0'; + } + + + // ------------------------------------------------------------------------- + // Debug-Funktionen + // ------------------------------------------------------------------------- + // +#ifdef smnLoopCheckDebug + + void LoopCheck::dbgGetStatistics(char *buffer, int idxItem) + { + switch(idxItem) + { + case 0: + sprintf(buffer,"lT=%d, lMaxT=%d, lMinT=%d, lAvgT=%d", + loopMicros,loopMaxMicros,loopMinMicros,loopAvgMicros); + break; + + case 1: + sprintf(buffer,"bT=%d, bMaxT=%d, bMinT=%d, bAvgT=%d", + backgroundMicros,backgroundMaxMicros,backgroundMinMicros,backgroundAvgMicros); + break; + + case 2: + sprintf(buffer,"rtAlCnt=%d, lCnt=%d, Scr=%d,%d,%d,%d,%d,%d", + periodFailCount, loopCounter, loopScreening[0],loopScreening[1],loopScreening[2],loopScreening[3],loopScreening[4],loopScreening[5]); + break; + } + } + +#endif diff --git a/sketches/_PIO_Sketches/Karger/SoaapBleMaster_Test_2/src/LoopCheck/LoopCheck.h b/sketches/_PIO_Sketches/Karger/SoaapBleMaster_Test_2/src/LoopCheck/LoopCheck.h new file mode 100644 index 0000000000000000000000000000000000000000..9588f3e56dc3ebe52890b772533793e533aad05d --- /dev/null +++ b/sketches/_PIO_Sketches/Karger/SoaapBleMaster_Test_2/src/LoopCheck/LoopCheck.h @@ -0,0 +1,343 @@ +//----------------------------------------------------------------------------- +// Thema: Social Manufacturing Network / Development Environment +// Datei: LoopCheck.h +// Editor: Robert Patzke +// URI/URL: www.mfp-portal.de +//----------------------------------------------------------------------------- +// Lizenz: CC-BY-SA (siehe Wikipedia: Creative Commons) +// +#ifndef _LoopCheck_h +#define _LoopCheck_h +//----------------------------------------------------------------------------- + +#define PeriodMinTime 5000 +// Wenn der Aufrufzyklus der Loop diese Zeit (in Mikrosekunden) überschreitet, +// dann wird ein Alarmbit gesetzt und ein Alarmzähler inkrementiert + +#ifndef LoopScreeningGrades + #define LoopScreeningGrades 6 +#endif + +#define NrOfTimerTasks 10 + +#define lcTimer0 0 +#define lcTimer1 1 +#define lcTimer2 2 +#define lcTimer3 3 +#define lcTimer4 4 +#define lcTimer5 5 +#define lcTimer6 6 +#define lcTimer7 7 +#define lcTimer8 8 +#define lcTimer9 9 + + +#define NrOfOnceTasks 4 + +#define lcOnce0 0 +#define lcOnce1 1 +#define lcOnce2 2 +#define lcOnce3 3 + +#define NrOfToggleTasks 4 + +#define lcToggle0 0 +#define lcToggle1 1 +#define lcToggle2 2 +#define lcToggle3 3 + +#define CalcAverageDepth 32 + +#ifdef UseGithubPath + #include "../environment/environment.h" +#else + #include "environment.h" +#endif + +#if defined(smnSimLinux) || defined(smnSimWindows) + #include <stdlib.h> + #include <string.h> + #include <time.h> + #define SYSMICSEC locMicros() +#endif + +#ifdef smnSimWindows +#include <Windows.h> +#endif + +#ifdef smnSloeber + #include "Arduino.h" + #define SYSMICSEC micros() +#endif + +#ifdef smnESP8266 + #define DIV(x,y) locDiv(x,y) +#else + #define DIV(x,y) div(x,y) +#endif + +typedef struct _OpHourMeter +{ + int Years; + int Days; + int Hours; + int Minutes; + int Seconds; + int Milliseconds; +} OpHourMeter; + +typedef struct _lcDateTime +{ + int Year; + int Month; + int Day; + int Hour; + int Minute; + int Second; + int Millisecond; +} lcDateTime; + +typedef struct _LoopStatistics +{ + unsigned int loopTime; // Schleifenzeit in Mikrosekunden + unsigned int loopMaxTime; // Maximale Schleifenzeit + unsigned int loopMinTime; // Minimale Schleifenzeit + unsigned int loopAvgTime; // Mittlere Schleifenzeit + + unsigned int bgTime; // Zeit außerhalb der Schleife + unsigned int bgMaxTime; // Maximale Außenzeit + unsigned int bgMinTime; // Minimale Außenzeit + unsigned int bgAvgTime; // Mittlere Außenzeit + + unsigned int loopPeriod; // Zeit zwischen loop-Aufrufen + unsigned int maxPeriod; // Maximale Aufrufdistanz + unsigned int minPeriod; // Minimale Aufrufdistanz + unsigned int avgPeriod; // Mittlere Aufrufdistanz + + bool periodAlarm; // Aufrufdistanz > PeriodMinTime + unsigned int alarmCount; // Anzahl der Überschreitungen + + unsigned int rtScreening[LoopScreeningGrades]; + // Echtzeitüberwachung (Klassierung der ms Überschreitungen) +} LoopStatistics; + + +// --------------------------------------------------------------------------- +// class LoopCheck +// --------------------------------------------------------------------------- +// +class LoopCheck +{ + // ------------------------------------------------------------------------- + // Klassenspezifische Datentypen + // ------------------------------------------------------------------------- + // + typedef struct _TimerTask + { + bool counterStarted; + bool finished; + bool firstRun; + unsigned long startCount; + unsigned long runCounter; + unsigned long delayCounter; + unsigned long ticks; + unsigned int repCounter; + } TimerTask; + + typedef struct _OnceTask + { + bool finished; + bool firstRun; + unsigned int waitCounter; + unsigned long startCount; + } OnceTask; + +private: + // ------------------------------------------------------------------------- + // Lokale Variablen + // ------------------------------------------------------------------------- + // + unsigned long checkStartMicros; // Zeit des ersten Aufrufs von begin() + + unsigned long backgroundMicros; // Zeit, die außerhalb von loop() + // verstrichen ist (in Mikrosekunden) + unsigned long loopMicros; // Zeit, die innerhalb von loop() + // verstrichen ist (in Mikrosekunden) + unsigned long loopStartMicros; // Loop-Startzeit (us seit CPU-Start) + unsigned long lastClockMicros; + unsigned long lastStartMicros; + unsigned long lastRestMicros; + + unsigned long loopEndMicros; // Loop-Endezeit (us seit CPU-Start) + unsigned long clockCycleMicros; // Abstand zwischen zwei clock ticks + unsigned long mainStartMicros; // Zählerstand bei Programmstart + + unsigned long backgroundMaxMicros; // Maximale Zeit außerhalb loop() + unsigned long backgroundMinMicros; // Minimale Zeit außerhalb loop() + unsigned long backgroundAvgMicros; // Mittlere Zeit außerhal loop() {32} + unsigned long backgroundSumMicros; // Summe für Mittelwertberechnung + + unsigned long loopMaxMicros; // Maximale Zeit innerhalb loop() + unsigned long loopMinMicros; // Minimale Zeit innerhalb loop() + unsigned long loopAvgMicros; // Mittlere Zeit innerhalb loop() + unsigned long loopSumMicros; // Summe für Mittelwertberechnung + + unsigned long loopCounter; // Anzahl der loop()-Durchläufe + + unsigned int loopScreening[LoopScreeningGrades]; + + int calcAvgCounter; // Zähler für die Mittelwertbildung + bool firstLoop; // Spezielle Kennzeichnung erste loop() + bool taskHappened; // Kennzeichnung: Es lief ein LoopTask + + TimerTask timerTaskList[NrOfTimerTasks]; // Steuerung der zyklischen + // Tasks (Timer-Ersatz in loop()) + OnceTask onceTaskList[NrOfOnceTasks]; + bool toggleTaskList[NrOfToggleTasks]; + + int year; // Betriebsstundenzähler gesamt + int day; + int hour; + int min; + int sec; + int msec; + bool toggleMilli; + + int dtYear; // Zeit / Uhr + int dtMonth; + int dtDay; + int dtHour; + int dtMin; + int dtSec; + int dtmSec; + int febLen; + char dateTimeStr[30]; + + unsigned int periodMicros; // Zeit zwischen zwei loop-Aufrufen + unsigned int periodMinMicros; + unsigned int periodMaxMicros; + unsigned int periodAvgMicros; + unsigned int periodSumMicros; + + bool periodFailAlarm; // periodMicros > Millisekunde + unsigned int periodFailCount; // Anzahl der Überschreitungen + + unsigned long measureTimeSet; // Mikrosekunden-Offset Zeitmessung + + unsigned long measureRuntime; // Laufzeit seit Start in Sekunden + +private: + // ------------------------------------------------------------------------- + // Lokale Funktionen + // ------------------------------------------------------------------------- + // + void initTasks(); + void initStatistics(); + void initClock(); + unsigned long locMicros(); +#ifdef smnESP8266 + div_t locDiv(int numer, int denom); +#endif + +public: + // ------------------------------------------------------------------------- + // Konstruktoren und Initialisierungen + // ------------------------------------------------------------------------- + // + LoopCheck(); + + // ------------------------------------------------------------------------- + // Anwenderfunktionen + // ------------------------------------------------------------------------- + // + void begin(); // Diese Funktion muss am Anfang der Schleife aufgerufen + // werden. + + unsigned int done(); // Diese Funktion kann vor dem Aufruf von end() + // genutzt werden und liefert die Laufzeit bis dahin + + void end(); // Diese Funktion muss am Ende der Schleife aufgerufen + // werden. + + bool timerMicro(int taskIdx, unsigned long repeatTime, unsigned int repetitions); + bool timerMicro(int taskIdx, unsigned long repeatTime, unsigned int repetitions, unsigned long delay); + // Diese Funktion muss als Bedingung (if) aufgerufen werden, um den + // nachfolgenden Block {} mit der Wiederholzeit <repeatTime> auszuführen + // Für jede Taskschleife muss ein anderer Index <taskIdx> aus dem Bereich + // 0 <= taskIdx < MaxNrOfLoopTasks angegeben werden. + // Mit <repetitions> wird angegeben, wie oft der Durchlauf überhaupt erfolgt. + // Der Wert 0 gibt an, dass der Task für immer läuft + + bool timerMilli(int taskIdx, unsigned long repeatTime, unsigned int repetitions); + bool timerMilli(int taskIdx, unsigned long repeatTime, unsigned int repetitions, unsigned long delay); + + bool once(int taskIdx); + // Diese Funktion liefert nur einmal den Wert <true> + + bool once(int taskIdx, unsigned int nrOfLoops); + // Diese Funktion liefert nur einmal den Wert <true> + // nach Ablauf von nrOfLoops Aufrufen + + bool onceDelayed(int taskIdx, unsigned long delay); + // Diese Funktion liefert nur einmal den Wert <true> + // nach Ablauf von <delay> Mikrosekunden + + bool toggle(int taskIdx); + // Diese Funktion liefert abwechselnd die Werte <true> oder <false> + + unsigned long timerCycle(int taskIdx); + // Rückgabe des aktuellen Timerablaufes (startet ab 0). + + bool timerCycleMod(int taskIdx, int modulo); + // Liefert alle <modulo> Timerabläufe den Wert <true> + + unsigned long tick(int taskIdx); + // Rückgabe des aktuellen Zählwertes in Mikrosekunden + + unsigned long operationTime(OpHourMeter *opHourMeter); + // Die Zeit ab Start der CPU + + unsigned long getStatistics(LoopStatistics *statistics); + // Statistik über Ablaufzeiten + + void resetStatistics(); + // Rücksetzen der Statistikdaten + + bool setDateTime(const char *dtStr); + // Setzen der Uhr über standardisierten String + + bool setDateTime(lcDateTime dt); + // Setzen der Uhr über lokal definierte Struktur + + bool getDateTime(lcDateTime *dt); + // Abfragen der Uhr über lokal definierte Struktur + + const char * refDateTime(); + // Zeiger auf Datum/Uhrzeit holen + + void startTimeMeasure(); + // Zeitmessung starten + + unsigned long getTimeMeasure(); + // Zeitmesswert holen + + unsigned long getRuntime(); + // Laufzeit in Sekunden + + void hexAsc(char * dest, byte val); + // Umwandlung byte in Hex-ASCII + + // ------------------------------------------------------------------------- + // Debug-Funtionen + // ------------------------------------------------------------------------- + // + +#ifdef smnLoopCheckDebug + void dbgGetStatistics(char *buffer, int idxItem); +#endif + +}; + +//----------------------------------------------------------------------------- +#endif + diff --git a/sketches/_PIO_Sketches/Karger/SoaapBleMaster_Test_2/src/LoopCheck/ReadMe.md b/sketches/_PIO_Sketches/Karger/SoaapBleMaster_Test_2/src/LoopCheck/ReadMe.md new file mode 100644 index 0000000000000000000000000000000000000000..7701d9d3347942f8c88807f2f8342bade47ace46 --- /dev/null +++ b/sketches/_PIO_Sketches/Karger/SoaapBleMaster_Test_2/src/LoopCheck/ReadMe.md @@ -0,0 +1,20 @@ +# Tools for cyclic called procedures +Arduino Sketches are build on two basic functions. +*void setup()* is called once when the CPU is reset and programmers place their initialisation code here. +*void loop()* is called in an endless loop, i.e. a cyclic entered function. +But the cycle time is not determined, it depends on the speed of the CPU and the used resources. +Many examples for Arduino use the function *delay(milliseconds)* to organise a kind of timing. +But this function is really freezing your program for the given number of milliseconds. +Using a real timer is a good solution, but some CPUs have only less timers +and they sometimes are already used for some libraries. + +The tools presented with LoopCheck-library give You the features of (many) timers inside *loop()* +based on the Arduino-function *micros()* which is called with the macro SYSMICSEC, +defined in *LoopCheck.h*. + +You will find, that there is another file included: *environment.h*, which you can find here: +https://github.com/RobertPatzke/homeautomation/blob/developer/libraries/environment/environment.h +*environment.h* defines the IDE you are using, the CPU and specific development boards. +Code is in several parts conditional, depending on the definitions you make in *environment.h*. +You will see, that this library is not fixed to Arduino, it may be used for any environment +where cyclic called functions happen. diff --git a/sketches/_PIO_Sketches/Karger/SoaapBleMaster_Test_2/src/LoopCheck/library.json b/sketches/_PIO_Sketches/Karger/SoaapBleMaster_Test_2/src/LoopCheck/library.json new file mode 100644 index 0000000000000000000000000000000000000000..3af69246689b448266e74521f4ff1d792450456f --- /dev/null +++ b/sketches/_PIO_Sketches/Karger/SoaapBleMaster_Test_2/src/LoopCheck/library.json @@ -0,0 +1,4 @@ +{ + "name": "LoopCheck", + "version": "0.0.0+20220823165932" +} \ No newline at end of file diff --git a/sketches/_PIO_Sketches/Karger/SoaapBleMaster_Test_2/src/MidiNotes/MidiNotes.cpp b/sketches/_PIO_Sketches/Karger/SoaapBleMaster_Test_2/src/MidiNotes/MidiNotes.cpp new file mode 100644 index 0000000000000000000000000000000000000000..ec91464f7411b1f25f33b3b536faf3b8dc1e8dcd --- /dev/null +++ b/sketches/_PIO_Sketches/Karger/SoaapBleMaster_Test_2/src/MidiNotes/MidiNotes.cpp @@ -0,0 +1,405 @@ +//----------------------------------------------------------------------------- +// Thema: Social Manufacturing Network / Development Environment +// Datei: Midi.cpp +// Editor: Robert Patzke +// URI/URL: www.mfp-portal.de +//----------------------------------------------------------------------------- +// Lizenz: CC-BY-SA (wikipedia: Creative Commons) +// Datum: 27. November 2021 +// +// Der Inhalt dieser Datei sind Festlegungen für steuerbare Midi-Controller. +// +// + +#include "MidiNotes.h" + +// ---------------------------------------------------------------------------- +// Initialisierungen +// ---------------------------------------------------------------------------- +// + +void MidiNotes::begin(int inBpm, NoteDiv inRes, int inMidiCycle, IntrfBuf *inCRB) +{ + dword stdNoteMicroTick; + + crb = inCRB; // Zeiger auf Ringpuffer + midiCycle = inMidiCycle; // Zuklus der ZM in Mikrosekunden + bpm = inBpm; // Beats Per Minute (Metronom) + stdNoteMicroTick = 60000000 / bpm; // Viertelnotenlänge in Mikrosekunden + stdNoteCount = stdNoteMicroTick / inMidiCycle; // " in Zyklen der ZM + stdNoteTick = 60000 / bpm; // Viertelnotenlänge in Millisekunden + minNoteTick = stdNoteTick / inRes; // Zu erwartende kürzeste Note (ms) + + typeList[nti0].length = 8 * stdNoteCount; + setNoteType(nti0); + + typeList[nti1].length = 4 * stdNoteCount; + setNoteType(nti1); + + typeList[nti2p].length = 3 * stdNoteCount; + setNoteType(nti2p); + + typeList[nti2].length = 2 * stdNoteCount; + setNoteType(nti2); + + typeList[nti4p].length = stdNoteCount + stdNoteCount / 2; + setNoteType(nti4p); + + // Standard-Note = Viertelnote ( + typeList[nti4].length = stdNoteCount; + setNoteType(nti4); + + typeList[nti8].length = stdNoteCount / 2; + setNoteType(nti8); + + typeList[nti8p].length = stdNoteCount / 2 + stdNoteCount / 4; + setNoteType(nti8p); + + typeList[nti16].length = stdNoteCount / 4; + setNoteType(nti16); + + typeList[nti16p].length = stdNoteCount / 4 + stdNoteCount / 8; + setNoteType(nti16p); + + typeList[nti32].length = stdNoteCount / 8; + setNoteType(nti32); + + typeList[nti32p].length = stdNoteCount / 8 + stdNoteCount / 16; + setNoteType(nti32p); + + typeList[nti64].length = stdNoteCount / 16; + setNoteType(nti64); + + typeList[nti64p].length = stdNoteCount / 16 + stdNoteCount / 32; + setNoteType(nti64p); + + opMode = momIdle; + setChannel(1); + stopRun = false; + stoppedRun = false; + next(smInit); +} + + +// ---------------------------------------------------------------------------- +// Konfiguration +// ---------------------------------------------------------------------------- +// +void MidiNotes::setNoteType(NoteTypeIdx nt) +{ + NoteTypePtr typePtr; + + typePtr = &typeList[nt]; + typePtr->attack = 0; + typePtr->decay = 0; + typePtr->sustain = typePtr->length; + typePtr->release = 0; + typePtr->pause = (typePtr->length * 20) / 100; + + typePtr->deltaAttack = 0; + typePtr->deltaDecay = 0; + typePtr->percentSustain = 70; + typePtr->deltaRelease = 0; +} + + +void MidiNotes::setNoteType(NoteTypeIdx nt, byte pAttL, byte pDecL, byte pSusL, byte pRelL, + byte pPauL, byte dAtt, byte dDec, byte pSusV, byte dRel) +{ + NoteTypePtr typePtr; + + typePtr = &typeList[nt]; + typePtr->attack = (typePtr->length * pAttL) / 100; + typePtr->decay = (typePtr->length * pDecL) / 100; + typePtr->sustain = (typePtr->length * pSusL) / 100; + typePtr->release = (typePtr->length * pRelL) / 100; + typePtr->pause = (typePtr->length * pPauL) / 100; + + typePtr->deltaAttack = dAtt; + typePtr->deltaDecay = dDec; + typePtr->percentSustain = pSusV; + typePtr->deltaRelease = dRel; +} + +int MidiNotes::addChordNote(NoteTypeIdx nti, byte val, byte vel) +{ + NotePtr notePtr; + int i; + + for(i = 0; i < MaxNrNoteSim; i++) + { + notePtr = &chord[i]; + if(notePtr->mode == NoteModeEmpty) + { + notePtr->mode = NoteModeRun; + notePtr->typeIdx = nti; + notePtr->value = val; + notePtr->veloc = vel; + break; + } + } + return(i); +} + +void MidiNotes::setChannel(int chnVal) +{ + if(chnVal < 1) chnVal = 1; + if(chnVal > 16) chnVal = 16; + chn = chnVal - 1; +} + +// ---------------------------------------------------------------------------- +// Betrieb +// ---------------------------------------------------------------------------- +// +void MidiNotes::setOpMode(MidiOpMode mom) +{ + opMode = mom; +} + + +void MidiNotes::setChordNote(int idx, NoteTypeIdx nti, int val, int vel) +{ + if(idx < 0) return; + if(idx >= MaxNrNoteSim) return; + + if(nti >= 0 && nti < ntiNr) + newNote[idx].typeIdx = nti; + + if(val >= 0 && val <= 127) + newNote[idx].value = val; + + if(vel >= 0 && vel <= 127) + newNote[idx].veloc = vel; + + newNote[idx].newVal = true; +} + + +// ---------------------------------------------------------------------------- +// Steuerung, Zustandsmaschine +// ---------------------------------------------------------------------------- +// + +void MidiNotes::stop() +{ + stopRun = true; +} + +void MidiNotes::resume() +{ + stopRun = false; + stoppedRun = false; +} + +void MidiNotes::run() +{ + runCounter++; + if(cycleCnt > 0) cycleCnt--; + + if(nextState != NULL) + (this->*nextState)(); +} + +void MidiNotes::smInit() +{ + next(smIdle); +} + +void MidiNotes::smIdle() +{ + switch(opMode) + { + case momIdle: + break; + + case momSequence: + next(smNoteOn); + break; + + case momRunDelta: + break; + } +} + +void MidiNotes::smNoteOn() +{ + int i, j, tIdx; + bool doAttack; + dword attack, sustain; + + if(stopRun || stoppedRun) // Unterbrechen/Stoppen des Ablaufs + { // vor dem Einschalten einer Note + stoppedRun = true; + return; + } + + if(crb == NULL) // Ohne Ausgabepuffer in Wartezustand + { + next(smIdle); + return; + } + + doAttack = false; // Voreinstellung kein Aufklingen + + // Auslesen der Noten aus dem Akkordspeicher + // + j = 0; + for(i = 0; i < MaxNrNoteSim; i++) + { + notePtr = &chord[i]; + + if(i == 0) // erste Note + { + if(notePtr->mode == NoteModeEmpty) // Wenn die erste Note leer ist + { // dann in den Wartezustand + next(smIdle); + return; + } + noteSeq[j++] = 0x90 | chn; // ansonsten startet die Notenfolge ** + } + else // weitere Noten + { + if(notePtr->mode == NoteModeEmpty) // bei leerer Note Schleife beendet + break; + } + + // Die Noten im Akkordspeicher können durch aktuelle Noten + // ersetzt werden. + + if(newNote[i].newVal) // wenn neue Note vorliegt + { + newNote[i].newVal = false; // neue Note quittieren + notePtr->typeIdx = newNote[i].typeIdx; // und Inhalte im + notePtr->value = newNote[i].value; // Akkordspeicher + notePtr->veloc = newNote[i].veloc; // überschreiben + } + + noteSeq[j++] = notePtr->value; // Notenwert in Sequenz eintragen ** + + // Daten für die Note aus der Typenliste holen + // + tIdx = notePtr->typeIdx; + typePtr = &typeList[tIdx]; + notePtr->cntAttack = typePtr->attack; // Aufklingzeit in Zähler + notePtr->cntDecay = typePtr->decay; // Abklingzeit in Zähler + notePtr->cntSustain = typePtr->sustain; // Klingzeit in Zähler + notePtr->cntRelease = typePtr->release; // Ausklingzeit in Zähler + notePtr->cntPause = typePtr->pause; // Pausenzeit in Zähler + + if(notePtr->cntAttack != 0) // Wenn ein Attack-Wert gegeben ist + { + doAttack = true; // dann attack markieren + attack = // und den Wert auf den erste Schritt setzen + (typePtr->deltaAttack * notePtr->veloc) / 100; + if(attack > 127) attack = 127; + noteSeq[j++] = attack; // Lautstärke in Sequenz eintragen ** + } + else // ohne Attack-Wert geht es hier gleich in Sustain weiter + { + sustain = (typePtr->percentSustain * notePtr->veloc) / 100; + if(sustain > 127) sustain = 127; + noteSeq[j++] = sustain; // Lautstärke in Sequenz eintragen ** + } + } + + crb->putSeq(noteSeq, j); // Sequenz an Puffer übergeben ***** + + if(doAttack) + next(smAttack); + else + next(smSustain); +} + +void MidiNotes::smAttack() +{ + +} + +void MidiNotes::smDecay() +{ + +} + +// TODO +// Es können noch nicht Noten unterschiedlicher Länge in einem Akkord +// verarbeitet werden. Bei mehreren eingetragenen Noten würde die +// kürzeste Note den Ablauf bestimmen. + +void MidiNotes::smSustain() +{ + int i; + bool sustFin; + + sustFin = false; + for(i = 0; i < MaxNrNoteSim; i++) + { + notePtr = &chord[i]; + if(notePtr->mode == NoteModeEmpty) + break; + + if(notePtr->cntSustain > 0) // Die Sustain-Zeit in diesem Zustand verweilen + notePtr->cntSustain--; + else + sustFin = true; + } + + if(sustFin) + next(smNoteOff); +} + +void MidiNotes::smRelease() +{ + +} + +void MidiNotes::smNoteOff() +{ + int i,j; + + j = 0; + for(i = 0; i < MaxNrNoteSim; i++) // Alle Noten im Akkord bearbeiten + { + notePtr = &chord[i]; + if(notePtr->mode == NoteModeEmpty) + break; + + if(i == 0) + { + noteSeq[j++] = 0x80 | chn; // Erste Note bestimmt den Befehl AUS ** + absPause = notePtr->cntPause; + } + + noteSeq[j++] = notePtr->value; //Erste und weitere Noten liefern Liste ** + noteSeq[j++] = 0; + } + + crb->putSeq(noteSeq, j); // Sequenz an Puffer übergeben ***** + + next(smPause); +} + +void MidiNotes::smPause() +{ + if(absPause > 0) + { + absPause--; + return; + } + + next(smNoteOn); +} + +// ---------------------------------------------------------------------------- +// Debugging +// ---------------------------------------------------------------------------- +// + + + + + + + + + diff --git a/sketches/_PIO_Sketches/Karger/SoaapBleMaster_Test_2/src/MidiNotes/MidiNotes.h b/sketches/_PIO_Sketches/Karger/SoaapBleMaster_Test_2/src/MidiNotes/MidiNotes.h new file mode 100644 index 0000000000000000000000000000000000000000..0f09fccd7d1a19c3c9171b0cf96c8320f5ad0b44 --- /dev/null +++ b/sketches/_PIO_Sketches/Karger/SoaapBleMaster_Test_2/src/MidiNotes/MidiNotes.h @@ -0,0 +1,226 @@ +//----------------------------------------------------------------------------- +// Thema: Social Manufacturing Network / Development Environment +// Datei: MidiNotes.h +// Editor: Robert Patzke +// URI/URL: www.mfp-portal.de +//----------------------------------------------------------------------------- +// Lizenz: CC-BY-SA (wikipedia: Creative Commons) +// Datum: 27. November 2021 +// +// Der Inhalt dieser Datei sind Festlegungen für steuerbare Midi-Controller +// + +#ifndef MidiNotes_h +#define MidiNotes_h +// ---------------------------------------------------------------------------- + +#include "arduinoDefs.h" +#include "ComRingBuf.h" + +#define MaxNrNoteSim 4 +#define MaxMidiSeq (2 * MaxNrNoteSim + 1) + +// Definierte Noten +// +#define SchlossC 60 +#define Kammerton 69 + +typedef enum _NoteDiv +{ + nd4 = 1, + nd8 = 2, + nd16 = 4, + nd32 = 8, + nd64 = 16 +} NoteDiv; + +typedef enum _MidiOpMode +{ + momIdle, + momSequence, + momRunDelta +} MidiOpMode; + + +// ---------------------------------------------------------------------------- +// M i d i N o t e s +// ---------------------------------------------------------------------------- +// +class MidiNotes +{ +#define next(x) nextState = &MidiNotes::x + +public: + // ------------------------------------------------------------------------- + // Öffentliche Datentypen + // ------------------------------------------------------------------------- + // + typedef enum _NoteTypeIdx + { + nti0 = 0, + nti1, + nti2p, + nti2, + nti4p, + nti4, + nti8p, + nti8, + nti16p, + nti16, + nti32p, + nti32, + nti64p, + nti64, + ntiNr + } NoteTypeIdx; + + +private: + // ------------------------------------------------------------------------- + // Private Datentypen + // ------------------------------------------------------------------------- + // + typedef void (MidiNotes::*cbVector)(void); + + typedef struct _NoteType + { + dword length; + dword attack; + dword decay; + dword sustain; + dword release; + dword pause; + byte deltaAttack; + byte deltaDecay; + byte percentSustain; + byte deltaRelease; + } NoteType, *NoteTypePtr; + + typedef struct _Note + { + byte mode; + byte typeIdx; + byte value; + byte veloc; + int state; + dword cntAttack; + dword cntDecay; + dword cntSustain; + dword cntRelease; + dword cntPause; + } Note, *NotePtr; + + typedef struct _NewNote + { + bool newVal; + byte typeIdx; + byte value; + byte veloc; + }NewNote; + +#define NoteModeEmpty 0x00 +#define NoteModeRun 0x01 +#define NoteModeDoChange 0x02 + + // -------------------------------------------------------------------------- + // Lokale Daten + // -------------------------------------------------------------------------- + // + IntrfBuf *crb; + cbVector nextState; + + MidiOpMode opMode; + + dword runCounter; + dword cycleCnt; + + dword midiCycle; // Zustandstakt in Mikrosekunden + dword minNoteTick; // minimale Notendauer in Millisekunden + dword bpm; // Beats per Minute (Metronom) + dword stdNoteTick; // Dauer einer Viertelnote in Millisekunden + dword stdNoteCount; // Viertelnote in Zyklen der Zustandsmaschine + + Note chord[MaxNrNoteSim]; // Liste der simultanen Noten (Akkord) + NoteType typeList[ntiNr]; // Liste der Notentypen + byte chn; // Aktueller Kanal + byte noteSeq[MaxMidiSeq]; // Lokaler Telegrammaufbau + + NotePtr notePtr; // Temporäre Notendaten + NoteTypePtr typePtr; // Temporärer Notentyp + + dword absPause; // Pause für den zyklischen Ablauf + NewNote newNote[MaxNrNoteSim]; // Übergabe neuer Noten + + bool stopRun; // Anhalten der Midi-Schleife + bool stoppedRun; // Midi-Schleife angehalten + + + // -------------------------------------------------------------------------- + // Lokale Funktionen + // -------------------------------------------------------------------------- + // + + // Zustandsmaschine + // ----------------------------- + void smInit(); + void smIdle(); + + void smNoteOn(); + void smAttack(); + void smDecay(); + void smSustain(); + void smRelease(); + void smNoteOff(); + void smPause(); + + + // -------------------------------------------------------------------------- + // Inline-Funktionen + // -------------------------------------------------------------------------- + // + +public: + // -------------------------------------------------------------------------- + // Initialisierungen + // -------------------------------------------------------------------------- + void begin(int inBpm, NoteDiv inRes, int inMidiCycle, IntrfBuf *inCRB); + + + // -------------------------------------------------------------------------- + // Konfiguration + // -------------------------------------------------------------------------- + // + void setNoteType(NoteTypeIdx nt); + + void setNoteType(NoteTypeIdx nt, byte pAttL, byte pDecL, byte pSusL, byte pRelL, + byte dAtt, byte dDec, byte pSusV, byte dRel, byte pPauL); + + int addChordNote(NoteTypeIdx nti, byte val, byte vel); + + void setChannel(int chnVal); + + // -------------------------------------------------------------------------- + // Betrieb + // -------------------------------------------------------------------------- + // + void setOpMode(MidiOpMode mom); + void setChordNote(int idx, NoteTypeIdx nti, int val, int vel); + + // -------------------------------------------------------------------------- + // Steuerung, Zustandsmaschine + // -------------------------------------------------------------------------- + // + void run(); + void stop(); + void resume(); + + // -------------------------------------------------------------------------- + // Debugging + // -------------------------------------------------------------------------- + // + +}; + + +// ---------------------------------------------------------------------------- +#endif // MidiNotes_h diff --git a/sketches/_PIO_Sketches/Karger/SoaapBleMaster_Test_2/src/MidiNotes/library.json b/sketches/_PIO_Sketches/Karger/SoaapBleMaster_Test_2/src/MidiNotes/library.json new file mode 100644 index 0000000000000000000000000000000000000000..a95d68926746af5b6e20d30d2a29ea5b513110ad --- /dev/null +++ b/sketches/_PIO_Sketches/Karger/SoaapBleMaster_Test_2/src/MidiNotes/library.json @@ -0,0 +1,4 @@ +{ + "name": "MidiNotes", + "version": "0.0.0+20220823165932" +} \ No newline at end of file diff --git a/sketches/_PIO_Sketches/Karger/SoaapBleMaster_Test_2/src/Monitor/Monitor.cpp b/sketches/_PIO_Sketches/Karger/SoaapBleMaster_Test_2/src/Monitor/Monitor.cpp new file mode 100644 index 0000000000000000000000000000000000000000..9c30d24b20011e8d22623c261a295ccfb42fe1ea --- /dev/null +++ b/sketches/_PIO_Sketches/Karger/SoaapBleMaster_Test_2/src/Monitor/Monitor.cpp @@ -0,0 +1,1165 @@ +//----------------------------------------------------------------------------- +// Thema: Social Manufacturing Network / Development Environment +// Datei: Monitor.cpp +// Editor: Robert Patzke +// URI/URL: www.mfp-portal.de +//----------------------------------------------------------------------------- +// Lizenz: CC-BY-SA (wikipedia: Creative Commons) +// Datum: 15. Mai 2021 +// +// Der Monitor dient zum direkten Zugriff auf die Ressourcen eines +// Mikrocontrollers über die serielle Schnittstelle. +// ACHTUNG! +// Er ist nicht für die Anwendung des "Serial Monitor" aus der Arduino-IDE +// bzw. aus Eclipse/Sloeber gedacht, sondern für ein typisches "Terminal". +// Verwendet wurde bei der Entwicklung unter Linux das GtkTerm. +// + +#include "Monitor.h" + +//----------------------------------------------------------------------------- +// Initialisierungen +//----------------------------------------------------------------------------- + +void Monitor::init(int inMode, int inCpu, LoopCheck *inLcPtr, IntrfTw *inTwPtr) +{ + mode = inMode; + cpu = inCpu; + wrIdx = 0; + rdIdx = 0; + blkOut = false; + blkIn = false; + inIdx = 0; + info = NULL; + readOffsAddr = 0; + doReadReg = false; + extraIn = false; + lcPtr = inLcPtr; + twiPtr = inTwPtr; + nrOfChnChar = '@'; + +#ifdef smnNANOBLE33 + + microTicValPtr = (dword *) 0x40009548; + microTicCapPtr = (dword *) 0x40009048; + +#endif + + nextState = + &Monitor::waitEnter; +} + + +Monitor::Monitor(int inMode, int inCpu) +{ + init(inMode, inCpu, NULL, NULL); +} + +Monitor::Monitor(int inMode, int inCpu, LoopCheck *inLcPtr) +{ + init(inMode, inCpu, inLcPtr, NULL); +} + +Monitor::Monitor(int inMode, int inCpu, LoopCheck *inLcPtr, IntrfTw *inTwiPtr) +{ + init(inMode, inCpu, inLcPtr, inTwiPtr); +} + +//----------------------------------------------------------------------------- +// Konfiguration, Hilfsfunktionen +//----------------------------------------------------------------------------- +// +int Monitor::putBuf(char c) +{ + if(blkIn) return(-1); + + int free = rdIdx - wrIdx - 1; + if(free < 0) free += BufSize; + if(free < 1) return(0); + buffer[wrIdx++] = c; + if(wrIdx == BufSize) + wrIdx = 0; + return(1); +} + +int Monitor::putBuf(char *txt) +{ + if(blkIn) return(-1); + + int free = rdIdx - wrIdx - 1; + int size = strlen(txt); + if(free < 0) free += BufSize; + if(free < size) return(0); + for(int i = 0; i < size; i++) + { + buffer[wrIdx++] = txt[i]; + if(wrIdx == BufSize) + wrIdx = 0; + } + return(size); +} + +char Monitor::getBuf() +{ + int num = wrIdx - rdIdx; + if(num == 0) return('\0'); + char c = buffer[rdIdx++]; + if(rdIdx == BufSize) + rdIdx = 0; + return(c); +} + +void Monitor::clrBuf() +{ + wrIdx = 0; + rdIdx = 0; +} + +void Monitor::sendConfig() +{ + int nrChn = nrOfChnChar & 0x3F; + int bufIdx = 0; + CfgMeasChnPtr cfgPtr; + + // Visualisierungskanäle (Anzahl) anfordern + outChar[bufIdx++] = '&'; + outChar[bufIdx++] = '@'; // Kanalnummer + outChar[bufIdx++] = '@'; // Typ + outChar[bufIdx++] = nrOfChnChar; + outChar[bufIdx++] = '$'; + + for(int i = 0; i < nrChn; i++) + { + cfgPtr = &cfgChnArr[i]; + outChar[bufIdx++] = '&'; + outChar[bufIdx++] = (i+1) | 0x40; + outChar[bufIdx++] = cfgPtr->type; + hexWord(&outChar[bufIdx], cfgPtr->maxVal); + bufIdx += 4; + hexWord(&outChar[bufIdx], cfgPtr->minVal); + bufIdx += 4; + if(cfgPtr->name != NULL) + { + bufIdx += cpyStr(&outChar[bufIdx], cfgPtr->name); + } + outChar[bufIdx++] = '$'; + } + outChar[bufIdx] = '\0'; + out(outChar); +} + +//----------------------------------------------------------------------------- +// Lokale Abläufe +//----------------------------------------------------------------------------- +// + +volatile dword calcTest1, calcTest2, calcTest3; + +void Monitor::waitEnter() +{ + char c; + + busy = false; + + if(!keyHit()) return; + c = keyIn(); + if(c != '\r' && c != '\n') + { + lastKeyIn = c; + return; + } + + busy = true; + + blkIn = true; + blkOut = true; + GoPrm +} + +void doSomeCode() +{ + for(int i = 0; i < 500; i++) + { + calcTest1++; + calcTest1++; + calcTest1++; + calcTest1++; + calcTest1++; + calcTest1++; + calcTest1++; + calcTest1++; + calcTest1++; + calcTest1++; + calcTest1++; + calcTest1++; + calcTest1++; + calcTest1++; + calcTest1++; + calcTest1++; + calcTest1++; + calcTest1++; + calcTest1++; + calcTest1++; + } +} + +volatile dword micTime; + +void Monitor::getKey() +{ + char cin,c1,c0; + + if(!keyHit()) return; + cin = keyIn(); + if(mode & modeEcho) + out(cin); + + c0 = c1 = '\0'; + + if(inIdx == 0) + c0 = cin; + else if(inIdx == 1) + { + c0 = inChar[0]; + c1 = cin; + } + else if(inIdx == 2) + { + c0 = inChar[0]; + c1 = inChar[1]; + } + + switch(c0) + { + case '\r': + out("\r\n"); + blkIn = false; + blkOut = false; + GoWt + break; + + case 'c': + case 'C': + if(inIdx == 0) + { + inChar[inIdx] = cin; + inIdx++; + } + else if(inIdx == 1) + { + + if(cin >= '0' && cin <= '9') + { + inIdx = 0; + out('='); + int cIdx = cin - 0x30; + if(cFlag[cIdx]) + { + cFlag[cIdx] = false; + out('0'); + } + else + { + cFlag[cIdx] = true; + out('1'); + } + GoPrm + } + + else if(cin == 'f' || cin == 'F') + { + inChar[inIdx] = cin; + inIdx++; + } + } + + else if(inIdx == 2) + { + inIdx = 0; + if(cin == 'g' || cin == 'G') + { + sendConfig(); + GoPrm + } + } + else + GoPrm + break; + + case 'i': + case 'I': + if(inIdx == 0) + { + inChar[inIdx] = cin; + inIdx++; + } + else if(inIdx == 1) + { + inIdx = 0; + out(' '); + if(cin == 'a' || cin == 'A') + nextState = &Monitor::getTwiAdr; + else if(cin == 'l' || cin == 'L') + nextState = &Monitor::readTwiList; + else if(cin == 'r' || cin == 'R') + nextState = &Monitor::readTwiByte; + else if(cin == 'w' || cin == 'W') + nextState = &Monitor::writeTwiByte; + } + break; + + case 'r': + case 'R': + if(inIdx == 0) + { + inChar[inIdx] = cin; + inIdx++; + } + else if(inIdx == 1) + { + inIdx = 0; + out(' '); + if(cin == 'o' || cin == 'O') + nextState = &Monitor::getRdOffsAdr; + else if(cin == 'r' || cin == 'R') + nextState = &Monitor::readRegVal; + } + break; + + // ------------------------------------------------------------------------ + case 't': // Zeitmessungen + case 'T': // + // ------------------------------------------------------------------------ + if(inIdx == 0) + { + inChar[inIdx] = cin; + inIdx++; + } + else if(inIdx == 1) + { + inIdx = 0; + nextState = &Monitor::getTiming; + if(cin == 'l' || cin == 'L') + { + cmdMode1 = 'L'; + } + else if(cin == 'b' || cin == 'B') + { + cmdMode1 = 'B'; + } + else if(cin == 'c' || cin == 'C') + { + cmdMode1 = 'C'; + } +#ifdef smnNANOBLE33 + else if(cin == 'p' || cin == 'P') + { + micTime = micsecs(); + doSomeCode(); + micTime = (micsecs() - micTime - 11) / 10; + out(' '); + out(micTime); + GoPrm + } +#endif + else if(cin == 'r' || cin == 'R') + { + if(lcPtr != NULL) + { + lcPtr->resetStatistics(); + out(' '); + } + GoPrm + } + else if(cin == 't' || cin == 'T') + { + dword micTime = micros(); + calcTest2 = micros(); + calcTest2 = micros(); + calcTest2 = micros(); + calcTest2 = micros(); + calcTest2 = micros(); + calcTest2 = micros(); + calcTest2 = micros(); + calcTest2 = micros(); + calcTest2 = micros(); + calcTest2 = micros(); + calcTest2 = micros(); + calcTest2 = micros(); + calcTest2 = micros(); + calcTest2 = micros(); + calcTest2 = micros(); + calcTest2 = micros(); + calcTest2 = micros(); + calcTest2 = micros(); + calcTest2 = micros(); + micTime = (micros() - micTime) / 20; + out(' '); + out(micTime); + GoPrm + } + else + { + GoPrm + } + } + break; + + case 'V': + case 'v': + out(' '); + nextState = &Monitor::version; + break; + + } +} + +void Monitor::prompt() +{ + if(mode & modeNl) + out('\n'); + + out("\rM>"); + GoInp +} + +void Monitor::version() +{ + out("Monitor: Version 0.1, May 16, 2021"); + GoPrm +} + +void Monitor::getRdOffsAdr() +{ + char cin; + dword val; + int valIdx; + + if(!keyHit()) return; + cin = keyIn(); + readOffsAddr = 0; + + if(cin != '\r') + { + if(cin >= '0' && cin <= '9') + inChar[inIdx] = cin - 0x30; + else if(cin >= 'A' && cin <= 'F') + inChar[inIdx] = cin - 0x37; + else if(cin >= 'a' && cin <= 'f') + inChar[inIdx] = cin - 0x57; + else + return; + + out(cin); + if(inIdx < 16) + inIdx++; + else + out((char) 0x08); + } + else + { + valIdx = 0; + inIdx--; + while(inIdx >= 0) + { + val = inChar[inIdx]; + readOffsAddr |= val << valIdx * 4; + inIdx--; + valIdx++; + } + + // TEST + //out(" = "); + //out(readOffsAddr); + inIdx = 0; + GoPrm + } +} + +void Monitor::readRegVal() +{ + char cin; + dword val,adr; + int valIdx; + + dword *regPtr; + + if(!keyHit()) return; + cin = keyIn(); + adr = 0; + + if(cin != '\r') + { + if(cin >= '0' && cin <= '9') + inChar[inIdx] = cin - 0x30; + else if(cin >= 'A' && cin <= 'F') + inChar[inIdx] = cin - 0x37; + else if(cin >= 'a' && cin <= 'f') + inChar[inIdx] = cin - 0x57; + else + return; + + out(cin); + if(inIdx < 16) + inIdx++; + else + out((char) 0x08); + } + else + { + valIdx = 0; + inIdx--; + while(inIdx >= 0) + { + val = inChar[inIdx]; + adr |= val << valIdx * 4; + inIdx--; + valIdx++; + } + + regPtr = (dword *) (readOffsAddr + adr); + val = *regPtr; + + out(": "); + hexDword(outChar, val); + out(outChar); + inIdx = 0; + GoPrm + } +} + +void Monitor::getTiming() +{ + LoopStatistics lStat; + unsigned int maxVal; + unsigned int minVal; + unsigned int avgVal; + char cin; + + if(lcPtr == NULL) + { + outl("Kein LoopCheck."); + GoPrm + return; + } + + if(!keyHit()) return; + cin = keyIn(); + if(mode & modeEcho) + out(cin); + + if(cin == 'r' || cin == 'R') + { + out(' '); + lcPtr->getStatistics(&lStat); + if(cmdMode1 == 'L') + { + maxVal = lStat.loopMaxTime; + minVal = lStat.loopMinTime; + avgVal = lStat.loopAvgTime; + } + else if(cmdMode1 == 'B') + { + maxVal = lStat.bgMaxTime; + minVal = lStat.bgMinTime; + avgVal = lStat.bgAvgTime; + } + else if(cmdMode1 == 'C') + { + maxVal = lStat.maxPeriod; + minVal = lStat.minPeriod; + avgVal = lStat.avgPeriod; + } + else + { + maxVal = 0; + minVal = 0; + avgVal = 0; + } + + out(maxVal); out("/"); out(minVal); out("/"); out(avgVal); out("\r"); + GoPrm + } + else if(cin == 'm' || cin == 'M') + { + lcPtr->resetStatistics(); + lcPtr->startTimeMeasure(); + nextState = &Monitor::getLoopMeasure; + } + +} + +void Monitor::getLoopMeasure() +{ + LoopStatistics lStat; + unsigned int maxVal; + unsigned int minVal; + unsigned int avgVal; + + if(lcPtr->getTimeMeasure() < 1000000) + return; + + out(' '); + lcPtr->getStatistics(&lStat); + if(cmdMode1 == 'L') + { + maxVal = lStat.loopMaxTime; + minVal = lStat.loopMinTime; + avgVal = lStat.loopAvgTime; + } + else if(cmdMode1 == 'B') + { + maxVal = lStat.bgMaxTime; + minVal = lStat.bgMinTime; + avgVal = lStat.bgAvgTime; + } + else if(cmdMode1 == 'C') + { + maxVal = lStat.maxPeriod; + minVal = lStat.minPeriod; + avgVal = lStat.avgPeriod; + } + else + { + maxVal = 0; + minVal = 0; + avgVal = 0; + } + + out(maxVal); out("/"); out(minVal); out("/"); out(avgVal); out("\r"); + GoPrm +} + + +void Monitor::getTwiAdr() +{ + char cin; + + if(!keyHit()) return; + cin = keyIn(); + twiAdr = 0; + + if(cin != '\r') + { + if(cin >= '0' && cin <= '9') + inChar[inIdx] = cin - 0x30; + else if(cin >= 'A' && cin <= 'F') + inChar[inIdx] = cin - 0x37; + else if(cin >= 'a' && cin <= 'f') + inChar[inIdx] = cin - 0x57; + else + return; + + out(cin); + if(inIdx < 2) + inIdx++; + else + out((char) 0x08); + } + else + { + twiAdr = (inChar[0] << 4) | inChar[1]; + + out(" = "); + out(twiAdr); + + inIdx = 0; + GoPrm + } +} + +void Monitor::readTwiList() +{ + char cin; + int reg; + int anz; + + char tmpOut[3]; + + TwiStatus twiStatus; + + if(twiPtr == NULL) + { + out("no Twi"); + inIdx = 0; + GoPrm + } + + if(!keyHit()) return; + cin = keyIn(); + + if(cin != '\r') + { + if(cin >= '0' && cin <= '9') + inChar[inIdx] = cin - 0x30; + else if(cin >= 'A' && cin <= 'F') + inChar[inIdx] = cin - 0x37; + else if(cin >= 'a' && cin <= 'f') + inChar[inIdx] = cin - 0x57; + else + return; + + out(cin); + if(inIdx == 1) + out(" "); + + if(inIdx < 4) + inIdx++; + else + out((char) 0x08); + } + else + { + reg = (inChar[0] << 4) | inChar[1]; + anz = (inChar[2] << 4) | inChar[3]; + + twiByteSeq.len = anz; + twiByteSeq.valueRef = byteArray; + + twiStatus = twiPtr->readByteRegSeq(twiAdr, reg, &twiByteSeq); + + out(" ["); + out((int) twiStatus); + out("] "); + + if((int) twiStatus == 128) + { + for(int i = 0; i < anz; i++) + { + hexByte(tmpOut, byteArray[i]); + out(tmpOut); + if(i != (anz-1)) out(':'); + } + } + + inIdx = 0; + GoPrm + } +} + +void Monitor::readTwiByte() +{ + char cin; + int reg; + byte val; + + if(twiPtr == NULL) + { + out("no Twi"); + inIdx = 0; + GoPrm + } + + if(!keyHit()) return; + cin = keyIn(); + + if(cin != '\r') + { + if(cin >= '0' && cin <= '9') + inChar[inIdx] = cin - 0x30; + else if(cin >= 'A' && cin <= 'F') + inChar[inIdx] = cin - 0x37; + else if(cin >= 'a' && cin <= 'f') + inChar[inIdx] = cin - 0x57; + else + return; + + out(cin); + if(inIdx < 2) + inIdx++; + else + out((char) 0x08); + } + else + { + reg = (inChar[0] << 4) | inChar[1]; + + val = twiPtr->readByteReg(twiAdr, reg); + + out(" = "); + binByte(outChar, val); + out(outChar); + + inIdx = 0; + GoPrm + } +} + +void Monitor::writeTwiByte() +{ + char cin; + int reg; + int val; + + TwiStatus twiStatus; + + if(twiPtr == NULL) + { + out("no Twi"); + inIdx = 0; + GoPrm + } + + if(!keyHit()) return; + cin = keyIn(); + + if(cin != '\r') + { + if(cin >= '0' && cin <= '9') + inChar[inIdx] = cin - 0x30; + else if(cin >= 'A' && cin <= 'F') + inChar[inIdx] = cin - 0x37; + else if(cin >= 'a' && cin <= 'f') + inChar[inIdx] = cin - 0x57; + else + return; + + out(cin); + if(inIdx == 1) + out(" "); + + if(inIdx < 4) + inIdx++; + else + out((char) 0x08); + } + else + { + reg = (inChar[0] << 4) | inChar[1]; + val = (inChar[2] << 4) | inChar[3]; + + twiStatus = twiPtr->writeByteReg(twiAdr, reg, val); + + out(" : "); + out((int) twiStatus); + + inIdx = 0; + GoPrm + } +} + +//----------------------------------------------------------------------------- +// Lokale Schnittstelle +//----------------------------------------------------------------------------- +// +void Monitor::print(char c, int eol) +{ + putBuf(c); + if(eol & eolCR) + putBuf('\r'); + if(eol & eolLF) + putBuf('\n'); +} + +void Monitor::print(char *txt, int eol) +{ + if(txt != NULL) + putBuf(txt); + if(eol & eolCR) + putBuf('\r'); + if(eol & eolLF) + putBuf('\n'); +} + +void Monitor::print(byte *hex, int nr, char fill, int eol) +{ + if(hex == NULL) return; + + for(int i = 0; i < nr; i++) + { + hexByte(tmpChar,hex[i]); + tmpChar[2] = fill; + tmpChar[3] = '\0'; + putBuf(tmpChar); + } + + if(eol & eolCR) + putBuf('\r'); + if(eol & eolLF) + putBuf('\n'); +} + +void Monitor::print(unsigned int iVal, int eol) +{ + char iBuf[16]; + + itoa(iVal, iBuf, 10); + putBuf(iBuf); + if(eol & eolCR) + putBuf('\r'); + if(eol & eolLF) + putBuf('\n'); +} + +void Monitor::prints(int iVal, int eol) +{ + char iBuf[16]; + + itoa(iVal, iBuf, 10); + putBuf(iBuf); + if(eol & eolCR) + putBuf('\r'); + if(eol & eolLF) + putBuf('\n'); +} + +//----------------------------------------------------------------------------- +// Datenaufbereitung +//----------------------------------------------------------------------------- +// +void Monitor::hexByte(char * dest, byte val) +{ + char cv; + + cv = val >> 4; + if(cv < 10) + cv += 0x30; + else + cv += 0x37; + dest[0] = cv; + + cv = val & 0x0F; + if(cv < 10) + cv += 0x30; + else + cv += 0x37; + dest[1] = cv; + + dest[2] = '\0'; +} + +void Monitor::binByte(char * dest, byte val) +{ + byte mask; + + mask = 0x80; + + for(int i = 0; i < 8; i++) + { + if((val & mask) != 0) + dest[i] = '1'; + else + dest[i] = '0'; + mask >>= 1; + } + + dest[8] = '\0'; +} + +int Monitor::cpyStr(char *dest, char *src) +{ + int i = 0; + + while((dest[i] = src[i]) != '\0') i++; + return(i); +} + +void Monitor::binDword(char *dest, dword dwVal) +{ + int idx = 0; + byte bVal; + + bVal = dwVal >> 24; + binByte(&dest[idx], bVal); + idx += 8; + dest[idx++] = ' '; + + bVal = dwVal >> 16; + binByte(&dest[idx], bVal); + idx += 8; + dest[idx++] = ' '; + + bVal = dwVal >> 8; + binByte(&dest[idx], bVal); + idx += 8; + dest[idx++] = ' '; + + bVal = dwVal; + binByte(&dest[idx], bVal); + idx += 8; + + dest[idx] = '\0'; +} + +void Monitor::hexDword(char *dest, dword dwVal) +{ + int idx = 0; + byte bVal; + + bVal = dwVal >> 24; + hexByte(&dest[idx], bVal); + idx += 2; + + bVal = dwVal >> 16; + hexByte(&dest[idx], bVal); + idx += 2; + + bVal = dwVal >> 8; + hexByte(&dest[idx], bVal); + idx += 2; + + bVal = dwVal; + hexByte(&dest[idx], bVal); + idx += 2; + + dest[idx] = '\0'; +} + +void Monitor::binWord(char *dest, word wVal) +{ + int idx = 0; + byte bVal; + + bVal = wVal >> 8; + binByte(&dest[idx], bVal); + idx += 8; + dest[idx++] = ' '; + + bVal = wVal; + binByte(&dest[idx], bVal); + idx += 8; + + dest[idx] = '\0'; +} + +void Monitor::hexWord(char *dest, word wVal) +{ + int idx = 0; + byte bVal; + + bVal = wVal >> 8; + hexByte(&dest[idx], bVal); + idx += 2; + + bVal = wVal; + hexByte(&dest[idx], bVal); + idx += 2; + + dest[idx] = '\0'; +} + + + +//----------------------------------------------------------------------------- +// Anwenderschnittstelle +//----------------------------------------------------------------------------- +// + +void Monitor::run() +{ + char c; + + if(!blkOut) + { + c = getBuf(); + if(c != '\0') + smnSerial.print(c); + } + (this->*nextState)(); +} + +void Monitor::cprint(char c) +{ + print(c, 0); +} + +void Monitor::cprintln(char c) +{ + print(c, eolCR | eolLF); +} + +void Monitor::cprintcr(char c) +{ + print(c, eolCR); +} + +void Monitor::print(char *txt) +{ + print(txt, 0); +} + +void Monitor::println(char *txt) +{ + print(txt, eolCR | eolLF); +} + +void Monitor::println() +{ + print((char *) NULL, eolCR | eolLF); +} + +void Monitor::printcr(char *txt) +{ + print(txt, eolCR); +} + +void Monitor::printcr() +{ + print((char *) NULL, eolCR); +} + +void Monitor::print(unsigned int iVal) +{ + print(iVal, 0); +} + +void Monitor::prints(int iVal) +{ + prints(iVal, 0); +} + +void Monitor::println(unsigned int iVal) +{ + print(iVal, eolCR | eolLF); +} + +void Monitor::printcr(unsigned int iVal) +{ + print(iVal, eolCR); +} + +void Monitor::print(byte *iVal, int nr, char fill) +{ + print(iVal, nr, fill, 0); +} + +void Monitor::printcr(byte *iVal, int nr, char fill) +{ + print(iVal, nr, fill, eolCR); +} + +void Monitor::println(byte *iVal, int nr, char fill) +{ + print(iVal, nr, fill, eolCR | eolLF); +} + +void Monitor::setInfo(char *txt) +{ + info = txt; +} + +void Monitor::config(int inNrOfChn) +{ + if(inNrOfChn < 0) return; + + if(inNrOfChn > MaxChn) + inNrOfChn = MaxChn; + + nrOfChnChar = inNrOfChn | 0x40; +} + +void Monitor::config(int inChn, char inType, word inMax, word inMin, char *inName) +{ + if(inChn < 1) return; + + if(inChn > MaxChn) + inChn = MaxChn; + + CfgMeasChnPtr chnPtr = &cfgChnArr[inChn-1]; + chnPtr->maxVal = inMax; + chnPtr->minVal = inMin; + chnPtr->name = inName; + chnPtr->type = inType; +} + + diff --git a/sketches/_PIO_Sketches/Karger/SoaapBleMaster_Test_2/src/Monitor/Monitor.h b/sketches/_PIO_Sketches/Karger/SoaapBleMaster_Test_2/src/Monitor/Monitor.h new file mode 100644 index 0000000000000000000000000000000000000000..1ee2bb11830c716703e5489655355c93a039d131 --- /dev/null +++ b/sketches/_PIO_Sketches/Karger/SoaapBleMaster_Test_2/src/Monitor/Monitor.h @@ -0,0 +1,211 @@ +//----------------------------------------------------------------------------- +// Thema: Social Manufacturing Network / Development Environment +// Datei: Monitor.h +// Editor: Robert Patzke +// URI/URL: www.mfp-portal.de +//----------------------------------------------------------------------------- +// Lizenz: CC-BY-SA (wikipedia: Creative Commons) +// Datum: 15. Mai 2021 +// +// Der Monitor dient zum direkten Zugriff auf die Ressourcen eines +// Mikrocontrollers über die serielle Schnittstelle. +// + +#include "Arduino.h" +#include "environment.h" +#include "arduinoDefs.h" +#include "LoopCheck.h" +#include "IntrfTw.h" + +#ifndef Monitor_h +#define Monitor_h +// ---------------------------------------------------------------------------- + +#define keyHit() smnSerial.available() +#define keyIn() smnSerial.read() +#define out(x) smnSerial.print(x) +#define outl(x) smnSerial.println(x) +#define GoInp nextState = &Monitor::getKey; +#define GoPrm nextState = &Monitor::prompt; +#define GoWt nextState = &Monitor::waitEnter; + +#define modeEcho 0x01 +#define modeNl 0x02 + +#define eolCR 0x01 +#define eolLF 0x02 +#define eolNL 0x03 + +#define BufSize 512 +#define MaxChn 32 + +class Monitor +{ + // ------------------------------------------------------------------------- + // class specific data types + // ------------------------------------------------------------------------- + // + typedef void (Monitor::*StatePtr)(void); + typedef struct _ConfMeasChannel + { + word maxVal; + word minVal; + char *name; + char type; + } CfgMeasChn, *CfgMeasChnPtr; + +private: + // -------------------------------------------------------------------------- + // Lokale Daten + // -------------------------------------------------------------------------- + // + int cpu; + int mode; + +#ifdef smnNANOBLE33 + dword *microTicValPtr; + dword *microTicCapPtr; +#endif + + char buffer[BufSize]; + int wrIdx; + int rdIdx; + bool blkOut; + bool blkIn; + + char inChar[16]; + char outChar[128]; + char tmpChar[8]; + int inIdx; + bool extraIn; + + char cmdMode1; + char cmdMode2; + + char *info; + + StatePtr nextState; + LoopCheck *lcPtr; + + IntrfTw *twiPtr; + int twiAdr; + TwiByteSeq twiByteSeq; + byte byteArray[32]; + + dword readOffsAddr; + bool doReadReg; + + CfgMeasChn cfgChnArr[MaxChn]; + char nrOfChnChar; + + // -------------------------------------------------------------------------- + // Lokale Funktionen + // -------------------------------------------------------------------------- + // + void init(int mode, int cpu); + void init(int mode, int cpu, LoopCheck *inLcPtr); + void init(int mode, int cpu, LoopCheck *inLcPtr, IntrfTw *inTwPtr); + + void waitEnter(); + void prompt(); + void getKey(); + void version(); + void getRdOffsAdr(); + void readRegVal(); + void getTiming(); + void getLoopMeasure(); + + void getTwiAdr(); + void readTwiList(); + void readTwiByte(); + void writeTwiByte(); + + void print(char c, int eol); + void print(char *txt, int eol); + void print(byte *hex, int nr, char fill, int eol); + void print(unsigned int iVal, int eol); + void prints(int iVal, int eol); + +#ifdef smnNANOBLE33 + + dword micsecs() + { + *microTicCapPtr = 1; + return(*microTicValPtr); + } + +#endif + + // -------------------------------------------------------------------------- + // Datenaufbereitung + // -------------------------------------------------------------------------- + // + void hexByte(char *dest, byte val); + void binByte(char *dest, byte val); + void hexWord(char *dest, word val); + void binWord(char *dest, word val); + void hexDword(char *dest, dword val); + void binDword(char *dest, dword val); + int cpyStr(char *dest, char *src); + +public: + // -------------------------------------------------------------------------- + // Initialisierungen + // -------------------------------------------------------------------------- + + Monitor(int mode, int cpu); + Monitor(int mode, int cpu, LoopCheck *inLcPtr); + Monitor(int mode, int cpu, LoopCheck *inLcPtr, IntrfTw *inTwiPtr); + + // -------------------------------------------------------------------------- + // Konfiguration und Hilfsfunktionen + // -------------------------------------------------------------------------- + // + void setInfo(char *txt); + int putBuf(char c); + int putBuf(char *txt); + char getBuf(); + void clrBuf(); + void sendConfig(); + + + // -------------------------------------------------------------------------- + // Anwenderschnittstelle + // -------------------------------------------------------------------------- + // + + // Funktionen + // + void run(); + void cprint(char c); + void print(char *txt); + void print(unsigned int iVal); + void prints(int iVal); + void print(byte *iVal, int nr, char fill); + void printcr(); + void cprintcr(char c); + void printcr(char *txt); + void printcr(unsigned int iVal); + void printcr(byte *iVal, int nr, char fill); + void println(); + void cprintln(char c); + void println(char *txt); + void println(unsigned int iVal); + void println(byte *iVal, int nr, char fill); + + void config(int inNrOfChn); + void config(int inChn, char inType, word inMax, word inMin, char *inName); + + + // Zustände (Variablen) + // + bool busy; + char lastKeyIn; + + // Steuerbits (Kommandobits) + // + bool cFlag[10]; + }; + +// ---------------------------------------------------------------------------- +#endif // Monitor_h diff --git a/sketches/_PIO_Sketches/Karger/SoaapBleMaster_Test_2/src/Monitor/library.json b/sketches/_PIO_Sketches/Karger/SoaapBleMaster_Test_2/src/Monitor/library.json new file mode 100644 index 0000000000000000000000000000000000000000..a9b281138760d16aa71d51ecec1518e22188a30f --- /dev/null +++ b/sketches/_PIO_Sketches/Karger/SoaapBleMaster_Test_2/src/Monitor/library.json @@ -0,0 +1,4 @@ +{ + "name": "Monitor", + "version": "0.0.0+20220823165932" +} \ No newline at end of file diff --git a/sketches/_PIO_Sketches/Karger/SoaapBleMaster_Test_2/src/SensorLSM9DS1/SensorLSM9DS1.cpp b/sketches/_PIO_Sketches/Karger/SoaapBleMaster_Test_2/src/SensorLSM9DS1/SensorLSM9DS1.cpp new file mode 100644 index 0000000000000000000000000000000000000000..5a57198a5bb3b3c340ffa5a725f7f7c009725d9a --- /dev/null +++ b/sketches/_PIO_Sketches/Karger/SoaapBleMaster_Test_2/src/SensorLSM9DS1/SensorLSM9DS1.cpp @@ -0,0 +1,875 @@ +//----------------------------------------------------------------------------- +// Thema: Social Manufacturing Network / Development Environment +// Datei: SensorLSM9DS1.cpp +// Editor: Robert Patzke +// URI/URL: www.mfp-portal.de +//----------------------------------------------------------------------------- +// Lizenz: CC-BY-SA (wikipedia: Creative Commons) +// + +#include "SensorLSM9DS1.h" +#include <string.h> + +// ---------------------------------------------------------------------------- +// Initialisierungen +// ---------------------------------------------------------------------------- + +SensorLSM9DS1::SensorLSM9DS1(IntrfTw *refI2C, int inRunCycle) +{ + TwiParams twiParams; + + twPtr = refI2C; + runState = rsInit; + twiByteSeq.len = 12; + twiByteSeq.valueRef = byteArray; + runCycle = inRunCycle; + + fullScaleA = 4; + fullScaleG = 2000; + fullScaleM = 4; + + newValueAG = false; + newValueM = false; + + avgSetAG = 0; + avgCntAG = 0; + avgSetM = 0; + avgCntM = 0; + + errorCntAdrNakAG = 0; + errorCntDataNakAG = 0; + errorCntOverAG = 0; + + errorCntAdrNakM = 0; + errorCntDataNakM = 0; + errorCntOverM = 0; + + timeOutTwiStatus = 0; + timeOutTwiDataAG = 0; + timeOutTwiDataM = 0; + + timeOutStatusAG = 0; + toValueStatusAG = 0; + timeOutStatusM = 0; + toValueStatusM = 0; + + toCntTwiStatusAG = 0; + toCntTwiStatusM = 0; + toCntTwiDataAG = 0; + toCntTwiDataM = 0; + toCntStatusAG = 0; + toCntStatusM = 0; + + sumA.x = sumA.y = sumA.z = sumG.x = sumG.y = sumG.z = 0; + waitCnt = 2; + + refI2C->getParams(&twiParams); + switch(twiParams.speed) + { + case Twi100k: + twiCycle = 10; + break; + + case Twi250k: + twiCycle = 4; + break; + + case Twi400k: + twiCycle = 2; + break; + } + + twiStatusCycle = 40 * twiCycle; + twiDataCycleAG = 160 * twiCycle; + twiDataCycleM = 100 * twiCycle; + + enableMeasAG = false; + enableMeasM = false; + + runStateCntTotal = 0; +} + +// ---------------------------------------------------------------------------- +// Konfiguration +// ---------------------------------------------------------------------------- +// +int SensorLSM9DS1::resetAG() +{ + twPtr->writeByteReg(AG_Adr, AG_Ctrl8, 0x05); + + // Get ID + return(twPtr->readByteReg(AG_Adr, AG_Id)); +} + +int SensorLSM9DS1::resetM() +{ + twPtr->writeByteReg(M_Adr, M_Ctrl2, 0x0C); + + // Get ID + return(twPtr->readByteReg(M_Adr, M_Id)); +} + +int SensorLSM9DS1::reset() +{ + int retv; + + twPtr->writeByteReg(AG_Adr, AG_Ctrl8, 0x05); + twPtr->writeByteReg(M_Adr, M_Ctrl2, 0x0C); + + retv = twPtr->readByteReg(AG_Adr, AG_Id); + retv += twPtr->readByteReg(M_Adr, M_Id); + return(retv); +} + +void SensorLSM9DS1::setScanAG(byte scValueAG, byte scValueA, byte scValueG) +{ + twPtr->writeByteReg(AG_Adr, AG_Ctrl6, scValueAG | scValueA); + twPtr->writeByteReg(AG_Adr, AG_Ctrl1, scValueAG | scValueG); +} + +void SensorLSM9DS1::setScanM(byte scValue1, byte scValue2, byte scValue3, byte scValue4) +{ + twPtr->writeByteReg(M_Adr, M_Ctrl1, scValue1); + twPtr->writeByteReg(M_Adr, M_Ctrl2, scValue2); + twPtr->writeByteReg(M_Adr, M_Ctrl3, scValue3); + twPtr->writeByteReg(M_Adr, M_Ctrl4, scValue4); +} + +void SensorLSM9DS1::setTimeOutValues(FreqAG fAG, FreqM fM) +{ + int freqA = 1190, freqM = 40000; + int cycleA, cycleM; + + enableMeasAG = true; + + switch(fAG) + { + case FreqAG14_9: + freqA = 149; + break; + + case FreqAG59_5: + freqA = 595; + break; + + case FreqAG119: + freqA = 1190; + break; + + case FreqAG238: + freqA = 2380; + break; + + case FreqAG476: + freqA = 4760; + break; + + case FreqAG952: + freqA = 9520; + break; + + case FreqAG_OFF: + freqA = 1190; + enableMeasAG = false; + break; + } + + cycleA = (freqA * runCycle) / 10; // Zyklusfrequenz + toValueStatusAG = 1200000 / cycleA; // Mikrosekunden + 20% Verlängerung + + // Test + //toValueStatusAG += 2; + + enableMeasM = true; + + switch(fM) + { + case FreqM0_625: + freqM = 625; + break; + + case FreqM1_25: + freqM = 1250; + break; + + case FreqM2_5: + freqM = 2500; + break; + + case FreqM5: + freqM = 5000; + break; + + case FreqM10: + freqM = 10000; + break; + + case FreqM20: + freqM = 20000; + break; + + case FreqM40: + freqM = 40000; + break; + + case FreqM80: + freqM = 80000; + break; + + case FreqM_OFF: + freqM = 40000; + enableMeasM = false; + break; + } + + cycleM = (freqM * runCycle) / 1000; // Zyklusfrequenz + toValueStatusM = 1200000 / cycleM; // Mikrosekunden + 20% Verlängerung + + // Test + //toValueStatusM += 3; + +} + +void SensorLSM9DS1::begin(FreqAG freqAG, int avgAG, MaxA maxA, MaxG maxG, FreqM freqM, int avgM, MaxM maxM) +{ + setScanAG((byte) freqAG, (byte) maxA | A_LpAuto, (byte) maxG | G_LpHH); + setScanM((byte) freqM | Mxy_PmMed | M_TmpOn, (byte) maxM, M_Contin, Mz_PmMed); + + setTimeOutValues(freqAG, freqM); + + if(avgAG == 1) + { + avgSetAG = 0; + avgCntAG = 0; + } + else + { + avgSetAG = avgAG; + avgCntAG = avgAG; + } + + if(avgM == 1) + { + avgSetM = 0; + avgCntM = 0; + } + else + { + avgSetM = avgM; + avgCntM = avgM; + } + + delay(10); +} + +void SensorLSM9DS1::begin() +{ + //reset(); + + delay(10); + + setScanAG(AG_Odr119, A_Fs4g | A_LpAuto, G_Fs2000 | G_LpHH); + setScanM(M_Odr40 | Mxy_PmMed | M_TmpOn, M_Fs4G, M_Contin, Mz_PmMed); + + avgSetAG = 6; + avgCntAG = 6; + + avgSetM = 0; + avgCntM = 0; + + + delay(10); +} + +// ---------------------------------------------------------------------------- +// Steuerfunktionen, gezielte Prozessorzugriffe und Hilfsfunktionen +// ---------------------------------------------------------------------------- +// +/* +void SensorLSM9DS1::run0() +{ + switch(runState) + { + case rsInit: + runState = rsScanAGReq; + break; + + // ------------ Accel & Gyro ------------ + + case rsScanAGReq: + twPtr->recByteReg(AG_Adr, AG_Status, &twiByte); + runState = rsScanAGChk; + break; + + case rsScanAGChk: + if(twiByte.twiStatus != TwStFin) + break; + + if((twiByte.value & 0x03) == 0) + { + waitCnt = 2; + runState = rsWaitAG; + break; + } + + twiByteSeq.len = 12; + twPtr->recByteRegSeq(AG_Adr, G_Out, &twiByteSeq); + runState = rsFetchAG; + break; + + case rsWaitAG: + if(waitCnt > 0) + { + waitCnt--; + break; + } + else + { + runState = rsScanAGReq; + } + break; + + case rsFetchAG: + if(twiByte.twiStatus != TwStFin) + break; + + for(int i = 0; i < 12; i++) + tmpDataAG.byteArray[i] = byteArray[i]; + + if(avgSetAG > 0) + { + sumA.x += (int) tmpDataAG.valueAG.A.x; + sumA.y += (int) tmpDataAG.valueAG.A.y; + sumA.z += (int) tmpDataAG.valueAG.A.z; + sumG.x += (int) tmpDataAG.valueAG.G.x; + sumG.y += (int) tmpDataAG.valueAG.G.y; + sumG.z += (int) tmpDataAG.valueAG.G.z; + avgCntAG--; + + if(avgCntAG == 0) + { + rawDataAG.valueAG.A.x = short (sumA.x / avgSetAG); + rawDataAG.valueAG.A.y = short (sumA.y / avgSetAG); + rawDataAG.valueAG.A.z = short (sumA.z / avgSetAG); + rawDataAG.valueAG.G.x = short (sumG.x / avgSetAG); + rawDataAG.valueAG.G.y = short (sumG.y / avgSetAG); + rawDataAG.valueAG.G.z = short (sumG.z / avgSetAG); + + sumA.x = sumA.y = sumA.z = sumG.x = sumG.y = sumG.z = 0; + avgCntAG = avgSetAG; + + newValueAG = true; + } + } + else + { + rawDataAG.valueAG.A.x = tmpDataAG.valueAG.A.x; + rawDataAG.valueAG.A.y = tmpDataAG.valueAG.A.x; + rawDataAG.valueAG.A.z = tmpDataAG.valueAG.A.x; + rawDataAG.valueAG.G.x = tmpDataAG.valueAG.A.x; + rawDataAG.valueAG.G.y = tmpDataAG.valueAG.A.x; + rawDataAG.valueAG.G.z = tmpDataAG.valueAG.A.x; + newValueAG = true; + } + + runState = rsScanAGReq; + break; + } +} + +void SensorLSM9DS1::run1() +{ + switch(runState) + { + case rsInit: + runState = rsScanAGReq; + break; + + // ------------ Accel & Gyro ------------ + + case rsScanAGReq: + twPtr->recByteReg(AG_Adr, AG_Status, &twiByte); + runState = rsScanAGChk; + break; + + case rsScanAGChk: + if(twiByte.twiStatus != TwStFin) + break; + + if((twiByte.value & 0x03) == 0) + { + waitCnt = 2; + runState = rsWaitAG; + break; + } + + twiByteSeq.len = 12; + twPtr->recByteRegSeq(AG_Adr, G_Out, &twiByteSeq); + runState = rsFetchAG; + break; + + case rsWaitAG: + if(waitCnt > 0) + { + waitCnt--; + break; + } + else + { + runState = rsScanAGReq; + } + break; + + case rsFetchAG: + if(twiByteSeq.twiStatus != TwStFin) + break; + + for(int i = 0; i < 12; i++) + rawDataAG.byteArray[i] = byteArray[i]; + + newValueAG = true; + + runState = rsScanAGReq; + break; + } +} + +*/ + +void SensorLSM9DS1::stop() +{ + enableMeasAG = false; + enableMeasM = false; +} + +void SensorLSM9DS1::resume() +{ + enableMeasAG = true; + enableMeasM = true; +} + +void SensorLSM9DS1::run() +{ + runStateCntTotal++; + + switch(runState) + { + // ------------------------------------------------------------------------ + case rsInit: + // ------------------------------------------------------------------------ + runStateCntArray[rsInit]++; + runState = rsScanAGReq; + timeOutStatusAG = toValueStatusAG; + timeOutStatusM = toValueStatusM; + break; + + // ------------ Accel & Gyro ------------ + + // ------------------------------------------------------------------------ + case rsScanAGReq: + // ------------------------------------------------------------------------ + runStateCntArray[rsScanAGReq]++; + if(!enableMeasAG) + { + runState = rsScanMReq; + break; + } + + twPtr->recByteReg(AG_Adr, AG_Status, &twiByte); + timeOutTwiStatus = twiStatusCycle / runCycle + 1; + runState = rsScanAGChk; + break; + + // ------------------------------------------------------------------------ + case rsWaitAG: + // ------------------------------------------------------------------------ + runStateCntArray[rsWaitAG]++; + break; + + // ------------------------------------------------------------------------ + case rsScanAGChk: + // ------------------------------------------------------------------------ + runStateCntArray[rsScanAGChk]++; + if((twiByte.twiStatus != TwStFin) && ((twiByte.twiStatus & TwStError) == 0)) + { + if(timeOutTwiStatus > 0) + timeOutTwiStatus--; + else + { + toCntTwiStatusAG++; + runState = rsScanAGReq; + } + break; + } + + if((twiByte.twiStatus & TwStError) != 0) + { + if(twiByte.twiStatus == TwStAdrNak) + errorCntAdrNakAG++; + else if(twiByte.twiStatus == TwStDataNak) + errorCntDataNakAG++; + else + errorCntOverAG++; + + runState = rsScanAGReq; + break; + } + + if((twiByte.value & 0x03) == 0) + { + if(timeOutStatusAG > 0) + timeOutStatusAG--; + else + { + timeOutStatusAG = toValueStatusAG; + toCntStatusAG++; + } + runState = rsScanMReq; // -> Magnet + break; + } + + timeOutStatusAG = toValueStatusAG; + twiByteSeq.len = 12; + twPtr->recByteRegSeq(AG_Adr, G_Out, &twiByteSeq); + timeOutTwiDataAG = twiDataCycleAG / runCycle + 1; + runState = rsFetchAG; + break; + + // ------------------------------------------------------------------------ + case rsFetchAG: + // ------------------------------------------------------------------------ + runStateCntArray[rsFetchAG]++; + if((twiByteSeq.twiStatus != TwStFin) && ((twiByte.twiStatus & TwStError) == 0)) + { + if(timeOutTwiDataAG > 0) + { + timeOutTwiDataAG--; + break; + } + } + + if(((twiByteSeq.twiStatus & TwStError) != 0) || (timeOutTwiDataAG == 0)) + { + if(twiByteSeq.twiStatus == TwStAdrNak) + errorCntAdrNakAG++; + else if(twiByteSeq.twiStatus == TwStDataNak) + errorCntDataNakAG++; + else if(twiByteSeq.twiStatus == TwStOverrun) + errorCntOverAG++; + else + toCntTwiDataAG++; + + twiByteSeq.len = 12; + twPtr->recByteRegSeq(AG_Adr, G_Out, &twiByteSeq); + timeOutTwiDataAG = twiDataCycleAG / runCycle + 1; + break; + } + + for(int i = 0; i < 12; i++) + comDataAG.byteArray[i] = byteArray[i]; + + if(avgSetAG > 0) + { + sumA.x += comDataAG.valueAG.A.x; + sumA.y += comDataAG.valueAG.A.y; + sumA.z += comDataAG.valueAG.A.z; + sumG.x += comDataAG.valueAG.G.x; + sumG.y += comDataAG.valueAG.G.y; + sumG.z += comDataAG.valueAG.G.z; + avgCntAG--; + + if(avgCntAG == 0) + { + rawDataAG.valueAG.A.x = sumA.x / avgSetAG; + rawDataAG.valueAG.A.y = sumA.y / avgSetAG; + rawDataAG.valueAG.A.z = sumA.z / avgSetAG; + rawDataAG.valueAG.G.x = sumG.x / avgSetAG; + rawDataAG.valueAG.G.y = sumG.y / avgSetAG; + rawDataAG.valueAG.G.z = sumG.z / avgSetAG; + sumA.x = sumA.y = sumA.z = sumG.x = sumG.y = sumG.z = 0; + avgCntAG = avgSetAG; + newValueAG = true; + } + } + else + { + rawDataAG.valueAG.A.x = comDataAG.valueAG.A.x; + rawDataAG.valueAG.A.y = comDataAG.valueAG.A.y; + rawDataAG.valueAG.A.z = comDataAG.valueAG.A.z; + rawDataAG.valueAG.G.x = comDataAG.valueAG.G.x; + rawDataAG.valueAG.G.y = comDataAG.valueAG.G.y; + rawDataAG.valueAG.G.z = comDataAG.valueAG.G.z; + newValueAG = true; + } + + runState = rsScanAGReq; + break; + + // ------------ Magnet ------------ + + // ------------------------------------------------------------------------ + case rsScanMReq: + // ------------------------------------------------------------------------ + runStateCntArray[rsScanMReq]++; + if(!enableMeasM) + { + runState = rsScanAGReq; + break; + } + + twPtr->recByteReg(M_Adr, M_Status, &twiByte); + timeOutTwiStatus = twiStatusCycle / runCycle + 1; + runState = rsScanMChk; + break; + + // ------------------------------------------------------------------------ + case rsScanMChk: + // ------------------------------------------------------------------------ + runStateCntArray[rsScanMChk]++; + if((twiByte.twiStatus != TwStFin) && ((twiByte.twiStatus & TwStError) == 0)) + { + if(timeOutTwiStatus > 0) + timeOutTwiStatus--; + else + { + toCntTwiStatusM++; + runState = rsScanMReq; + } + break; + } + + if((twiByte.twiStatus & TwStError) != 0) + { + if(twiByte.twiStatus == TwStAdrNak) + errorCntAdrNakM++; + else if(twiByte.twiStatus == TwStDataNak) + errorCntDataNakM++; + else + errorCntOverM++; + + runState = rsScanAGReq; + break; + } + + if((twiByte.value & 0x08) == 0) + { + if(timeOutStatusM > 0) + timeOutStatusM--; + else + { + timeOutStatusM = toValueStatusM; + toCntStatusM++; + } + runState = rsScanAGReq; // -> Accel,Gyro + break; + } + + timeOutStatusM = toValueStatusM; + twiByteSeq.len = 6; + twPtr->recByteRegSeq(M_Adr, M_Out, &twiByteSeq); + timeOutTwiDataM = twiDataCycleM / runCycle + 1; + runState = rsFetchM; + break; + + // ------------------------------------------------------------------------ + case rsFetchM: + // ------------------------------------------------------------------------ + runStateCntArray[rsFetchM]++; + if((twiByteSeq.twiStatus != TwStFin) && ((twiByte.twiStatus & TwStError) == 0)) + { + if(timeOutTwiDataM > 0) + { + timeOutTwiDataM--; + break; + } + } + + if( ((twiByteSeq.twiStatus & TwStError) != 0) || (timeOutTwiDataM == 0) ) + { + if(twiByteSeq.twiStatus == TwStAdrNak) + errorCntAdrNakM++; + else if(twiByteSeq.twiStatus == TwStDataNak) + errorCntDataNakM++; + else if(twiByteSeq.twiStatus == TwStOverrun) + errorCntOverM++; + else + toCntTwiDataM++; + + twiByteSeq.len = 6; + twPtr->recByteRegSeq(AG_Adr, M_Out, &twiByteSeq); + timeOutTwiDataM = twiDataCycleM / runCycle + 1; + break; + } + + for(int i = 0; i < 6; i++) + rawDataM.byteArray[i] = byteArray[i]; + + if(avgSetM > 0) + { + sumM.x += rawDataM.valueM.x; + sumM.y += rawDataM.valueM.y; + sumM.z += rawDataM.valueM.z; + avgCntM--; + + if(avgCntM == 0) + { + rawDataM.valueM.x = sumM.x / avgSetM; + rawDataM.valueM.y = sumM.y / avgSetM; + rawDataM.valueM.z = sumM.z / avgSetM; + sumM.x = sumM.y = sumM.z = 0; + avgCntM = avgSetM; + newValueM = true; + } + } + else + { + newValueM = true; + } + + runState = rsScanAGReq; + break; + } +} + +void SensorLSM9DS1::syncValuesM() +{ + newValueM = false; +} + +bool SensorLSM9DS1::getValuesM(RawDataMPtr rdptr) +{ + if(!newValueM) return(false); + for(int i = 0; i < 6; i++) + rdptr->byteArray[i] = rawDataM.byteArray[i]; + newValueM = false; + return(true); +} + +bool SensorLSM9DS1::getValuesM(CalValuePtr calPtr) +{ + if(!newValueM) return(false); + + calPtr->x = (float) fullScaleM * (float) rawDataM.valueM.x / (float) 32767; + calPtr->y = (float) fullScaleM * (float) rawDataM.valueM.y / (float) 32767; + calPtr->z = (float) fullScaleM * (float) rawDataM.valueM.z / (float) 32767; + + newValueM = false; + return(true); +} + +void SensorLSM9DS1::syncValuesAG() +{ + newValueAG = false; +} + +bool SensorLSM9DS1::getValuesAG(RawDataAGPtr rdptr) +{ + if(!newValueAG) return(false); + for(int i = 0; i < 12; i++) + rdptr->byteArray[i] = rawDataAG.byteArray[i]; + newValueAG = false; + return(true); +} + +bool SensorLSM9DS1::getValuesAG(CalValueAGPtr calPtr) +{ + if(!newValueAG) return(false); + + calPtr->G.x = (float) fullScaleG * (float) rawDataAG.valueAG.G.x / (float) 32767; + calPtr->G.y = (float) fullScaleG * (float) rawDataAG.valueAG.G.y / (float) 32767; + calPtr->G.z = (float) fullScaleG * (float) rawDataAG.valueAG.G.z / (float) 32767; + + calPtr->A.x = (float) fullScaleA * (float) rawDataAG.valueAG.A.x / (float) 32767; + calPtr->A.y = (float) fullScaleA * (float) rawDataAG.valueAG.A.y / (float) 32767; + calPtr->A.z = (float) fullScaleA * (float) rawDataAG.valueAG.A.z / (float) 32767; + + newValueAG = false; + return(true); +} + +bool SensorLSM9DS1::getAvgValuesAG(CalValueAGPtr calPtr) +{ + if(!newValueAG) return(false); + newValueAG = false; + + if(avgSetAG > 0) + { + sumA.x += rawDataAG.valueAG.A.x; + sumA.y += rawDataAG.valueAG.A.y; + sumA.z += rawDataAG.valueAG.A.z; + sumG.x += rawDataAG.valueAG.G.x; + sumG.y += rawDataAG.valueAG.G.y; + sumG.z += rawDataAG.valueAG.G.z; + avgCntAG--; + + if(avgCntAG > 0) return(false); + + calPtr->G.x = (float) fullScaleG * (float) (sumG.x / avgSetAG) / (float) 32767; + calPtr->G.y = (float) fullScaleG * (float) (sumG.y / avgSetAG) / (float) 32767; + calPtr->G.z = (float) fullScaleG * (float) (sumG.z / avgSetAG) / (float) 32767; + + calPtr->A.x = (float) fullScaleA * (float) (sumA.x / avgSetAG) / (float) 32767; + calPtr->A.y = (float) fullScaleA * (float) (sumA.y / avgSetAG) / (float) 32767; + calPtr->A.z = (float) fullScaleA * (float) (sumA.z / avgSetAG) / (float) 32767; + + avgCntAG = avgSetAG; + return(true); + } + + calPtr->G.x = (float) fullScaleG * (float) rawDataAG.valueAG.G.x / (float) 32767; + calPtr->G.y = (float) fullScaleG * (float) rawDataAG.valueAG.G.y / (float) 32767; + calPtr->G.z = (float) fullScaleG * (float) rawDataAG.valueAG.G.z / (float) 32767; + + calPtr->A.x = (float) fullScaleA * (float) rawDataAG.valueAG.A.x / (float) 32767; + calPtr->A.y = (float) fullScaleA * (float) rawDataAG.valueAG.A.y / (float) 32767; + calPtr->A.z = (float) fullScaleA * (float) rawDataAG.valueAG.A.z / (float) 32767; + + return(true); +} + + + + +// ---------------------------------------------------------------------------- +// Ereignisbearbeitung und Interrupts +// ---------------------------------------------------------------------------- +// + +// ---------------------------------------------------------------------------- +// D e b u g - H i l f e n +// ---------------------------------------------------------------------------- +// +dword SensorLSM9DS1::debGetDword(int code) +{ + dword retv; + + + switch(code) + { + case 1: + retv = toValueStatusAG; + break; + + case 2: + retv = toValueStatusM; + break; + + default: + retv = 0; + break; + } + return(retv); +} + + +dword SensorLSM9DS1::debGetRunState(int code) +{ + if(0 <= code < 9) + return(runStateCntArray[code]); + else + return(0); +} + + + + diff --git a/sketches/_PIO_Sketches/Karger/SoaapBleMaster_Test_2/src/SensorLSM9DS1/SensorLSM9DS1.h b/sketches/_PIO_Sketches/Karger/SoaapBleMaster_Test_2/src/SensorLSM9DS1/SensorLSM9DS1.h new file mode 100644 index 0000000000000000000000000000000000000000..63cb831c96688b30a85397927a14a52dcb6a15f2 --- /dev/null +++ b/sketches/_PIO_Sketches/Karger/SoaapBleMaster_Test_2/src/SensorLSM9DS1/SensorLSM9DS1.h @@ -0,0 +1,363 @@ +//----------------------------------------------------------------------------- +// Thema: Social Manufacturing Network / Development Environment +// Datei: SensorLSM9DS1.h +// Editor: Robert Patzke +// URI/URL: www.mfp-portal.de +//----------------------------------------------------------------------------- +// Lizenz: CC-BY-SA (wikipedia: Creative Commons) +// + +#ifndef SENSORLSM9DS1_H +#define SENSORLSM9DS1_H + +#include "Arduino.h" +#include "arduinoDefs.h" +#include "IntrfTw.h" + +// ---------------------------------------------------------------------------- + +// ------------------------ Acceleration and Gyroscope ------- +#define AG_Adr 0x6B +// ------------------------ Acceleration and Gyroscope ------- +#define AG_Id 0x0F +#define AG_Ctrl1 0x10 +#define G_Out 0x18 +#define AG_Ctrl6 0x20 +#define AG_Ctrl8 0x22 +#define AG_Status 0x27 + +#define AG_Rate(x) (x << 5) +#define AG_Odr14_9 0x20 +#define AG_Odr59_5 0x40 +#define AG_Odr119 0x60 +#define AG_Odr238 0x80 +#define AG_Odr476 0xA0 +#define AG_Odr952 0xC0 + +typedef enum _FreqAG +{ + FreqAG_OFF = 0xFF, + FreqAG14_9 = AG_Odr14_9, + FreqAG59_5 = AG_Odr59_5, + FreqAG119 = AG_Odr119, + FreqAG238 = AG_Odr238, + FreqAG476 = AG_Odr476, + FreqAG952 = AG_Odr952 +} FreqAG; + +#define AG_FullScale(x) (x << 3) +#define A_Fs2g 0x00 +#define A_Fs4g 0x10 +#define A_Fs8g 0x18 +#define A_Fs16g 0x08 +#define G_Fs245 0x00 +#define G_Fs2000 0x18 +#define G_Fs500 0x08 + +typedef enum _MaxA +{ + MaxAcc2g = A_Fs2g, + MaxAcc4g = A_Fs4g, + MaxAcc8g = A_Fs8g, + MaxAcc16g = A_Fs16g +} MaxA; + +typedef enum _MaxG +{ + MaxGyro245dps = G_Fs245, + MaxGyro500dps = G_Fs500, + MaxGyro2000dps = G_Fs2000 +} MaxG; + +#define AG_LowPass(x) (x) +#define A_LpAuto 0x00 +#define A_Lp50 0x07 +#define A_Lp105 0x06 +#define A_Lp211 0x05 +#define A_Lp408 0x04 +#define G_LpLL 0x00 +#define G_LpLH 0x01 +#define G_LpHL 0x02 +#define G_LpHH 0x03 + +// ------------------------ Magnetic Field ------- +#define M_Adr 0x1E +// ------------------------ Magnetic Field ------- +#define M_Id 0x0F +#define M_Ctrl1 0x20 +#define M_Ctrl2 0x21 +#define M_Ctrl3 0x22 +#define M_Ctrl4 0x23 +#define M_Ctrl5 0x24 +#define M_Status 0x27 +#define M_Out 0x28 + +// Control 1 +#define M_Rate(x) (x << 2) +#define M_Odr0_625 0x00 +#define M_Odr1_25 0x04 +#define M_Odr2_5 0x08 +#define M_Odr5 0x0C +#define M_Odr10 0x10 +#define M_Odr20 0x14 +#define M_Odr40 0x18 +#define M_Odr80 0x1C + +typedef enum _FreqM +{ + FreqM_OFF = 0xFF, + FreqM0_625 = M_Odr0_625, + FreqM1_25 = M_Odr1_25, + FreqM2_5 = M_Odr2_5, + FreqM5 = M_Odr5, + FreqM10 = M_Odr10, + FreqM20 = M_Odr20, + FreqM40 = M_Odr40, + FreqM80 = M_Odr80 +} FreqM; + +#define M_Temp(x) (x << 7) +#define M_TmpOn 0x80 +#define M_TmpOff 0x00 + +#define Mxy_Power(x) (x << 6) +#define Mxy_PmLow 0x00 +#define Mxy_PmMed 0x20 +#define Mxy_PmHigh 0x40 +#define Mxy_PmUhigh 0x60 + +// Control 2 +#define M_FullScale(x) (x << 5) +#define M_Fs4G 0x00 +#define M_Fs8G 0x20 +#define M_Fs12G 0x40 +#define M_Fs16G 0x60 + +typedef enum _MaxM +{ + MaxMag4G = M_Fs4G, + MaxMag8G = M_Fs8G, + MaxMag12G = M_Fs12G, + MaxMag16G = M_Fs16G +} MaxM; + + +// Control 3 +#define M_OpMode(x) (x) +#define M_Contin 0x00 +#define M_Single 0x01 +#define M_Down 0x10 + +// Control 4 +#define Mz_Power(x) (x << 2) +#define Mz_PmLow 0x00 +#define Mz_PmMed 0x04 +#define Mz_PmHigh 0x08 +#define Mz_PmUhigh 0x0C + + +typedef enum _RunState +{ + rsInit, + rsScanAGReq, + rsWaitAG, + rsScanAGChk, + rsFetchAG, + rsScanMReq, + rsScanMChk, + rsFetchM +} RunState; + +#define NrOfRunStates 8 + +typedef struct _RawValue +{ + short int x; + short int y; + short int z; +} RawValue; + +typedef struct _SumValue +{ + int x; + int y; + int z; +} SumValue, *SumValuePtr; + +typedef struct _RawValueAG +{ + RawValue G; + RawValue A; +} RawValueAG; + +typedef union _RawDataAG +{ + byte byteArray[12]; + RawValueAG valueAG; +} RawDataAG, *RawDataAGPtr; + +typedef union _RawDataM +{ + byte byteArray[6]; + RawValue valueM; +} RawDataM, *RawDataMPtr; + +typedef struct _CalValue +{ + float x; + float y; + float z; +} CalValue, *CalValuePtr; + +typedef struct _CalValueAG +{ + CalValue G; + CalValue A; +} CalValueAG, *CalValueAGPtr; + +typedef struct _SensorErrors +{ + +} SensorErrors, *SensorErrorsPtr; + +class SensorLSM9DS1 +{ +private: + // -------------------------------------------------------------------------- + // Lokale Daten und Funktionen + // -------------------------------------------------------------------------- + // + IntrfTw *twPtr; + TwiByte twiByte; + TwiByteSeq twiByteSeq; + byte byteArray[12]; + + bool enableMeasAG; + bool newValueAG; + RawDataAG rawDataAG; + RawDataAG comDataAG; + + bool enableMeasM; + bool newValueM; + RawDataM rawDataM; + + int fullScaleA; + int fullScaleG; + int fullScaleM; + + SumValue sumA; + SumValue sumG; + int avgSetAG; + int avgCntAG; + + SumValue sumM; + int avgSetM; + int avgCntM; + + dword timeOutTwiStatus; + dword timeOutTwiDataAG; + dword timeOutTwiDataM; + + dword timeOutStatusAG; + dword toValueStatusAG; + dword timeOutStatusM; + dword toValueStatusM; + + int twiCycle; + int twiStatusCycle; + int twiDataCycleAG; + int twiDataCycleM; + + RunState runState; + int waitCnt; + int runCycle; + + void setTimeOutValues(FreqAG fAG, FreqM fM); + +public: + // -------------------------------------------------------------------------- + // Initialisierungen der Basis-Klasse + // -------------------------------------------------------------------------- + + SensorLSM9DS1(IntrfTw *refI2C, int inRunCycle); + + // -------------------------------------------------------------------------- + // Konfigurationen + // -------------------------------------------------------------------------- + // + int resetAG(); + int resetM(); + int reset(); + + void setScanAG(byte scValueAG, byte scValueA, byte scValueG); + // Messparameter für Accel und Gyro + // scValueAG = Abtastrate + // scValueA = Vollausschlag und Tiefpass für Beschleunigung + // scValueB = Vollausschlag und Tiefpass für Gyrometer + + void setScanM(byte scValue1, byte scValue2, byte scValue3, byte scValue4); + // Messparameter für Magnetfeld + // scValue1 = Abtastrate, Temperaturkompensation und XY-Powermode + // scValue2 = Vollausschlag + // scValue3 = Betriebsart + // scValue4 = Z-Powermode + + + void begin(FreqAG freqAG, int avgAG, MaxA maxA, MaxG maxG, FreqM freqM, int avgM, MaxM maxM); + void begin(); + + // -------------------------------------------------------------------------- + // Steuerfunktionen + // -------------------------------------------------------------------------- + // + void run(); + void run0(); + void run1(); + void stop(); + void resume(); + + // -------------------------------------------------------------------------- + // Datenaustausch + // -------------------------------------------------------------------------- + // + dword errorCntOverAG; + dword errorCntAdrNakAG; + dword errorCntDataNakAG; + + dword errorCntOverM; + dword errorCntAdrNakM; + dword errorCntDataNakM; + + dword toCntTwiStatusAG; + dword toCntTwiStatusM; + dword toCntTwiDataAG; + dword toCntTwiDataM; + dword toCntStatusAG; + dword toCntStatusM; + + void syncValuesAG(); + bool getValuesAG(RawDataAGPtr rdptr); + bool getValuesAG(CalValueAGPtr calPtr); + bool getAvgValuesAG(CalValueAGPtr calPtr); + void syncValuesM(); + bool getValuesM(RawDataMPtr rdptr); + bool getValuesM(CalValuePtr calPtr); + + // ---------------------------------------------------------------------------- + // Ereignisbearbeitung und Interrupts + // ---------------------------------------------------------------------------- + // + + // ---------------------------------------------------------------------------- + // D e b u g - H i l f e n + // ---------------------------------------------------------------------------- + // + dword runStateCntArray[NrOfRunStates]; + dword runStateCntTotal; + dword debGetDword(int code); + dword debGetRunState(int code); + +}; + +#endif // SENSORLSM9DS1_H + diff --git a/sketches/_PIO_Sketches/Karger/SoaapBleMaster_Test_2/src/SensorLSM9DS1/library.json b/sketches/_PIO_Sketches/Karger/SoaapBleMaster_Test_2/src/SensorLSM9DS1/library.json new file mode 100644 index 0000000000000000000000000000000000000000..6432e5ccb8930ce40504aa4f03e463f2df00fac0 --- /dev/null +++ b/sketches/_PIO_Sketches/Karger/SoaapBleMaster_Test_2/src/SensorLSM9DS1/library.json @@ -0,0 +1,4 @@ +{ + "name": "SensorLSM9DS1", + "version": "0.0.0+20220823165932" +} \ No newline at end of file diff --git a/sketches/_PIO_Sketches/Karger/SoaapBleMaster_Test_2/src/SoaapComDue/SoaapComDue.cpp b/sketches/_PIO_Sketches/Karger/SoaapBleMaster_Test_2/src/SoaapComDue/SoaapComDue.cpp new file mode 100644 index 0000000000000000000000000000000000000000..b24e6f4f90c3ecc1588b5af5dde88b4b922e8ee7 --- /dev/null +++ b/sketches/_PIO_Sketches/Karger/SoaapBleMaster_Test_2/src/SoaapComDue/SoaapComDue.cpp @@ -0,0 +1,212 @@ +//----------------------------------------------------------------------------- +// Thema: Steuerung optischer und akustischer Ausgaben für Perfomer +// Datei: SoaapComDue.cpp +// Editor: Robert Patzke +// URI/URL: www.hs-hannover.de +//----------------------------------------------------------------------------- +// Lizenz: CC-BY-SA (wikipedia: Creative Commons) +// Datum: 01.April 2022 +// +// Diese Bibliothek (Klassse) enthält diverse Ressourcen zum Zugriff auf den +// SOAAP-Master über eine serielle Schnittstelle des Arduino DUE. +// + +#include "SoaapComDue.h" + +#define next(x) nextState = &SoaapComDue::x + +// ---------------------------------------------------------------------------- +// Konstruktoren und Initialisierungen +// ---------------------------------------------------------------------------- +// +SoaapComDue::SoaapComDue(USARTClass *serial, SoaapMsg *soaMsg) +{ + pCom = serial; + pMsg = soaMsg; + nextState = &SoaapComDue::runInit; + + nrBytesIn = 0; + serInIdx = 0; + serInChar = 0; + serInCount = 0; + slaveAdr = 0; + slaveArea = 0; + appId = (SoaapApId) 0; + + measIdx = 0; + nrMeas = 0; + resMeas = 0; + slaveIdx = 0; + anyNewVal = false; +} + +// -------------------------------------------------------------------------- +// lokale Methoden (Zustandsmaschine) +// -------------------------------------------------------------------------- +// +void SoaapComDue::runInit() +{ + next(runWaitMsg); +} + +void SoaapComDue::runWaitMsg() +{ + nrBytesIn = pCom->available(); + // Anzahl der über <serial> eingetroffenen Bytes (Zeichen) + + if(nrBytesIn < 1) return; + // Beim nächsten Takt wieder in diesen Zustand, wenn kein Zeichen da + + for(serInIdx = 0; serInIdx < nrBytesIn; serInIdx++) + { // Suchen nach Startzeichen + serInChar = pCom->read(); + if(serInChar < 0x20) break; + } + + if(serInIdx == nrBytesIn) return; + // Beim nächsten Takt wieder in diesen Zustand, wenn Startzeichen nicht dabei + + slaveArea = serInChar & 0x1F; // Bereich auskodieren + + serInIdx = 0; // Index neu setzen für Inhaltszuordnung + next(runHeader); + // Beim nächsten Takt zum Zustand <runHeader> + +} + +void SoaapComDue::runHeader() +{ + nrBytesIn = pCom->available(); + // Anzahl der über Serial1 eingetroffenen Bytes (Zeichen) + + if(nrBytesIn < 1) return; + // Beim nächsten Takt wieder in diesen Zustand, wenn kein Zeichen da + + serInChar = pCom->read(); + // einzelnes Zeichen lesen + + if(serInIdx == 0) // nach der Area folgt die Slaveadresse + { + slaveAdr = serInChar & 0x1F; // 1 - 31 + slaveIdx = slaveAdr; // vorläufig lineare Adress/Index-Zuordnung + serInIdx++; + // Beim nächsten Takt wieder in diesen Zustand + } + else // und dann die Anwendungskennung + { + appId = (SoaapApId) serInChar; + measIdx = 0; // Index für Messwertunterscheidung + serInIdx = 0; // Index für Messwertaufbau + nrMeas = pMsg->measCnt(appId); // Anzahl Messwerte im Telegramm + resMeas = pMsg->measRes(appId); // Auflösung der Messwerte in Zeichen + next(runValues); + // Beim nächsten Takt zum Zustand <runValues> + } +} + +void SoaapComDue::runValues() +{ + int i; + + do + { + nrBytesIn = pCom->available(); + // Anzahl der über Serial1 eingetroffenen Bytes (Zeichen) + + if(nrBytesIn < 1) return; + // Beim nächsten Takt wieder in diesen Zustand, wenn kein Zeichen da + + for(i = 0; i < nrBytesIn; i++) + { + tmpBuffer[serInIdx++] = pCom->read(); + // einzelnes Zeichen lesen + + if(serInIdx == resMeas) break; + // Alle Zeichen vom Messwert da, also raus + } + + if(serInIdx < resMeas) return; + // Wenn noch nicht ale Zeichen vom Messwert erfasst, dann von vorn + + slValList[slaveIdx].measList[measIdx++] = pMsg->asc2meas(tmpBuffer); + // Zeichenkette in Messwert wandeln und speichern + + if(measIdx == nrMeas) break; + // Falls mehr als ein Telegramm eingetroffen ist + // muss hier ein Ausstieg erfolgen + + serInIdx = 0; // Nächste Zeichenfolge + } + while (pCom->available() > 0); + // Die Taktzeit der Zustandsmaschine ist größer, als die + // Übertragungszeit von einem Zeichen. + // Deshalb werden in einem Zustandstakt alle inzwischen eingetroffenen + // Zeichen bearbeitet. + + if(measIdx < nrMeas) return; + // Im Zustand bleiben, bis alle Messwerte gewandelt sind + + slValList[slaveIdx].newVal = true; + anyNewVal = true; + + next(runWaitMsg); +} + +// -------------------------------------------------------------------------- +// lokale Methoden (Hilfsfunktionen) +// -------------------------------------------------------------------------- +// + +// Erster Slave (kleinste Adresse) mit Daten +// +int SoaapComDue::getSlDataAvail() +{ + for(int i = 1; i <= ScdNrOfSlaves; i++) + if(slValList[i].newVal) + return(i); + return(0); +} + +// ---------------------------------------------------------------------------- +// Anwenderschnittstelle (Funktionen/Methoden) +// ---------------------------------------------------------------------------- +// + +// (zyklischer) Aufruf zum Ablauf +// +void SoaapComDue::run() +{ + if(nextState != NULL) + (this->*nextState)(); +} + +// Daten von irgendeinem Slave verfügbar +// +int SoaapComDue::anyDataAvail() +{ + if(!anyNewVal) return(0); + else return(getSlDataAvail()); +} + +// Daten von bestimmtem Slave verfügbar +// +bool SoaapComDue::slDataAvail(int slAdr) +{ + return(slValList[getSlIdxAdr(slAdr)].newVal); +} + +// Daten von einem bestimmten Slave abholen +// +int SoaapComDue::getData(int slAdr, pMeasValues pMeas) +{ + int slIdx = getSlIdxAdr(slAdr); + for(int i = 0; i < 8; i++) + pMeas->defShort[i] = slValList[slIdx].measList[i]; + slValList[slIdx].newVal = false; + anyNewVal = false; + for(int i = 1; i <= ScdNrOfSlaves; i++) + if(slValList[i].newVal) anyNewVal = true; + return(0); +} + + diff --git a/sketches/_PIO_Sketches/Karger/SoaapBleMaster_Test_2/src/SoaapComDue/SoaapComDue.h b/sketches/_PIO_Sketches/Karger/SoaapBleMaster_Test_2/src/SoaapComDue/SoaapComDue.h new file mode 100644 index 0000000000000000000000000000000000000000..990faa3710733dedfd4819f254c11b8900f15d65 --- /dev/null +++ b/sketches/_PIO_Sketches/Karger/SoaapBleMaster_Test_2/src/SoaapComDue/SoaapComDue.h @@ -0,0 +1,132 @@ +//----------------------------------------------------------------------------- +// Thema: Steuerung optischer und akustischer Ausgaben für Perfomer +// Datei: SoaapComDue.h +// Editor: Robert Patzke +// URI/URL: www.hs-hannover.de +//----------------------------------------------------------------------------- +// Lizenz: CC-BY-SA (wikipedia: Creative Commons) +// Datum: 01.April 2022 +// +// Diese Bibliothek (Klassse) enthält diverse Ressourcen zum Zugriff auf den +// SOAAP-BLE-Master über eine serielle Schnittstelle des Arduino DUE. +// + +#ifndef SoaapComDue_h +#define SoaapComDue_h + +#define ScdNrOfSlaves 6 + +#include "USARTClass.h" +#include "SoaapMsg.h" + +#ifndef byte +#define byte unsigned char +#endif + + +class SoaapComDue +{ +public: + // -------------------------------------------------------------------------- + // Konstruktoren und Initialisierungen + // -------------------------------------------------------------------------- + // + SoaapComDue(USARTClass *serial, SoaapMsg *soaMsg); + + // -------------------------------------------------------------------------- + // öffentliche Datentypen + // -------------------------------------------------------------------------- + // + typedef union + { + short defShort[9]; + short maxShort[13]; + float maxFloat[6]; + } MeasValues, *pMeasValues; + +private: + // -------------------------------------------------------------------------- + // lokale Datentypen + // -------------------------------------------------------------------------- + // + + typedef void (SoaapComDue::*CbVector)(void); + typedef struct + { + int slaveArea; + int slaveAdr; + SoaapApId apId; + bool newVal; + short measList[13]; + } SlaveValues, *pSlaveValues; + +private: + // -------------------------------------------------------------------------- + // lokale Variablen + // -------------------------------------------------------------------------- + // + USARTClass *pCom; + SoaapMsg *pMsg; + CbVector nextState; + + int nrBytesIn; // Antahl aktuell empfangener Zeichen + int serInCount; // Zähler für empfangene Zeichen + int serInIdx; // Index für besonderes Zeichen + byte serInChar; // Einzelnes empfangenes Zeichen + int slaveAdr; // Adresse des Soaap-Slave + int slaveArea; // Quellennetzwerk-Info, Bereich, o.ä. + SoaapApId appId; // Anwendungskennung, Datentyp, o.ä. + + int measIdx; // Index für den aktuellen Messwert + int nrMeas; // Anzahl der Messwerte im Telegramm + int resMeas; // Auflösung der Messwerte in Zeichen + bool anyNewVal; // Neuer Wert von beliebigem Slave + + SlaveValues slValList[ScdNrOfSlaves + 1]; // Vorläufige Liste aller Messwerte + int slaveIdx; // Index für lokale Slaveverwaltung + + byte tmpBuffer[128]; // Zwischenspeicher für empfangene Zeichen + + // -------------------------------------------------------------------------- + // Inline-Methoden + // -------------------------------------------------------------------------- + // + + // Index von Slave best. Adresse für Datenliste + // + int getSlIdxAdr(int slAdr) + { + // Zur Zeit sind Index und Slaveadresse identisch (1-6) + // Das wir später bei freier Zuordnung angepasst + return(slAdr); + } + + // -------------------------------------------------------------------------- + // lokale Methoden (Zustandsmaschine) + // -------------------------------------------------------------------------- + // + void runInit(); + void runWaitMsg(); + void runHeader(); + void runValues(); + + // -------------------------------------------------------------------------- + // lokale Methoden (Hilfsfunktionen) + // -------------------------------------------------------------------------- + // + int getSlDataAvail(); + +public: + // -------------------------------------------------------------------------- + // Anwenderschnittstelle (Funktionen) + // -------------------------------------------------------------------------- + // + void run(); // (zyklischer) Aufruf zum Ablauf + int anyDataAvail(); // Daten von irgendeinem Slave verfügbar + bool slDataAvail(int slAdr); // Daten von bestimmtem Slave verfügbar + int getData(int slAdr, pMeasValues pMeas); + // Daten von einem bestimmten Slave abholen + +}; + +#endif // SoaapComDue_h diff --git a/sketches/_PIO_Sketches/Karger/SoaapBleMaster_Test_2/src/SoaapComDue/library.json b/sketches/_PIO_Sketches/Karger/SoaapBleMaster_Test_2/src/SoaapComDue/library.json new file mode 100644 index 0000000000000000000000000000000000000000..d2cf1518adba3b9cb3a57d0eca8963fbceca345c --- /dev/null +++ b/sketches/_PIO_Sketches/Karger/SoaapBleMaster_Test_2/src/SoaapComDue/library.json @@ -0,0 +1,4 @@ +{ + "name": "SoaapComDue", + "version": "0.0.0+20220804174235" + } \ No newline at end of file diff --git a/sketches/_PIO_Sketches/Karger/SoaapBleMaster_Test_2/src/SoaapMsg/SoaapMsg.cpp b/sketches/_PIO_Sketches/Karger/SoaapBleMaster_Test_2/src/SoaapMsg/SoaapMsg.cpp new file mode 100644 index 0000000000000000000000000000000000000000..0f3f29704b3b1d5e02528071b0527804940435bd --- /dev/null +++ b/sketches/_PIO_Sketches/Karger/SoaapBleMaster_Test_2/src/SoaapMsg/SoaapMsg.cpp @@ -0,0 +1,159 @@ +//----------------------------------------------------------------------------- +// Thema: Steuerung optischer und akustischer Ausgaben für Perfomer +// Datei: SoaapMsg.h +// Editor: Robert Patzke +// URI/URL: www.hs-hannover.de +//----------------------------------------------------------------------------- +// Lizenz: CC-BY-SA (wikipedia: Creative Commons) +// Datum: 18. März 2022 +// +// Diese Bibliothek (Klassse) enthält diverse Ressourcen zur Generierung +// von Meldungen und Telegrammen, die im Rahmen des SOAAP-Projektes +// eingesetzt werden. +// + +#include "SoaapMsg.h" + +// ---------------------------------------------------------------------------- +// Konstruktoren und Initialisierungen +// ---------------------------------------------------------------------------- +// +SoaapMsg::SoaapMsg() +{ + +} + +// ---------------------------------------------------------------------------- +// Anwenderschnittstelle (Funktionen) +// ---------------------------------------------------------------------------- +// + +// Erstellen eines ASCII-Telegramms zum Übertragen der Messwerte +// +int SoaapMsg::getMsgA(int area, int slvNr, SoaapApId appId, char *dest, byte *meas) +{ + int msgIdx = 0; + int measIdx; + int measLen; + byte measByte; + char measChar; + + dest[msgIdx++] = (char) (area | 0x10); + dest[msgIdx++] = (char) (slvNr | 0x60); + dest[msgIdx++] = (char) (appId); + + switch(appId) + { + case saiDefaultMeas: + measLen = 18; + break; + + case saiDefaultMeasCtrl: + measLen = 18; + break; + + case saiMaximalMeas: + measLen = 26; + break; + } + + for(measIdx = 0; measIdx < measLen; measIdx++) + { + measByte = meas[measIdx]; + + // Erst das niederwertige Nibble als Hex-Ascii eintragen + // + measChar = (measByte & 0x0F) | 0x30; + if (measChar > 0x39) measChar += 7; + dest[msgIdx++] = measChar; + + // dann das höherwertige Nibble + // + measChar = (measByte >> 4) | 0x30; + if (measChar > 0x39) measChar += 7; + dest[msgIdx++] = measChar; + } + + if(appId == saiDefaultMeasCtrl) + { + measByte = meas[20]; + + // Erst das niederwertige Nibble als Hex-Ascii eintragen + // + measChar = (measByte & 0x0F) | 0x30; + if (measChar > 0x39) measChar += 7; + dest[msgIdx++] = measChar; + + // dann das höherwertige Nibble + // + measChar = (measByte >> 4) | 0x30; + if (measChar > 0x39) measChar += 7; + dest[msgIdx++] = measChar; + } + + dest[msgIdx] = '\0'; + return(msgIdx); +} + +// Umwandeln eines Messwert aus ASCII-Telegramm in Integer +// +short SoaapMsg::asc2meas(byte *ascList) +{ + unsigned short retv; + + retv = getVal(ascList[0]); + retv += getVal(ascList[1]) << 4; + retv += getVal(ascList[2]) << 8; + retv += getVal(ascList[3]) << 12; + + return((short) retv); +} + +// Auflösung der Messwerte in Zeichen (Bytes) +// +int SoaapMsg::measRes(SoaapApId appId) +{ + int retv = 0; + + switch(appId) + { + case saiDefaultMeas: + retv = 4; + break; + + case saiDefaultMeasCtrl: + retv = 4; + break; + + case saiMaximalMeas: + retv = 4; + break; + } + + return(retv); +} + +// Anzahl der Messwerte im Telegramm +// +int SoaapMsg::measCnt(SoaapApId appId) +{ + int retv = 0; + + switch(appId) + { + case saiDefaultMeas: + retv = 9; + break; + + case saiDefaultMeasCtrl: + retv = 9; + break; + + case saiMaximalMeas: + retv = 13; + break; + } + + return(retv); +} + diff --git a/sketches/_PIO_Sketches/Karger/SoaapBleMaster_Test_2/src/SoaapMsg/SoaapMsg.h b/sketches/_PIO_Sketches/Karger/SoaapBleMaster_Test_2/src/SoaapMsg/SoaapMsg.h new file mode 100644 index 0000000000000000000000000000000000000000..20df5732381c353181e02ce74cf3cf193789c5a0 --- /dev/null +++ b/sketches/_PIO_Sketches/Karger/SoaapBleMaster_Test_2/src/SoaapMsg/SoaapMsg.h @@ -0,0 +1,73 @@ +//----------------------------------------------------------------------------- +// Thema: Steuerung optischer und akustischer Ausgaben für Perfomer +// Datei: SoaapMsg.h +// Editor: Robert Patzke +// URI/URL: www.hs-hannover.de +//----------------------------------------------------------------------------- +// Lizenz: CC-BY-SA (wikipedia: Creative Commons) +// Datum: 18. März 2022 +// +// Diese Bibliothek (Klassse) enthält diverse Ressourcen zur Generierung +// von Meldungen und Telegrammen, die im Rahmen des SOAAP-Projektes +// eingesetzt werden. +// + +#ifndef SoaapMsg_h +#define SoaapMsg_h + +#include "arduinoDefs.h" + +typedef enum +{ + saiDefaultMeas = 0x68, + saiMaximalMeas = 0x69, + saiDefaultMeasCtrl = 0x6A +} SoaapApId; + +class SoaapMsg +{ +public: + // -------------------------------------------------------------------------- + // Konstruktoren und Initialisierungen + // -------------------------------------------------------------------------- + // + SoaapMsg(); + +private: + // -------------------------------------------------------------------------- + // lokale Variablen + // -------------------------------------------------------------------------- + // + + // -------------------------------------------------------------------------- + // Inline-Methoden + // -------------------------------------------------------------------------- + // + int getVal(char hexAsc) + { + if(hexAsc < 0x39) return(hexAsc - 0x30); + else return(hexAsc - 0x37); + } + + +public: + // -------------------------------------------------------------------------- + // Anwenderschnittstelle (Funktionen) + // -------------------------------------------------------------------------- + // + + int getMsgA(int area, int slvNr, SoaapApId appId, char *dest, byte *meas); + // Erstellen eines ASCII-Telegramms zum Übertragen der Messwerte + + short asc2meas(byte *ascList); + // Umwandeln eines Messwert aus ASCII-Telegramm in Integer + + int measRes(SoaapApId appId); + // Auflösung der Messwerte in Zeichen (Bytes) + + int measCnt(SoaapApId appId); + // Anzahl der Messwerte + +}; + +#endif // SoaapMsg_h diff --git a/sketches/_PIO_Sketches/Karger/SoaapBleMaster_Test_2/src/SoaapMsg/library.json b/sketches/_PIO_Sketches/Karger/SoaapBleMaster_Test_2/src/SoaapMsg/library.json new file mode 100644 index 0000000000000000000000000000000000000000..86be2b961f0f6f6dae95ed22fadc55f7a1c58826 --- /dev/null +++ b/sketches/_PIO_Sketches/Karger/SoaapBleMaster_Test_2/src/SoaapMsg/library.json @@ -0,0 +1,4 @@ +{ + "name": "SoaapMsg", + "version": "0.0.0+20220823165932" +} \ No newline at end of file diff --git a/sketches/_PIO_Sketches/Karger/SoaapBleMaster_Test_2/src/StateMachine/StateMachine.cpp b/sketches/_PIO_Sketches/Karger/SoaapBleMaster_Test_2/src/StateMachine/StateMachine.cpp new file mode 100644 index 0000000000000000000000000000000000000000..9c1f78d3b83eabbc30463d78e693b470e345e140 --- /dev/null +++ b/sketches/_PIO_Sketches/Karger/SoaapBleMaster_Test_2/src/StateMachine/StateMachine.cpp @@ -0,0 +1,480 @@ +// --------------------------------------------------------------------------- +// File: StateMachine.cpp +// Editors: Robert Patzke, +// Start: 07. February 2018 +// Last change: 22. February 2021 +// URI/URL: www.mfp-portal.de, homeautomation.x-api.de +// Licence: Creative Commons CC-BY-SA +// --------------------------------------------------------------------------- +// + +#include "StateMachine.h" + +// --------------------------------------------------------------------------- +// Constructors and initialisations +// --------------------------------------------------------------------------- +// + +int StateMachine::StateMachine_InstCounter; + +StateMachine::StateMachine(){;} // @suppress("Class members should be properly initialized") + +StateMachine::StateMachine(StatePtr firstState, StatePtr anyState, int cycle) +{ + begin(firstState, anyState, cycle); +} + +StateMachine::StateMachine(StatePtr firstState, StatePtr anyState, int cycle, MicsecFuPtr micsecFu) +{ + begin(firstState, anyState, cycle, micsecFu); +} + +void StateMachine::begin(StatePtr firstState, StatePtr anyState, int cycle) +{ + begin(firstState, anyState, cycle, NULL); +} + +void StateMachine::begin(StatePtr firstState, StatePtr anyState, int cycle, MicsecFuPtr micsecFu) +{ + nextState = firstState; + doAlways = anyState; + cycleTime = cycle; + frequency = 1000 / cycle; + delay = 0; + delaySet = 0; + repeatDelay = false; + userStatus = 0; + + StateMachine_InstCounter++; + instNumber = StateMachine_InstCounter; + micsFuPtr = micsecFu; +} + +// --------------------------------------------------------------------------- +// run State enter function, has to be cyclic called +// --------------------------------------------------------------------------- +// +void StateMachine::run() +{ + unsigned long startMics = 0, diffMics; + + runCounter++; + + if(timeOutCounter > 0) + timeOutCounter--; + + if(timeMeasureOn) + timeMeasureCounter++; + + if(doAlways != NULL) + doAlways(); + + if(delay > 0) + { + delay--; + return; + } + + if(repeatDelay) + delay = delaySet; + + if(useProgList) + { + if(progIndex == progEndIdx) + { + if(loopProgList) + { + progIndex = 0; + nextState = progList[progIndex]; + progIndex++; + } + else + { + useProgList = false; + nextState = finProgState; + } + } + else + { + nextState = progList[progIndex]; + progIndex++; + } + } + + if(nextState != NULL) + { + if(micsFuPtr != NULL) + startMics = micsFuPtr(); + + nextState(); + + if(micsFuPtr != NULL) + { + diffMics = micsFuPtr() - startMics; + curStateRuntime = diffMics; + + if(diffMics > maxStateRuntime[0]) + { + maxStateRuntime[0] = diffMics; + maxRuntimeNumber[0] = curStateNumber; + } + else if(diffMics > maxStateRuntime[1]) + { + if(curStateNumber != maxRuntimeNumber[0]) + { + maxStateRuntime[1] = diffMics; + maxRuntimeNumber[1] = curStateNumber; + } + } + else if(diffMics > maxStateRuntime[2]) + { + if(curStateNumber != maxRuntimeNumber[1]) + { + maxStateRuntime[2] = diffMics; + maxRuntimeNumber[2] = curStateNumber; + } + } + else if(diffMics > maxStateRuntime[3]) + { + if(curStateNumber != maxRuntimeNumber[2]) + { + maxStateRuntime[3] = diffMics; + maxRuntimeNumber[3] = curStateNumber; + } + } + } + } + else + noStateCounter++; + +} + +// --------------------------------------------------------------------------- +// service functions/methods for manipulating the state machine +// --------------------------------------------------------------------------- +// + +// checking a state for staying (not enter new state) +// +bool StateMachine::stayHere() +{ + if(repeatState > 0) + { + repeatState--; + if(repeatState == 0) + { + repeatDelay = false; + } + return(true); + } + + firstEnterToggle = true; + return(false); +} + +// setting delay before next state +// +void StateMachine::setDelay(int delayTime) +{ + delay = (delayTime * frequency) / 1000; + repeatDelay = false; +} + +// setting internal speed of the state machine +// can only be slower than the calling frequency +// +void StateMachine::setSpeed(int freq) +{ + delaySet = delay = frequency / freq; + repeatDelay = true; +} + +// setting future state to be called by run +// +void StateMachine::enter() +{ + if(stayHere()) return; + + pastState = nextState; + nextState = futureState; +} + +// setting next state to be called by run +// +void StateMachine::enter(StatePtr next) +{ + if(stayHere()) return; + + pastState = nextState; + nextState = next; +} + +// setting next state with delay (before) +// +void StateMachine::enter(StatePtr next, int delayTime) +{ + if(stayHere()) return; + + delay = (delayTime * frequency) / 1000; + repeatDelay = false; + + pastState = nextState; + nextState = next; +} + +// setting next state with repetition +// +void StateMachine::enterRep(StatePtr next, int count) +{ + if(stayHere()) return; + + repeatState = count; + pastState = nextState; + nextState = next; +} + +// setting next state with repetition and delay +// +void StateMachine::enterRep(StatePtr next, int count, int delayTime) +{ + if(stayHere()) return; + + delaySet = delay = (delayTime * frequency) / 1000; + repeatDelay = true; + + repeatState = count; + pastState = nextState; + nextState = next; +} + +// setting state and state after +// +void StateMachine::enterVia(StatePtr next, StatePtr then) +{ + if(stayHere()) return; + + pastState = nextState; + nextState = next; + futureState = then; +} + +// calling state +// +void StateMachine::call(StatePtr next) +{ + if(stayHere()) return; + + pastState = nextState; + futureState = nextState; + nextState = next; +} + +// setting state and state after with delay +// +void StateMachine::enterVia(StatePtr next, StatePtr after, int delayTime) +{ + if(stayHere()) return; + + delay = (delayTime * frequency) / 1000; + repeatDelay = false; + + pastState = nextState; + nextState = next; + futureState = after; +} + +// calling state +// +void StateMachine::call(StatePtr next, int delayTime) +{ + if(stayHere()) return; + + delay = (delayTime * frequency) / 1000; + repeatDelay = false; + + pastState = nextState; + futureState = nextState; + nextState = next; +} + + +// setting state to state list (program) +// +void StateMachine::enterList(StatePtr fin) +{ + if(stayHere()) return; + + pastState = nextState; + useProgList = true; + progIndex = 0; + finProgState = fin; +} + +// setting state to state list (program)and delay +// +void StateMachine::enterList(StatePtr fin, int delayTime) +{ + if(stayHere()) return; + + delay = (delayTime * frequency) / 1000; + repeatDelay = false; + + pastState = nextState; + useProgList = true; + progIndex = 0; + finProgState = fin; +} + +// setting state to state list (program) at a position +// +void StateMachine::enterListAt(StatePtr fin, int index) +{ + if(stayHere()) return; + + pastState = nextState; + useProgList = true; + progIndex = index; + finProgState = fin; +} + +// setting state to state list (program)at a position and delay +// +void StateMachine::enterListAt(StatePtr fin, int index, int delayTime) +{ + if(stayHere()) return; + + delay = (delayTime * frequency) / 1000; + repeatDelay = false; + + pastState = nextState; + useProgList = true; + progIndex = index; + finProgState = fin; +} + +// detecting the first call of a state +// +bool StateMachine::firstEnter() +{ + if(!firstEnterToggle) + return(false); + firstEnterToggle = false; + return(true); +} + +// reset first enter detector +// +void StateMachine::resetEnter() +{ + firstEnterToggle = true; +} + +// counting local cycles +// +bool StateMachine::cycle(int cnt) +{ + if(callCycleCnt <= 0) + { + callCycleCnt = cnt; + return(true); + } + callCycleCnt--; + return(false); +} +// +bool StateMachine::cycleSec() +{ + if(callCycleCnt <= 0) + { + callCycleCnt = frequency; + return(true); + } + callCycleCnt--; + return(false); +} + +// Alternativly returning true and false +// +bool StateMachine::toggle() +{ + markToggle = !markToggle; + return(markToggle); +} + +// Doing only once +// +bool StateMachine::oneShot() +{ + if(!markOneShot) return(false); + + markOneShot = false; + return (true); +} + +void StateMachine::setOneShot() +{ + markOneShot = true; +} + + +// Setable number of returning TRUE +// +void StateMachine::setCondCounter(unsigned int condVal) +{ + condCounter = condVal; +} + +bool StateMachine::condOpen() +{ + if(condCounter == 0) + return(false); + condCounter--; + return(true); +} + +// set the time-out value (milliseconds) +// +void StateMachine::setTimeOut(int toValue) +{ + timeOutCounter = (toValue * frequency) / 1000; +} + +// check the time-out counter +// +bool StateMachine::timeOut() +{ + if(timeOutCounter > 0) + return(false); + return(true); +} + +// start time measurement +// +void StateMachine::startTimeMeasure() +{ + timeMeasureCounter = 0; + timeMeasureOn = true; +} + +int StateMachine::getTimeMeasure(bool stop) +{ + if(stop) + timeMeasureOn = false; + return(cycleTime * timeMeasureCounter); +} + +unsigned long StateMachine::getExtTimeMeasure(bool stop) +{ + if(stop) + timeMeasureOn = false; + return(cycleTime * timeMeasureCounter); +} + +// --------------------------------------------------------------------------- +// Debug and statistic functions/methods +// --------------------------------------------------------------------------- +// +int StateMachine::getDelay() +{ + return(delay); +} diff --git a/sketches/_PIO_Sketches/Karger/SoaapBleMaster_Test_2/src/StateMachine/StateMachine.h b/sketches/_PIO_Sketches/Karger/SoaapBleMaster_Test_2/src/StateMachine/StateMachine.h new file mode 100644 index 0000000000000000000000000000000000000000..b5a6ecea89a1a4a81795bf2992e52dd58bb350d2 --- /dev/null +++ b/sketches/_PIO_Sketches/Karger/SoaapBleMaster_Test_2/src/StateMachine/StateMachine.h @@ -0,0 +1,171 @@ +// --------------------------------------------------------------------------- +// File: StateMachine.cpp +// Editors: Robert Patzke, +// Start: 07. February 2018 +// Last change: 07. February 2018 +// URI/URL: www.mfp-portal.de, homeautomation.x-api.de +// Licence: Creative Commons CC-BY-SA +// --------------------------------------------------------------------------- +// + +#include "stdlib.h" + + +#ifndef _StateMachine_h +#define _StateMachine_h +// --------------------------------------------------------------------------- + +#define NrOfSteps 32 + +#define AUTBREAK(x,y) { x.enter(y); return; } + +// --------------------------------------------------------------------------- +// class StateMachine +// --------------------------------------------------------------------------- +// + +class StateMachine +{ + // ------------------------------------------------------------------------- + // class specific data types + // ------------------------------------------------------------------------- + // + typedef void (*StatePtr)(void); + typedef unsigned long (*MicsecFuPtr)(void); + +private: + // ------------------------------------------------------------------------- + // local variables + // ------------------------------------------------------------------------- + // + int delay; // Setting of delay for next state + int delaySet; // Setup value for repeated delays + bool repeatDelay; // If true, every state is delayed (speed set) + int repeatState; // Controlled repeating a state + bool useVarState; // breaking the fixed sequence of states by + // using a variable state (in futureState) + + bool useProgList; // control progList usage + bool loopProgList; // looping proglist + StatePtr progList[NrOfSteps]; // dynamically created state run list + int progIndex; // Program counter (index to next state) + int progEndIdx; // Index to next empty progList entry + StatePtr finProgState; // State after using state list + MicsecFuPtr micsFuPtr; // Pointer to micsec function + + bool firstEnterToggle; // Is set to true when state changes + int timeOutCounter; // automatic decremented counter + + bool timeMeasureOn; // control of the measurement counter + unsigned long timeMeasureCounter; // triggered automatic incremented counter + + int callCycleCnt; // For cycles inside a state + bool markToggle; // For bit complements + bool markOneShot; // for doing only one time + + unsigned int condCounter; // Counter for questionable conditions + + // ------------------------------------------------------------------------- + // local functions/methods + // ------------------------------------------------------------------------- + // + bool stayHere(); + +public: + // ------------------------------------------------------------------------- + // public variables + // ------------------------------------------------------------------------- + // + StatePtr nextState; // Pointer for indirect calling next state + StatePtr pastState; // Pointer of the past state + StatePtr futureState; // Pointer to a future state (see useVarState) + StatePtr doAlways; // Pointer to a always called state + int cycleTime; // Cycle time in milliseconds + int frequency; // Frequency in Hertz (1/s) + int userStatus; // A number presenting the visible state + + // statistic information + // + static int StateMachine_InstCounter; + + unsigned int noStateCounter; // Counter for empty running of state machine + unsigned int instNumber; // Number of this instance + unsigned int runCounter; // Counter for running states + unsigned int curStateNumber; // Number of current state + + unsigned long curStateRuntime; // run time of latest state + unsigned long maxStateRuntime[4]; // Maximum run time of a state + unsigned long maxRuntimeNumber[4]; // Number of the state of maximum runtime + + // error and debug support + // + int userError; + + // ------------------------------------------------------------------------- + // constructors and initialisations + // ------------------------------------------------------------------------- + // + StateMachine(); + StateMachine(StatePtr firstState, StatePtr anyState, int cycle); + void begin(StatePtr firstState, StatePtr anyState, int cycle); + StateMachine(StatePtr firstState, StatePtr anyState, int cycle, MicsecFuPtr micsecFu); + void begin(StatePtr firstState, StatePtr anyState, int cycle, MicsecFuPtr micsecFu); + + // ------------------------------------------------------------------------- + // user functions + // ------------------------------------------------------------------------- + // + void run(); // has to be cyclic called + void setDelay(int delayTime); // delay before next state + void setSpeed(int freq); // internal run frequency + + void enter(); // set next to future state + void enter(StatePtr state); // set next state to run + void enter(StatePtr state, int delayTime); // ... delayed + + void enterRep(StatePtr state, int count); // repeat next state + void enterRep(StatePtr state, int count, int delayTime); + + void call(StatePtr state); // set next state and return + void call(StatePtr state, int delayTime); // ... delayed + + void enterVia(StatePtr next, StatePtr future); // next and then + void enterVia(StatePtr next, StatePtr future, int delayTime); + + void enterList(StatePtr fin); + void enterList(StatePtr fin, int delayTime); + + void enterListAt(StatePtr fin, int index); + void enterListAt(StatePtr fin, int index, int delayTime); + + bool firstEnter(); // true only, if the state is first entered + void resetEnter(); // reset first enter mark + bool cycle(int cnt); // true only, if called <cnt> times + bool cycleSec(); // true only, if a second passed + bool toggle(); // alternating return true and false + bool oneShot(); // only one time true for a call + void setOneShot(); // preparing oneShot to be true + + void setTimeOut(int toValue); // Set time-out counter + bool timeOut(); // Check time-out counter + void startTimeMeasure(); // Start time measurement + int getTimeMeasure(bool stop); // Time in milliseconds + + unsigned long getExtTimeMeasure(bool stop); // Time in milliseconds + + void setCondCounter(unsigned int cntVal); // Set condition counter + bool condOpen(); // Ask for open conditions + + // ------------------------------------------------------------------------- + // debug functions + // ------------------------------------------------------------------------- + // + int getDelay(); + +}; + + + + +// --------------------------------------------------------------------------- +#endif diff --git a/sketches/_PIO_Sketches/Karger/SoaapBleMaster_Test_2/src/StateMachine/library.json b/sketches/_PIO_Sketches/Karger/SoaapBleMaster_Test_2/src/StateMachine/library.json new file mode 100644 index 0000000000000000000000000000000000000000..4dbee447df0f4ef48684a8d78288826ff419108f --- /dev/null +++ b/sketches/_PIO_Sketches/Karger/SoaapBleMaster_Test_2/src/StateMachine/library.json @@ -0,0 +1,4 @@ +{ + "name": "StateMachine", + "version": "0.0.0+20220823165932" +} \ No newline at end of file diff --git a/sketches/_PIO_Sketches/Karger/SoaapBleMaster_Test_2/src/environment/IntrfBuf.h b/sketches/_PIO_Sketches/Karger/SoaapBleMaster_Test_2/src/environment/IntrfBuf.h new file mode 100644 index 0000000000000000000000000000000000000000..c2f41d77dacb2618fee37685820740222e70b8b3 --- /dev/null +++ b/sketches/_PIO_Sketches/Karger/SoaapBleMaster_Test_2/src/environment/IntrfBuf.h @@ -0,0 +1,48 @@ +//----------------------------------------------------------------------------- +// Thema: Social Manufacturing Network / Development Environment +// Datei: IntrfBuf.h +// Editor: Robert Patzke +// URI/URL: www.mfp-portal.de +//----------------------------------------------------------------------------- +// Lizenz: CC-BY-SA (wikipedia: Creative Commons) +// Datum: 22. November 2021 +// +// Eine Schnittstelle zu Puffern (speziell Ringpuffer für Kommunikation) +// + +#ifndef IntrfBuf_h +#define IntrfBuf_h +// ---------------------------------------------------------------------------- + +#include "arduinoDefs.h" + + +class IntrfBuf +{ +public: + // -------------------------------------------------------------------------- + // Konfigurationen + // -------------------------------------------------------------------------- + // + + // -------------------------------------------------------------------------- + // Steuerfunktionen + // -------------------------------------------------------------------------- + // + + + // -------------------------------------------------------------------------- + // Datenzugriffe + // -------------------------------------------------------------------------- + // + virtual bool getByteSnd(byte *dest); // Byte aus Puffer zum Senden holen + // Rückgabe FALSE: Puffer leer + + virtual void putByteRec(byte b); // Byte vom Empfang an Puffer geben + + virtual int putSeq(byte *msg, int n); // Bytefolge an Puffer übergeben + +}; + +// ---------------------------------------------------------------------------- +#endif // IntrfBuf_h diff --git a/sketches/_PIO_Sketches/Karger/SoaapBleMaster_Test_2/src/environment/IntrfGpio.h b/sketches/_PIO_Sketches/Karger/SoaapBleMaster_Test_2/src/environment/IntrfGpio.h new file mode 100644 index 0000000000000000000000000000000000000000..d37fdf6765d077ac1bc20944080dc257f55e0a8a --- /dev/null +++ b/sketches/_PIO_Sketches/Karger/SoaapBleMaster_Test_2/src/environment/IntrfGpio.h @@ -0,0 +1,122 @@ +//----------------------------------------------------------------------------- +// Thema: Social Manufacturing Network / Development Environment +// Datei: IntrfGpio.h +// Editor: Robert Patzke +// URI/URL: www.mfp-portal.de +//----------------------------------------------------------------------------- +// Lizenz: CC-BY-SA (wikipedia: Creative Commons) +// Datum: 04. April 2022 +// +// Eine Schnittstelle zu den unterschiedlichen Ports in Mikrocontrollern +// + +#ifndef IntrfGpio_h +#define IntrfGpio_h +// ---------------------------------------------------------------------------- + +#include "arduinoDefs.h" + +typedef enum _ifPortNumber +{ + ifPort0, + ifPort1, + ifPort2, + ifPort3, + ifPort4, + ifPort5, + ifPort6, + ifPort7, + ifPort8, + ifPort9 +} ifPortNumber; + +typedef enum +{ + GEnoError, + GEcdictPar +} GpioError; + +typedef struct _GpioMask +{ + dword port; + dword pins; +} GpioMask, *GpioMaskPtr; + +typedef struct _GpioExtMask +{ + dword port; + dword pins; + _GpioExtMask *next; +} GpioExtMask, *GpioExtMaskPtr; + +typedef struct _GpioRef +{ + dword *ioPtr; + dword pins; +} GpioRef, *GpioRefPtr; + +typedef struct _GpioExtRef +{ + dword *ioPtr; + dword pins; + _GpioExtRef *next; +} GpioExtRef, *GpioExtRefPtr; + +typedef struct _GpioExtVal +{ + dword value; + _GpioExtVal *next; +} GpioExtVal, *GpioExtValPtr; + +// Spezifikation der Schnittstellentreiber +// +#define IfDrvInput 0x0000 +#define IfDrvOutput 0x0001 +#define IfDrvStrongHigh 0x0002 +#define IfDrvStrongLow 0x0004 +#define IfDrvOpenDrain 0x0008 +#define IfDrvOpenSource 0x0010 +#define IfDrvPullUp 0x0020 +#define IfDrvPullDown 0x0040 +#define IfDrvPullStrong 0x0080 + +typedef enum +{ + ArdD2D5, + ArdA0A3, + ArdA4A5, + ArdA0A5, + ArdA4A7, + ArdA0A7 +} ArdMask; + +class IntrfGpio +{ +public: + + //virtual ~IntrfGpio(); + + // -------------------------------------------------------------------------- + // Konfigurationen + // -------------------------------------------------------------------------- + // + virtual GpioError config(int nr, unsigned int cnfBits, GpioExtRefPtr refPtr); + virtual GpioError config(int nrFrom, int nrTo, unsigned int cnfBits, GpioExtRefPtr refPtr); + virtual GpioError config(GpioExtMask mask, unsigned int cnfBits, GpioExtRefPtr refPtr); + virtual GpioError configArd(ArdMask ardMask, unsigned int cnfBits); + + // -------------------------------------------------------------------------- + // Anwendungsfunktionen + // -------------------------------------------------------------------------- + // + virtual void read(GpioExtRefPtr refPtr, GpioExtValPtr valPtr); + virtual dword readArd(ArdMask ardMask); + + virtual void write(GpioExtRefPtr refPtr, GpioExtValPtr valPtr); + virtual void writeArd(ArdMask ardMask, dword value); + virtual void set(GpioExtRefPtr refPtr); + virtual void clr(GpioExtRefPtr refPtr); +}; + +// ---------------------------------------------------------------------------- +#endif //IntrfGpio_h diff --git a/sketches/_PIO_Sketches/Karger/SoaapBleMaster_Test_2/src/environment/IntrfRadio.h b/sketches/_PIO_Sketches/Karger/SoaapBleMaster_Test_2/src/environment/IntrfRadio.h new file mode 100644 index 0000000000000000000000000000000000000000..470277ab4f365581507365d1f412a47683463662 --- /dev/null +++ b/sketches/_PIO_Sketches/Karger/SoaapBleMaster_Test_2/src/environment/IntrfRadio.h @@ -0,0 +1,154 @@ +//----------------------------------------------------------------------------- +// Thema: Social Manufacturing Network / Development Environment +// Datei: IntrfRadio.h +// Editor: Robert Patzke +// URI/URL: www.mfp-portal.de +//----------------------------------------------------------------------------- +// Lizenz: CC-BY-SA (wikipedia: Creative Commons) +// Datum: 9. Mai 2021 +// +// Eine Schnittstelle zu den unterschiedlichen Transceivern in Mikrocontrollern +// oder Boards mit Mikrocontrollern und Radio-Transceivern +// + +#ifndef IntrfRadio_h +#define IntrfRadio_h +// ---------------------------------------------------------------------------- + +#include "arduinoDefs.h" +#include "bleSpec.h" + +typedef struct _TxState +{ + unsigned int prgLoopPrep; + unsigned int evtLoopRampUp; + unsigned int evtLoopTrans; + byte * txBufferPtr; +} TxState, *TxStatePtr; + +typedef struct _Channel +{ + int idx; + int freq; +} Channel, *ChannelPtr; + +// Zustand des Datenempfangs (Bit) +// +#define RECSTAT_ADDRESS 0x0001 +#define RECSTAT_PAYLOAD 0x0002 +#define RECSTAT_END 0x0004 +#define RECSTAT_DISABLED 0x0008 +#define RECSTAT_CRCOK 0x0010 + +// Modi für das Senden von Telegrammen +// +typedef enum _TxMode +{ + txmBase, // Einzelne Sendung, Endezustand DISABLED + txmRepStart, // Wiederholte Sendung Start, Endezustand END + txmRepCont, // Wiederholte Sendung Fortsetzung, Endezustand END + txmRepEnd, // Wiederholte Sendung Ende, Endezustand DISABLED + txmReadPrep, // Einzelne Sendung mit Empfangsvorbereitung, Endezustand READY + txmRead, // Einzelne Sendung und Empfang, Endezustand END + txmPoll, // Einzelne Sendung und Empfang, Endezustand DISABLED + txmReadS, // Einzelne sendung und Empfang mit Daten, Endezustand END + txmRespE, // Empfang für spezifische Antwort (leeres Polling) + txmResp // Empfang für spezifische Antwort (Datenübertragung) +} TxMode; +// +#define NrOfTxModes 10 + +// Protokollspezifische Adresseninhalte und Festlegungen +// +#define PollPduSize 8 +#define PollAdrSize 6 + +// len = PduMem[1] +#define BLE_LEN pduMem[1] +// Adr[1] = PduMem[3] +#define BLE_ADR1 pduMem[3] + +#define SOAAP_NAK 0x40 +#define SOAAP_EADR 0x80 + +// Modeabhängige Statistikdaten +// +typedef struct _TxStatistics +{ + TxMode mode; + dword interrupts; + dword recs; + dword sendings; + dword aliens; + dword wrongs; + dword pollAcks; + dword pollNaks; + dword crcErrors; + dword intErrors; + byte memDumpRec[16]; + byte memDumpSnd[16]; +} TxStatistics, *TxStatisticsPtr; + +class IntrfRadio +{ +public: + // Kanalfrequenzen (Offsets zur Basisfrequenz) und Whitening-Preset + // Die ersten 3 Kanäle sind Bewerbungskanäle. + // Daran anschließend sind die Kanäle grob nach Frequenz einsortiert. + // Diese Liste kann zur Laufzeit an Störungen angepasst werden und wird aufsteigend angewendet + // + Channel channelList[40] = + { + {37, 2} , {38,26} , {39,80} , { 1, 6} , { 3,10} , { 5,14} , { 7,18} , { 9,22} , + {12,30} , {14,34} , {16,38} , {18,42} , {20,46} , {22,50} , {24,54} , {26,58} , + {28,62} , {30,66} , {32,70} , {34,74} , {35,76} , { 2, 8} , { 4,12} , { 6,16} , + { 8,20} , {33,72} , {31,68} , {13,32} , {15,36} , {17,40} , {19,44} , {21,48} , + {23,52} , {25,56} , {27,60} , {29,64} , {11,28} , {10,24} , { 0, 4} , {36,78} + }; + + //virtual ~IntrfRadio(); + + // -------------------------------------------------------------------------- + // Konfigurationen + // -------------------------------------------------------------------------- + // + virtual void begin(); + virtual void setAccessAddress(dword addr); + virtual void setPacketParms(blePduType type); + + // -------------------------------------------------------------------------- + // Steuerfunktionen + // -------------------------------------------------------------------------- + // + virtual void setChannel(int chnr); // Schalten physikalischer Kanal + virtual int sendSync(bcPduPtr inPduPtr, TxStatePtr refState); + + virtual void send(bcPduPtr inPduPtr, TxMode txMode); + virtual void send(bcPduPtr inPduPtrE, bcPduPtr inPduPtrS, TxMode txMode, bool newValues); + // Senden (und/oder Empfang) eines Telegramms in einem festgelegten Modus + + virtual void disable(TxMode txMode); // Funk AUS für Betriebswechsel + virtual bool disabled(TxMode txMode); // Abfrage, ob ausgeschaltet + virtual void cont(TxMode txMode); // aktuellen Vorgang fortsetzen + virtual bool fin(TxMode txMode, bool *err); // Abfrage ob aktueller Vorgang beendet +// virtual int getRecData(bcPduPtr data, TxMode txMode, int max); // Lennard: Deaktiviert + + virtual int startRec(); // Datenempfang starten + virtual int contRec(); // Datenempfang fortsetzen + virtual int endRec(); // Datenempfang beenden + virtual int checkRec(); // Zustand Datenempfang feststellen + virtual int getRecData(bcPduPtr data, int max); // Empfangene Daten lesen + + virtual void setPower(int DBm); // Leistung des Senders in DBm + + // -------------------------------------------------------------------------- + // Datenzugriffe + // -------------------------------------------------------------------------- + // + virtual int getStatistics(TxStatisticsPtr dest); + virtual int getState(); // Chip-abhängiger Funk-Status + +}; + +// ---------------------------------------------------------------------------- +#endif // IntrfRadio_h diff --git a/sketches/_PIO_Sketches/Karger/SoaapBleMaster_Test_2/src/environment/IntrfSerial.h b/sketches/_PIO_Sketches/Karger/SoaapBleMaster_Test_2/src/environment/IntrfSerial.h new file mode 100644 index 0000000000000000000000000000000000000000..909a810a3282ef0e1ee36e79286bd5c4df0bb929 --- /dev/null +++ b/sketches/_PIO_Sketches/Karger/SoaapBleMaster_Test_2/src/environment/IntrfSerial.h @@ -0,0 +1,101 @@ +//----------------------------------------------------------------------------- +// Thema: Social Manufacturing Network / Development Environment +// Datei: IntrfSerial.h +// Editor: Robert Patzke +// URI/URL: www.mfp-portal.de +//----------------------------------------------------------------------------- +// Lizenz: CC-BY-SA (wikipedia: Creative Commons) +// Datum: 17. November 2021 +// +// Eine Schnittstelle zu den seriellen Schnittstellen in Mikrocontrollern +// oder Boards mit Mikrocontrollern und seriellen schnittstellen +// + +#ifndef IntrfSerial_h +#define IntrfSerial_h +// ---------------------------------------------------------------------------- + +#include "arduinoDefs.h" +#include "IntrfBuf.h" + +typedef enum _SerSpeed +{ + Baud1200, + Baud2400, + Baud4800, + Baud9600, + Baud14400, + Baud19200, + Baud28800, + Baud31250, + Baud38400, + Baud56000, + Baud57600, + Baud76800, + Baud115200, + Baud230400, + Baud250000, + Baud460800, + Baud921600, + Baud1Meg +} SerSpeed; + +typedef enum _SerType +{ + stStd, // Typischer Ausgang ca. 2 mA + stPow, // Starker Ausgang ca. 10 mA + stCur // Open Collector/Drain ca. 10 mA Stromschleife +} SerType; + +typedef struct _SerParams +{ + int inst; // Nummer (Index) der Ser-Instanz + int txdPort; // Nummer (Index) des Port fuer TX + int txdPin; // Nummer (Index) des Pin fuer TX + int rxdPort; // Nummer (Index) des Port fuer RX + int rxdPin; // Nummer (Index) des Pin fuer RX + SerSpeed speed; // Bitrate (Baud) + SerType type; // Ausgang +} SerParams, *SerParamsPtr; + +typedef enum _SerError +{ + SEnoError +} SerError; + + +class IntrfSerial +{ +public: + // -------------------------------------------------------------------------- + // Konfigurationen + // -------------------------------------------------------------------------- + // + virtual void begin(SerParamsPtr serParPtr, IntrfBuf * bufferIf); + + // -------------------------------------------------------------------------- + // Steuerfunktionen + // -------------------------------------------------------------------------- + // + virtual void resuSend(); // Fortsetzen des Interrupt-Sendebetriebs + virtual void startSend(); // Starten des Sendebetriebs + virtual void stopSend(); // Anhalten des Sendebetriebs + + virtual void startRec(); // Starten des Empfangsbetriebs + virtual void stopRec(); // Anhalten des Empfangsbetriebs + + + // -------------------------------------------------------------------------- + // Datenzugriffe + // -------------------------------------------------------------------------- + // + virtual bool condSend(byte c); // Bedingtes Senden eines Zeichens + + virtual int getLastError(); // Letzten Fehler lesen (Bits) + virtual int getAnyError(); // Alle vorgekommenen Fehlerbits + virtual dword getErrCount(); // Anzahl der Fehler lesen + +}; + +// ---------------------------------------------------------------------------- +#endif // IntrfRadio_h diff --git a/sketches/_PIO_Sketches/Karger/SoaapBleMaster_Test_2/src/environment/IntrfTimer.h b/sketches/_PIO_Sketches/Karger/SoaapBleMaster_Test_2/src/environment/IntrfTimer.h new file mode 100644 index 0000000000000000000000000000000000000000..2777f5ba7b80b1116baa9030c452037dc4507952 --- /dev/null +++ b/sketches/_PIO_Sketches/Karger/SoaapBleMaster_Test_2/src/environment/IntrfTimer.h @@ -0,0 +1,55 @@ +//----------------------------------------------------------------------------- +// Thema: Social Manufacturing Network / Development Environment +// Datei: IntrfTimer.h +// Editor: Robert Patzke +// URI/URL: www.mfp-portal.de +//----------------------------------------------------------------------------- +// Lizenz: CC-BY-SA (wikipedia: Creative Commons) +// Datum: 29. Juni 2021 +// +// Eine Schnittstelle zu den unterschiedlichen Timern in Mikrocontrollern +// + +#ifndef IntrfTimer_h +#define IntrfTimer_h +// ---------------------------------------------------------------------------- + +#include "arduinoDefs.h" + +typedef enum _ifTimerNumber +{ + ifTimer0, + ifTimer1, + ifTimer2, + ifTimer3, + ifTimer4, + ifTimer5, + ifTimer6, + ifTimer7, + ifTimer8, + ifTimer9 +} ifTimerNumber; + +class IntrfTimer +{ +public: + + //virtual ~IntrfTimer(); + + // -------------------------------------------------------------------------- + // Konfigurationen + // -------------------------------------------------------------------------- + // + virtual void setMilli(ifTimerNumber timNr, int milliSec, int repeat); + //virtual void setMilli(ifTimerNumber timNr, int milliSec, int repeat, dword ISR); + + // -------------------------------------------------------------------------- + // Steuerfunktionen + // -------------------------------------------------------------------------- + // + virtual bool milli(); // Abfrage des Timer, <true> wenn abgelaufen + +}; + +// ---------------------------------------------------------------------------- +#endif //IntrfTimer_h diff --git a/sketches/_PIO_Sketches/Karger/SoaapBleMaster_Test_2/src/environment/IntrfTw.h b/sketches/_PIO_Sketches/Karger/SoaapBleMaster_Test_2/src/environment/IntrfTw.h new file mode 100644 index 0000000000000000000000000000000000000000..f0d97b622e98f8f48ee8f066912caf1b4723bc89 --- /dev/null +++ b/sketches/_PIO_Sketches/Karger/SoaapBleMaster_Test_2/src/environment/IntrfTw.h @@ -0,0 +1,125 @@ +//----------------------------------------------------------------------------- +// Thema: Social Manufacturing Network / Development Environment +// Datei: IntrfTw.h +// Editor: Robert Patzke +// URI/URL: www.mfp-portal.de +//----------------------------------------------------------------------------- +// Lizenz: CC-BY-SA (wikipedia: Creative Commons) +// Datum: 3. Juni 2021 +// +// Eine Schnittstelle zu den unterschiedlichen I2C Schnittstellen +// oder Boards mit geeigneten Mikrocontrollern +// + +#ifndef IntrfTw_h +#define IntrfTw_h +// ---------------------------------------------------------------------------- + +#include "arduinoDefs.h" + +typedef enum _TwiDevType +{ + TwiMaster, + TwiSlave +} TwiDevType; + +typedef enum _TwiSpeed +{ + Twi100k, // Standard, sollte unterstützt werden + Twi250k, + Twi400k // Schnell, sollte unterstützt werden +} TwiSpeed; + +typedef struct _TwiParams +{ + int inst; // Nummer (Index) der Twi-Instanz + TwiDevType type; // Auswahl Master/Slave + int clkPort; // Nummer (Index) des Port fuer Takt + int clkPin; // Nummer (Index) des Pin fuer Takt + int dataPort; // Nummer (Index) des Port fuer Daten + int dataPin; // Nummer (Index) des Pin fuer Daten + TwiSpeed speed; +} TwiParams, *TwiParamsPtr; + +typedef enum _TwiError +{ + TEnoError +} TwiError; + +typedef enum _TwiStatus +{ + TwStUnborn, + TwStRdReq, + TwStWrReq, + TwStSent, + TwStRecvd, + TwStFin = 0x0080, + TwStError = 0x0100, + TwStOverrun = 0x0101, + TwStAdrNak = 0x0102, + TwStDataNak = 0x0104 +} TwiStatus; + +typedef struct _TwiByte +{ + TwiStatus twiStatus; + byte value; +} TwiByte, *TwiBytePtr; + +typedef struct _TwiWord +{ + TwiStatus twiStatus; + word value; +} TwiWord, *TwiWordPtr; + +typedef struct _TwiByteSeq +{ + TwiStatus twiStatus; + int len; + byte *valueRef; +} TwiByteSeq, *TwiByteSeqPtr; + + +class IntrfTw +{ +public: + // -------------------------------------------------------------------------- + // Konstruktoren und Initialisierungen + // -------------------------------------------------------------------------- + // + virtual TwiError begin(TwiParamsPtr inParPtr); + + //virtual ~IntrfTw(); + + // -------------------------------------------------------------------------- + // Konfigurationen + // -------------------------------------------------------------------------- + // + virtual void getParams(TwiParamsPtr parPtr); + + // -------------------------------------------------------------------------- + // Steuerfunktionen + // -------------------------------------------------------------------------- + // + + // -------------------------------------------------------------------------- + // Datenaustausch + // -------------------------------------------------------------------------- + // + // asynchrone Kommunikation, Zustand in TwiByte.twiStatus + // + virtual TwiError sendByte(int adr, TwiBytePtr refByte); + virtual TwiError sendByteReg(int adr, int reg, TwiBytePtr refByte); + virtual TwiError recByteReg(int adr, int reg, TwiBytePtr refByte); + virtual TwiError recByteRegSeq(int adr, int reg, TwiByteSeqPtr refByteSeq); + + // synchrone Kommunikation + // + virtual TwiStatus writeByteReg(int adr, int reg, byte value); + virtual int readByteReg(int adr, int reg); + virtual TwiStatus readByteRegSeq(int adr, int reg, TwiByteSeqPtr refByteSeq); + +}; + +// ---------------------------------------------------------------------------- +#endif // IntrfTw_h diff --git a/sketches/_PIO_Sketches/Karger/SoaapBleMaster_Test_2/src/environment/SoaapBleMaster.h b/sketches/_PIO_Sketches/Karger/SoaapBleMaster_Test_2/src/environment/SoaapBleMaster.h new file mode 100644 index 0000000000000000000000000000000000000000..98bd22eb99c0839cf9f5ad554dd116b21c0afd81 --- /dev/null +++ b/sketches/_PIO_Sketches/Karger/SoaapBleMaster_Test_2/src/environment/SoaapBleMaster.h @@ -0,0 +1,63 @@ +// ---------------------------------------------------------------------------- +// SoaapBleMaster.h +// Beispielhafte Anwendung SOAAP / Steuerung optischer und akustischer Ausgaben +// Kommunikation über BLE-Funkanäle mit Bewerbungstelegrammen +// P o l l i n g - M a s t e r +// ---------------------------------------------------------------------------- +// Editor: Robert Patzke +// URI/URL: www.mfp-portal.de +//----------------------------------------------------------------------------- +// Lizenz: CC-BY-SA (wikipedia: Creative Commons) +// Datum: 1. November 2021 +// Letzte Bearbeitung: 15. März 2022 +// + +#ifndef SoaapBleMaster_h +#define SoaapBleMaster_h + +// Vordefinitionen, Festlegungen zur Kompilierung +// +#define DebugTerminal +// Mit dieser Definition werden die Klasse Monitor und weitere Testmethoden +// eingebunden, womit ein anwendungsorientiertes Debugging möglich ist + +//#define TEST001 +// Ausgaben an serielle schnittstelle zur Prüfung der ap-Zustandsmaschine + +#include "LoopCheck.h" +#include "StateMachine.h" +#include "nRF52840Radio.h" +#include "BlePoll.h" +#include "ComRingBuf.h" +#include "nRF52840Ser.h" +#include "SoaapMsg.h" +#include "Monitor.h" + +// ---------------------------------------------------------------------------- +// Vorwärtsreferenzen +// ---------------------------------------------------------------------------- +// +void ctrlIdle(); +void ctrlInit(); +void sendCtrl(); +void checkCtrl(); + +void apInit(); +void apWaitDE(); +void apWaitMeas(); +void apProcMeas(); + + +#ifdef DebugTerminal +// ---------------------- +void smInit() ; +void smCheckJobs() ; +void smDebDword() ; +void smCtrlPolling() ; +void smWaitPolling() ; +void smReadPollValues() ; +void smCheckSer(); +// ---------------------- +#endif + +#endif /* SoaapBleMaster_h */ diff --git a/sketches/_PIO_Sketches/Karger/SoaapBleMaster_Test_2/src/environment/SoaapBleSlave.h b/sketches/_PIO_Sketches/Karger/SoaapBleMaster_Test_2/src/environment/SoaapBleSlave.h new file mode 100644 index 0000000000000000000000000000000000000000..f3ae7f7500126e35f19524b4188a3044d43dfaf4 --- /dev/null +++ b/sketches/_PIO_Sketches/Karger/SoaapBleMaster_Test_2/src/environment/SoaapBleSlave.h @@ -0,0 +1,43 @@ +#ifndef SoaapBleSlave_h +#define SoaapBleSlave_h + +#include "LoopCheck.h" +#include "StateMachine.h" +#include "nRF52840Radio.h" +#include "BlePoll.h" +#include "ComRingBuf.h" +#include "nRF52840Ser.h" +#include "SoaapMsg.h" +#include "Monitor.h" +#include "nRF52840Twi.h" +#include "SensorLSM9DS1.h" +#include "nRF52840Gpio.h" + +//#define SlaveACM1 +bool sendData(PlpType plpType, byte *dest); +bool getValues(PlpType plpType, byte *dest); +void smInit(); +void smCheckJobs(); +void smCheckSens(); + +void smDebDword(); +void smCtrlPolling(); +void smWaitPolling(); +void smSensReset1(); +void smSensReset2(); + +void smSensGetValues1(); +void smSensGetValues2(); +void smSensGetValues3(); +void smSensGetValues4(); +void smSensGetValues5(); +void smSensGetValues6(); +void smSensGetValues7(); + +void smSensGetSoaapValues(); +void smSensDebugValues(); + +void smSensGetErrors(); +void smSensGetTimeOuts(); +void smSensGetRunCounts(); +#endif \ No newline at end of file diff --git a/sketches/_PIO_Sketches/Karger/SoaapBleMaster_Test_2/src/environment/arduinoDefs.h b/sketches/_PIO_Sketches/Karger/SoaapBleMaster_Test_2/src/environment/arduinoDefs.h new file mode 100644 index 0000000000000000000000000000000000000000..4830c5d860683336800903c177b10c53fcb73736 --- /dev/null +++ b/sketches/_PIO_Sketches/Karger/SoaapBleMaster_Test_2/src/environment/arduinoDefs.h @@ -0,0 +1,53 @@ +//----------------------------------------------------------------------------- +// Thema: Social Manufacturing Network / Definitions instead Arduino +// Datei: arduinoDefs.h +// Editor: Robert Patzke +// URI/URL: www.mfp-portal.de +//----------------------------------------------------------------------------- +// Lizenz: CC-BY-SA (wikipedia: Creative Commons) +// +// These definitions shall encapsulate the Arduino environment +// The file should be included instead of Arduino.h for arbitrary environments +// + +#ifndef _arduinoDefs_h +#define _arduinoDefs_h + +// --------------------------------------------------------------------------- +// Simple type definitions and settings +// --------------------------------------------------------------------------- +// +#undef byte +#undef word +#undef dword + +#define byte unsigned char +#define word unsigned short +#define dword unsigned long + +#ifdef smnLinGcc64 + +#undef byte +#undef word +#undef dword + +#define byte unsigned char +#define word unsigned short +#define dword unsigned int + +#endif + +// --------------------------------------------------------------------------- +// Complex type definitions +// --------------------------------------------------------------------------- +// The following types are more complex definitions with Arduino. +// But here simple types are used if possible, because we only care for the +// environment that is needed by Social Manufacturing Network +// + +#ifndef IPAddress + #define IPAddress byte * +#endif + + +#endif // _arduinoDefs_h diff --git a/sketches/_PIO_Sketches/Karger/SoaapBleMaster_Test_2/src/environment/bleSpec.h b/sketches/_PIO_Sketches/Karger/SoaapBleMaster_Test_2/src/environment/bleSpec.h new file mode 100644 index 0000000000000000000000000000000000000000..a4993a39fee05fa5162fc888acf0804e5fc59254 --- /dev/null +++ b/sketches/_PIO_Sketches/Karger/SoaapBleMaster_Test_2/src/environment/bleSpec.h @@ -0,0 +1,86 @@ +//----------------------------------------------------------------------------- +// Thema: Social Manufacturing Network / Development Environment +// Datei: bleSpec.h +// Editor: Robert Patzke +// URI/URL: www.mfp-portal.de +//----------------------------------------------------------------------------- +// Lizenz: CC-BY-SA (wikipedia: Creative Commons) +// Datum: 8. Mai 2021 +// +// Der Inhalt dieser Datei ist der Blootooth Spezifikation 5.2 entnommen +// bzw. daran angelehnt. +// Insbesondere dem Teil 6, Low Energy Controller +// + +#ifndef bleSpec_h +#define bleSpec_h +// ---------------------------------------------------------------------------- + +#ifndef octet +typedef unsigned char octet; +#endif + +#define VersionBTS 52 +#define TypeBTS BLE + +// ---------------------------------------------------------------------------- +// Festlegungen für die Bewerbungskanäle (Advertizing Physical Channels) +// ---------------------------------------------------------------------------- + +// Basisfrequenz in MHz +#define BaseFrequency 2400 + +// Zugriffsadresse (Access Address) +#define AdvAccAddr 0x8E89BED6 + +// CRC-Polynom +#define PolynomCRC 0x0100065B + +// CRC-Startwert +#define AdvStartCRC 0x555555 + +// Geräteadresse +typedef octet BD_ADR[6]; + +// Telegrammtypen (PDU Types) +#define ADV_IND 0x0 +#define ADV_DIRECT_IND 0x1 +#define ADV_NONCONN_IND 0x2 +#define SCAN_REQ 0x3 +#define SCAN_RSP 0x4 +#define CONNECT_IND 0x5 +#define ADV_SCAN_IND 0x6 + +// Kennzeichnung Art der Geräteadresse (Device Address Mark, TxAdd = 1, random) +#define DevAdrType 0x2 + +// Telegrammkopf ohne Längenbyte +#define HeadS0B ((ADV_NONCONN_IND << 4) | DevAdrType) +#define HeadS0BS ((ADV_SCAN_IND << 4) | DevAdrType) + +// Datenstruktur für das zu sendende Telegramm +// bei der Bewerbung (Advertising) +// +typedef struct _bcPdu // Beacon - PDU +{ + byte head; // Header = PDU-Typ und Adresskennung (S0 bei nRF52840) + byte len; // Länge des Telegramms inkl. Adresse (LENGTH bei nRF52840) + byte adr0; // niedrigstwertiges Adressbyte (S1 bei nRF52840) + byte adr1; // + byte adr2; // Das ist die Geräteadresse, die hier wahlfrei ist + byte adr3; // Sie wird zur Identifikation des Gerätes verwendet + byte adr4; // + byte adr5; // höchstwertiges Addressbyte + byte data[31]; // Nutzdaten (maximale Anzahl nach BLE-Spez.) +} bcPdu, *bcPduPtr; + +// Telegrammtypen +// +typedef enum _blePduType +{ + bptAdv, // Standard-Bewerbungstelegramm + bptAux +} blePduType; + +// ---------------------------------------------------------------------------- +#endif // bleSpec_h diff --git a/sketches/_PIO_Sketches/Karger/SoaapBleMaster_Test_2/src/environment/environment.h b/sketches/_PIO_Sketches/Karger/SoaapBleMaster_Test_2/src/environment/environment.h new file mode 100644 index 0000000000000000000000000000000000000000..311c3331bd39a97884ba12b85375b08a418813d0 --- /dev/null +++ b/sketches/_PIO_Sketches/Karger/SoaapBleMaster_Test_2/src/environment/environment.h @@ -0,0 +1,126 @@ +//----------------------------------------------------------------------------- +// Thema: Social Manufacturing Network / Development Environment +// Datei: environment.h +// Editor: Robert Patzke +// URI/URL: www.mfp-portal.de +//----------------------------------------------------------------------------- +// Lizenz: CC-BY-SA (wikipedia: Creative Commons) +// + +#ifndef _environment_h +#define _environment_h + +#ifdef smnDEFBYBUILD + +// Alternative Festlegungen durch Settings in der Build-Umgebung der IDE +// Das erspart die Verwaltung mehrerer/unterschiedlicher environment.h Dateien +// in den Projekten +// + #ifdef smnUBUNTU_ECLIPSE + // Meine Entwicklungs- und Testumgebung auf dem Notebook unter UBUNTU + // für Sketche, die auf dem PC laufen (u.a. zum Debuggen) + + #define smnSimLinux + #define smnNotebook + #define smnLINUX + #define smnDebugLinuxConsole + + #endif + + #ifdef smnWIN32_VS + // Meine Entwicklungs- und Testumgebung auf dem Notebook unter Windows + // für Sketche, die auf dem PC laufen (u.a. zum Debuggen) + + #define smnSimWindows + #define smnNotebook + #define smnWIN32 + #define smnDebugWindowsConsole + + #endif + + #ifdef smnSLOELIN + // Mit Sloeber auf Ubuntu/Linux für Entwicklungen zum ESP32 + // + + #define smnDebugArduino + #define smnSloeber + #define smnESP32_DEV + #define smnESP32 + #define smnSerial Serial + #endif + + #ifdef smnSLOEDUE + // Mit Sloeber auf Ubuntu/Linux für Entwicklungen zum Arduino Due + // + + #define smnDebugArduino + #define smnSloeber + #define smnArduinoDUE + #define smnArduinoShieldEth + #define smnSAM3X + #define smnSerial Serial + #endif + + #ifdef smnNANOBLE33 + #define smnDebugArduino + #define smnSloeber + #define smnArduinoNanoBLE33 + #define smnNRF52840 + #define smnSerial Serial + #endif + + #ifdef smnSLOESAMD21 + #define smnDebugArduino + #define smnSloeber + #define smnArduinoZeroSamD21 + #define smnSAMD21G18 + #define smnSD21MINI + #define smnSerial SerialUSB + #endif + +#else + +// Die Definitionen werden hier in den meisten Fällen grundsetzlich ausgewertet, +// nicht über spezifische Werte. +// Die Abfrage geschieht also mit #ifdef +// Daraus folgt hier eine Liste der Möglichkeiten, die beliebig erweitert werden kann. +// Die Auswahl erfolgt schließlich über aus- bzw. einkommentieren. +// + +// Übergeordnete Festlegungen +// --------------------------------------------------------------------------- +// +#define smnDebugArduino +//#define smnDebugLinuxConsole +// + +// IDE, Editor, etc. +// --------------------------------------------------------------------------- +// +//#define smnSimLinux +#define smnSloeber +//#define smnArduinoIDE +//#define smnPlatformIO + +// Hardware, Boards, etc. +// --------------------------------------------------------------------------- +// +//#define smnNotebook +//#define smnESP32_DEV +#define smnNodeMCU10 +//#define smnArduinoDUE +//#define smnArduinoShieldEth +//#define smnArduinoShieldWiFi +#define smnSerial Serial + +// Prozessoren, Microcontroller, Betriebssysteme, etc. +// --------------------------------------------------------------------------- +// +//#define smnLINUX +//#define smnESP32 +#define smnESP8266 +//#define smnSAM3X + +#endif // smnDEFBYBUILD + +#endif // _environment_h diff --git a/sketches/_PIO_Sketches/Karger/SoaapBleMaster_Test_2/src/environment/library.json b/sketches/_PIO_Sketches/Karger/SoaapBleMaster_Test_2/src/environment/library.json new file mode 100644 index 0000000000000000000000000000000000000000..9e3641f6fb0e38c5e74b3c3cee96651efbb2fdaa --- /dev/null +++ b/sketches/_PIO_Sketches/Karger/SoaapBleMaster_Test_2/src/environment/library.json @@ -0,0 +1,4 @@ +{ + "name": "environment", + "version": "0.0.0+20220823165932" +} \ No newline at end of file diff --git a/sketches/_PIO_Sketches/Karger/SoaapBleMaster_Test_2/src/environment/socManNetUser.h b/sketches/_PIO_Sketches/Karger/SoaapBleMaster_Test_2/src/environment/socManNetUser.h new file mode 100644 index 0000000000000000000000000000000000000000..4809a3b98de3da0b84f1f25ba7cda8af91bb2672 --- /dev/null +++ b/sketches/_PIO_Sketches/Karger/SoaapBleMaster_Test_2/src/environment/socManNetUser.h @@ -0,0 +1,315 @@ +//----------------------------------------------------------------------------- +// Thema: Social Manufacturing Network / Broadcast Socket Interface +// Datei: socManNetUser.h +// Editor: Igor Farber, Robert Patzke +// URI/URL: www.mfp-portal.de +//----------------------------------------------------------------------------- +// Lizenz: CC-BY-SA (wikipedia: Creative Commons) +// + +#ifndef _socManNetUser_h +#define _socManNetUser_h + +#define smnMULTIBOARDS + +#define smnBOARD001 +//#define smnBOARD002 +//#define smnBOARD003 +//#define smnBOARD004 +//#define smnBOARD005 +//#define smnBOARD006 + + + +#ifndef smnMyNet +// *************************************************************************** +// define smnMyNet in project properties (Arduino) with -DsmnMyNet +// to use your own network definition file included at the end of this file + + +//---------------------------------------------------------------------------// +//------------------------------------------------------------------------- +// MAC-Adresse des Ethernet-Shield +//------------------------------------------------------------------------- +#ifdef smnMULTIBOARDS + + #ifdef smnBOARD001 + #define LOCAL_MAC_ADR_B0 0x90 + #define LOCAL_MAC_ADR_B1 0xa2 + #define LOCAL_MAC_ADR_B2 0xda + #define LOCAL_MAC_ADR_B3 0x0f + #define LOCAL_MAC_ADR_B4 0x1b + #define LOCAL_MAC_ADR_B5 0x84 + // MAC-Adresse + + #define LOCAL_MAC_ADR_STR (char *) "90-a2-da-0f-1b-84" + // MAC-Adresse als String + #endif + + #ifdef smnBOARD002 + #define LOCAL_MAC_ADR_B0 0x90 + #define LOCAL_MAC_ADR_B1 0xa2 + #define LOCAL_MAC_ADR_B2 0xda + #define LOCAL_MAC_ADR_B3 0x0f + #define LOCAL_MAC_ADR_B4 0x63 + #define LOCAL_MAC_ADR_B5 0xb0 + // MAC-Adresse + + #define LOCAL_MAC_ADR_STR (char *) "90-a2-da-0f-63-b0" + // MAC-Adresse als String + #endif + + #ifdef smnBOARD003 + #define LOCAL_MAC_ADR_B0 0x90 + #define LOCAL_MAC_ADR_B1 0xa2 + #define LOCAL_MAC_ADR_B2 0xda + #define LOCAL_MAC_ADR_B3 0x0f + #define LOCAL_MAC_ADR_B4 0x5b + #define LOCAL_MAC_ADR_B5 0xe1 + // MAC-Adresse + + #define LOCAL_MAC_ADR_STR (char *) "90-a2-da-0f-5b-e1" + // MAC-Adresse als String + #endif + + #ifdef smnBOARD004 + #define LOCAL_MAC_ADR_B0 0x90 + #define LOCAL_MAC_ADR_B1 0xa2 + #define LOCAL_MAC_ADR_B2 0xda + #define LOCAL_MAC_ADR_B3 0x0f + #define LOCAL_MAC_ADR_B4 0x5b + #define LOCAL_MAC_ADR_B5 0x8f + // MAC-Adresse + + #define LOCAL_MAC_ADR_STR (char *) "90-a2-da-0f-62-d0" + // MAC-Adresse als String + #endif + + #ifdef smnBOARD005 + #define LOCAL_MAC_ADR_B0 0x90 + #define LOCAL_MAC_ADR_B1 0xa2 + #define LOCAL_MAC_ADR_B2 0xda + #define LOCAL_MAC_ADR_B3 0x0f + #define LOCAL_MAC_ADR_B4 0x62 + #define LOCAL_MAC_ADR_B5 0xd0 + // MAC-Adresse + + #define LOCAL_MAC_ADR_STR (char *) "90-a2-da-0f-62-d0" + // MAC-Adresse als String + #endif + + #ifdef smnBOARD006 + #define LOCAL_MAC_ADR_B0 0x90 + #define LOCAL_MAC_ADR_B1 0xa2 + #define LOCAL_MAC_ADR_B2 0xda + #define LOCAL_MAC_ADR_B3 0x0f + #define LOCAL_MAC_ADR_B4 0x62 + #define LOCAL_MAC_ADR_B5 0xd0 + // MAC-Adresse + + #define LOCAL_MAC_ADR_STR (char *) "90-a2-da-0f-62-d0" + // MAC-Adresse als String + #endif + +#else + #define LOCAL_MAC_ADR_B0 0x90 + #define LOCAL_MAC_ADR_B1 0xa2 + #define LOCAL_MAC_ADR_B2 0xda + #define LOCAL_MAC_ADR_B3 0x0f + #define LOCAL_MAC_ADR_B4 0x62 + #define LOCAL_MAC_ADR_B5 0xd0 + // MAC-Adresse + + #define LOCAL_MAC_ADR_STR (char *) "90-a2-da-0f-62-d0" + // MAC-Adresse als String +#endif + +#define LOCAL_PORT 4100 +// Portnummer lokal + +#define BROADCAST_PORT 4100 +// Portnummer Rundruf + +#define CONFIG_PORT 4001 + +//------------------------------------------------------------------------- +// Sub-Netz-Maske +//------------------------------------------------------------------------- +#define SUB_NET_MASK_B0 255 +#define SUB_NET_MASK_B1 255 +#define SUB_NET_MASK_B2 255 +#define SUB_NET_MASK_B3 0 + +//---------------------------------------------------------------------------- +// IP-Adresse, ist auf das verwendete Netzwerk anzupassen (kein DHCP) +//---------------------------------------------------------------------------- + +// Das Netzwerk an sich +#define LOCAL_IP_B0 192 +#define LOCAL_IP_B1 168 +#define LOCAL_IP_B2 99 + +#define BROADCAST_IP_B0 192 +#define BROADCAST_IP_B1 168 +#define BROADCAST_IP_B2 99 +#define BROADCAST_IP_B3 255 + +#ifdef smnMULTIBOARDS + + #ifdef smnBOARD001 + + // IP-Lokal + // ---------------------------------------------- + // + #define LOCAL_IP_B3 201 + #define LOCAL_IP_ADR_STR (char *) "192.168.99.201" + + // IP-Broadcast + // ---------------------------------------------- + // + #define BROADCAST_IP_ADR_STR (char *) "192.168.99.255" + + #endif + + + #ifdef smnBOARD002 + + // IP-Lokal + // ---------------------------------------------- + // + #define LOCAL_IP_B3 202 + #define LOCAL_IP_ADR_STR (char *) "192.168.99.202" + + // IP-Broadcast + // ---------------------------------------------- + // + #define BROADCAST_IP_ADR_STR (char *) "192.168.99.255" + + #endif + + + #ifdef smnBOARD003 + + // IP-Lokal + // ---------------------------------------------- + // + #define LOCAL_IP_B3 203 + #define LOCAL_IP_ADR_STR (char *) "192.168.99.203" + + // IP-Broadcast + // ---------------------------------------------- + // + #define BROADCAST_IP_ADR_STR (char *) "192.168.99.255" + + #endif + + + #ifdef smnBOARD004 + + // IP-Lokal + // ---------------------------------------------- + // + #define LOCAL_IP_B3 204 + #define LOCAL_IP_ADR_STR (char *) "192.168.99.204" + + // IP-Broadcast + // ---------------------------------------------- + // + #define BROADCAST_IP_ADR_STR (char *) "192.168.99.255" + + #endif + + + #ifdef smnBOARD005 + + // IP-Lokal + // ---------------------------------------------- + // + #define LOCAL_IP_B3 205 + #define LOCAL_IP_ADR_STR (char *) "192.168.99.205" + + // IP-Broadcast + // ---------------------------------------------- + // + #define BROADCAST_IP_ADR_STR (char *) "192.168.99.255" + + #endif + + + #ifdef smnBOARD006 + + // IP-Lokal + // ---------------------------------------------- + // + #define LOCAL_IP_B3 206 + #define LOCAL_IP_ADR_STR (char *) "192.168.99.205" + + // IP-Broadcast + // ---------------------------------------------- + // + #define BROADCAST_IP_ADR_STR (char *) "192.168.99.255" + + #endif + + +#else + + // IP-Lokal + // ---------------------------------------------- + // + #define LOCAL_IP_B3 205 + #define LOCAL_IP_ADR_STR (char *) "192.168.99.205" + + // IP-Broadcast + // ---------------------------------------------- + // + #define BROADCAST_IP_B3 255 + #define BROADCAST_IP_ADR_STR (char *) "192.168.99.255" + +#endif + +// IP-Gateway +// ---------------------------------------------- +// +#define GATEWAY_IP_B0 192 +#define GATEWAY_IP_B1 168 +#define GATEWAY_IP_B2 99 +#define GATEWAY_IP_B3 1 + + +/****************************************************************************** + * Netzwerkname + * Passwort + */ +#define SMNSSID "MPZ-Labor" //Netzwerk Name +#define SMNPASS "MPZMPZMPZ" //Netzwerk Passwort + +// IP-primaryDNS +// ---------------------------------------------- +// +#define PRIMDNS_IP_B0 8 +#define PRIMDNS_IP_B1 8 +#define PRIMDNS_IP_B2 8 +#define PRIMDNS_IP_B3 8 + +// IP-secondaryDNS +// ---------------------------------------------- +// +#define SECDNS_IP_B0 8 +#define SECDNS_IP_B1 8 +#define SECDNS_IP_B2 4 +#define SECDNS_IP_B3 4 + +#else +// *************************************************************************** + #undef _socManNetUser_h + #include MyNetFile + // Define MyNetFile in Project-Properties with -DMyNetFile=\"xxxxx\" + // and xxxxx being your filename. + // Define also smnMyNet with -DsmnMyNet to enter this include directive + +#endif // smnMyNet +// *************************************************************************** + +//---------------------------------------------------------------------------// +#endif // _socManNetUser_h diff --git a/sketches/_PIO_Sketches/Karger/SoaapBleMaster_Test_2/src/main.cpp b/sketches/_PIO_Sketches/Karger/SoaapBleMaster_Test_2/src/main.cpp new file mode 100644 index 0000000000000000000000000000000000000000..cc5c3622d1c730e194ae97c530e1f11bfdb2d4a1 --- /dev/null +++ b/sketches/_PIO_Sketches/Karger/SoaapBleMaster_Test_2/src/main.cpp @@ -0,0 +1,688 @@ +// ---------------------------------------------------------------------------- +// SoaapBleMaster.ino +// Beispielhafte Anwendung SOAAP / Steuerung optischer und akustischer Ausgaben +// Kommunikation über BLE-Funkanäle mit Bewerbungstelegrammen +// P o l l i n g - M a s t e r +// ---------------------------------------------------------------------------- +// Editor: Robert Patzke +// URI/URL: www.hs-hannover.de +//----------------------------------------------------------------------------- +// Lizenz: CC-BY-SA (wikipedia: Creative Commons) +// Datum: 1. November 2021 +// Letzte Bearbeitung: 4. Februar 2022 +// + +#include "Arduino.h" +#include "SoaapBleMaster.h" + +// ---------------------------------------------------------------------------- +LoopCheck lc; +// ---------------------------------------------------------------------------- +// Eine statische Instanz der Klasse LoopCheck +// Darüber wird das Zeitverhalten gesteuert (Software-Timer) und geprüft + +// ---------------------------------------------------------------------------- +nRF52840Radio bleCom; +// ---------------------------------------------------------------------------- +// Eine statische Instanz der Klasse nRF52840Radio +// Darüber wird direkt die CPU (nRF52840) auf dem Arduino-Board zum Senden und +// Empfangen von BLE-Beacons angesprochen. + + +#define bleCycleTime 250 +// ---------------------------------------------------------------------------- +BlePoll blePoll((IntrfRadio *) &bleCom, micros); +// ---------------------------------------------------------------------------- +// Eine statische Instanz der Klasse BlePoll +// Darüber werden das Polling des Masters als auch die Antworten der Slaves +// gesteuert. Es können Geräte entwickelt werden, die nur Master oder Slave +// sind und solche mit Doppelfunktion, wenn kein expliziter Master +// eingesetzt und das Netzwerk über Spontan-Master quasi dezentral +// betrieben werden soll. +// ----- Parameter ------------------------------------------------------------ +// <&bleCom> Die Klasse (vom angenommenen Typ IntrfRadio), die die Daten- +// übertragung abwickelt. Hier wird eine Instanz von nRF52840Radio +// angebunden. Für andere Hardware kann eine entsprechende Klasse +// verwendet werden, die von IntrfRadio abgeleitet wurde. +// <micros> Eine Funktion, die die verstrichene Zeit in Mikrosekunden gibt. +// Damit werden Zeiten (z.B. Time-Out) berechnet. +// Wird hier der Wert NULL übergeben, dann werden die Zeiten aus +// dem Aufrufzyklus (bleCycleTime) in Mikrosekunden berechnet, +// was hier einer Auflösung von 250 Mikrosekunden entspricht. + +#define NrOfSlavesToPoll 5 +// Die Anzahl der Slaves, die der Master aufrufen soll (Polling). +// Es wird grundsätzlich mit der Adresse 1 begonnen und nach dem Aufruf die +// Adresse inkrementiert, also immer die Slaves Adr = 1 bis +// Adr = NrOfSlavesToPoll+1 aufgerufen. +// ACHTUNG! +// Diese Zahl muss kleiner/gleich der in BlePoll.h definierten maximalen +// Anzahl der Slaves (MAXSLAVE) sein, weil die Ressourcen darüber statisch +// festgelegt werden. + +SerParams ttyParams; +// ---------------------------------------------------------------------------- +nRF52840Ser tty; +// ---------------------------------------------------------------------------- +// Eine statische Instanz der Klasse nRF52840Ser (UART) +// Darüber werden die seriellen Schnittstellen (UARTE0 und UARTE1) des +// nRF52840 bedient. +// Die Parameter werden in einer Struktur <SerParams> über die Funktion +// <begin(...)> gesetzt. + +#define sndBufSize 256 +byte sndBuffer[sndBufSize]; +// ---------------------------------------------------------------------------- +ComRingBuf crb; +// ---------------------------------------------------------------------------- +// Eine statische Instanz der Klasse <ComRingBuf> +// Damit wird ein Ringpuffer aufgebaut, der eine serielle Schnittstelle bedient. +// Der Speicher muss extra eingerichtet und mit der Funktion +// <setWriteBuffer(sndBufSize, sndBuffer)> übergeben werden. +// Die Klasse für die serielle Schnittstelle muss von <IntrfSerial> abgeleitet +// sein, die Instanz wird mit der Funktion <begin(...)> übergeben. + +#define appCycleTime 500 +StateMachine ap(apInit, NULL, appCycleTime); +// Eine statische Instanz für die Zustandsmaschine, die hier für die +// Anwendung (App) von SOAAP eingesetzt wird +// ----- Parameter ------------------------------------------------------------ +// <smInit> Der zuerst aufgerufene Zustand (Funktion). Weitere Zustände +// werden in den weiteren Zustandsfunktionen eingesetzt. +// <NULL> Hier kann eine weitere Zustandsfunktion angegeben werden, +// die dann grundsätzlich vor dem Verzweigen in einen Zustand +// aufgerufen wird. +// <smCycleTime> Die Zukluszeit (Takt) der Zustandsmaschine in Mikrosekunden + + +// ---------------------------------------------------------------------------- +SoaapMsg sMsg; +// ---------------------------------------------------------------------------- +// Eine statische Instanz der Klasse <SoaapMsg> +// Damit werden SOAAP-spezifische Meldungen/Telegramme generiert und ausgewertet +// und SOAAP-spezifische Datentypen und Parameter definiert. + +#ifdef DebugTerminal +// ---------------------------------------------------------------------------- +// Zum Debuggen und weitere Analysen der Programmumgebung und Funktionstests +// Es ist ein (richtiges) Terminal erforderlich, mit dem einzelnen Zeichen +// direkt abgeschickt und die eintreffenden direkt angezeigt werden. +// ---------------------------------------------------------------------------- +#define smCycleTime 5 +StateMachine sm(smInit, NULL, smCycleTime); +// Eine statische Instanz für die Zustandsmaschine, die hier für allgemeine +// Steuerungen, Überwachungen und zum Debugging verwendet wird +// ----- Parameter ------------------------------------------------------------ +// <smInit> Der zuerst aufgerufene Zustand (Funktion). Weitere Zustände +// werden in den weiteren Zustandsfunktionen eingesetzt. +// <NULL> Hier kann eine weitere Zustandsfunktion angegeben werden, +// die dann grundsätzlich vor dem Verzweigen in einen Zustand +// aufgerufen wird. +// <smCycleTime> Die Zukluszeit (Takt) der Zustandsmaschine in Millisekunden + +Monitor mon(modeEcho | modeNl,0,&lc); +// Eine statische Instanz (mit Konstruktordaten) der Klasse Monitor +// Darüber wird mit (direkten) Terminals (z.B. VT100) kommuniziert +// Unter Linux werden hier GtkTerm (siehe Internet) und +// ArduinoMonTerm (eigene Entwicklung mit grafischen Wertanzeigen) eingesetzt. +// Das in den IDEs integrierte Terminal ist dafür meistens nicht geeigent, +// weil damit keine direkte Kommunikation (getipptes Zeichen sofort gesendet) +// möglich ist. +// ----- Parameter ------------------------------------------------------------ +// <mode Echo> Alle eintreffenden Zeichen werden sofort zurückgesendet +// <mode NL> Vor der Ausgabe des Prompt (M>) erfolgt CR/LF +// <0> Für Speicherzugriffe wird von 32 Bit ARM ausgegangen +// <&lc> Für Zeitüberwachungen und entsprechende statisctische Daten +// greift die Monitor-Klasse auf die LoopCheck-Klasse zu +// ---------------------------------------------------------------------------- +#endif + + +// ============================================================================ +void setup() +// ============================================================================ +{ + bleCom.begin(); // Initialisierung der Datenübertragung + //bleCom.setPower(0x08); // Maximale Sendeleistung bei nRF52840 + // TEST + bleCom.setPower(0x0FC); // Reduzierte Sendeleistung beim Schreibtisch-Test + + blePoll.begin(BlePoll::ctMASTER, NrOfSlavesToPoll, BlePoll::atDevSOAAP, 10000); + // Initialisierung des Polling mit folgenden Parametern: + // <BlePoll::ctMASTER> Es wird ein Master eingerichtet + // <NrOfSlavesToPoll> Anzahl gepollter Slaves (s.o.) + // <BlePoll::atSOAAP> Spezielle Anwendung SOAAP + // <10000> INT-Watchdog-Timeout beim Lesen in Mikrosekunden + + blePoll.setEmptyPollParams(2000, 500, 2000); + // Setzen der Parameter für das leere Polling zur Feststellung der + // vorhandenen Slaves und Aufbau einer Poll-Liste für den Datenaustausch + // ----- Parameter ---------------------------------------------------------- + // <2000> Anzahl der Poll-Durchläufe, solange kein Slave gefunden wird + // <500> Anzahl weiterer Durchläufe, nachdem wenigstens ein Slave gefunden ist + // <2000> Time-Out (Zeit für Slave zum Antworten) in Mikrosekunden + + for(int i = 1; i <= NrOfSlavesToPoll; i++) + blePoll.setDataPollParams(i, 1, 10, 1000); + // Setzen der Parameter beim Datenpolling, für Slaves individuell + // ----- Parameter ---------------------------------------------------------- + // <i> Adresse des Slave (1-..) + // <1> Priorität beim Aufruf, 0 = immer bis max 65535 = sehr selten + // <10> minimale Priorität bei automatischer Prioritätsreduzierung + // im Fall von Störungen (Time-Out) + // <1000> Time-Out (Zeit für Slave zum Antworten) in Mikrosekunden + +#ifdef DebugTerminal + blePoll.stopEP(); // Das Polling muss extra gestartet werden +#endif + + // Initialisierung von serieller Schnittstelle und Ringpuffer + // -------------------------------------------------------------------------- + ttyParams.inst = 0; // Instanzindex der Schnittstelle (0,1) + ttyParams.rxdPort = 1; // Nummer des IO-Port mit RxD-Pin + ttyParams.rxdPin = 10; // Nummer des RxD-Pin am Port + ttyParams.txdPort = 1; // Nummer des IO-Port mit TxD-Pin + ttyParams.txdPin = 3; // Nummer des TxD-Pin am Port + ttyParams.speed = Baud115200; // Enumerator für Bitrate + ttyParams.type = stStd; // Spannungsausgang + + tty.begin(&ttyParams, (IntrfBuf *) &crb); + // Übergeben von Parametern und Referenz auf Ringpufferverwaltung + // für die Übergabe empfangener Zeichen + + tty.startSend(); // Sendebetrieb aktivieren + + crb.setWriteBuffer(sndBufSize, sndBuffer); + // Speicher an Ringpufferverwaltung übergeben + + crb.begin((IntrfSerial *) &tty); + // Referenz auf Schnittstelle an Ringpufferverwaltung + // für die Übergabe zu sendender Zeichen +} + +// ============================================================================ +void loop() +// ============================================================================ +{ + lc.begin(); // Muss am Anfang von LOOP aufgerufen werden + // -------------------------------------------------------------------------- + +#ifdef DebugTerminal + mon.run(); // Der Monitor bekommt bei jedem Durchlauf die CPU +#endif + + // Alle 250 Mikrosekunden erfolgt der Aufruf des Ble-Polling + // + if(lc.timerMicro(lcTimer0, bleCycleTime, 0)) + blePoll.run(); + // ----- Parameter der Software-Timer --------------------------------------- + // <lcTimer0> Id/Nummer des Timer, zur Zeit werden bis 10 Timer unterstützt + // lcTimer0 bis lcTimer9 (einstellbar in LoopCheck.h) + // <bleCycleTime> Ablaufzeit in Einheit des Timer-Typ (Micro/Milli) + // hier in Mikrosekunden (timerMicro) + // <0> Anzahl der Wiederholungen, 0 = unbegrenzt + + // Alle 500 Mikrosekunden erfolgt der Aufruf der Anwendung + // + if(lc.timerMicro(lcTimer1, appCycleTime, 0, 10000)) + ap.run(); + + +#ifdef DebugTerminal + // Jede Sekunde erfolgt die Ausgabe einer Versionsmeldung + // das kann über c0 am Terminal abgeschaltet werden + // + if(lc.timerMilli(lcTimer2, 1000, 0)) + { + if(!mon.cFlag[0]) + mon.printcr((char *)"%@TestBleMaster (ttyACM0), Version 20220303"); + smWaitPolling(); + } + // Die Zeichen %@ am Anfang steuern die Ausgabe bei AndroidMonTerm in ein + // Textfeld (Label) statt auf das Terminal-Display + + // Alle 5 Millisekunden erfolgt der Aufruf der Zustandsmaschine + // + if(lc.timerMilli(lcTimer3, smCycleTime, 0)) + { + sm.run(); + } +#endif + + // -------------------------------------------------------------------------- + lc.end(); // Muss vor dem Ende von LOOP aufgerufen werden +} + +// **************************************************************************** +// Z u s t a n d s m a s c h i n e S O A A P - A n w e n d u n g (ap) +// **************************************************************************** +// +byte apTmpByteArray[256]; // Zwischenspeicher für Zeichenfolgen +int apNrOfMeasBytes; // Anzahl der empfangenen Messwertbytes +int apNrOfCtrlBytes; // Anzahl der empfangenen Steuerbytes inkl count und path +byte apMeasByteArray[32]; // Zwischenspeicher für Messwerte +byte apCtrlByteArray[32]; // Zwischenspeicher für Steuerbytes +byte apSlaveList[NrOfSlavesToPoll]; // Merker für gepollte Slaves +int apNrOfSlaves; // Aktuelle Anzahl von Slaves +int curListIdx; // Aktueller Index für Slaveliste +int area; // Area des aktuellen Slave +int sMsgLen; // Länge einer SOAAP-Meldung +int slNr; // Slave-Nummer (Adresse) +int txNr; // Anzahl versendeter Zeichen + +SoaapApId sAppId; // Anwendungs-Id aus Sicht SOAAP +PlpType pAppId; // Anwendungs-Id aus Polling-Sicht + +#ifdef TEST001 +char testMsgBuf[256]; +#endif +// ---------------------------------------------------------------------------- +// Initialisierungen +// +void apInit() +{ +#ifdef TEST001 + crb.putLine("Initialisierung"); +#endif + + // Eventuelle Initialisierung + ap.enter(apWaitDE); // in nächsten Zustand schalten +} + +// ---------------------------------------------------------------------------- +// Warten, bis Datenaustausch Master/Slave erfolgt +// +void apWaitDE() +{ + if(!blePoll.DataExchange) + return; // Verbleiben in diesem Zustand bis Leerpolling beendet + + apNrOfSlaves = blePoll.getSlaveList(apSlaveList, NrOfSlavesToPoll); + // Ermitteln der angeschlossenen Slaves + +#ifdef TEST001 + crb.putStr("Slaveliste\r\n"); +#endif + + ap.enter(apWaitMeas); +} + +// ---------------------------------------------------------------------------- +// Warten auf neuen Messwert von einem Slave +// +void apWaitMeas() +{ + // Ermitteln, ob einer der Slaves einen Messwert hat + // + for(curListIdx = 0; curListIdx < apNrOfSlaves; curListIdx++) + { + slNr = apSlaveList[curListIdx]; + if(blePoll.measAvail(slNr)) break; + } + if(curListIdx == apNrOfSlaves) return; + // Wenn kein Slave neue Messwerte hat, + // dann im nächsten Zustandstakt Abfrage wiederholen + +#ifdef TEST001 + crb.putStr("Messwerte\r\n"); +#endif + + // Slave (curListIdx) hat Messwerte übermittelt + // diese werden mit dem nächsten Takt verarbeitet + ap.enter(apProcMeas); +} + +// ---------------------------------------------------------------------------- +// Verarbeiten der Daten vom Slave +// +void apProcMeas() +{ +#ifdef TEST001 + if(ap.firstEnter()) + { + slNr = apSlaveList[curListIdx]; + sprintf(testMsgBuf,"Slave-Nr = %d\r\n",slNr); + crb.putStr(testMsgBuf); + } + //ap.enter(apWaitMeas); + //return; +#endif + + // Parameter und Daten für die SOAAP-Meldung holen + // + slNr = apSlaveList[curListIdx]; + area = blePoll.getArea(slNr); + pAppId = blePoll.getAppId(slNr); + apNrOfMeasBytes = blePoll.getMeas(slNr, apMeasByteArray); + apNrOfCtrlBytes = blePoll.getCtrlM(slNr, apCtrlByteArray); + +#ifdef TEST001 + ap.enter(apWaitMeas); + return; +#endif + + // Abbildung des Polling-Telegramm-Typs auf die SOAAP-Anwendungs-Id + // + switch(pAppId) + { + case plptMeas9: + sAppId = saiDefaultMeas; + break; + + case plptMeas13: + sAppId = saiMaximalMeas; + break; + + case plptMeas9Ctrl4: + sAppId = saiDefaultMeasCtrl; + break; + + default: + sAppId = saiDefaultMeas; + break; + } + + // Konstruktion der SOAAP-Meldung + // + sMsgLen = sMsg.getMsgA(area, slNr, sAppId, (char *) apTmpByteArray, apMeasByteArray); + + // Senden des Telegramm über serielle Schnittstelle + // + txNr = crb.putStr((char *) apTmpByteArray); + + // Auf nächsten Messwert von einem Slave warten + // + ap.enter(apWaitMeas); +} + + + +#ifdef DebugTerminal +// **************************************************************************** +// Z u s t a n d s m a s c h i n e z u m D e b u g g e n (sm) +// **************************************************************************** +// +dword debDword; +byte tmpByteArray[256]; + + +void smInit() +{ + sm.enter(smCheckJobs); +} + +// ---------------------------------------------------------------------------- +// Abfrage der Monitorschalter +// ---------------------------------------------------------------------------- +// + +void smCheckJobs() +{ + if(mon.cFlag[1] && !mon.busy) + sm.enter(smDebDword); + else if(mon.cFlag[2] && !mon.busy) + sm.enter(smCtrlPolling); + else if(mon.cFlag[3] && !mon.busy) + sm.enter(smReadPollValues); + else if(mon.cFlag[4] && !mon.busy) + sm.enter(smCheckSer); +} + +// ---------------------------------------------------------------------------- +// Debug-Informationen +// ---------------------------------------------------------------------------- +// + +void smDebDword() +{ + int idx; + + if(sm.firstEnter()) + { + mon.print((char *) "DebDword["); + mon.lastKeyIn = ':'; + } + + if(mon.lastKeyIn == ':') return; + + if(mon.lastKeyIn >= 0x30 && mon.lastKeyIn <= 0x39) + { + idx = mon.lastKeyIn & 0x0F; + mon.print(idx); + mon.print((char *) "]="); + debDword = blePoll.debGetDword(idx); + mon.println(debDword); + sm.resetEnter(); + } + else + { + if(mon.lastKeyIn == ' ') + { + mon.cFlag[1] = false; + mon.print((char *) "-- Schleifenabbruch - drücke Enter"); + sm.enter(smCheckJobs); + } + } +} + +// ---------------------------------------------------------------------------- +// Steuern des Polling-Prozesses +// ---------------------------------------------------------------------------- +// + +TxStatistics txStatistics; + +void smCtrlPolling() +{ + dword tmpDw; + short tmpShort; + int i; + + PlpMeas6Ptr resPtr; + + if(sm.firstEnter()) + { + mon.print((char *) "polling "); + mon.lastKeyIn = ':'; + } + + if(mon.lastKeyIn == ':') return; + + // -------------------------------------------------------------------------- + if(mon.lastKeyIn == 'P' || mon.lastKeyIn == 'p') + { + if(blePoll.stoppedEP()) + { + blePoll.resumeEP(); + mon.println((char *) "fortgesetzt"); + sm.resetEnter(); + } + else + { + blePoll.stopEP(); + sm.enter(smWaitPolling); + } + } + + // -------------------------------------------------------------------------- + else if(mon.lastKeyIn == 'C' || mon.lastKeyIn == 'c') + { + blePoll.resetPollCounters(); + mon.println((char *) "Zähler zurückgesetzt"); + sm.resetEnter(); + } + + + // -------------------------------------------------------------------------- + else if(mon.lastKeyIn == 'R' || mon.lastKeyIn == 'r') + { + mon.print((char *) "Radiopuffer = "); + bleCom.getPduMem(tmpByteArray, 0, 10); + mon.println(tmpByteArray, 10, ' '); + sm.resetEnter(); + } + + + // -------------------------------------------------------------------------- + else if(mon.lastKeyIn == 'S' || mon.lastKeyIn == 's') + { + mon.print((char *) "Sendepuffer = "); + bleCom.getPduSent(tmpByteArray, 0, 10); + mon.println(tmpByteArray, 10, ' '); + sm.resetEnter(); + } + + // -------------------------------------------------------------------------- + else if(mon.lastKeyIn == 'K' || mon.lastKeyIn == 'k') + { + mon.print(slNr); mon.print((char *)"|"); + for(int i= 0; i< apNrOfCtrlBytes; i++){ + mon.print(apCtrlByteArray[i]); + mon.print((char *)" "); + } + mon.print((char *) "\n"); + sm.resetEnter(); + } + // -------------------------------------------------------------------------- + else if(mon.lastKeyIn == 'L' || mon.lastKeyIn == 'l') + { + mon.print((char *) "Slave-Liste: "); + int nrOfSlaves = blePoll.getSlaveList(tmpByteArray, 255); + mon.println(tmpByteArray, nrOfSlaves, ','); + sm.resetEnter(); + } + + // -------------------------------------------------------------------------- + else if(mon.lastKeyIn == 'T' || mon.lastKeyIn == 't') + { + mon.print((char *) "TxStat ["); + dword bleStat = blePoll.getStatistics(&txStatistics); + mon.print(bleStat); + mon.print((char *) "] "); + mon.print(txStatistics.mode); mon.cprint(' '); + mon.print(txStatistics.interrupts); mon.cprint(' '); + mon.print(txStatistics.recs); mon.cprint(' '); + mon.print(txStatistics.sendings); mon.cprint(' '); + mon.print(txStatistics.aliens); mon.cprint(' '); + mon.print(txStatistics.wrongs); mon.cprint(' '); + mon.print(txStatistics.pollAcks); mon.cprint(' '); + mon.print(txStatistics.pollNaks); mon.cprint(' '); + mon.print(txStatistics.crcErrors); mon.print(" s[ "); + mon.print(txStatistics.memDumpSnd,8,' '); mon.print("] r[ "); + mon.print(txStatistics.memDumpRec,16,' '); mon.cprintln(']'); + sm.resetEnter(); + } + + // -------------------------------------------------------------------------- + else if(mon.lastKeyIn >= '0' && mon.lastKeyIn <= '9') + { + int idx = mon.lastKeyIn & 0x0F; + SlavePtr slPtr = blePoll.getSlavePtr(idx); + PollStatePtr pPtr = blePoll.getPollPtr(slPtr->pIdx); + + mon.print((char *) "Slave["); + mon.print(idx); + mon.print((char *) "] "); + mon.print(slPtr->cntTo); mon.cprint(' '); + mon.print(slPtr->cntNakEP); mon.cprint(' '); + mon.print(slPtr->cntAckDP); mon.cprint(' '); + + if(slPtr->cntAckDP == 0) + { + if(slPtr->cntTo == 0) + tmpDw = slPtr->cntNakEP; + else + tmpDw = slPtr->cntNakEP / slPtr->cntTo; + } + else + { + if(slPtr->cntTo == 0) + tmpDw = slPtr->cntAckDP; + else + tmpDw = slPtr->cntAckDP / slPtr->cntTo; + } + mon.print(tmpDw); mon.cprint(' '); + + resPtr = (PlpMeas6Ptr) &slPtr->result; + + mon.print(slPtr->cntLostPdu); mon.cprint('|'); + mon.print(slPtr->cntErrCrc); mon.cprint('|'); + //mon.print(slPtr->result.measCnt); mon.cprint('|'); + mon.print(resPtr->measCnt); mon.cprint('|'); + mon.print(slPtr->cntLostMeas); mon.cprint(' '); + + for(i = 0; i < 6; i++) + { + //tmpShort = (short) slPtr->result.meas[i]; + tmpShort = (short) resPtr->meas[i]; + mon.prints(tmpShort); mon.cprint(' '); + } + mon.print((char *) " Poll["); + mon.print(slPtr->pIdx); + mon.print((char *) "] "); + mon.print(pPtr->status); mon.cprint(' '); + mon.println(pPtr->slIdx); + sm.resetEnter(); + } + + + + else + { + if(mon.lastKeyIn == ' ') + { + mon.cFlag[2] = false; + mon.print((char *) "-- Schleifenabbruch - drücke Enter"); + sm.enter(smCheckJobs); + } + } +} + +void smWaitPolling() +{ + if(!blePoll.stoppedEP()) return; + + mon.println((char *) "angehalten"); + sm.enter(smCtrlPolling); +} + +// ---------------------------------------------------------------------------- +// Testen der seriellen Schnittstelle +// ---------------------------------------------------------------------------- +// +void smCheckSer() +{ + if(sm.firstEnter()) + { + mon.print((char *) "TestSer..."); + mon.lastKeyIn = ':'; + } + + if(mon.lastKeyIn == ':') return; + + if(mon.lastKeyIn == ' ') + { + mon.cFlag[4] = false; + mon.print((char *) "-- Schleifenabbruch - drücke Enter"); + sm.enter(smCheckJobs); + } + else + { + crb.putChr(mon.lastKeyIn); + mon.cprint(mon.lastKeyIn); + mon.lastKeyIn = ':'; + } +} + +// ---------------------------------------------------------------------------- +// Debug-Informationen +// ---------------------------------------------------------------------------- +// + +void smReadPollValues() +{ + +} + +#endif // DebugTerminal + diff --git a/sketches/_PIO_Sketches/Karger/SoaapBleMaster_Test_2/src/nRF52840Gpio/library.json b/sketches/_PIO_Sketches/Karger/SoaapBleMaster_Test_2/src/nRF52840Gpio/library.json new file mode 100644 index 0000000000000000000000000000000000000000..a099c0c6f9c5ede5584dbf9ab24da0199b348548 --- /dev/null +++ b/sketches/_PIO_Sketches/Karger/SoaapBleMaster_Test_2/src/nRF52840Gpio/library.json @@ -0,0 +1,4 @@ +{ + "name": "nRF52840Gpio", + "version": "0.0.0+20220823165932" +} \ No newline at end of file diff --git a/sketches/_PIO_Sketches/Karger/SoaapBleMaster_Test_2/src/nRF52840Gpio/nRF52840Gpio.cpp b/sketches/_PIO_Sketches/Karger/SoaapBleMaster_Test_2/src/nRF52840Gpio/nRF52840Gpio.cpp new file mode 100644 index 0000000000000000000000000000000000000000..47a25ddebcff11a2d9ef003cf83ddf1be250d057 --- /dev/null +++ b/sketches/_PIO_Sketches/Karger/SoaapBleMaster_Test_2/src/nRF52840Gpio/nRF52840Gpio.cpp @@ -0,0 +1,353 @@ +//----------------------------------------------------------------------------- +// Thema: Social Manufacturing Network / Development Environment +// Datei: nRF52840Gpio.cpp +// Editor: Robert Patzke +// URI/URL: www.mfp-portal.de +//----------------------------------------------------------------------------- +// Lizenz: CC-BY-SA (wikipedia: Creative Commons) +// Datum: 29. Juni 2021 +// + +#include "nRF52840Gpio.h" + + // -------------------------------------------------------------------------- + // Konstruktoren + // -------------------------------------------------------------------------- + // + nRF52840Gpio::nRF52840Gpio() + { + gpioPtr = NULL; + } + + + + // -------------------------------------------------------------------------- + // Konfigurationen + // -------------------------------------------------------------------------- + // + +dword nRF52840Gpio::getCnfValue(unsigned int cnfBits) +{ + dword tmpMask = 0; + + if(cnfBits & IfDrvPullUp) tmpMask |= GpioPinCnf_PULL(GpioPullUp); + if(cnfBits & IfDrvPullDown) tmpMask |= GpioPinCnf_PULL(GpioPullDown); + + if((cnfBits & IfDrvOutput)) // Ausgang ********************************** + { + tmpMask |= GpioPinCnf_DIR; + + if(cnfBits & IfDrvStrongHigh) // StrongHigh = H1 + { + if(cnfBits & IfDrvOpenSource) // OpenSource = D0 + tmpMask |= GpioPinCnf_DRIVE(GpioDriveD0H1); + else if(cnfBits & IfDrvStrongLow) // StrongLow = H0 + tmpMask |= GpioPinCnf_DRIVE(GpioDriveH0H1); + else + tmpMask |= GpioPinCnf_DRIVE(GpioDriveS0H1); + } + else if(cnfBits & IfDrvStrongLow) // StrongLow = H0 + { + if(cnfBits & IfDrvOpenDrain) // OpenDrain = D1 + tmpMask |= GpioPinCnf_DRIVE(GpioDriveH0D1); + else + tmpMask |= GpioPinCnf_DRIVE(GpioDriveH0S1); + } + else + { + if(cnfBits & IfDrvOpenSource) // OpenSource = D0 + tmpMask |= GpioPinCnf_DRIVE(GpioDriveD0S1); + else if(cnfBits & IfDrvOpenDrain) // OpenDrain = D1 + tmpMask |= GpioPinCnf_DRIVE(GpioDriveS0D1); + else + tmpMask |= GpioPinCnf_DRIVE(GpioDriveS0S1); + } + } + else // Eingang ********************************** + { + tmpMask &= 0xFFFFFFFC; + } + + return(tmpMask); +} + +GpioError nRF52840Gpio::config(int nrFrom, int nrTo, unsigned int cnfBits, GpioExtRefPtr refPtr) +{ + GpioError retv = GEnoError; + int portNum; + int pinNum; + dword tmpMask; + dword cnfValue; + + tmpMask = IfDrvOpenDrain | IfDrvOpenSource; + if((cnfBits & tmpMask) == tmpMask) return (GEcdictPar); + + tmpMask = IfDrvPullDown | IfDrvPullUp; + if((cnfBits & tmpMask) == tmpMask) return (GEcdictPar); + + cnfValue = getCnfValue(cnfBits); + tmpMask = 0; + + // Bedienen des angegebenen Bereiches + // + for(int i = nrFrom; i <= nrTo; i++) + { + portNum = (i & 0x0E0) >> 5; + pinNum = i & 0x01F; + + tmpMask |= (1 << i); + + if(portNum == 0) + gpioPtr = NrfGpioPtr0; + else + gpioPtr = NrfGpioPtr1; + + gpioPtr->PIN_CNF[pinNum] = cnfValue; + } + + refPtr->ioPtr = (dword *) gpioPtr; + refPtr->pins = tmpMask; + + return(retv); +} + +GpioError nRF52840Gpio::config(int nr, unsigned int cnfBits, GpioExtRefPtr refPtr) +{ + return(config(nr,nr,cnfBits, refPtr)); +} + +GpioError nRF52840Gpio::config(GpioExtMask mask, unsigned int cnfBits, GpioExtRefPtr refPtr) +{ + GpioError retv = GEnoError; + dword cnfVal; + + cnfVal = IfDrvOpenDrain | IfDrvOpenSource; + if((cnfBits & cnfVal) == cnfVal) return (GEcdictPar); + + cnfVal = IfDrvPullDown | IfDrvPullUp; + if((cnfBits & cnfVal) == cnfVal) return (GEcdictPar); + + cnfVal = getCnfValue(cnfBits); + + // Bedienen des angegebenen Bereiches + // + dword chkMask = 1; + + for(int i = 0; i < 32; i++) + { + if(mask.port == 0) + gpioPtr = NrfGpioPtr0; + else + gpioPtr = NrfGpioPtr1; + + if(mask.pins & chkMask) + gpioPtr->PIN_CNF[i] = cnfVal; + + chkMask <<= 1; + } + + if(refPtr != NULL) + { + refPtr->ioPtr = (dword *) gpioPtr; + refPtr->pins = mask.pins; + } + + return(retv); +} + +GpioError nRF52840Gpio::configArd(ArdMask ardMask, unsigned int cnfBits) +{ + GpioExtMask ioMask; + + switch(ardMask) + { + case ArdA0A3: + ioMask.port = 0; + ioMask.pins = ArdA0Mask | ArdA1Mask | ArdA2Mask | ArdA3Mask; + break; + + case ArdA4A7: + ioMask.port = 0; + ioMask.pins = ArdA4Mask | ArdA5Mask | ArdA6Mask | ArdA7Mask; + break; + + case ArdA0A7: + ioMask.port = 0; + ioMask.pins = ArdA0Mask | ArdA1Mask | ArdA2Mask | ArdA3Mask | + ArdA4Mask | ArdA5Mask | ArdA6Mask | ArdA7Mask; + break; + + case ArdD2D5: + ioMask.port = 1; + ioMask.pins = ArdD2Mask | ArdD3Mask | ArdD4Mask | ArdD5Mask; + break; + } + + return config(ioMask, cnfBits, NULL); +} + + + + // -------------------------------------------------------------------------- + // Anwendungsfunktionen + // -------------------------------------------------------------------------- + // +void nRF52840Gpio::read(GpioExtRefPtr ioRefPtr, GpioExtValPtr valPtr) +{ + gpioPtr = (nrfGpioPtr) ioRefPtr->ioPtr; + valPtr->value = gpioPtr->IN; +} + +dword nRF52840Gpio::readArd(ArdMask ardMask) +{ + dword inVal; + dword retVal; + + retVal = 0; + + switch(ardMask) + { + case ArdA0A3: + inVal = NrfGpioPtr0->IN; + if(inVal & ArdA0Mask) retVal |= 0x01; + if(inVal & ArdA1Mask) retVal |= 0x02; + if(inVal & ArdA2Mask) retVal |= 0x04; + if(inVal & ArdA3Mask) retVal |= 0x08; + break; + + case ArdA4A7: + inVal = NrfGpioPtr0->IN; + if(inVal & ArdA4Mask) retVal |= 0x01; + if(inVal & ArdA5Mask) retVal |= 0x02; + if(inVal & ArdA6Mask) retVal |= 0x04; + if(inVal & ArdA7Mask) retVal |= 0x08; + break; + + case ArdA0A7: + inVal = NrfGpioPtr0->IN; + if(inVal & ArdA0Mask) retVal |= 0x01; + if(inVal & ArdA1Mask) retVal |= 0x02; + if(inVal & ArdA2Mask) retVal |= 0x04; + if(inVal & ArdA3Mask) retVal |= 0x08; + if(inVal & ArdA4Mask) retVal |= 0x10; + if(inVal & ArdA5Mask) retVal |= 0x20; + if(inVal & ArdA6Mask) retVal |= 0x40; + if(inVal & ArdA7Mask) retVal |= 0x80; + break; + + case ArdD2D5: + inVal = NrfGpioPtr1->IN; + if(inVal & ArdD2Mask) retVal |= 0x01; + if(inVal & ArdD3Mask) retVal |= 0x02; + if(inVal & ArdD4Mask) retVal |= 0x04; + if(inVal & ArdD5Mask) retVal |= 0x08; + break; + } + + return(retVal); +} + + +void nRF52840Gpio::write(GpioExtRefPtr refPtr, GpioExtValPtr valPtr) +{ + ((nrfGpioPtr) refPtr->ioPtr)->OUTSET = valPtr->value & refPtr->pins; + ((nrfGpioPtr) refPtr->ioPtr)->OUTCLR = ~valPtr->value & refPtr->pins; + if(refPtr->next == NULL) return; + ((nrfGpioPtr) refPtr->next->ioPtr)->OUTSET = valPtr->next->value & refPtr->next->pins; + ((nrfGpioPtr) refPtr->next->ioPtr)->OUTCLR = ~valPtr->next->value & refPtr->next->pins; +} + +void nRF52840Gpio::set(GpioExtRefPtr refPtr) +{ + ((nrfGpioPtr) refPtr->ioPtr)->OUTSET = refPtr->pins; + if(refPtr->next == NULL) return; + ((nrfGpioPtr) refPtr->next->ioPtr)->OUTSET = refPtr->next->pins; +} + +void nRF52840Gpio::clr(GpioExtRefPtr refPtr) +{ + ((nrfGpioPtr) refPtr->ioPtr)->OUTCLR = refPtr->pins; + if(refPtr->next == NULL) return; + ((nrfGpioPtr) refPtr->next->ioPtr)->OUTCLR = refPtr->next->pins; +} + + + +void nRF52840Gpio::writeArd(ArdMask ardMask, dword value) +{ + dword set0 = 0, set1 = 0; + dword clr0 = 0, clr1 = 0; + + switch(ardMask) + { + case ArdA0A3: + if(value & 0x01) set0 |= ArdA0Mask; + else clr0 |= ArdA0Mask; + if(value & 0x02) set0 |= ArdA1Mask; + else clr0 |= ArdA1Mask; + if(value & 0x04) set0 |= ArdA2Mask; + else clr0 |= ArdA2Mask; + if(value & 0x08) set0 |= ArdA3Mask; + else clr0 |= ArdA3Mask; + + NrfGpioPtr0->OUTSET = set0; + NrfGpioPtr0->OUTCLR = clr0; + break; + + case ArdA4A7: + if(value & 0x01) set0 |= ArdA4Mask; + else clr0 |= ArdA4Mask; + if(value & 0x02) set0 |= ArdA5Mask; + else clr0 |= ArdA5Mask; + if(value & 0x04) set0 |= ArdA6Mask; + else clr0 |= ArdA6Mask; + if(value & 0x08) set0 |= ArdA7Mask; + else clr0 |= ArdA7Mask; + + NrfGpioPtr0->OUTSET = set0; + NrfGpioPtr0->OUTCLR = clr0; + break; + + case ArdA0A7: + if(value & 0x01) set0 |= ArdA0Mask; + else clr0 |= ArdA0Mask; + if(value & 0x02) set0 |= ArdA1Mask; + else clr0 |= ArdA1Mask; + if(value & 0x04) set0 |= ArdA2Mask; + else clr0 |= ArdA2Mask; + if(value & 0x08) set0 |= ArdA3Mask; + else clr0 |= ArdA3Mask; + if(value & 0x01) set0 |= ArdA4Mask; + else clr0 |= ArdA4Mask; + if(value & 0x02) set0 |= ArdA5Mask; + else clr0 |= ArdA5Mask; + if(value & 0x04) set0 |= ArdA6Mask; + else clr0 |= ArdA6Mask; + if(value & 0x08) set0 |= ArdA7Mask; + else clr0 |= ArdA7Mask; + + NrfGpioPtr0->OUTSET = set0; + NrfGpioPtr0->OUTCLR = clr0; + break; + + case ArdD2D5: + if(value & 0x01) set1 |= ArdD2Mask; + else clr1 |= ArdD2Mask; + if(value & 0x02) set1 |= ArdD3Mask; + else clr1 |= ArdD3Mask; + if(value & 0x04) set1 |= ArdD4Mask; + else clr1 |= ArdD4Mask; + if(value & 0x08) set1 |= ArdD5Mask; + else clr1 |= ArdD5Mask; + + NrfGpioPtr1->OUTSET = set1; + NrfGpioPtr1->OUTCLR = clr1; + break; + } +} + + + // ---------------------------------------------------------------------------- + // Ereignisbearbeitung und Interrupts + // ---------------------------------------------------------------------------- + // diff --git a/sketches/_PIO_Sketches/Karger/SoaapBleMaster_Test_2/src/nRF52840Gpio/nRF52840Gpio.h b/sketches/_PIO_Sketches/Karger/SoaapBleMaster_Test_2/src/nRF52840Gpio/nRF52840Gpio.h new file mode 100644 index 0000000000000000000000000000000000000000..addf5ad533ddfecabd2c540824238c278a117998 --- /dev/null +++ b/sketches/_PIO_Sketches/Karger/SoaapBleMaster_Test_2/src/nRF52840Gpio/nRF52840Gpio.h @@ -0,0 +1,181 @@ +//----------------------------------------------------------------------------- +// Thema: Social Manufacturing Network / Development Environment +// Datei: nRF52840Gpio.h +// Editor: Robert Patzke +// URI/URL: www.mfp-portal.de +//----------------------------------------------------------------------------- +// Lizenz: CC-BY-SA (wikipedia: Creative Commons) +// Datum: 29. Juni 2021 +// + +#ifndef NRF52840GPIO_H +#define NRF52840GPIO_H + +#include "Arduino.h" +#include "arduinoDefs.h" +#include "IntrfGpio.h" + +#ifndef nrfGpioDef +// ---------------------------------------------------------------------------- +typedef struct _nrfGpio +{ + volatile dword Reserve01; // 000 + volatile dword OUT; // 004 + volatile dword OUTSET; // 008 + volatile dword OUTCLR; // 00C + volatile dword IN; // 010 + volatile dword DIR; // 014 + volatile dword DIRSET; // 018 + volatile dword DIRCLR; // 01C + volatile dword LATCH; // 020 + volatile dword DETECTMODE; // 024 + volatile dword Reserve02[118]; // 026 + volatile dword PIN_CNF[32]; // 200 +} nrfGpio, *nrfGpioPtr; + +#define NrfGpioBase 0x50000000 +#define NrfGpioBase0 0x50000500 +#define NrfGpioPtr0 ((nrfGpioPtr) NrfGpioBase0) +#define NrfGpioBase1 0x50000800 +#define NrfGpioPtr1 ((nrfGpioPtr) NrfGpioBase1) + +#define GpioPinCnf_DIR ((dword) 0x00000001) + +#define GpioPinCnf_INPUT ((dword) 0x00000001 << 1) + +#define GpioPinCnf_PULL(x) ((dword) x << 2) +#define GpioPullDown 1 +#define GpioPullUp 3 + +#define GpioPinCnf_DRIVE(x) ((dword) x << 8) +#define GpioDriveS0S1 0 +#define GpioDriveH0S1 1 +#define GpioDriveS0H1 2 +#define GpioDriveH0H1 3 +#define GpioDriveD0S1 4 +#define GpioDriveD0H1 5 +#define GpioDriveS0D1 6 +#define GpioDriveH0D1 7 + +#define GpioPinCnf_SENSE(x) ((dword) x << 16) +#define GpioSenseHigh 2 +#define GpioSenseLow 3 + +#define nrfGpioDef +// ---------------------------------------------------------------------------- +#endif + +#define P0(x) (x) +#define P1(x) (32+x) + +#ifdef smnNANOBLE33 +// ---------------------------------------------------------------------------- +#define ArdA0Bit 4 +#define ArdA1Bit 5 +#define ArdA2Bit 30 +#define ArdA3Bit 29 +#define ArdA4Bit 31 +#define ArdA5Bit 2 +#define ArdA6Bit 28 +#define ArdA7Bit 3 + +#define ArdA0 P0(4) +#define ArdA1 P0(5) +#define ArdA2 P0(30) +#define ArdA3 P0(29) +#define ArdA4 P0(31) +#define ArdA5 P0(2) +#define ArdA6 P0(28) +#define ArdA7 P0(3) + +#define ArdA0Mask (1 << 4) +#define ArdA1Mask (1 << 5) +#define ArdA2Mask (1 << 30) +#define ArdA3Mask (1 << 29) +#define ArdA4Mask (1 << 31) +#define ArdA5Mask (1 << 2) +#define ArdA6Mask (1 << 28) +#define ArdA7Mask (1 << 3) + + +#define ArdD2 P1(11) +#define ArdD3 P1(12) +#define ArdD4 P1(15) +#define ArdD5 P1(13) +#define ArdD6 P0(14) +#define ArdD7 P0(23) +#define ArdD8 P1(21) +#define ArdD9 P0(27) +#define ArdD10 P1(2) +#define ArdD11 P1(1) +#define ArdD12 P1(8) +#define ArdD13 P0(13) + +#define ArdD2Mask (1 << 11) +#define ArdD3Mask (1 << 12) +#define ArdD4Mask (1 << 15) +#define ArdD5Mask (1 << 13) +#define ArdD6Mask (1 << 14) +#define ArdD7Mask (1 << 23) +#define ArdD8Mask (1 << 21) +#define ArdD9Mask (1 << 27) +#define ArdD10Mask (1 << 2) +#define ArdD11Mask (1 << 1) +#define ArdD12Mask (1 << 8) +#define ArdD13Mask (1 << 13) + +// ---------------------------------------------------------------------------- +#endif + +class nRF52840Gpio : IntrfGpio +{ +private: + // -------------------------------------------------------------------------- + // lokale Variablen + // -------------------------------------------------------------------------- + // + nrfGpioPtr gpioPtr; + +public: + // -------------------------------------------------------------------------- + // Konstruktoren + // -------------------------------------------------------------------------- + // + nRF52840Gpio(); + + // -------------------------------------------------------------------------- + // Konfigurationen + // -------------------------------------------------------------------------- + // + 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 configArd(ArdMask ardMask, unsigned int cnfBits); + + // -------------------------------------------------------------------------- + // Anwendungsfunktionen + // -------------------------------------------------------------------------- + // + void read(GpioExtRefPtr ioRef, GpioExtValPtr valPtr); + dword readArd(ArdMask ardMask); + + void write(GpioExtRefPtr refPtr, GpioExtValPtr valPtr); + void writeArd(ArdMask ardMask, dword value); + void set(GpioExtRefPtr refPtr); + void clr(GpioExtRefPtr refPtr); + + // ---------------------------------------------------------------------------- + // Ereignisbearbeitung und Interrupts + // ---------------------------------------------------------------------------- + // + + // -------------------------------------------------------------------------- + // Debugging und globale Variablen + // -------------------------------------------------------------------------- + // + +}; + +#endif //NRF52840GPIO_H diff --git a/sketches/_PIO_Sketches/Karger/SoaapBleMaster_Test_2/src/nRF52840Radio/library.json b/sketches/_PIO_Sketches/Karger/SoaapBleMaster_Test_2/src/nRF52840Radio/library.json new file mode 100644 index 0000000000000000000000000000000000000000..a18f8f0f08e3ee567cac8bd59e8774c14b3effe7 --- /dev/null +++ b/sketches/_PIO_Sketches/Karger/SoaapBleMaster_Test_2/src/nRF52840Radio/library.json @@ -0,0 +1,4 @@ +{ + "name": "nRF52840Radio", + "version": "0.0.0+20220823165932" +} \ No newline at end of file diff --git a/sketches/_PIO_Sketches/Karger/SoaapBleMaster_Test_2/src/nRF52840Radio/nRF52840Radio.cpp b/sketches/_PIO_Sketches/Karger/SoaapBleMaster_Test_2/src/nRF52840Radio/nRF52840Radio.cpp new file mode 100644 index 0000000000000000000000000000000000000000..5639480f98f812bc2170a24674d34534dd95d5e6 --- /dev/null +++ b/sketches/_PIO_Sketches/Karger/SoaapBleMaster_Test_2/src/nRF52840Radio/nRF52840Radio.cpp @@ -0,0 +1,943 @@ +//----------------------------------------------------------------------------- +// Thema: Social Manufacturing Network / Development Environment +// Datei: nRF52840Radio.h +// Editor: Robert Patzke +// URI/URL: www.mfp-portal.de +//----------------------------------------------------------------------------- +// Lizenz: CC-BY-SA (wikipedia: Creative Commons) +// + +#include "Arduino.h" +#include "nRF52840Radio.h" +#include <string.h> + +// ---------------------------------------------------------------------------- +// Initialisierungen +// ---------------------------------------------------------------------------- + +nRF52840Radio::nRF52840Radio() +{ + NrfRadioPtr->TASKS_DISABLE; // Sender/Empfänger abgeschaltet +#ifdef nrfPowerDCDCEN + *nrfPowerDCDCEN = 1; +#endif +#ifdef nrfClockTASKS_HFCLKSTART + *nrfClockTASKS_HFCLKSTART = 1; +#endif + NrfRadioPtr->POWER = 0; + NrfRadioPtr->POWER = 1; + + irqCounter = 0; + trfMode = txmBase; + statisticPtr = NULL; + recMode = true; + pmPtr = (bcPduPtr) pduMem; + psPtr = (bcPduPtr) pduSentS; + pePtr = (bcPduPtr) pduSentE; + eadM = false; + nakM = false; + comFin = false; + comError = false; + newValues = false; + + memset(statList,0,NrOfTxModes * sizeof(TxStatistics)); +} + +// ---------------------------------------------------------------------------- +// Konfiguration +// ---------------------------------------------------------------------------- + +// Allgemeine Vorbereitungen +// +void nRF52840Radio::begin() +{ + instPtr0 = this; // Verzweigung im statischen Bereich setzen + + NrfRadioPtr->INTENCLR = 0xFFFFFFFF; // Vorsichtshalber keine Interrupts + + // Interruptvektor setzen + // + __NVIC_SetVector((IRQn_Type) 1, (dword) nRF52840Radio::irqHandler0); + __NVIC_SetPriority((IRQn_Type) 1, 1); + __NVIC_EnableIRQ((IRQn_Type) 1); +} + +// Setzen der Zugriffsadresse +// +void nRF52840Radio::setAccessAddress(dword addr) +{ + dword prefix = addr >> 24; + dword base = addr << 8; + + cfgData.base0 = NrfRadioPtr->BASE0 = base; + cfgData.prefix0 = NrfRadioPtr->PREFIX0 = prefix; + cfgData.txAddr = NrfRadioPtr->TXADDRESS = 0; + cfgData.rxAddr = NrfRadioPtr->RXADDRESSES = 0x01; +} + +// Telegrammparameter setzen +// +void nRF52840Radio::setPacketParms(blePduType type) +{ + switch(type) + { + case bptAdv: + cfgData.pCnf0 = NrfRadioPtr->PCNF0 = PCNF0_LFLEN(8) | PCNF0_S0LEN(1) | PCNF0_S1LEN(0); + cfgData.pCnf1 = NrfRadioPtr->PCNF1 = PCNF1_MAXLEN(42) | PCNF1_BALEN(3) | PCNF1_WHITEEN(1); + cfgData.modeCnf0 = NrfRadioPtr->MODECNF0 = 1; + cfgData.crcCnf = NrfRadioPtr->CRCCNF = CRCCNF_LEN(3) | CRCCNF_SKIPADDR(1); + cfgData.crcPoly = NrfRadioPtr->CRCPOLY = PolynomCRC; + cfgData.crcInit = NrfRadioPtr->CRCINIT = AdvStartCRC; + cfgData.packetPtr = NrfRadioPtr->PACKETPTR = (dword) pduMem; + cfgData.mode = NrfRadioPtr->MODE = 3; + cfgData.dacnf = NrfRadioPtr->DACNF = 0x0FF00; + break; + + case bptAux: + break; + } +} + + +// ---------------------------------------------------------------------------- +// Steuerfunktionen und gezielte Prozessorzugriffe +// ---------------------------------------------------------------------------- + +// Schalten des Bewerbungskanals +// +void nRF52840Radio::setChannel(int nr) +{ + cfgData.frequency = NrfRadioPtr->FREQUENCY = channelList[nr].freq; + cfgData.whiteInit = NrfRadioPtr->DATAWHITEIV = channelList[nr].idx; +} + +// ---------------------------------------------------------------------------- +// S e n d e n +// ---------------------------------------------------------------------------- + +// Einstellen der Sendeleistung +// +void nRF52840Radio::setPower(int DBm) +{ + cfgData.txPower = NrfRadioPtr->TXPOWER = DBm; +} +// Senden eines Telegramms +// Es wird davon ausgeganen, das der Radio-Zustand = DISABLED ist +// +int nRF52840Radio::sendSync(bcPduPtr inPduPtr, TxStatePtr refState) +{ + int retv = 0; + NrfRadioPtr->INTENCLR = 0xFFFFFFFF; + NrfRadioPtr->EVENTS_READY = 0; + NrfRadioPtr->EVENTS_END = 0; + memcpy((void *)pduMem, (void *)inPduPtr, sizeof(bcPdu)); // Daten kopieren + if(refState != NULL) + refState->prgLoopPrep = retv = 3 + sizeof(bcPdu); + NrfRadioPtr->TASKS_TXEN = 1; // Starten des Anlaufes + while(NrfRadioPtr->EVENTS_READY != 1) retv++; // Warten bis angelaufen + if(refState != NULL) + refState->evtLoopRampUp = retv - 3; + NrfRadioPtr->TASKS_START = 1; // Starten des Sendevorgangs + while(NrfRadioPtr->EVENTS_END != 1) retv++; // Warten bis gesendet + NrfRadioPtr->TASKS_DISABLE = 1; // Sender abschalten + if(refState != NULL) + { + refState->evtLoopTrans = retv - refState->evtLoopRampUp; + refState->txBufferPtr = pduMem; + } + return(retv); +} + +void nRF52840Radio::send(bcPduPtr inPduPtr, TxMode txMode) +{ + send(inPduPtr, NULL, txMode, false); +} + +void nRF52840Radio::send(bcPduPtr inPduPtrE, bcPduPtr inPduPtrS, TxMode txMode, bool inNewValues) +{ + NrfRadioPtr->INTENCLR = 0xFFFFFFFF; + NrfRadioPtr->EVENTS_READY = 0; + NrfRadioPtr->EVENTS_END = 0; + NrfRadioPtr->EVENTS_DISABLED = 0; + NrfRadioPtr->EVENTS_RXREADY = 0; + NrfRadioPtr->EVENTS_TXREADY = 0; + NrfRadioPtr->EVENTS_ADDRESS = 0; + + // TODO + // Das muss Alles noch einmal überarbeitet werden. + // Hier stecken zu viele Redundanzen drin, Altlast aus diversen Tests mit der Hardware + + memcpy((void *)pduMem, (void *)inPduPtrE, sizeof(bcPdu)); // Daten in Funkpuffer kopieren + + memcpy((void *)pduSentE, (void *)inPduPtrE, sizeof(bcPdu)); // Daten in extra Puffer kopieren + // Die übergebenen Daten werden in einen Extrapuffer kopiert zur Entkopplung für eventuelle + // lokale Modifikationen + + if(inPduPtrS != NULL) // Falls Daten für eine Antwort gegeben sind + memcpy((void *)pduSentS, (void *)inPduPtrS, sizeof(bcPdu));// Daten in extra Puffer kopieren + // Die übergebenen Daten werden in einen Extrapuffer kopiert zur Entkopplung für eventuelle + // lokale Modifikationen + + comFin = false; + comError = false; + newValues = inNewValues; + + trfMode = txMode; + +#if (defined smnDEBUG && defined nRF52840RadioDEB) + statisticPtr = &statList[(int) txMode]; + statisticPtr->mode = txMode; + memset(statisticPtr->memDumpRec,0,16); + memset(statisticPtr->memDumpSnd,0,16); +#endif + + switch(txMode) + { + case txmPoll: + recMode = false; + NrfRadioPtr->SHORTS = NrfScTXREADY_START | NrfScEND_DISABLE | NrfScDISABLED_RXEN | NrfScRXREADY_START; + NrfRadioPtr->INTENSET = NrfIntRXREADY; + NrfRadioPtr->TASKS_TXEN = 1; + break; + + case txmResp: + case txmRespE: + recMode = true; + NrfRadioPtr->SHORTS = NrfScREADY_START; + NrfRadioPtr->INTENSET = NrfIntEND; + NrfRadioPtr->TASKS_RXEN = 1; + break; + + case txmBase: + NrfRadioPtr->SHORTS = NrfScREADY_START | NrfScEND_DISABLE; + NrfRadioPtr->TASKS_TXEN = 1; + break; + + case txmRepStart: + NrfRadioPtr->SHORTS = NrfScREADY_START; + NrfRadioPtr->TASKS_TXEN = 1; + break; + + case txmRepCont: + NrfRadioPtr->SHORTS = 0; + NrfRadioPtr->TASKS_START = 1; + break; + + case txmRepEnd: + NrfRadioPtr->SHORTS = NrfScEND_DISABLE; + NrfRadioPtr->TASKS_START = 1; + break; + + case txmReadPrep: + NrfRadioPtr->SHORTS = NrfScTXREADY_START | NrfScEND_DISABLE | NrfScDISABLED_RXEN; + NrfRadioPtr->TASKS_TXEN = 1; + break; + + case txmReadS: + NrfRadioPtr->SHORTS = NrfScTXREADY_START | NrfScEND_DISABLE | NrfScDISABLED_RXEN | NrfScRXREADY_START; + NrfRadioPtr->INTENSET = NrfIntADDRESS; + NrfRadioPtr->TASKS_TXEN = 1; + break; + + case txmRead: + NrfRadioPtr->SHORTS = NrfScTXREADY_START | NrfScEND_DISABLE | NrfScDISABLED_RXEN | NrfScRXREADY_START; + NrfRadioPtr->INTENSET = NrfIntADDRESS | NrfIntEND; + NrfRadioPtr->TASKS_TXEN = 1; + break; + } +} + +void nRF52840Radio::disable(TxMode txMode) +{ + switch(txMode) + { + case txmBase: + break; + + case txmRepStart: + break; + + case txmRepCont: + break; + + case txmRepEnd: + break; + + case txmReadPrep: + break; + + case txmRead: + NrfRadioPtr->TASKS_DISABLE = 1; + break; + + case txmPoll: + NrfRadioPtr->INTENCLR = 0xFFFFFFFF; + NrfRadioPtr->EVENTS_DISABLED = 0; + NrfRadioPtr->TASKS_DISABLE = 1; + break; + + case txmResp: + case txmRespE: + NrfRadioPtr->TASKS_DISABLE = 1; + break; + } + NrfRadioPtr->SHORTS = 0; +} + +bool nRF52840Radio::disabled(TxMode txMode) +{ + bool retv = false; + + switch(txMode) + { + case txmBase: + break; + + case txmRepStart: + break; + + case txmRepCont: + break; + + case txmRepEnd: + break; + + case txmReadPrep: + break; + + case txmRead: + case txmPoll: + if(NrfRadioPtr->EVENTS_DISABLED == 1) + { + NrfRadioPtr->EVENTS_DISABLED = 0; + retv = true; + } + else + { + if(NrfRadioPtr->STATE == NrfStDISABLED) + retv = true; + } + break; + + case txmResp: + case txmRespE: + if(NrfRadioPtr->EVENTS_DISABLED == 1) + { + NrfRadioPtr->EVENTS_DISABLED = 0; + retv = true; + } + else + { + if(NrfRadioPtr->STATE == NrfStDISABLED) + retv = true; + } + break; + } + return(retv); +} + +bool nRF52840Radio::fin(TxMode txMode, bool *crcErr) +{ + bool retv = false; + + *crcErr = comError; + + switch(txMode) + { + case txmBase: + break; + + case txmRepStart: + break; + + case txmRepCont: + break; + + case txmRepEnd: + break; + + case txmReadPrep: + break; + + case txmReadS: + retv = comFin; + break; + + case txmRead: + /* + if(NrfRadioPtr->EVENTS_END == 1) + { + NrfRadioPtr->EVENTS_END = 0; + retv = true; + } + else + { + if(NrfRadioPtr->STATE == NrfStRXIDLE) + retv = true; + } + */ + retv = comFin; + break; + + case txmPoll: + retv = comFin; + break; + + case txmResp: + retv = comFin; + break; + + case txmRespE: + if(NrfRadioPtr->STATE == NrfStDISABLED && !recMode) + retv = true; + break; + } + return(retv); +} + +void nRF52840Radio::cont(TxMode txMode) +{ + switch(txMode) + { + case txmBase: + break; + + case txmRepStart: + break; + + case txmRepCont: + break; + + case txmRepEnd: + break; + + case txmReadPrep: + break; + + case txmRead: + comFin = false; + NrfRadioPtr->TASKS_START = 1; + break; + } +} + +int nRF52840Radio::getRecData(bcPduPtr data, TxMode txMode, int max) +{ + byte *bPtr = (byte *) data; + int retv = 0; + + switch(txMode) + { + case txmResp: + data->head = pduSentE[0]; + retv = data->len = pduSentE[1]; + + for(int i = 2; i < (retv + 2); i++) + { + if(i == max) break; + bPtr[i] = pduSentE[i]; + } + + break; + + case txmBase: + break; + + case txmRepStart: + break; + + case txmRepCont: + break; + + case txmRepEnd: + break; + + case txmReadPrep: + break; + + case txmRead: + break; + } + + + return(retv); +} + + + +// ---------------------------------------------------------------------------- +// E m p f a n g e n +// ---------------------------------------------------------------------------- + +// Starten des Datenempfangs +// +int nRF52840Radio::startRec() +{ + int retv; + NrfRadioPtr->INTENCLR = 0xFFFFFFFF; + NrfRadioPtr->EVENTS_READY = 0; + NrfRadioPtr->EVENTS_END = 0; + NrfRadioPtr->EVENTS_ADDRESS = 0; + NrfRadioPtr->EVENTS_PAYLOAD = 0; + NrfRadioPtr->EVENTS_CRCOK = 0; + NrfRadioPtr->EVENTS_CRCERROR = 0; + NrfRadioPtr->TASKS_RXEN = 1; // Anlauf Empfänger starten + retv = 8; + while(NrfRadioPtr->EVENTS_READY != 1) retv++; // Warten bis angelaufen + NrfRadioPtr->TASKS_START = 1; // Starten des Empfangs + return(retv + 1); +} + +// Fortsetzen des Datenempfangs +// +int nRF52840Radio::contRec() +{ + NrfRadioPtr->EVENTS_END = 0; + NrfRadioPtr->EVENTS_ADDRESS = 0; + NrfRadioPtr->EVENTS_PAYLOAD = 0; + NrfRadioPtr->EVENTS_CRCOK = 0; + NrfRadioPtr->EVENTS_CRCERROR = 0; + NrfRadioPtr->TASKS_START = 1; // Starten des Empfangs + return(6); +} + +// Beenden des Datenempfangs +// +int nRF52840Radio::endRec() +{ + int retv; + NrfRadioPtr->EVENTS_DISABLED = 0; + NrfRadioPtr->EVENTS_END = 0; + NrfRadioPtr->EVENTS_ADDRESS = 0; + NrfRadioPtr->EVENTS_PAYLOAD = 0; + NrfRadioPtr->EVENTS_CRCOK = 0; + NrfRadioPtr->EVENTS_CRCERROR = 0; + NrfRadioPtr->TASKS_DISABLE = 1; // Anlauf Empfänger beenden + retv = 7; + while(NrfRadioPtr->EVENTS_DISABLED != 1) retv++; // Warten bis abgelaufen + return(retv); +} + +// Empfangszustand abfragen +// +int nRF52840Radio::checkRec() +{ + int retv = 0; + + if(NrfRadioPtr->EVENTS_ADDRESS != 0) + retv |= RECSTAT_ADDRESS; + + if(NrfRadioPtr->EVENTS_PAYLOAD != 0) + retv |= RECSTAT_PAYLOAD; + + if(NrfRadioPtr->EVENTS_END != 0) + retv |= RECSTAT_END; + + if(NrfRadioPtr->CRCSTATUS != 0) + retv |= RECSTAT_CRCOK; + + if(NrfRadioPtr->EVENTS_DISABLED != 0) + retv |= RECSTAT_DISABLED; + + return(retv); +} + +int nRF52840Radio::getRecData(bcPduPtr data, int max) +{ + int retv; + byte *bPtr = (byte *) data; + + data->head = pduMem[0]; + retv = data->len = pduMem[1]; + + for(int i = 2; i < (retv + 2); i++) + { + if(i == max) break; + bPtr[i] = pduMem[i]; + } + + return(retv); +} + +// ---------------------------------------------------------------------------- +// Interruptverarbeitung +// ---------------------------------------------------------------------------- +// + +nRF52840Radio *nRF52840Radio::instPtr0 = NULL; + +void nRF52840Radio::irqHandler0() +{ + if(instPtr0 == NULL) return; + instPtr0->irqCounter++; + instPtr0->irqHandler(); +} + +void nRF52840Radio::irqHandler() +{ + statisticPtr->interrupts++; + + switch(trfMode) + { + // ------------------------------------------------------------------------ + case txmRead: // Empty Polling für Master + // ------------------------------------------------------------------------ + + if((NrfRadioPtr->STATE & 0x08) != 0) // Noch im Sendemodus + { // -------------------------------------------------------------------- + if(NrfRadioPtr->EVENTS_ADDRESS == 1) // AC-Adr gesendet + { + NrfRadioPtr->EVENTS_ADDRESS = 0; // nur quittieren + } + + if(NrfRadioPtr->EVENTS_END == 1) // Senden fertig + { + NrfRadioPtr->EVENTS_END = 0; // nur quittieren + statisticPtr->sendings++; + memcpy(statisticPtr->memDumpSnd,pduMem,8); + } + } + else // im Empfangsmodus + { // -------------------------------------------------------------------- + if(NrfRadioPtr->EVENTS_ADDRESS == 1) // AC-Adr empfangen + { + NrfRadioPtr->EVENTS_ADDRESS = 0; // quittieren + NrfRadioPtr->SHORTS = 0; // Direktverbindungen löschen + } + + if(NrfRadioPtr->EVENTS_END == 1) // Empfang fertig + { + NrfRadioPtr->EVENTS_END = 0; // nur quittieren + comFin = true; + statisticPtr->recs++; + memcpy(statisticPtr->memDumpRec,pduMem,8); + } + } + + break; + + // ------------------------------------------------------------------------ + case txmPoll: // Empty Polling und Datenempfang für Master -> DISABLED + // ------------------------------------------------------------------------ + if(NrfRadioPtr->EVENTS_RXREADY == 1) // Empfang aktiviert + { + NrfRadioPtr->EVENTS_RXREADY = 0; // Int quittieren + +#if (defined smnDEBUG && defined nRF52840RadioDEB) + statisticPtr->sendings++; + memcpy(statisticPtr->memDumpSnd,pduMem,8); +#endif + NrfRadioPtr->EVENTS_DISABLED = 0; // Neu erwartet, zurücksetzen + NrfRadioPtr->SHORTS = NrfScEND_DISABLE | NrfScRXREADY_START; + NrfRadioPtr->INTENSET = NrfIntDISABLED; + recMode = true; + } + + if(NrfRadioPtr->EVENTS_DISABLED == 1) // Empfang beendet + { + NrfRadioPtr->EVENTS_DISABLED = 0; // Int quittieren + comFin = true; + if(NrfRadioPtr->CRCSTATUS == 0) + comError = true; + +#if (defined smnDEBUG && defined nRF52840RadioDEB) + statisticPtr->recs++; + if(comError) statisticPtr->crcErrors++; + memcpy(statisticPtr->memDumpRec,pduMem,16); + if(!recMode) + { + // Das darf nicht passieren, sonst neue Int-Verarbeitung erforderlich + statisticPtr->intErrors++; + } +#endif + } + break; + + // ------------------------------------------------------------------------ + case txmReadS: // Datenübertragung für Master (Slave->Master) + // ------------------------------------------------------------------------ + + if(NrfRadioPtr->EVENTS_ADDRESS == 1) // AC-Adr gesendet + { + NrfRadioPtr->EVENTS_ADDRESS = 0; // quittieren + + if((NrfRadioPtr->STATE & 0x08) != 0) // im Sendezustand + break; // nichts weiter + // -------------------------------------------------------------------- + else // Im Empfangszustand + { + NrfRadioPtr->SHORTS = NrfScEND_DISABLE; // automatisch abschalten + NrfRadioPtr->INTENCLR = 0xFFFFFFFF; // und nur noch DISABLED + NrfRadioPtr->INTENSET = NrfIntDISABLED; // Interrupt freischalten + } + } + + if(NrfRadioPtr->EVENTS_DISABLED == 1) // Übertragung fertig + { + NrfRadioPtr->EVENTS_DISABLED = 0; // quittieren + comFin = true; + } + + + break; + + // ---------------------------------------------------------------------- + case txmRespE: // Empty Polling für Slave + // ---------------------------------------------------------------------- + + // -------------------------------------------------------------------- + if(NrfRadioPtr->EVENTS_END == 1) // Übertragung beendet + // -------------------------------------------------------------------- + { + NrfRadioPtr->EVENTS_END = 0; // Event quittieren + + if(recMode) // im Empfangsmodus + { // ---------------------------------------------------------------- + NrfRadioPtr->SHORTS = 0; // keine direkte Kopplung mehr + + statisticPtr->recs++; + memcpy(statisticPtr->memDumpRec,pduMem,8); + + // ---------------------------------------------------------------- + // Reaktion + // ---------------------------------------------------------------- + // + if((pduSentE[5] == pduMem[5]) && (pduSentE[6] == pduMem[6]) && (pduSentE[7] == pduMem[7])) + { + // Die richtige Protokollumgebung (z.B. Soaap) + // + if(pduSentE[2] != pduMem[2]) + { + // aber die falsche Adresse + // Datenempfang fortsetzen + statisticPtr->wrongs++; + NrfRadioPtr->TASKS_START = 1; + } + else + { // richtige Adresse, Antwort schicken + // ------------------------------------------------------------ + statisticPtr->pollNaks++; + + // zunächst alle Funk-Interrupts sperren + NrfRadioPtr->INTENCLR = 0xFFFFFFFF; + + // Interrupt freigeben für "Abgeschaltet" + NrfRadioPtr->INTENSET = NrfIntDISABLED; + + // Empfangsbetrieb abschalten + NrfRadioPtr->TASKS_DISABLE = 1; + } + + } + else + { + // Fremde Umgebung (nicht akzeptierte PDU) + // Datenempfang fortsetzen + statisticPtr->aliens++; + NrfRadioPtr->TASKS_START = 1; + } + } + else // im Sendemodus + { // ---------------------------------------------------------------- + + + } + } + + // -------------------------------------------------------------------- + if(NrfRadioPtr->EVENTS_DISABLED == 1) // ausgeschaltet + // -------------------------------------------------------------------- + { + NrfRadioPtr->EVENTS_DISABLED = 0; // quittieren + + if(recMode) + { + // zunächst alle Funk-Interrupts sperren + NrfRadioPtr->INTENCLR = 0xFFFFFFFF; + + // Interrupt freigeben für "Abgeschaltet" + NrfRadioPtr->INTENSET = NrfIntDISABLED; + + // Kopplung automatisch starten und abschalten nach Ende + NrfRadioPtr->SHORTS = NrfScREADY_START | NrfScEND_DISABLE; + + NrfRadioPtr->TASKS_TXEN = 1; // Sender einschalten + recMode = false; + + // Daten in Funkpuffer kopieren + memcpy((void *)pduMem, (void *)pduSentE, sizeof(bcPdu)); + } + else + { + NrfRadioPtr->SHORTS = 0; + statisticPtr->sendings++; + } + } + + break; + + // ---------------------------------------------------------------------- + case txmResp: // Datenübertragung Slave + // ---------------------------------------------------------------------- + + // -------------------------------------------------------------------- + if(NrfRadioPtr->EVENTS_END == 1) // Übertragung beendet + // Polling-Daten empfangen + // -------------------------------------------------------------------- + { + NrfRadioPtr->EVENTS_END = 0; // Event quittieren + +#if (defined smnDEBUG && defined nRF52840RadioDEB) + statisticPtr->recs++; + memcpy(statisticPtr->memDumpRec,pduMem,8); +#endif + + if((pduSentE[5] != pduMem[5]) || (pduSentE[6] != pduMem[6]) || (pduSentE[7] != pduMem[7])) + { + // Das empfangene Telegramm gehört nicht zum eigenen Netzwerk + // +#if (defined smnDEBUG && defined nRF52840RadioDEB) + statisticPtr->aliens++; +#endif + NrfRadioPtr->SHORTS = 0; // Keine Direktverbindungen + NrfRadioPtr->TASKS_START = 1; // Datenempfang fortsetzen + break; + } + + if((pduSentE[2] != pduMem[2]) || ((pduSentE[3] & 0x3F) != (pduMem[3] & 0x3F))) + { + // Das empfangene Telegramm ist für einen anderen Slave oder Bereich + // +#if (defined smnDEBUG && defined nRF52840RadioDEB) + statisticPtr->wrongs++; +#endif + NrfRadioPtr->SHORTS = 0; // Keine Direktverbindungen + NrfRadioPtr->TASKS_START = 1; // Datenempfang fortsetzen + break; + // TODO + // Hier wird das Protokoll noch erweitert zum Belauschen anderer Slaves + } + + eadM = ((pduMem[3] & SOAAP_EADR) != 0); // Merker für Empfangspolling + nakM = ((pduMem[3] & SOAAP_NAK) != 0); // Merker für NAK-Polling + +#if (defined smnDEBUG && defined nRF52840RadioDEB) + if(nakM) + statisticPtr->pollNaks++; + else + statisticPtr->pollAcks++; +#endif + if(eadM) + { + // Empfangsaufforderung + // Eadr-Nak-Daten in Funkpuffer kopieren + // + memcpy((void *)pduMem, (void *)pduSentE, sizeof(bcPdu)); + } + else + { + // Sendeaufforderung + // Polling-Steuerdaten in Empfangspuffer und + // Sadr-Ack-Daten in Funkpuffer kopieren + // + memcpy((void *)pduSentE, (void *)pduMem, sizeof(bcPdu)); + memcpy((void *)pduMem, (void *)pduSentS, sizeof(bcPdu)); + } + + // Setzen der Direktverbinder auf vollständigen Durchlauf bis Ende der Sendung + // ACHTUNG! Freigegebene Interrupts treten auf, auch wenn sie zu einer + // Direktverbindung gehören. + // + NrfRadioPtr->SHORTS = NrfScDISABLED_TXEN | NrfScREADY_START | NrfScEND_DISABLE; + NrfRadioPtr->EVENTS_READY = 0; // Evt. hängendes Ereignis löschen + NrfRadioPtr->INTENSET = NrfIntREADY; // Int zur Vorbereitung des Sendeabschlusses + NrfRadioPtr->TASKS_DISABLE = 1; // Abschalten des Empfangsbetriebs + break; + } + + // -------------------------------------------------------------------- + if(NrfRadioPtr->EVENTS_READY == 1) // Bereit zum Senden + // -------------------------------------------------------------------- + { + NrfRadioPtr->EVENTS_READY = 0; // Event quittieren + + // Vorbereiten auf das Ende der Sendung mit Abschalten + // NrfScREADY_START | NrfScEND_DISABLE sind weiter wirksam + // + NrfRadioPtr->SHORTS = NrfScREADY_START | NrfScEND_DISABLE; + NrfRadioPtr->EVENTS_DISABLED = 0; // Evt. hängendes Ereignis löschen + recMode = false; + NrfRadioPtr->INTENSET = NrfIntDISABLED; // Int zum Sendeabschluss + break; + } + + // -------------------------------------------------------------------- + if(NrfRadioPtr->EVENTS_DISABLED == 1) // Sendevorgang beendet + // -------------------------------------------------------------------- + { + NrfRadioPtr->EVENTS_DISABLED = 0; // Event quittieren + comFin = true; +#if (defined smnDEBUG && defined nRF52840RadioDEB) + statisticPtr->sendings++; + memcpy(statisticPtr->memDumpSnd,pduMem,16); +#endif + } + + break; + + } +} + +// -------------------------------------------------------------------------- +// Datenzugriffe +// -------------------------------------------------------------------------- +// +int nRF52840Radio::getStatistics(TxStatisticsPtr dest) +{ + int retv = 0; + + *dest = *statisticPtr; + return(retv); +} + +int nRF52840Radio::getState() +{ + return(NrfRadioPtr->STATE); +} + +// ---------------------------------------------------------------------------- +// D e b u g - H i l f e n +// ---------------------------------------------------------------------------- +// +int nRF52840Radio::getPduMem(byte *dest, int start, int end) +{ + int i,j; + + j = 0; + + for(i = start; i < end; i++) + { + dest[j++] = pduMem[i]; + } + return(j); +} + +int nRF52840Radio::getPduSent(byte *dest, int start, int end) +{ + int i,j; + + j = 0; + + for(i = start; i < end; i++) + { + dest[j++] = pduSentE[i]; + } + return(j); +} + + + + + + + diff --git a/sketches/_PIO_Sketches/Karger/SoaapBleMaster_Test_2/src/nRF52840Radio/nRF52840Radio.h b/sketches/_PIO_Sketches/Karger/SoaapBleMaster_Test_2/src/nRF52840Radio/nRF52840Radio.h new file mode 100644 index 0000000000000000000000000000000000000000..0e61246043b8b3bd78928b3e33e31f81e180d011 --- /dev/null +++ b/sketches/_PIO_Sketches/Karger/SoaapBleMaster_Test_2/src/nRF52840Radio/nRF52840Radio.h @@ -0,0 +1,313 @@ +//----------------------------------------------------------------------------- +// Thema: Social Manufacturing Network / Development Environment +// Datei: nRF52840Radio.h +// Editor: Robert Patzke +// URI/URL: www.mfp-portal.de +//----------------------------------------------------------------------------- +// Lizenz: CC-BY-SA (wikipedia: Creative Commons) +// + +#ifndef NRF52840RADIO_H +#define NRF52840RADIO_H + +#include "arduinoDefs.h" +#include "bleSpec.h" +#include "IntrfRadio.h" + +#define nRF52840RadioDEB + +// ---------------------------------------------------------------------------- + +typedef struct _NRF_RADIO_Type +{ + volatile dword TASKS_TXEN; + volatile dword TASKS_RXEN; + volatile dword TASKS_START; + volatile dword TASKS_STOP; + volatile dword TASKS_DISABLE; + volatile dword TASKS_RSSISTART; + volatile dword TASKS_RSSISTOP; + volatile dword TASKS_BCSTART; + volatile dword TASKS_BCSTOP; + volatile dword TASKS_EDSTART; + volatile dword TASKS_EDSTOP; + volatile dword TASKS_CCASTART; + volatile dword TASKS_CCASTOP; + volatile dword RESERVED0[51]; + volatile dword EVENTS_READY; + volatile dword EVENTS_ADDRESS; + volatile dword EVENTS_PAYLOAD; + volatile dword EVENTS_END; + volatile dword EVENTS_DISABLED; + volatile dword EVENTS_DEVMATCH; + volatile dword EVENTS_DEVMISS; + volatile dword EVENTS_RSSIEND; + volatile dword RESERVED1[2]; + volatile dword EVENTS_BCMATCH; + volatile dword RESERVED2; + volatile dword EVENTS_CRCOK; + volatile dword EVENTS_CRCERROR; + volatile dword EVENTS_FRAMESTART; + volatile dword EVENTS_EDEND; + volatile dword EVENTS_EDSTOPPED; + volatile dword EVENTS_CCAIDLE; + volatile dword EVENTS_CCABUSY; + volatile dword EVENTS_CCASTOPPED; + volatile dword EVENTS_RATEBOOST; + volatile dword EVENTS_TXREADY; + volatile dword EVENTS_RXREADY; + volatile dword EVENTS_MHRMATCH; + volatile dword RESERVED3[2]; + volatile dword EVENTS_SYNC; + volatile dword EVENTS_PHYEND; + volatile dword RESERVED4[36]; + volatile dword SHORTS; + volatile dword RESERVED5[64]; + volatile dword INTENSET; + volatile dword INTENCLR; + volatile dword RESERVED6[61]; + volatile dword CRCSTATUS; + volatile dword RESERVED7; + volatile dword RXMATCH; + volatile dword RXCRC; + volatile dword DAI; + volatile dword PDUSTAT; + volatile dword RESERVED8[59]; + volatile dword PACKETPTR; + volatile dword FREQUENCY; + volatile dword TXPOWER; + volatile dword MODE; + volatile dword PCNF0; + volatile dword PCNF1; + volatile dword BASE0; + volatile dword BASE1; + volatile dword PREFIX0; + volatile dword PREFIX1; + volatile dword TXADDRESS; + volatile dword RXADDRESSES; + volatile dword CRCCNF; + volatile dword CRCPOLY; + volatile dword CRCINIT; + volatile dword RESERVED9; + volatile dword TIFS; + volatile dword RSSISAMPLE; + volatile dword RESERVED10; + volatile dword STATE; + volatile dword DATAWHITEIV; + volatile dword RESERVED11[2]; + volatile dword BCC; + volatile dword RESERVED12[39]; + volatile dword DAB[8]; + volatile dword DAP[8]; + volatile dword DACNF; + volatile dword MHRMATCHCONF; + volatile dword MHRMATCHMAS; + volatile dword RESERVED13; + volatile dword MODECNF0; + volatile dword RESERVED14[3]; + volatile dword SFD; + volatile dword EDCNT; + volatile dword EDSAMPLE; + volatile dword CCACTRL; + volatile dword RESERVED15[611]; + volatile dword POWER; +} *nrfRadioPtr; + + + +#define NrfRadioBase 0x40001000 +#define NrfRadioPtr ((nrfRadioPtr) NrfRadioBase) + +#ifndef NrfPowerBase +#define NrfPowerBase 0x40000000 +#define nrfPowerDCDCEN ((dword *) 0x40000578) +#endif + +#ifndef NrfClockBase +#define NrfClockBase 0x40000000 +#define nrfClockTASKS_HFCLKSTART ((dword *) 0x40000000) +#endif + +// Direktverbindungen (shortcuts) zwischen events und Tasks +// +#define NrfScREADY_START 0x00000001 +#define NrfScEND_DISABLE 0x00000002 +#define NrfScDISABLED_TXEN 0x00000004 +#define NrfScDISABLED_RXEN 0x00000008 +#define NrfScTXREADY_START 0x00040000 +#define NrfScRXREADY_START 0x00080000 + +// Interrupts +// +#define NrfIntREADY 0x00000001 +#define NrfIntADDRESS 0x00000002 +#define NrfIntPAYLOAD 0x00000004 +#define NrfIntEND 0x00000008 +#define NrfIntDISABLED 0x00000010 +#define NrfIntRSSIEND 0x00000080 +#define NrfIntTXREADY 0x00200000 +#define NrfIntRXREADY 0x00400000 + +// Zustände +// +#define NrfStDISABLED 0 +#define NrfStRXRU 1 +#define NrfStRXIDLE 2 +#define NrfStRX 3 +#define NrfStRXDISABLE 4 +#define NrfStTXRU 9 +#define NrfStTXIDLE 10 +#define NrfStTX 11 +#define NrfStTXDISABLE 12 + +// Festlegungen für die Paketkonfigurationsregister +// + +#define PCNF0_LFLEN(x) x +// Anzahl der Bits im Längenfeld (0-15) + +#define PCNF0_S0LEN(x) (x << 8) +// Länge des Header0 (S0) in Bytes (0 oder 1) + +#define PCNF0_S1LEN(x) (x << 16) +// Länge des S1-Feldes in Bit (0 bis 15) + +#define PCNF1_MAXLEN(x) x +// Maximale Telegrammlänge (0 bis 255) + +#define PCNF1_BALEN(x) (x << 16) +// Basislänge der Zugriffsadresse (Access Address, 2-4) + +#define PCNF1_WHITEEN(x) (x << 25) +// Whitening (Bitmischung) Ein/Aus (1/0) + +// Festlegungen für die CRC-Generierung +// + +#define CRCCNF_LEN(x) x +// Anzahl der Bytes für CRC (0-3) + +#define CRCCNF_SKIPADDR(x) (x << 8) +// Zugriffsadresse (Access Address) nicht im CRC (1), im CRC (0) + + +typedef struct _nrf52840Cfg +{ + dword pCnf0; + dword pCnf1; + dword whiteInit; + dword modeCnf0; + dword crcPoly; + dword crcInit; + dword crcCnf; + dword packetPtr; + dword frequency; + dword txPower; + dword mode; + dword dacnf; + dword rxAddrEn; + dword base0; + dword prefix0; + dword txAddr; + dword rxAddr; + +}nrf52840Cfg, *nrf52840CfgPtr; + +// ---------------------------------------------------------------------------- + +class nRF52840Radio : IntrfRadio +{ +private: + // -------------------------------------------------------------------------- + // Lokale Daten + // -------------------------------------------------------------------------- + // + byte pduMem[256]; + byte pduSentE[256]; + byte pduSentS[256]; + + bcPduPtr pmPtr; + bcPduPtr pePtr; + bcPduPtr psPtr; + + nrf52840Cfg cfgData; + + bool recMode; + bool eadM; + bool nakM; + bool comFin; + bool comError; + bool newValues; + + dword irqCounter; + TxMode trfMode; + + TxStatistics statList[NrOfTxModes]; + TxStatisticsPtr statisticPtr; + +public: + // -------------------------------------------------------------------------- + // Initialisierungen der Basis-Klasse + // -------------------------------------------------------------------------- + + nRF52840Radio(); + + // -------------------------------------------------------------------------- + // Konfigurationen + // -------------------------------------------------------------------------- + // + void begin(); + void setAccessAddress(dword addr); // Setzen der Zugriffsadresse + void setPacketParms(blePduType type); + + // -------------------------------------------------------------------------- + // Steuerfunktionen + // -------------------------------------------------------------------------- + // + void setChannel(int nr); // Schalten physikalischer Kanal + int sendSync(bcPduPtr inPduPtr, TxStatePtr refState); + + void send(bcPduPtr inPduPtr, TxMode txMode); + void send(bcPduPtr inPduPtrE, bcPduPtr inPduPtrS, TxMode txMode, bool newValues); + int getRecData(bcPduPtr data, TxMode txMode, int max); // Empfangene Daten lesen + + void disable(TxMode txMode); + bool disabled(TxMode txMode); // Abfrage, ob ausgeschaltet + void cont(TxMode txMode); + bool fin(TxMode txMode, bool *err); + // Senden eines Telegramms (und warten) + int startRec(); // Datenempfang starten + int contRec(); // Datenempfang fortsetzen + int endRec(); // Datenempfang beenden + int checkRec(); // Zustand Datenempfang feststellen + int getRecData(bcPduPtr data, int max); // Empfangene Daten lesen + + void setPower(int DBm); // Leistung des Senders in DBm + + void readCheckCfg(); // Konfigurationsdaten auslesen + + static nRF52840Radio *instPtr0; + static void irqHandler0(); + + void irqHandler(); + + // -------------------------------------------------------------------------- + // Datenzugriffe + // -------------------------------------------------------------------------- + // + int getStatistics(TxStatisticsPtr dest); + int getState(); + + // ---------------------------------------------------------------------------- + // D e b u g - H i l f e n + // ---------------------------------------------------------------------------- + // + int getPduMem(byte *dest, int start, int end); + int getPduSent(byte *dest, int start, int end); + + +}; + + +#endif // NRF52840RADIO_H + diff --git a/sketches/_PIO_Sketches/Karger/SoaapBleMaster_Test_2/src/nRF52840Ser/library.json b/sketches/_PIO_Sketches/Karger/SoaapBleMaster_Test_2/src/nRF52840Ser/library.json new file mode 100644 index 0000000000000000000000000000000000000000..fa5d17537ce11418ad11ee8b2689c1ae0ba6a20b --- /dev/null +++ b/sketches/_PIO_Sketches/Karger/SoaapBleMaster_Test_2/src/nRF52840Ser/library.json @@ -0,0 +1,4 @@ +{ + "name": "nRF52840Ser", + "version": "0.0.0+20220823165932" +} \ No newline at end of file diff --git a/sketches/_PIO_Sketches/Karger/SoaapBleMaster_Test_2/src/nRF52840Ser/nRF52840Ser.cpp b/sketches/_PIO_Sketches/Karger/SoaapBleMaster_Test_2/src/nRF52840Ser/nRF52840Ser.cpp new file mode 100644 index 0000000000000000000000000000000000000000..86b66bb6cd5ba3f8e3a58c8587d7df52eac240f5 --- /dev/null +++ b/sketches/_PIO_Sketches/Karger/SoaapBleMaster_Test_2/src/nRF52840Ser/nRF52840Ser.cpp @@ -0,0 +1,323 @@ +//----------------------------------------------------------------------------- +// Thema: Social Manufacturing Network / Development Environment +// Datei: nRF52840Ser.cpp +// Editor: Robert Patzke +// URI/URL: www.mfp-portal.de +//----------------------------------------------------------------------------- +// Lizenz: CC-BY-SA (wikipedia: Creative Commons) +// + +#include "nRF52840Ser.h" +#include <string.h> + +// ---------------------------------------------------------------------------- +// Initialisierungen +// ---------------------------------------------------------------------------- + +nRF52840Ser::nRF52840Ser() +{ + serPtr = NULL; + instPtr0 = NULL; + irqCounter = 0; + curIntEn = 0; + curIRQ = 0; + lastError = 0; + cntError = 0; +} + +dword speedArr[18] = +{ + 0x0004F000, 0x0009D000, 0x0013B000, + 0x00275000, 0x003B0000, 0x004EA000, + 0x0075F000, 0x00800000, 0x009D5000, + 0x00E50000, 0x00EBF000, 0x013A9000, + 0x01D7E000, 0x03AFB000, 0x04000000, + 0x075F7000, 0x0EBED000, 0x10000000 +}; + +// ---------------------------------------------------------------------------- +// Konfiguration +// ---------------------------------------------------------------------------- +// +void nRF52840Ser::begin(SerParamsPtr inParPtr, IntrfBuf *bufferIf) +{ + nrfGpioPtr gpioPtr; + dword regVal; + + // Setzen des Peripheriezeigers anhand der Instanz + // und Initialisieren weiterer Variablen/Zeiger + // + serPtr = NrfSerPtr0; + clrAllEvents(); + instPtr0 = this; + curIRQ = 2; + + // Interruptvektor setzen + // + __NVIC_SetVector((IRQn_Type) 2, (dword) nRF52840Ser::irqHandler0); + __NVIC_SetPriority((IRQn_Type) 2, 1); + __NVIC_EnableIRQ((IRQn_Type) 2); + + // Alternative Peripherie (gleiche ID, also Alles) abschalten + // + serPtr->ENABLE = SerDisable; + + + // TxD + // ------------------------------------------------- + // + // Pins zuweisen und initialisieren + // + if(inParPtr->txdPort == 1) + { + regVal = 32 + inParPtr->txdPin; + gpioPtr = NrfGpioPtr1; + } + else + { + regVal = inParPtr->txdPin; + gpioPtr = NrfGpioPtr0; + } + + + // Connect (hoechstwertiges Bit) beruecksichtigen + // + serPtr->PSEL_TXD = regVal | 0x7FFFFFC0; + + // Zugewiesenen Pin als Ausgang schalten und Treibermodus setzen + // Laut Datenblatt ist das entsprechende Bit im Konfigurationsregister + // mit dem DIR-Register physikalisch verbunden + // + if(inParPtr->type == stStd) + regVal = GpioPinCnf_DRIVE(GpioDriveS0S1); + else if(inParPtr->type == stPow) + regVal = GpioPinCnf_DRIVE(GpioDriveH0H1); + else + regVal = GpioPinCnf_DRIVE(GpioDriveH0D1); + + gpioPtr->PIN_CNF[inParPtr->txdPin] = regVal | GpioPinCnf_DIROUT; + + // RXD + // ------------------------------------------------- + // + if(inParPtr->rxdPort == 1) + { + regVal = 32 + inParPtr->rxdPin; + gpioPtr = NrfGpioPtr1; + } + else + { + regVal = inParPtr->rxdPin; + gpioPtr = NrfGpioPtr0; + } + + // Connect (hoechstwertiges Bit) beruecksichtigen + // + serPtr->PSEL_RXD = regVal | 0x7FFFFFC0; + + // Zugewiesenen Pin als Eingang schalten und Treibermodus setzen + // Laut Datenblatt ist das entsprechende Bit im Konfigurationsregister + // mit dem DIR-Register physikalisch verbunden + // + gpioPtr->PIN_CNF[inParPtr->rxdPin] = GpioPinCnf_PULL(GpioPullUp); + + // Bitrate einstellen + // + regVal = speedArr[inParPtr->speed]; + serPtr->BAUDRATE = regVal; + serPtr->SHORTS = 0; + + // Interrupts freischalten + // + curIntEn = (SerInt_TXDRDY | SerInt_RXDRDY | SerInt_ERROR); + serPtr->INTENSET = curIntEn; + + // Und bereit machen + // + serPtr->ENABLE = SerEnable; + txdFin = true; + + bufIf = bufferIf; + delay(10); +} + + +// ---------------------------------------------------------------------------- +// Steuerfunktionen, gezielte Prozessorzugriffe und Hilfsfunktionen +// ---------------------------------------------------------------------------- +// +void nRF52840Ser::clrAllEvents() +{ + serPtr->EVENTS_RXDRDY = 0; + serPtr->EVENTS_TXDRDY = 0; + serPtr->EVENTS_ERROR = 0; +} + +// Fortsetzen des Interrupt-Sendebetriebs +// +void nRF52840Ser::resuSend() +{ + byte td; + + if(!txdFin) return; + if(bufIf == NULL) return; + if(!bufIf->getByteSnd(&td)) return; + + txdFin = false; + serPtr->EVENTS_TXDRDY = 0; + serPtr->TXD = td; +} + +// Starten des Sendebetriebs +// +void nRF52840Ser::startSend() +{ + serPtr->TASKS_STARTTX = 1; +} + +// Anhalten des Sendebetriebs +// +void nRF52840Ser::stopSend() +{ + serPtr->TASKS_STOPTX = 1; +} + +// Starten des Empfangsbetriebs +// +void nRF52840Ser::startRec() +{ + serPtr->TASKS_STARTRX = 1; +} + +// Anhalten des Empfangsbetriebs +// +void nRF52840Ser::stopRec() +{ + serPtr->TASKS_STOPRX = 1; +} + + +// Bedingtes Ausgeben eines Zeichens +// +bool nRF52840Ser::condSend(byte c) +{ + if(!txdFin) return(false); + + txdFin = false; + serPtr->EVENTS_TXDRDY = 0; + serPtr->TXD = c; + return(true); +} + +// ---------------------------------------------------------------------------- +// Ereignisbearbeitung und Interrupts +// ---------------------------------------------------------------------------- +// +nRF52840Ser *nRF52840Ser::instPtr0 = NULL; + +void nRF52840Ser::irqHandler0() +{ + if(instPtr0 == NULL) return; + instPtr0->irqCounter++; + instPtr0->irqHandler(); +} + + + // -------------------------------------------------------------------------- + // Interrupts (Ereignisbehandlung) + // -------------------------------------------------------------------------- + // +void nRF52840Ser::irqHandler() +{ + byte b; + + if(serPtr->EVENTS_TXDRDY != 0) + { + serPtr->EVENTS_TXDRDY = 0; + if(bufIf == NULL) return; + + if(!bufIf->getByteSnd(&b)) + txdFin = true; + else + serPtr->TXD = b; + } + else if(serPtr->EVENTS_RXDRDY != 0) + { + serPtr->EVENTS_RXDRDY = 0; + b = serPtr->RXD; + if(bufIf == NULL) return; + bufIf->putByteRec(b); + } + else if(serPtr->EVENTS_ERROR != 0) + { + serPtr->EVENTS_ERROR = 0; + cntError++; + lastError = serPtr->ERRORSRC; + anyError |= lastError; + } +} + +// -------------------------------------------------------------------------- +// Datenzugriffe +// -------------------------------------------------------------------------- +// +// Letzten Fehler lesen (Bits) +// +int nRF52840Ser::getLastError() +{ + return(lastError); +} + +// Alle vorgekommenen Fehlerbits +// +int nRF52840Ser::getAnyError() +{ + return(anyError); +} + +// Anzahl der Fehler lesen +// +dword nRF52840Ser::getErrCount() +{ + return(cntError); +} + + + +// ---------------------------------------------------------------------------- +// D e b u g - H i l f e n +// ---------------------------------------------------------------------------- +// +dword nRF52840Ser::getIrqCount() +{ + return(irqCounter); +} + +void nRF52840Ser::resetIrqList() +{ + irqIdx = 0; + firstRead = true; + + for(int i = 0; i < 8; i++) + irqList[i] = 0; +} + +void nRF52840Ser::getIrqList(char *dest) +{ + int destIdx = 0; + + for(int i = 0; i < 8; i++) + { + if(irqList[i] == 0) break; + + dest[destIdx++] = ' '; + dest[destIdx++] = irqList[i] + 0x30; + } + + dest[destIdx] = '\0'; +} + + + + + diff --git a/sketches/_PIO_Sketches/Karger/SoaapBleMaster_Test_2/src/nRF52840Ser/nRF52840Ser.h b/sketches/_PIO_Sketches/Karger/SoaapBleMaster_Test_2/src/nRF52840Ser/nRF52840Ser.h new file mode 100644 index 0000000000000000000000000000000000000000..37fcae4b19bc8ec15a2a83040f6f086d35e68efd --- /dev/null +++ b/sketches/_PIO_Sketches/Karger/SoaapBleMaster_Test_2/src/nRF52840Ser/nRF52840Ser.h @@ -0,0 +1,234 @@ +//----------------------------------------------------------------------------- +// Thema: Social Manufacturing Network / Development Environment +// Datei: nRF52840Ser.h +// Editor: Robert Patzke +// URI/URL: www.mfp-portal.de +//----------------------------------------------------------------------------- +// Lizenz: CC-BY-SA (wikipedia: Creative Commons) +// + +#ifndef NRF52840SER_H +#define NRF52840SER_H + +#include "Arduino.h" +#include "arduinoDefs.h" +#include "IntrfBuf.h" +#include "IntrfSerial.h" + +// ---------------------------------------------------------------------------- + +typedef struct _nrfSer +{ + volatile dword TASKS_STARTRX; // 000 + volatile dword TASKS_STOPRX; // 004 + volatile dword TASKS_STARTTX; // 008 + volatile dword TASKS_STOPTX; // 00C + volatile dword Reserve01[3]; // 010 + volatile dword TASKS_SUSPEND; // 01C + volatile dword Reserve02[56]; // 020 + volatile dword EVENTS_CTS; // 100 + volatile dword EVENTS_NCTS; // 104 + volatile dword EVENTS_RXDRDY; // 108 + volatile dword Reserve03[4]; // 10C + volatile dword EVENTS_TXDRDY; // 11C + volatile dword Reserve04; // 120 + volatile dword EVENTS_ERROR; // 124 + volatile dword Reserve05[7]; // 128 + volatile dword EVENTS_RXTO; // 144 + volatile dword Reserve06[46]; // 148 + volatile dword SHORTS; // 200 + volatile dword Reserve07[64]; // 204 + volatile dword INTENSET; // 304 + volatile dword INTENCLR; // 308 + volatile dword Reserve08[93]; // 30C + volatile dword ERRORSRC; // 480 + volatile dword Reserve09[31]; // 484 + volatile dword ENABLE; // 500 + volatile dword Reserve10; // 504 + volatile dword PSEL_RTS; // 508 + volatile dword PSEL_TXD; // 50C + volatile dword PSEL_CTS; // 510 + volatile dword PSEL_RXD; // 514 + volatile dword RXD; // 518 + volatile dword TXD; // 51C + volatile dword Reserve11; // 520 + volatile dword BAUDRATE; // 524 + volatile dword Reserve12[17]; // 528 + volatile dword CONFIG; // 56C +} nrfSer, *nrfSerPtr; + +#define NrfSerBase0 0x40002000 +#define NrfSerPtr0 ((nrfSerPtr) NrfSerBase0) + +#ifndef nrfGpioDef + +typedef struct _nrfGpio +{ + volatile dword Reserve01; // 000 + volatile dword OUT; // 004 + volatile dword OUTSET; // 008 + volatile dword OUTCLR; // 00C + volatile dword IN; // 010 + volatile dword DIR; // 014 + volatile dword DIRSET; // 018 + volatile dword DIRCLR; // 01C + volatile dword LATCH; // 020 + volatile dword DETECTMODE; // 024 + volatile dword Reserve02[118]; // 026 + volatile dword PIN_CNF[32]; // 200 +} nrfGpio, *nrfGpioPtr; + +#define NrfGpioBase 0x50000000 +#define NrfGpioBase0 0x50000500 +#define NrfGpioPtr0 ((nrfGpioPtr) NrfGpioBase0) +#define NrfGpioBase1 0x50000800 +#define NrfGpioPtr1 ((nrfGpioPtr) NrfGpioBase1) + +#define GpioPinCnf_DIROUT ((dword) 0x00000001) + +#define GpioPinCnf_DISBUF ((dword) 0x00000002) + +#define GpioPinCnf_PULL(x) ((dword) x << 2) +#define GpioPullDown 1 +#define GpioPullUp 3 + +#define GpioPinCnf_DRIVE(x) ((dword) x << 8) +#define GpioDriveS0S1 0 +#define GpioDriveH0S1 1 +#define GpioDriveS0H1 2 +#define GpioDriveH0H1 3 +#define GpioDriveD0S1 4 +#define GpioDriveD0H1 5 +#define GpioDriveS0D1 6 +#define GpioDriveH0D1 7 + +#define GpioPinCnf_SENSE(x) ((dword) x << 16) +#define GpioSenseHigh 2 +#define GpioSenseLow 3 + +#define nrfGpioDef +#endif + +// Festlegungen für die Paketkonfigurationsregister +// + +#define SerInt_RXDRDY ((dword) 0x00000001 << 2) +// Interrupt für Event RXDRDY + +#define SerInt_TXDRDY ((dword) 0x00000001 << 7) +// Interrupt für Event TXDRDY + +#define SerInt_ERROR ((dword) 0x00000001 << 9) +// Interrupt für Event ERROR + + +#define SerEnable 4 +#define SerDisable 0 + +// Bit-Masken fuer Kommunikationsbedingungen +// +#define BM_REC_NOT_COND 0x00 +// Keine Bedingungen beim Empfang +#define BM_REC_END_CHR 0x01 +// Empfang Stoppen beim Eintreffen des vorgegebenen Zeichens +#define BM_REC_RINGBUF 0x02 +// Receive characters in ring buffer +#define BM_SND_RINGBUF 0x04 +// Transmit characters via ring buffer + + + +// ---------------------------------------------------------------------------- + +class nRF52840Ser : IntrfSerial +{ +private: + // -------------------------------------------------------------------------- + // Lokale Daten und Funktionen + // -------------------------------------------------------------------------- + // + nrfSerPtr serPtr; + dword irqCounter; + + int lastError; + int anyError; + dword cntError; + + int curIRQ; + dword curIntEn; + + IntrfBuf *bufIf; + bool txdFin; // TRUE = Sendevorgang beendet + + void clrAllEvents(); + +public: + // -------------------------------------------------------------------------- + // Initialisierungen der Basis-Klasse + // -------------------------------------------------------------------------- + + nRF52840Ser(); + + // -------------------------------------------------------------------------- + // Konfigurationen + // -------------------------------------------------------------------------- + // + void begin(SerParamsPtr serParPtr, IntrfBuf *bufferIf); + + + // -------------------------------------------------------------------------- + // Steuerfunktionen + // -------------------------------------------------------------------------- + // + void resuSend(); // Fortsetzen des Interrupt-Sendebetriebs + void startSend(); // Starten des Sendebetriebs + void stopSend(); // Anhalten des Sendebetriebs + + void startRec(); // Starten des Empfangsbetriebs + void stopRec(); // Anhalten des Empfangsbetriebs + + + // -------------------------------------------------------------------------- + // Datenzugriffe + // -------------------------------------------------------------------------- + // + bool condSend(byte c); // Bedingtes Senden eines Zeichens + + int getLastError(); // Letzten Fehler lesen (Bits) + int getAnyError(); // Alle vorgekommenen Fehlerbits + dword getErrCount(); // Anzahl der Fehler lesen + + + // ---------------------------------------------------------------------------- + // Ereignisbearbeitung und Interrupts + // ---------------------------------------------------------------------------- + // + static nRF52840Ser *instPtr0; + static void irqHandler0(); + + void irqHandler(); + + // -------------------------------------------------------------------------- + // lokale Variablen + // -------------------------------------------------------------------------- + // + + + // ---------------------------------------------------------------------------- + // D e b u g - H i l f e n + // ---------------------------------------------------------------------------- + // + int irqIdx; + int irqList[8]; + + byte extraValue; + bool firstRead; + + dword getIrqCount(); + void resetIrqList(); + void getIrqList(char *dest); + +}; + +#endif // NRF52840SER_H + diff --git a/sketches/_PIO_Sketches/Karger/SoaapBleMaster_Test_2/src/nRF52840Twi/library.json b/sketches/_PIO_Sketches/Karger/SoaapBleMaster_Test_2/src/nRF52840Twi/library.json new file mode 100644 index 0000000000000000000000000000000000000000..16ae3922cdc02214ba2709422d1f9acfa86d132d --- /dev/null +++ b/sketches/_PIO_Sketches/Karger/SoaapBleMaster_Test_2/src/nRF52840Twi/library.json @@ -0,0 +1,4 @@ +{ + "name": "nRF52840Twi", + "version": "0.0.0+20220823165932" +} \ No newline at end of file diff --git a/sketches/_PIO_Sketches/Karger/SoaapBleMaster_Test_2/src/nRF52840Twi/nRF52840Twi.cpp b/sketches/_PIO_Sketches/Karger/SoaapBleMaster_Test_2/src/nRF52840Twi/nRF52840Twi.cpp new file mode 100644 index 0000000000000000000000000000000000000000..81fdb263721b902935a3a21f952b214796e8c9d5 --- /dev/null +++ b/sketches/_PIO_Sketches/Karger/SoaapBleMaster_Test_2/src/nRF52840Twi/nRF52840Twi.cpp @@ -0,0 +1,586 @@ +//----------------------------------------------------------------------------- +// Thema: Social Manufacturing Network / Development Environment +// Datei: nRF52840Radio.cpp +// Editor: Robert Patzke +// URI/URL: www.mfp-portal.de +//----------------------------------------------------------------------------- +// Lizenz: CC-BY-SA (wikipedia: Creative Commons) +// + +#include "nRF52840Twi.h" +#include <string.h> + +// ---------------------------------------------------------------------------- +// Initialisierungen +// ---------------------------------------------------------------------------- + +nRF52840Twi::nRF52840Twi() +{ + twiPtr = NULL; + instPtr0 = NULL; + instPtr1 = NULL; + irqCounter = 0; +} + +// ---------------------------------------------------------------------------- +// Konfiguration +// ---------------------------------------------------------------------------- +// +TwiError nRF52840Twi::begin(TwiParamsPtr inParPtr) +{ + TwiError retv; + nrfGpioPtr gpioPtr; + dword regVal; + + retv = TEnoError; + + params = *inParPtr; + + // Setzen des Peripheriezeigers anhand der Instanz + // und Initialisieren weiterer Variablen/Zeiger + // + if(inParPtr->inst == 0) + { + twiPtr = NrfTwiPtr0; + clrAllEvents(); + instPtr0 = this; + curIRQ = 3; + + // Interruptvektor setzen + // + __NVIC_SetVector((IRQn_Type) 3, (dword) nRF52840Twi::irqHandler0); + __NVIC_SetPriority((IRQn_Type) 3, 1); + __NVIC_EnableIRQ((IRQn_Type) 3); + } + else + { + twiPtr = NrfTwiPtr1; + clrAllEvents(); + instPtr1 = this; + curIRQ = 4; + + // Interruptvektor setzen + // + __NVIC_SetVector((IRQn_Type) 4, (dword) nRF52840Twi::irqHandler1); + __NVIC_SetPriority((IRQn_Type) 4, 1); + __NVIC_EnableIRQ((IRQn_Type) 4); + } + + // Alternative Peripherie (gleiche ID, also Alles) abschalten + // + twiPtr->ENABLE = TwiDisable; + + + // Takt + // ------------------------------------------------- + // + // Pins zuweisen und initialisieren + // + if(inParPtr->clkPort == 1) + { + regVal = 32 + inParPtr->clkPin; + gpioPtr = NrfGpioPtr1; + } + else + { + regVal = inParPtr->clkPin; + gpioPtr = NrfGpioPtr0; + } + + // Connect (hoechstwertiges Bit) beruecksichtigen + // + twiPtr->PSEL_SCL = regVal | 0x7FFFFFC0; + + // Zugewiesenen Pin als Eingang schalten und Treibermodus setzen + // Laut Datenblatt ist das entsprechende Bit im Konfigurationsregister + // mit dem DIR-Register physikalisch verbunden + // + gpioPtr->PIN_CNF[inParPtr->clkPin] = GpioPinCnf_DRIVE(GpioDriveS0D1); + + // Daten + // ------------------------------------------------- + // + if(inParPtr->dataPort == 1) + { + regVal = 32 + inParPtr->dataPin; + gpioPtr = NrfGpioPtr1; + } + else + { + regVal = inParPtr->dataPin; + gpioPtr = NrfGpioPtr0; + } + + // Connect (hoechstwertiges Bit) beruecksichtigen + // + twiPtr->PSEL_SDA = regVal | 0x7FFFFFC0; + + // Zugewiesenen Pin als Eingang schalten und Treibermodus setzen + // Laut Datenblatt ist das entsprechende Bit im Konfigurationsregister + // mit dem DIR-Register physikalisch verbunden + // + gpioPtr->PIN_CNF[inParPtr->dataPin] = GpioPinCnf_DRIVE(GpioDriveS0D1); + + // Frequenz einstellen + // + if(inParPtr->speed == Twi100k) + regVal = NrfTwi100k; + else if(inParPtr->speed == Twi400k) + regVal = NrfTwi400k; + else + regVal = NrfTwi250k; + + twiPtr->FREQUENCY = regVal; + + twiPtr->SHORTS = 0; + + // Interrupts freischalten + // + curIntEn = (TwiInt_TXDSENT | TwiInt_RXDREADY | TwiInt_ERROR | TwiInt_STOPPED); + twiPtr->INTENSET = curIntEn; + + // Und bereit machen + // + twiPtr->ENABLE = TwiEnable; + + delay(10); + + return(retv); +} + + +void nRF52840Twi::getParams(TwiParamsPtr parPtr) +{ + *parPtr = params; +} + + +// ---------------------------------------------------------------------------- +// Steuerfunktionen, gezielte Prozessorzugriffe und Hilfsfunktionen +// ---------------------------------------------------------------------------- +// +void nRF52840Twi::clrAllEvents() +{ + twiPtr->EVENTS_STOPPED = 0; + twiPtr->EVENTS_RXDREADY = 0; + twiPtr->EVENTS_TXDSENT = 0; + twiPtr->EVENTS_SUSPENDED = 0; + twiPtr->EVENTS_BB = 0; + twiPtr->EVENTS_ERROR = 0; +} + +// ---------------------------------------------------------------------------- +// M a s t e r +// ---------------------------------------------------------------------------- +// + + // -------------------------------------------------------------------------- + // Datenaustausch + // -------------------------------------------------------------------------- + // +TwiError nRF52840Twi::sendByte(int adr, TwiBytePtr refByte) +{ + TwiError retv = TEnoError; + lastError = 0; + + resetIrqList(); + + byteStruPtr = refByte; + twiPtr->ADDRESS = adr; + + byteStruPtr->twiStatus = TwStWrReq; + trfMode = ttmWriteByte; + + twiPtr->TASKS_STARTTX = 1; + twiPtr->TXD = refByte->value; + + return(retv); +} + +TwiError nRF52840Twi::sendByteReg(int adr, int reg, TwiBytePtr refByte) +{ + TwiError retv = TEnoError; + + //dynHand = &nRF52840Twi::irqHandler; + + resetIrqList(); + + byteStruPtr = refByte; + twiPtr->ADDRESS = adr; + + byteStruPtr->twiStatus = TwStWrReq; + trfMode = ttmWriteByteReg; + comIdx = 1; + irqIdx = 0; + + twiPtr->TASKS_STARTTX = 1; + twiPtr->TXD = reg; + + return(retv); +} + +TwiStatus nRF52840Twi::writeByteReg(int adr, int reg, byte value) +{ + twiPtr->INTENCLR = curIntEn; + + tmpByte.value = value; + + sendByteReg(adr, reg, &tmpByte); + + while(tmpByte.twiStatus != TwStFin) + { + irqHandler(); + + if(tmpByte.twiStatus & TwStError) + break; + } + + twiPtr->INTENSET = curIntEn; + + return(tmpByte.twiStatus); +} + + +TwiError nRF52840Twi::recByteReg(int adr, int reg, TwiBytePtr refByte) +{ + TwiError retv = TEnoError; + + //dynHand = &nRF52840Twi::irqHandler; + + byteStruPtr = refByte; + twiPtr->ADDRESS = adr; + + resetIrqList(); + + byteStruPtr->twiStatus = TwStRdReq; + trfMode = ttmReadByteReg; + + twiPtr->TASKS_STARTTX = 1; + twiPtr->TXD = reg; + + return(retv); +} + +int nRF52840Twi::readByteReg(int adr, int reg) +{ + twiPtr->INTENCLR = curIntEn; + + recByteReg(adr, reg, &tmpByte); + + while(tmpByte.twiStatus != TwStFin) + { + irqHandler(); + + if(tmpByte.twiStatus & TwStError) + break; + } + + twiPtr->INTENSET = curIntEn; + + if(tmpByte.twiStatus == TwStFin) + return(tmpByte.value); + else + return(-1); +} + + +TwiError nRF52840Twi::recByteRegSeq(int adr, int reg, TwiByteSeqPtr refByteSeq) +{ + TwiError retv = TEnoError; + + byteSeqPtr = refByteSeq; + comIdx = 0; + twiPtr->ADDRESS = adr; + + byteSeqPtr->twiStatus = TwStRdReq; + trfMode = ttmReadByteRegSeq; + + twiPtr->TASKS_STARTTX = 1; + twiPtr->TXD = reg; + + return(retv); +} + +TwiStatus nRF52840Twi::readByteRegSeq(int adr, int reg, TwiByteSeqPtr refByteSeq) +{ + byteSeqPtr = refByteSeq; + comIdx = 0; + twiPtr->ADDRESS = adr; + + byteSeqPtr->twiStatus = TwStRdReq; + trfMode = ttmReadByteRegSeq; + + twiPtr->INTENCLR = curIntEn; + + twiPtr->TASKS_STARTTX = 1; + twiPtr->TXD = reg; + + while(byteSeqPtr->twiStatus != TwStFin) + { + irqHandler(); + + if(byteSeqPtr->twiStatus & TwStError) + break; + } + + twiPtr->INTENSET = curIntEn; + + return(byteSeqPtr->twiStatus); +} + +// ---------------------------------------------------------------------------- +// Ereignisbearbeitung und Interrupts +// ---------------------------------------------------------------------------- +// +nRF52840Twi *nRF52840Twi::instPtr0 = NULL; + +void nRF52840Twi::irqHandler0() +{ + if(instPtr0 == NULL) return; + instPtr0->irqCounter++; + instPtr0->irqHandler(); +} + +nRF52840Twi *nRF52840Twi::instPtr1 = NULL; + +void nRF52840Twi::irqHandler1() +{ + if(instPtr1 == NULL) return; + instPtr1->irqCounter++; + instPtr1->irqHandler(); +} + + + // -------------------------------------------------------------------------- + // Interrupts (Ereignisbehandlung) + // -------------------------------------------------------------------------- + // +void nRF52840Twi::irqHandler() +{ + switch(trfMode) + { + case ttmWriteByte: + // ------------------------------------------------------------------------ + + if(twiPtr->EVENTS_ERROR) + { + twiPtr->EVENTS_ERROR = 0; + lastError = twiPtr->ERRORSRC; + twiPtr->ERRORSRC = (lastError & 0x06); // Clear AdrNak/DataNak + byteStruPtr->twiStatus = (TwiStatus) ( (int) TwStError + lastError); + twiPtr->TASKS_STOP = 1; + + irqList[irqIdx++] = 8; + return; + } + + if(twiPtr->EVENTS_TXDSENT) + { + twiPtr->EVENTS_TXDSENT = 0; + byteStruPtr->twiStatus = TwStSent; + twiPtr->TASKS_STOP = 1; + + irqList[irqIdx++] = 1; + return; + } + + if(twiPtr->EVENTS_STOPPED) + { + twiPtr->EVENTS_STOPPED = 0; + if(lastError == 0) + byteStruPtr->twiStatus = TwStFin; + + irqList[irqIdx++] = 3; + return; + } + + break; + + case ttmWriteByteReg: + // ------------------------------------------------------------------------ + + if(twiPtr->EVENTS_ERROR) + { + twiPtr->EVENTS_ERROR = 0; + lastError = twiPtr->ERRORSRC; + twiPtr->ERRORSRC = (lastError & 0x06); // Clear AdrNak/DataNak + byteStruPtr->twiStatus = (TwiStatus) ( (int) TwStError + lastError); + twiPtr->TASKS_STOP = 1; + return; + } + + if(twiPtr->EVENTS_TXDSENT) + { + twiPtr->EVENTS_TXDSENT = 0; + byteStruPtr->twiStatus = TwStSent; + if(comIdx == 1) + { + comIdx = 0; + twiPtr->TXD = byteStruPtr->value; + } + else + twiPtr->TASKS_STOP = 1; + return; + } + + if(twiPtr->EVENTS_STOPPED) + { + twiPtr->EVENTS_STOPPED = 0; + if(lastError == 0) + byteStruPtr->twiStatus = TwStFin; + return; + } + + break; + + case ttmReadByteReg: + // ------------------------------------------------------------------------ + + if(twiPtr->EVENTS_ERROR) + { + twiPtr->EVENTS_ERROR = 0; + lastError = twiPtr->ERRORSRC; + twiPtr->ERRORSRC = (lastError & 0x06); // Clear AdrNak/DataNak + byteStruPtr->twiStatus = (TwiStatus) ( (int) TwStError + lastError); + twiPtr->TASKS_STOP = 1; + + irqList[irqIdx++] = 8; + return; + } + + if(twiPtr->EVENTS_TXDSENT) + { + twiPtr->EVENTS_TXDSENT = 0; + byteStruPtr->twiStatus = TwStSent; + twiPtr->TASKS_STARTRX = 1; + twiPtr->SHORTS = 2; + + irqList[irqIdx++] = 1; + return; + } + + if(twiPtr->EVENTS_STOPPED) + { + twiPtr->EVENTS_STOPPED = 0; + if(lastError == 0) + byteStruPtr->twiStatus = TwStFin; + + irqList[irqIdx++] = 3; + twiPtr->SHORTS = 0; + return; + } + + if(twiPtr->EVENTS_RXDREADY) + { + twiPtr->EVENTS_RXDREADY = 0; + byteStruPtr->twiStatus = TwStRecvd; + byteStruPtr->value = twiPtr->RXD; + + irqList[irqIdx++] = 2; + return; + } + + break; + + case ttmReadByteRegSeq: + // ------------------------------------------------------------------------ + + if(twiPtr->EVENTS_ERROR) + { + twiPtr->EVENTS_ERROR = 0; + lastError = twiPtr->ERRORSRC; + twiPtr->ERRORSRC = (lastError & 0x06); // Clear AdrNak/DataNak + byteSeqPtr->twiStatus = (TwiStatus) ( (int) TwStError + lastError); + twiPtr->TASKS_STOP = 1; + return; + } + + if(twiPtr->EVENTS_TXDSENT) + { + twiPtr->EVENTS_TXDSENT = 0; + byteSeqPtr->twiStatus = TwStSent; + twiPtr->TASKS_STARTRX = 1; + return; + } + + if(twiPtr->EVENTS_STOPPED) + { + twiPtr->EVENTS_STOPPED = 0; + if(lastError == 0) + byteSeqPtr->twiStatus = TwStFin; + twiPtr->SHORTS = 0; + return; + } + + if(twiPtr->EVENTS_RXDREADY) + { + twiPtr->EVENTS_RXDREADY = 0; + byteSeqPtr->twiStatus = TwStRecvd; + /* + if(comIdx == (byteSeqPtr->len - 2)) + twiPtr->SHORTS = 2; + byteSeqPtr->valueRef[comIdx] = twiPtr->RXD; + if(comIdx < (byteSeqPtr->len - 1)) + comIdx++; + */ + if(comIdx == (byteSeqPtr->len - 2)) + twiPtr->SHORTS = 2; + + lastIn = twiPtr->RXD; + + if(comIdx < (byteSeqPtr->len)) + byteSeqPtr->valueRef[comIdx] = lastIn; + + comIdx++; + return; + } + + break; + + } +} + +// ---------------------------------------------------------------------------- +// S l a v e +// ---------------------------------------------------------------------------- + +// Starten des Datenempfangs +// + +// ---------------------------------------------------------------------------- +// D e b u g - H i l f e n +// ---------------------------------------------------------------------------- +// +dword nRF52840Twi::getIrqCount() +{ + return(irqCounter); +} + +void nRF52840Twi::resetIrqList() +{ + irqIdx = 0; + firstRead = true; + + for(int i = 0; i < 8; i++) + irqList[i] = 0; +} + +void nRF52840Twi::getIrqList(char *dest) +{ + int destIdx = 0; + + for(int i = 0; i < 8; i++) + { + if(irqList[i] == 0) break; + + dest[destIdx++] = ' '; + dest[destIdx++] = irqList[i] + 0x30; + } + + dest[destIdx] = '\0'; +} + + + + + diff --git a/sketches/_PIO_Sketches/Karger/SoaapBleMaster_Test_2/src/nRF52840Twi/nRF52840Twi.h b/sketches/_PIO_Sketches/Karger/SoaapBleMaster_Test_2/src/nRF52840Twi/nRF52840Twi.h new file mode 100644 index 0000000000000000000000000000000000000000..e33ca74b72c254311a695ab5ea7fd3152a8ebf4d --- /dev/null +++ b/sketches/_PIO_Sketches/Karger/SoaapBleMaster_Test_2/src/nRF52840Twi/nRF52840Twi.h @@ -0,0 +1,250 @@ +//----------------------------------------------------------------------------- +// Thema: Social Manufacturing Network / Development Environment +// Datei: nRF52840Twi.h +// Editor: Robert Patzke +// URI/URL: www.mfp-portal.de +//----------------------------------------------------------------------------- +// Lizenz: CC-BY-SA (wikipedia: Creative Commons) +// + +#ifndef NRF52840TWI_H +#define NRF52840TWI_H + +#include "Arduino.h" +#include "arduinoDefs.h" +#include "IntrfTw.h" + +// ---------------------------------------------------------------------------- + +typedef struct _nrfTwi +{ + volatile dword TASKS_STARTRX; // 000 + volatile dword Reserve01; // 004 + volatile dword TASKS_STARTTX; // 008 + volatile dword Reserve02[2]; // 00C + volatile dword TASKS_STOP; // 014 + volatile dword Reserve03; // 018 + volatile dword TASKS_SUSPEND; // 01C + volatile dword TASKS_RESUME; // 020 + volatile dword Reserve04[56]; // 024 + volatile dword EVENTS_STOPPED; // 104 + volatile dword EVENTS_RXDREADY; // 108 + volatile dword Reserve05[4]; // 118 + volatile dword EVENTS_TXDSENT; // 11C + volatile dword Reserve06; // 120 + volatile dword EVENTS_ERROR; // 124 + volatile dword Reserve07[4]; // 128 + volatile dword EVENTS_BB; // 138 + volatile dword Reserve08[3]; // 13C + volatile dword EVENTS_SUSPENDED; // 148 + volatile dword Reserve09[45]; // 14C + volatile dword SHORTS; // 200 + volatile dword Reserve10[64]; // 204 + volatile dword INTENSET; // 304 + volatile dword INTENCLR; // 308 + volatile dword Reserve11[110]; // 30C + volatile dword ERRORSRC; // 4C4 + volatile dword Reserve12[14]; // 4C8 + volatile dword ENABLE; // 500 + volatile dword Reserve13; // 504 + volatile dword PSEL_SCL; // 508 + volatile dword PSEL_SDA; // 50C + volatile dword Reserve14[2]; // 510 + volatile dword RXD; // 518 + volatile dword TXD; // 51C + volatile dword Reserve15; // 520 + volatile dword FREQUENCY; // 524 + volatile dword Reserve16[24]; // 528 + volatile dword ADDRESS; // 588 +} nrfTwi, *nrfTwiPtr; + +#define NrfTwiBase0 0x40003000 +#define NrfTwiPtr0 ((nrfTwiPtr) NrfTwiBase0) +#define NrfTwiBase1 0x40004000 +#define NrfTwiPtr1 ((nrfTwiPtr) NrfTwiBase1) + +#define NrfTwi100k 0x01980000 +#define NrfTwi250k 0x04000000 +#define NrfTwi400k 0x06680000 + +typedef enum _TwiTrfMode +{ + ttmWriteByte = 1, + ttmWriteByteReg, + ttmReadByteReg, + ttmReadByteRegSeq +} TwiTrfMode; + +#ifndef nrfGpioDef + +typedef struct _nrfGpio +{ + volatile dword Reserve01; // 000 + volatile dword OUT; // 004 + volatile dword OUTSET; // 008 + volatile dword OUTCLR; // 00C + volatile dword IN; // 010 + volatile dword DIR; // 014 + volatile dword DIRSET; // 018 + volatile dword DIRCLR; // 01C + volatile dword LATCH; // 020 + volatile dword DETECTMODE; // 024 + volatile dword Reserve02[118]; // 026 + volatile dword PIN_CNF[32]; // 200 +} nrfGpio, *nrfGpioPtr; + +#define NrfGpioBase 0x50000000 +#define NrfGpioBase0 0x50000500 +#define NrfGpioPtr0 ((nrfGpioPtr) NrfGpioBase0) +#define NrfGpioBase1 0x50000800 +#define NrfGpioPtr1 ((nrfGpioPtr) NrfGpioBase1) + +#define GpioPinCnf_DIR ((dword) 0x00000001) + +#define GpioPinCnf_INPUT ((dword) 0x00000001 << 1) + +#define GpioPinCnf_PULL(x) ((dword) x << 2) +#define GpioPullDown 1 +#define GpioPullUp 3 + +#define GpioPinCnf_DRIVE(x) ((dword) x << 8) +#define GpioDriveS0S1 0 +#define GpioDriveH0S1 1 +#define GpioDriveS0H1 2 +#define GpioDriveH0H1 3 +#define GpioDriveD0S1 4 +#define GpioDriveD0H1 5 +#define GpioDriveS0D1 6 +#define GpioDriveH0D1 7 + +#define GpioPinCnf_SENSE(x) ((dword) x << 16) +#define GpioSenseHigh 2 +#define GpioSenseLow 3 + +#define nrfGpioDef +#endif + +// Festlegungen für die Paketkonfigurationsregister +// + +#define TwiInt_STOPPED ((dword) 0x00000001 << 1) +// Interrupt für Event STOPPED + +#define TwiInt_RXDREADY ((dword) 0x00000001 << 2) +// Interrupt für Event RXDREADY + +#define TwiInt_TXDSENT ((dword) 0x00000001 << 7) +// Interrupt für Event TXDSENT + +#define TwiInt_ERROR ((dword) 0x00000001 << 9) +// Interrupt für Event ERROR + +#define TwiInt_BB ((dword) 0x00000001 << 14) +// Interrupt für Event BB + +#define TwiInt_SUSPENDED ((dword) 0x00000001 << 18) +// Interrupt für Event SUSPENDED + +#define TwiEnable 5 +#define TwiDisable 0 + + + + +// ---------------------------------------------------------------------------- + +class nRF52840Twi : IntrfTw +{ +private: + // -------------------------------------------------------------------------- + // Lokale Daten und Funktionen + // -------------------------------------------------------------------------- + // + nrfTwiPtr twiPtr; + dword irqCounter; + + TwiBytePtr byteStruPtr; + TwiWordPtr wordStruPtr; + TwiByteSeqPtr byteSeqPtr; + + TwiTrfMode trfMode; + dword lastError; + byte lastIn; + int comIdx; + + int curIRQ; + dword curIntEn; + + TwiByte tmpByte; + + TwiParams params; + + void clrAllEvents(); + +public: + // -------------------------------------------------------------------------- + // Initialisierungen der Basis-Klasse + // -------------------------------------------------------------------------- + + nRF52840Twi(); + + // -------------------------------------------------------------------------- + // Konfigurationen + // -------------------------------------------------------------------------- + // + TwiError begin(TwiParamsPtr inParPtr); + void getParams(TwiParamsPtr parPtr); + + + // -------------------------------------------------------------------------- + // Steuerfunktionen + // -------------------------------------------------------------------------- + // + + // -------------------------------------------------------------------------- + // Datenaustausch + // -------------------------------------------------------------------------- + // + // asynchrone Kommunikation, Zustand in TwiByte.twiStatus + // + TwiError sendByte(int adr, TwiBytePtr refByte); + TwiError sendByteReg(int addr, int reg, TwiBytePtr refByte); + TwiError recByteReg(int addr, int reg, TwiBytePtr refByte); + TwiError recByteRegSeq(int adr, int reg, TwiByteSeqPtr refByteSeq); + + // synchrone Kommunikation + // + TwiStatus writeByteReg(int adr, int reg, byte value); + int readByteReg(int adr, int reg); + TwiStatus readByteRegSeq(int adr, int reg, TwiByteSeqPtr refByteSeq); + + // ---------------------------------------------------------------------------- + // Ereignisbearbeitung und Interrupts + // ---------------------------------------------------------------------------- + // + static nRF52840Twi *instPtr0; + static void irqHandler0(); + + static nRF52840Twi *instPtr1; + static void irqHandler1(); + + void irqHandler(); + + // ---------------------------------------------------------------------------- + // D e b u g - H i l f e n + // ---------------------------------------------------------------------------- + // + int irqIdx; + int irqList[8]; + + byte extraValue; + bool firstRead; + + dword getIrqCount(); + void resetIrqList(); + void getIrqList(char *dest); + +}; + +#endif // NRF52840RADIO_H + diff --git a/sketches/_PIO_Sketches/Karger/SoaapBleMaster_Test_2/template_platformio.txt b/sketches/_PIO_Sketches/Karger/SoaapBleMaster_Test_2/template_platformio.txt new file mode 100644 index 0000000000000000000000000000000000000000..15fc69d85e05ee9d499f73ed91bde12711b55562 --- /dev/null +++ b/sketches/_PIO_Sketches/Karger/SoaapBleMaster_Test_2/template_platformio.txt @@ -0,0 +1,59 @@ +; PlatformIO Project Configuration File +; +; Build options: build flags, source filter +; Upload options: custom upload port, speed and extra flags +; Library options: dependencies, extra library storages +; Advanced options: extra scripting +; +; Please visit documentation for the other options and examples +; https://docs.platformio.org/page/projectconf.html + +[env:nano33ble] +platform = nordicnrf52 +board = nano33ble +framework = arduino +upload_port = COM3 +build_flags = + -DsmnDEFBYBUILD -DsmnNANOBLE33 -DsmnDEBUG +lib_deps = + symlink://C:\Users\lenna\OneDrive\Dokumente\Git\SOAAP\libraries\BlePoll + symlink://C:\Users\lenna\OneDrive\Dokumente\Git\SOAAP\libraries\environment + symlink://C:\Users\lenna\OneDrive\Dokumente\Git\SOAAP\libraries\ComRingBuf + symlink://C:\Users\lenna\OneDrive\Dokumente\Git\SOAAP\libraries\LoopCheck + symlink://C:\Users\lenna\OneDrive\Dokumente\Git\SOAAP\libraries\MidiNotes + symlink://C:\Users\lenna\OneDrive\Dokumente\Git\SOAAP\libraries\Monitor + symlink://C:\Users\lenna\OneDrive\Dokumente\Git\SOAAP\libraries\nRF52840Gpio + symlink://C:\Users\lenna\OneDrive\Dokumente\Git\SOAAP\libraries\nRF52840Radio + symlink://C:\Users\lenna\OneDrive\Dokumente\Git\SOAAP\libraries\nRF52840Ser + symlink://C:\Users\lenna\OneDrive\Dokumente\Git\SOAAP\libraries\nRF52840Twi + symlink://C:\Users\lenna\OneDrive\Dokumente\Git\SOAAP\libraries\SensorLSM9DS1 + symlink://C:\Users\lenna\OneDrive\Dokumente\Git\SOAAP\libraries\SoaapMsg + symlink://C:\Users\lenna\OneDrive\Dokumente\Git\SOAAP\libraries\StateMachine + ;symlink://C:\Users\lenna\OneDrive\Dokumente\Git\SOAAP\libraries\SoaapComDue + +[env:Logging] +platform = nordicnrf52 +board = nano33ble +framework = arduino +upload_port = COM3 +build_flags = + -DsmnDEFBYBUILD -DsmnNANOBLE33 -DsmnDEBUG +lib_deps = + symlink://C:\Users\lenna\OneDrive\Dokumente\Git\SOAAP\libraries\BlePoll + symlink://C:\Users\lenna\OneDrive\Dokumente\Git\SOAAP\libraries\environment + symlink://C:\Users\lenna\OneDrive\Dokumente\Git\SOAAP\libraries\ComRingBuf + symlink://C:\Users\lenna\OneDrive\Dokumente\Git\SOAAP\libraries\LoopCheck + symlink://C:\Users\lenna\OneDrive\Dokumente\Git\SOAAP\libraries\MidiNotes + symlink://C:\Users\lenna\OneDrive\Dokumente\Git\SOAAP\libraries\Monitor + symlink://C:\Users\lenna\OneDrive\Dokumente\Git\SOAAP\libraries\nRF52840Gpio + symlink://C:\Users\lenna\OneDrive\Dokumente\Git\SOAAP\libraries\nRF52840Radio + symlink://C:\Users\lenna\OneDrive\Dokumente\Git\SOAAP\libraries\nRF52840Ser + symlink://C:\Users\lenna\OneDrive\Dokumente\Git\SOAAP\libraries\nRF52840Twi + symlink://C:\Users\lenna\OneDrive\Dokumente\Git\SOAAP\libraries\SensorLSM9DS1 + symlink://C:\Users\lenna\OneDrive\Dokumente\Git\SOAAP\libraries\SoaapMsg + symlink://C:\Users\lenna\OneDrive\Dokumente\Git\SOAAP\libraries\StateMachine + ;symlink://C:\Users\lenna\OneDrive\Dokumente\Git\SOAAP\libraries\SoaapComDue +monitor_filters = + default ; Remove typical terminal control codes from input + time ; Add timestamp with milliseconds for each new line + log2file ; Log data to a file “platformio-device-monitor-*.log” located in the current working directory \ No newline at end of file diff --git a/sketches/_PIO_Sketches/Karger/SoaapBleMaster_Test_2/test/README b/sketches/_PIO_Sketches/Karger/SoaapBleMaster_Test_2/test/README new file mode 100644 index 0000000000000000000000000000000000000000..9b1e87bc67c90e7f09a92a3e855444b085c655a6 --- /dev/null +++ b/sketches/_PIO_Sketches/Karger/SoaapBleMaster_Test_2/test/README @@ -0,0 +1,11 @@ + +This directory is intended for PlatformIO Test Runner and project tests. + +Unit Testing is a software testing method by which individual units of +source code, sets of one or more MCU program modules together with associated +control data, usage procedures, and operating procedures, are tested to +determine whether they are fit for use. Unit testing finds problems early +in the development cycle. + +More information about PlatformIO Unit Testing: +- https://docs.platformio.org/en/latest/advanced/unit-testing/index.html diff --git a/sketches/_PIO_Sketches/Karger/SoaapBleSlave_Test_2/.vscode/extensions.json b/sketches/_PIO_Sketches/Karger/SoaapBleSlave_Test_2/.vscode/extensions.json new file mode 100644 index 0000000000000000000000000000000000000000..080e70d08b9811fa743afe5094658dba0ed6b7c2 --- /dev/null +++ b/sketches/_PIO_Sketches/Karger/SoaapBleSlave_Test_2/.vscode/extensions.json @@ -0,0 +1,10 @@ +{ + // See http://go.microsoft.com/fwlink/?LinkId=827846 + // for the documentation about the extensions.json format + "recommendations": [ + "platformio.platformio-ide" + ], + "unwantedRecommendations": [ + "ms-vscode.cpptools-extension-pack" + ] +} diff --git a/sketches/_PIO_Sketches/Karger/SoaapBleSlave_Test_2/README.md b/sketches/_PIO_Sketches/Karger/SoaapBleSlave_Test_2/README.md new file mode 100644 index 0000000000000000000000000000000000000000..629d5c9a969b8193a9fb1ec9fd4df89bb5e23681 --- /dev/null +++ b/sketches/_PIO_Sketches/Karger/SoaapBleSlave_Test_2/README.md @@ -0,0 +1,2 @@ +Projektsnapshot der mit alten Versionen der Bibliotheken läuft. +Die Versionen sind hier direkt im Projektverzeichnis gespeichert. \ No newline at end of file diff --git a/sketches/_PIO_Sketches/Karger/SoaapBleSlave_Test_2/include/README b/sketches/_PIO_Sketches/Karger/SoaapBleSlave_Test_2/include/README new file mode 100644 index 0000000000000000000000000000000000000000..194dcd43252dcbeb2044ee38510415041a0e7b47 --- /dev/null +++ b/sketches/_PIO_Sketches/Karger/SoaapBleSlave_Test_2/include/README @@ -0,0 +1,39 @@ + +This directory is intended for project header files. + +A header file is a file containing C declarations and macro definitions +to be shared between several project source files. You request the use of a +header file in your project source file (C, C++, etc) located in `src` folder +by including it, with the C preprocessing directive `#include'. + +```src/main.c + +#include "header.h" + +int main (void) +{ + ... +} +``` + +Including a header file produces the same results as copying the header file +into each source file that needs it. Such copying would be time-consuming +and error-prone. With a header file, the related declarations appear +in only one place. If they need to be changed, they can be changed in one +place, and programs that include the header file will automatically use the +new version when next recompiled. The header file eliminates the labor of +finding and changing all the copies as well as the risk that a failure to +find one copy will result in inconsistencies within a program. + +In C, the usual convention is to give header files names that end with `.h'. +It is most portable to use only letters, digits, dashes, and underscores in +header file names, and at most one dot. + +Read more about using header files in official GCC documentation: + +* Include Syntax +* Include Operation +* Once-Only Headers +* Computed Includes + +https://gcc.gnu.org/onlinedocs/cpp/Header-Files.html diff --git a/sketches/_PIO_Sketches/Karger/SoaapBleSlave_Test_2/lib/README b/sketches/_PIO_Sketches/Karger/SoaapBleSlave_Test_2/lib/README new file mode 100644 index 0000000000000000000000000000000000000000..6debab1e8b4c3faa0d06f4ff44bce343ce2cdcbf --- /dev/null +++ b/sketches/_PIO_Sketches/Karger/SoaapBleSlave_Test_2/lib/README @@ -0,0 +1,46 @@ + +This directory is intended for project specific (private) libraries. +PlatformIO will compile them to static libraries and link into executable file. + +The source code of each library should be placed in a an own separate directory +("lib/your_library_name/[here are source files]"). + +For example, see a structure of the following two libraries `Foo` and `Bar`: + +|--lib +| | +| |--Bar +| | |--docs +| | |--examples +| | |--src +| | |- Bar.c +| | |- Bar.h +| | |- library.json (optional, custom build options, etc) https://docs.platformio.org/page/librarymanager/config.html +| | +| |--Foo +| | |- Foo.c +| | |- Foo.h +| | +| |- README --> THIS FILE +| +|- platformio.ini +|--src + |- main.c + +and a contents of `src/main.c`: +``` +#include <Foo.h> +#include <Bar.h> + +int main (void) +{ + ... +} + +``` + +PlatformIO Library Dependency Finder will find automatically dependent +libraries scanning project source files. + +More information about PlatformIO Library Dependency Finder +- https://docs.platformio.org/page/librarymanager/ldf.html diff --git a/sketches/_PIO_Sketches/Karger/SoaapBleSlave_Test_2/platformio.ini b/sketches/_PIO_Sketches/Karger/SoaapBleSlave_Test_2/platformio.ini new file mode 100644 index 0000000000000000000000000000000000000000..bcf5898434bb08619b2e8f18f2bf32500807e6e1 --- /dev/null +++ b/sketches/_PIO_Sketches/Karger/SoaapBleSlave_Test_2/platformio.ini @@ -0,0 +1,32 @@ +; PlatformIO Project Configuration File +; +; Build options: build flags, source filter +; Upload options: custom upload port, speed and extra flags +; Library options: dependencies, extra library storages +; Advanced options: extra scripting +; +; Please visit documentation for the other options and examples +; https://docs.platformio.org/page/projectconf.html + +[env:nano33ble] +platform = nordicnrf52 +board = nano33ble +framework = arduino +upload_port = COM5 +build_flags = + -DsmnDEFBYBUILD -DsmnNANOBLE33 -DsmnDEBUG ;-DSlaveACM3 +lib_deps = + ;symlink://C:\Users\Lennard\Documents\Git_local\REP_STR\libraries\BlePoll + ;symlink://C:\Users\Lennard\Documents\Git_local\REP_STR\libraries\environment + ;symlink://C:\Users\Lennard\Documents\Git_local\REP_STR\libraries\ComRingBuf + ;symlink://C:\Users\Lennard\Documents\Git_local\REP_STR\libraries\LoopCheck + ;symlink://C:\Users\Lennard\Documents\Git_local\REP_STR\libraries\MidiNotes + ;symlink://C:\Users\Lennard\Documents\Git_local\REP_STR\libraries\Monitor + ;symlink://C:\Users\Lennard\Documents\Git_local\REP_STR\libraries\nRF52840Gpio + ;symlink://C:\Users\Lennard\Documents\Git_local\REP_STR\libraries\nRF52840Radio + ;symlink://C:\Users\Lennard\Documents\Git_local\REP_STR\libraries\nRF52840Ser + ;symlink://C:\Users\Lennard\Documents\Git_local\REP_STR\libraries\nRF52840Twi + ;symlink://C:\Users\Lennard\Documents\Git_local\REP_STR\libraries\SensorLSM9DS1 + ;symlink://C:\Users\Lennard\Documents\Git_local\REP_STR\libraries\SoaapMsg + ;symlink://C:\Users\Lennard\Documents\Git_local\REP_STR\libraries\StateMachine + ;symlink://C:\Users\lenna\OneDrive\Dokumente\Git\SOAAP\libraries\SoaapComDue \ No newline at end of file diff --git a/sketches/_PIO_Sketches/Karger/SoaapBleSlave_Test_2/src/BlePoll/BlePoll.cpp b/sketches/_PIO_Sketches/Karger/SoaapBleSlave_Test_2/src/BlePoll/BlePoll.cpp new file mode 100644 index 0000000000000000000000000000000000000000..f2b89ae3d67d527cf753ec12a685ac02e0bde3ae --- /dev/null +++ b/sketches/_PIO_Sketches/Karger/SoaapBleSlave_Test_2/src/BlePoll/BlePoll.cpp @@ -0,0 +1,1624 @@ +//----------------------------------------------------------------------------- +// Thema: Social Manufacturing Network / Development Environment +// Datei: BlePoll.cpp +// Editor: Robert Patzke +// URI/URL: www.mfp-portal.de +//----------------------------------------------------------------------------- +// Lizenz: CC-BY-SA (wikipedia: Creative Commons) +// Datum: 1. September 2021 +// +// Diese Bibliothek (Klassse) enthält diverse Ressourcen zur Kommunikation +// über BLE-Funkmodule auf niedriger Ebene, also dem direkten Telegrammaustausch. +// Darauf aufbauend sollen mehrkanalige Messeinrichtungen mit möglichst +// geringen Latenzzeiten entwickelt werden. +// + +#include "BlePoll.h" + +// -------------------------------------------------------------------------- +// Textmakros zur Vereinfachung der Programmierung +// -------------------------------------------------------------------------- + +#define next(x) nextState = &BlePoll::x + +// -------------------------------------------------------------------------- +// Initialisierungen +// -------------------------------------------------------------------------- + +BlePoll::BlePoll(IntrfRadio *refRadio, dword inCycleMics) +{ + init(refRadio, inCycleMics, NULL); +} + +BlePoll::BlePoll(IntrfRadio *refRadio, MicsecFuPtr inMicroFu) +{ + init(refRadio, 0, inMicroFu); +} + +void BlePoll::init(IntrfRadio *refRadio, dword inCycleMics, MicsecFuPtr inMicroFu) +{ + radio = refRadio; + radio->setPacketParms(bptAdv); + radio->setAccessAddress(AdvAccAddr); + chn = adr = area = 0; + master = nak = eadr = false; + plMode = plmIdle; + plpType = plptEmpty; + micSec = inMicroFu; + cycleMics = inCycleMics; + cycleCnt = 0; + toValue = 0; + toSet = 0; + nextState = NULL; + slaveIdx = 0; + pollIdx = 0; + pollNr = 0; + maxAdr = MAXSLAVE; + curSlave = NULL; + cntAlien = 0; + cntWrong = 0; + cntAllNaks = 0; + cntWaitDisabled = 0; + cntPolling = 0; + cntAllRecs = 0; + cntAllTo = 0; + pollStopped = false; + pollStop = false; + recStopped = false; + recStop = false; + runCounter = 0; + newValue = false; + cbData = NULL; + + for(int i = 1; i <= MAXSLAVE; i++) + { + slaveList[i].cntNakEP = 0; + slaveList[i].cntTo = 0; + slaveList[i].pIdx = 0; + slaveList[i].delayCnt = 5; + slaveList[i].newPdu = false; + slaveList[i].newMeas = false; + pollList[i].prioCnt = 0; + pollList[i].slIdx = 0; + pollList[i].status = 0; + } + + DataExchange = false; +} + +// ---------------------------------------------------------------------------- +void BlePoll::begin(ComType typeIn, int adrIn, AppType appType, dword watchDog) +{ + // TODO + // -------------------------------------------------------------------------- + // Das muss nochmal völlig neu überarbeitet werden. + // Zur Zeit sind viele Redundanzen und teilweise Mehrdeutigkeiten enthalten, + // weil für jede Testanwendung spezifische Vorbereitungen gemacht wurden. + // -------------------------------------------------------------------------- + // + wdTimeOut = watchDog; // WatchDog-Time-Out in Mikrosekunden + + if(typeIn == ctMASTER) + master = true; + else + master = false; void resetPollCounters(); + + + chn = 0; // 1. Bewerbungskanal + area = 0; // Default-Anwendungsbereich + eadr = true; // Start mit leerem Polling + + // -------------------------------------------------------------------------- + plMode = plmEmpty; // Leeres Polling (Adressenliste) + // -------------------------------------------------------------------------- + + if(master) + { + nak = true; // Nak-Bit vom Master forciert leere Antwort + maxAdr = adrIn; + if(maxAdr > MAXSLAVE) + maxAdr = MAXSLAVE; + adr = 1; + slaveIdx = adr; // Reserve für getrennte Verwaltung von adr und slaveIdx + next(smInit); + } + else + { + nak = true; + adr = adrIn; + next(smInit); + } + + if(appType == atSOAAP || appType == atTestSend || appType == atDevSOAAP) + { + pduOut.adr5 = 0x53; + pduOut.adr4 = 0x4F; + pduOut.adr3 = 0x41; + + pduIn.adr5 = 0x53; + pduIn.adr4 = 0x4F; + pduIn.adr3 = 0x41; + } + + if(appType == atTestSend) + plMode = plmTest; + + pduOut.head = HeadS0B; + pduIn.head = HeadS0B; + + pduOut.data[0] = 0; // Pdu-Zähler (CNT) + pduIn.data[0] = 0; + + pduOut.data[1] = appType; // Pdu-Typ (TYPE) + pduIn.data[1] = appType; + + if(appType == atSOAAP) + { + if(master) + { + valuePdu.appId = plptMeas9Ctrl4; + ctrlPdu.appId = plptCtrlX; + plMode = plmSoaapM; + fullCycle = true; + } + else + { + valuePdu.appId = plptMeas9Ctrl4; + ctrlPdu.appId = plptCtrlX; + plMode = plmSoaapS; + } + } + else if (appType == atDevSOAAP) + { + if(master) + { + valuePdu.appId = plptMeas13; + ctrlPdu.appId = plptCtrl2; + plMode = plmSoaapM; + fullCycle = true; + } + else + { + valuePdu.appId = plptMeas13; + ctrlPdu.appId = plptCtrl2; + plMode = plmSoaapS; + } + } + + valuePdu.measCnt = 0; + valuePdu.counter = 0; + valuePdu.type = appType; +} + + +// -------------------------------------------------------------------------- +// Konfiguration +// -------------------------------------------------------------------------- +// +void BlePoll::setPollAddress(int chnIn, int adrIn, int areaIn, bool masterIn, bool eadrIn, bool nakIn) +{ + chn = chnIn; + adr = adrIn; + area = areaIn; + master = masterIn; + eadr = eadrIn; + nak = nakIn; +} + +void BlePoll::setPduAddress() +{ + setPduAddress(&pduOut); +} + +void BlePoll::setPduAddress(bcPduPtr pduPtr) +{ + pduPtr->adr0 = (byte) adr; + pduPtr->adr1 = (byte) (area & 0x3F); + if(nak) pduPtr->adr1 |= 0x40; + if(eadr) pduPtr->adr1 |= 0x80; + pduPtr->adr2 = (byte) chn; + if(master) pduPtr->adr2 |= 0x80; +} + +void BlePoll::setEmptyPollParams(int cycleTotal, int cycleRun, dword timeOut) +{ + epCycleTotal = cycleTotal; + epCycleRun = cycleRun; + epTimeOut = timeOut; +} + +void BlePoll::setDataPollParams(int slAdr, int prio, int minPrio, dword timeOut) +{ + if(slAdr > MAXSLAVE) return; + slaveList[slAdr].prioSet = prio; + slaveList[slAdr].minPrio = minPrio; + slaveList[slAdr].timeOut = timeOut; +} + +void BlePoll::setCbDataPtr(cbDataPtr cbPtr) +{ + cbData = cbPtr; +} + +void BlePoll::setCbCtrlPtr(cbCtrlPtr cbPtr) +{ + cbCtrl = cbPtr; +} + + +dword smStartComESCnt; +bcPdu recBeacon; +int lenBeacon = 0; + +// -------------------------------------------------------------------------- +// Hilfsfunktionen +// -------------------------------------------------------------------------- +// +void BlePoll::setTimeOut(dword value) +{ + if(micSec != NULL) + { + toSet = micSec(); + toValue = value; + } + else + { + if(cycleMics > 1) + cycleCnt = value / cycleMics; + else + cycleCnt = value; + } +} + +bool BlePoll::timeOut() +{ + if(micSec != NULL) + { + if((micSec() - toSet) > toValue) + return(true); + else + return(false); + } + else + { + if(cycleCnt > 0) + return(false); + else + return(true); + } +} + +bool BlePoll::getValues(bcPduPtr pduPtr, PlpType appId) +{ + bool retv = false; + + switch (appId) + { + case plptMeas6: + pduPtr->len = sizeof(PlpMeas6) + 6; + break; + + case plptMeas9Ctrl4: + pduPtr->len = sizeof(PlpM9C4) + 6; + break; + } + pduPtr->data[0]++; // Pdu-Counter + pduPtr->data[1] = valuePdu.type; + pduPtr->data[2] = appId; + + newValue = cbData(appId, &pduPtr->data[4]); + + if(newValue) + { + retv = true; + pduPtr->data[3]++; // measCnt + } + return(retv); +} + + +bool BlePoll::getCtrls(bcPduPtr pduPtr, PlpType appId) +{ + int ctrlLen; + + if(recBeacon.len > 6) + ctrlLen = recBeacon.len - 6; + else + ctrlLen = 4; + + newCtrl = cbCtrl((PlpType) appId, &pduPtr->data[22], &recBeacon.data[0], ctrlLen); + + return(newCtrl); +} + + +// -------------------------------------------------------------------------- +// Steuerung des Polling +// -------------------------------------------------------------------------- +// + +// Aktuellen Betriebszustand einstellen +// +void BlePoll::start(PlMode inPlMode) +{ + oldPlMode = plMode; + plMode = inPlMode; + pollStop = true; +} + +// Anhalten des leeren Polling +// +void BlePoll::stopEP() +{ + pollStop = true; +} + +// Weiterlaufen des leeren Polling +// +void BlePoll::resumeEP() +{ + pollStop = false; + pollStopped = false; +} + +// Abfrage, ob gestoppt +// +bool BlePoll::stoppedEP() +{ + return(pollStopped); +} + +// Anhalten des Empfangs beim Slave +// +void BlePoll::stopSR() +{ + recStop = true; +} + +// Weiterlaufen des Empfangs beim Slave +// +void BlePoll::resumeSR() +{ + recStop = false; + recStopped = false; +} + +// Abfrage, ob Slaveempfang gestoppt +// +bool BlePoll::stoppedSR() +{ + return(recStopped); +} + + +// Eintritt in die Zustandsmaschine +// +void BlePoll::run() +{ + runCounter++; + if(cycleCnt > 0) cycleCnt--; + + if(nextState != NULL) + (this->*nextState)(); +} + +// -------------------------------------------------------------------------- +// Zugriff auf Polling-Informationen +// -------------------------------------------------------------------------- +// +int BlePoll::getSlaveList(byte *dest, int maxByte) +{ + int slIdx; + + for(int i = 1; i <= pollMaxNr; i++) + { + if(i == maxByte) break; + slIdx = pollList[i].slIdx; + dest[i-1] = slaveList[slIdx].adr; + } + return(pollMaxNr); +} + +void BlePoll::resetPollCounters() +{ + int slIdx; + SlavePtr slPtr; + + for(int i = 1; i <= pollMaxNr; i++) + { + slIdx = pollList[i].slIdx; + slPtr = &slaveList[slIdx]; + slPtr->cntAckDP = 0; + slPtr->cntErrCrc = 0; + slPtr->cntLostMeas = 0; + slPtr->cntLostPdu = 0; + slPtr->cntNakEP = 0; + slPtr->cntTo = 0; + } +} + + + + +// **************************************************************************** +// Zustandsmaschine +// **************************************************************************** +// + +// ---------------------------------------------------------------------------- +// Verzweigung nach Anwendung (nach Anlauf) +// ---------------------------------------------------------------------------- +// +dword smInitCnt; + +void BlePoll::smInit() +{ + bleState = 100; + smInitCnt++; + + switch(plMode) + { + case plmIdle: + break; + + case plmTest: + next(smStartTest); + break; + + case plmEmpty: + epCycleTotal = -1; + epCycleRun = -1; + next(smStartEP); + break; + + case plmScan: + break; + + case plmSoaapM: + if(pollStop) + pollStopped = true; + if(!pollStopped) + next(smStartEP); + break; + + case plmSoaapS: + next(smStartComES); + break; + + case plmXchg: + break; + } +} + +// ---------------------------------------------------------------------------- +// Verzweigung nach Anwendung (im Betrieb) +// ---------------------------------------------------------------------------- +// +dword smIdleCnt; + +void BlePoll::smIdle() +{ + bleState = 200; + smIdleCnt++; + + switch(plMode) + { + case plmIdle: + break; + + case plmTest: + next(smStartTest); + break; + + case plmEmpty: + next(smStartEP); + break; + + case plmScan: + if(master) + next(smReqComS); + break; + + case plmXchg: + if(!master) + next(smStartComES); + break; + + case plmSoaapM: + if(!pollStopped) + next(smStartEP); + break; + } +} + +// ---------------------------------------------------------------------------- +// Low Level Tests +// ---------------------------------------------------------------------------- +// +void BlePoll::smStartTest() +{ + bleState = 500; + + if(master) + { + nak = false; + adr = 1; + slaveIdx = adr; + setTimeOut(500000); + } + else + { + nak = true; + } + pduOut.len = 6; + setPduAddress(); + radio->setChannel(chn); + next(smWaitTest); +} + +void BlePoll::smWaitTest() +{ + if(!timeOut()) return; + radio->disable(txmRead); + next(smLoopTest); +} + +void BlePoll::smLoopTest() +{ + pduOut.adr0++; + radio->send(&pduOut, txmRead); + setTimeOut(500000); + next(smWaitTest); +} + + + +// ---------------------------------------------------------------------------- +// L e e r e s P o l l i n g +// ---------------------------------------------------------------------------- +// +void BlePoll::smStartEP() +{ + bleState = 1000; + + pduOut.len = 6; // Nur Adresse + radio->setChannel(chn); + pollMaxNr = 0; + + nak = true; + + if(master) + { + adr = 1; + slaveIdx = adr; // Slave-Array[0] reserviert + pollIdx = 1; // Poll-Array[0] reserviert + pollNr = 0; // Anzahl in der Poll-Liste + next(smReqEadr); + } + else + { + next(smWaitEadr); + } +} + +// ---------------------------------------------------------------------------- +// Leeres Polling M a s t e r +// ---------------------------------------------------------------------------- +// + +void BlePoll::smReqEadr() +{ + bleState = 1100; + + // Datenstruktur für den Slave definieren + // + curSlave = &slaveList[slaveIdx]; // Zeiger auf zu pollenden Slave + curSlave->adr = adr; + curSlave->area = area; + curSlave->chn = chn; + + curPoll = &pollList[pollIdx]; // Zeiger auf freien Platz in Poll-Liste + + setPduAddress(); + setTimeOut(epTimeOut); + + radio->getStatistics(&statistic); + + radio->send(&pduOut, txmPoll); + cntPolling++; + next(smWaitNak); +} + + +void BlePoll::smWaitNak() +{ + bleState = 1110; + + if(timeOut()) + { + // Für die Adresse ist kein Teilnehmer vorhanden, oder die Übertragung ist gestört + // + radio->disable(txmPoll); + + if(curSlave->pIdx != 0) + { + // Wenn der Teilnehmer bereits in die Poll-Liste eingetragen ist + // dann wird darin seine temporäre Abwesenheit markiert + pollList[(int) curSlave->pIdx].status &= ~psSlaveIsPresent; + } + + // Der Time-Out-Zähler macht erkenntlich, wie stark sich Störungen auswirken + // + curSlave->cntTo++; + cntAllTo++; + + // Nächste Adresse und zur Anforderung + // + adr++; + slaveIdx = adr; + if(adr > maxAdr) + next(smEndEP); + else + next(smReqEadr); + return; + } + + + if(radio->fin(txmPoll, &crcError)) + { + // Auf dem Kanal wurde ein Datensatz (BLE-Beacon) empfangen + // und es werden die ersten 8 Byte (Header, Len und Adresse) geholt + // + cntAllRecs++; + radio->getRecData(&pduIn, 8); + + if(pduIn.adr3 != pduOut.adr3 || pduIn.adr4 != pduOut.adr4 || pduIn.adr5 != pduOut.adr5) + { + // Wenn die höherwertigen 3 Byte der Adresse nicht mit der Anwendungskodierung + // übereinstimmen, dann ist es ein Fremd-Beacon. + // Diese werden gezählt und kennzeichnen, wie stark aktiv ein anderes + // BLE-Netzwerk in Reichweite ist. + // + cntAlien++; + + // Nächste Adresse und zur Anforderung, nicht auf Time-Out warten + // + adr++; + slaveIdx = adr; + if(adr > maxAdr) + next(smEndEP); + else + next(smReqEadr); + return; + } + + if(pduIn.adr0 != pduOut.adr0 || (pduIn.adr1 & 0x3F) != (pduOut.adr1 & 0x3F)) + { + // Wenn die Teinehmernummer oder die Gebietsnummer falsch sind, dann ist + // möglicherweise ein weiterer Master aktiv, der fehlerhafterweise denselben + // Kanal verwendet. + // Auch dieses Ereignis wird gezäht. + cntWrong++; + + // Nächste Adresse und zur Anforderung, nicht auf Time-Out warten + // + adr++; + slaveIdx = adr; + if(adr > maxAdr) + next(smEndEP); + else + next(smReqEadr); + return; + } + + // Alles korrekt, der adressierte Teilnehmer hat rechtzeitig geantwortet + // Radio ist abgeschaltet + // + + if(curSlave->pIdx != 0) + { + // Wenn der Teilnehmer bereits in die Poll-Liste eingetragen ist, + // dann wird er darin als aktuell anwesend markiert + // + pollList[(int) curSlave->pIdx].status |= psSlaveIsPresent; + pollNr++; + } + else + { + // Wenn nicht, wird der aktuelle Listeneintrag definiert + // + curPoll->status |= psSlaveIsPresent | psSlaveWasPresent; + curPoll->slIdx = slaveIdx; // Querverweis zur Liste möglicher Teilnehmer + curSlave->pIdx = pollIdx; // Und in der Liste auch ein Verweis zur Poll-Liste + pollIdx++; // Weiter mit nächstem Listenplatz + pollNr++; // Anzahl der beantworteten Pollings + } + + // Die Nak-Antworten werden gezählt + // + curSlave->cntNakEP++; // Teilnehmerspezifisch + cntAllNaks++; // und insgesamt + + // Weiter mit nächstem Teilnehmer und nächster Adresse (TN-Nummer) + // + adr++; + slaveIdx = adr; + + // Wenn die vorgegeben Endadresse erreicht ist + // dann zum Ende des Polldurchgangs über alle möglichen Teilnehmer, + // ansonsten nächsten Teilnehmer pollen + // + if(adr > maxAdr) + next(smEndEP); + else + next(smReqEadr); + } +} + + +void BlePoll::smEndEP() +{ + // Nach jedem vollständigen Polldurchlauf kann das Polling + // abgebrochen werden. + // + if(pollStop || pollStopped) + { + pollStopped = true; + next(smIdle); + return; + } + + // Es werden die Maximalwerte der rechtzeitigen Antworten gebildet + // + if(pollNr > pollMaxNr) + pollMaxNr = pollNr; + + if(pollMaxNr == 0) + { + // Wenn noch kein Teilnehmer angeschlossen ist (oder Kanal total gestört) + // + if(epCycleTotal > 0) + { + // dann wird der Pollvorgang so oft wie vorgegeben wiederholt + // + epCycleTotal--; + pollNr = 0; + pollIdx = 1; + adr = 1; + slaveIdx = adr; + next(smReqEadr); + return; + } + else if(epCycleTotal == 0) + { + // und anschließend der Idle-Zustand angenommen + next(smIdle); + return; + } + } + else + { + // Wenn wenigstens schon ein Teilnehmer geantwortet hat + // + if(epCycleRun > 0) + { + // dann wird der Pollvorgang auch so oft wie anderweitig vorgegeben wiederholt + // + epCycleRun--; + pollNr = 0; + //pollIdx = 1; falsch, pollIdx zeigt auf nächsten freien Platz + adr = 1; + slaveIdx = adr; + next(smReqEadr); + return; + } + else if(epCycleRun == 0) + { + // und anschließend die Datenübertragung gestartet + // oder das Polling ganz beendet + // + if(fullCycle) + next(smStartCom); + else + next(smIdle); + return; + } + } + + // Nächster Poll-Lauf, wenn epCycleXXX noch nicht abgelaufen ist + // oder auf einen wert kleiner 0 gestellt wurde + // + pollNr = 0; + //pollIdx = 1; falsch, pollIdx zeigt auf nächsten freien Platz + adr = 1; + slaveIdx = adr; + next(smReqEadr); +} + +// ---------------------------------------------------------------------------- +// Leeres Polling S l a v e +// ---------------------------------------------------------------------------- +// +void BlePoll::smWaitEadr() +{ + bleState = 1200; + + if(!radio->disabled(txmRespE)) + { + radio->disable(txmRespE); + cntWaitDisabled++; + return; + } + + setPduAddress(); + radio->send(&pduOut, txmRespE); + next(smEvalPoll); +} + +void BlePoll::smEvalPoll() +{ + bleState = 1210; + + radio->getStatistics(&statistic); + if(!radio->fin(txmRespE, &crcError)) return; + next(smWaitEadr); +} + +// ---------------------------------------------------------------------------- +// D a t e n ü b e r t r a g u n g +// ---------------------------------------------------------------------------- +// + +// Vorbereitung der Datenübertragung +// +void BlePoll::smStartCom() +{ + bleState = 2000; + + if(pollStop || pollStopped) // Der Start der Datenübertragung kann + { // verzögert werden + pollStopped = true; + return; + } + + // -------------------------------------------- + // Auswahl des Funkkanals (Frequenz) + // -------------------------------------------- + // + radio->setChannel(chn); + + // -------------------------------------------- + // Voreinstellungen für den Master + // -------------------------------------------- + // + if(master) + { + // Aufbau der Polling-Liste + // + for(int i = 1; i <= pollMaxNr; i++) + { + int slIdx = pollList[i].slIdx; + pollList[i].prioCnt = slaveList[slIdx].prioSet; + } + pollIdx = 1; + + // Vorbereitung der mit dem Polling übermittelten Daten + // + pduOut.len = 13; // Adresse (6) + 7 Byte Steuerung + ctrlPdu.counter = 0; // Zähler im Steuertelegramm + ctrlPdu.appId = plptMeas9Ctrl4; // Info für Slave zur Antwort + + next(smReqComS); + } + // -------------------------------------------- + // Voreinstellungen für den Slave + // -------------------------------------------- + // + else + { + nak = true; + next(smWaitEadr); + } + + DataExchange = true; +} + +// ---------------------------------------------------------------------------- +// Datenübertragung Master S l a v e - > M a s t e r +// ---------------------------------------------------------------------------- +// + +// M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M +// Polling : Anfordern von Daten beim Slave +// ---------------------------------------------------------------------------- +// +void BlePoll::smReqComS() +{ + bleState = 2100; + + if(pollStop || pollStopped) // Das Polling kann + { // angehalten werden + pollStopped = true; + return; + } + + // Es ist von einem vorherigen Funkempfang auszugehen + // Die Hardware muss erst ausgeschaltet werden + // + if(!radio->disabled(txmPoll)) + { + radio->disable(txmPoll); + return; + } + + // Der aufzufordernde Teilnehmer wird der Poll-Liste entnommen + // + curPoll = &pollList[pollIdx]; + + // Ein Aufruf erfolgt nur, wenn der Prioritätszähler auf 0 steht + // ansonsten wird er dekrementiert und der nächste Teilnehmer + // im nächsten Zustandslauf ausgewählt. + // + if(curPoll->prioCnt > 0) + { + curPoll->prioCnt--; + pollIdx++; + if(pollIdx > pollMaxNr) + pollIdx = 1; + return; + } + + // Zugriff auf den Slave aus der Poll-Liste vorbereiten + // + slaveIdx = curPoll->slIdx; + curSlave = &slaveList[slaveIdx]; + + // Slave-spezifische Parameter setzen + // + eadr = false; // Ist true, wenn Daten nur zum Slave übertragen werden + nak = false; // Ist true, wenn keine Daten übertragen werden (empty poll) + adr = curSlave->adr; + area = curSlave->area; + setPduAddress(); + setTimeOut(curSlave->timeOut); + + + // Statistic-Daten einholen für evt. Auswertung + // + radio->getStatistics(&statistic); + + // Aufruf des Slave starten + // + radio->send(&pduOut, txmPoll); + + cntPolling++; + next(smWaitAckComS); +} + +// M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M M +// Warten auf die Antwort vom Slave +// ---------------------------------------------------------------------------- +// +void BlePoll::smWaitAckComS() +{ + byte tmpByte; + short tmpShort; + + // Zeiger zur spezifischen Betrachtung von Empfangsdaten + PlPduMeasPtr resPtr; + + bleState = 2110; + + if(timeOut()) + { + // Wenn der Slave nicht antwortet (kann auch eine Störung sein), + // dann wird seine Priorität heruntergesetzt (Zählwert erhöht) + // und der nächste Slave aus der Poll-Liste angefragt + // byte oldPduCount; + + curSlave->prioSet++; + if(curSlave->prioSet > curSlave->minPrio) + curSlave->prioSet = curSlave->minPrio; + + curPoll->prioCnt = curSlave->prioSet; + + curSlave->cntTo++; + pollIdx++; + if(pollIdx > pollMaxNr) + pollIdx = 1; + + radio->disable(txmPoll); + next(smReqComS); + return; + } + + if(radio->fin(txmPoll, &crcError)) + { + cntAllRecs++; + + // Wenn (irgend-) ein Beacon eingegangen ist, + // wird die maximale (BLE-Standard) Anzahl von Bytes kopiert + // + radio->getRecData(&pduIn, 39); + + if(pduIn.adr3 != pduOut.adr3 || pduIn.adr4 != pduOut.adr4 || pduIn.adr5 != pduOut.adr5) + { + // Beacons aus fremdem Netzen werden nur gezählt und es wird weiter gewartet + // + cntAlien++; + pollIdx++; + if(pollIdx > pollMaxNr) + pollIdx = 1; + + next(smReqComS); + return; + } + + if(pduIn.adr0 != pduOut.adr0 || (pduIn.adr1 & 0x3F) != (pduOut.adr1 & 0x3F)) + { + // Beacons mit falscher Slaveadresse werden ebenfalls nur gezählt + // Hier wird später die Rundrufübertragung implementiert + // + cntWrong++; + pollIdx++; + if(pollIdx > pollMaxNr) + pollIdx = 1; + + next(smReqComS); + return; + } + + // Antwort vom richtigen Teilnehmer ist eingegangen + // + + if(crcError) + { + // Die Daten werden bei einem CRC-Fehler verworfen. + // Der Fehler wird gezählt und ist ein Hinweis auf fremde + // Funkaktivitäten + // + curSlave->cntErrCrc++; + pollIdx++; + if(pollIdx > pollMaxNr) + pollIdx = 1; + + next(smReqComS); + return; + } + + // Die Daten werden in der Slave-Struktur abgelegt + // + resPtr = (PlPduMeasPtr) &curSlave->result; + + resPtr->counter = pduIn.data[0]; + resPtr->type = pduIn.data[1]; + resPtr->appId = pduIn.data[2]; + resPtr->measCnt = pduIn.data[3]; + + // Die Inhalte sind abhängig von der <appId> + // + switch(resPtr->appId) + { + case plptMeas9Ctrl4: + ((PlpM9C4Ptr) resPtr)->meas[0] = *(word *) &pduIn.data[4]; + ((PlpM9C4Ptr) resPtr)->meas[1] = *(word *) &pduIn.data[6]; + ((PlpM9C4Ptr) resPtr)->meas[2] = *(word *) &pduIn.data[8]; + ((PlpM9C4Ptr) resPtr)->meas[3] = *(word *) &pduIn.data[10]; + ((PlpM9C4Ptr) resPtr)->meas[4] = *(word *) &pduIn.data[12]; + ((PlpM9C4Ptr) resPtr)->meas[5] = *(word *) &pduIn.data[14]; + ((PlpM9C4Ptr) resPtr)->meas[6] = *(word *) &pduIn.data[16]; + ((PlpM9C4Ptr) resPtr)->meas[7] = *(word *) &pduIn.data[18]; + ((PlpM9C4Ptr) resPtr)->meas[8] = *(word *) &pduIn.data[20]; + ((PlpM9C4Ptr) resPtr)->ctrlPath = pduIn.data[22]; + ((PlpM9C4Ptr) resPtr)->procCnt = pduIn.data[23]; + ((PlpM9C4Ptr) resPtr)->ctrl[0] = pduIn.data[24]; + ((PlpM9C4Ptr) resPtr)->ctrl[1] = pduIn.data[25]; + break; + + case plptMeas6: + ((PlpM9C4Ptr) resPtr)->meas[0] = *(word *) &pduIn.data[4]; + ((PlpM9C4Ptr) resPtr)->meas[1] = *(word *) &pduIn.data[6]; + ((PlpM9C4Ptr) resPtr)->meas[2] = *(word *) &pduIn.data[8]; + ((PlpM9C4Ptr) resPtr)->meas[3] = *(word *) &pduIn.data[10]; + ((PlpM9C4Ptr) resPtr)->meas[4] = *(word *) &pduIn.data[12]; + ((PlpM9C4Ptr) resPtr)->meas[5] = *(word *) &pduIn.data[14]; + ((PlpM9C4Ptr) resPtr)->meas[6] = *(word *) &pduIn.data[16]; + break; + } + + + // Zählen der verlorenen Telegramme und Messwerte + // beginnt um <delayCnt> Pollzyklen verzögert + // + if(curSlave->delayCnt == 0) + { + tmpByte = curSlave->result.counter - curSlave->oldPduCount; + if(tmpByte > 1) + curSlave->cntLostPdu += tmpByte - 1; + + tmpByte = resPtr->measCnt - curSlave->oldMeasCount; + if(tmpByte != 0) + curSlave->newMeas = true; + if(tmpByte > 1) + curSlave->cntLostMeas += tmpByte - 1; + } + else curSlave->delayCnt--; + + curSlave->oldPduCount = curSlave->result.counter; + curSlave->oldMeasCount = resPtr->measCnt; + + curSlave->newPdu = true; + curSlave->cntAckDP++; + curPoll->prioCnt = curSlave->prioSet; + + pollIdx++; + if(pollIdx > pollMaxNr) + pollIdx = 1; + + next(smReqComS); + return; + } +} + +void BlePoll::smEndComS() +{ + if(pollStop || pollStopped) + { + pollStopped = true; + return; + } + // Von vorne (zur Zeit, Test) + // + adr = 1; + slaveIdx = adr; + next(smReqEadr); +} + +// ---------------------------------------------------------------------------- +// Datenübertragung Master M a s t e r - > S l a v e +// ---------------------------------------------------------------------------- +// +void BlePoll::smReqComE() +{ + bleState = 4100; + + if(!radio->disabled(txmRead)) + { + radio->disable(txmRead); + return; + } + + curSlave = &slaveList[slaveIdx]; + curSlave->adr = adr; + curSlave->area = area; + curSlave->chn = chn; + + setPduAddress(); + //setTimeOut(2000); + // Test + setTimeOut(1000000); + radio->send(&pduOut, txmRead); + radio->getStatistics(&statistic); + cntPolling++; + next(smWaitNak); +} + +void BlePoll::smWaitAckComE() +{ + bleState = 4110; + + if(timeOut()) + { + radio->disable(txmRead); + curSlave->cntTo++; + adr++; + slaveIdx = adr; + if(adr > maxAdr) + next(smEndEP); + else + next(smReqEadr); + return; + } + + + if(radio->fin(txmRead, &crcError)) + { + radio->getRecData(&pduIn, 8); + + if(pduIn.adr3 != pduOut.adr3 || pduIn.adr4 != pduOut.adr4 || pduIn.adr5 != pduOut.adr5) + { + cntAlien++; + radio->cont(txmRead); + return; + } + + if(pduIn.adr0 != pduOut.adr0 || (pduIn.adr1 & 0x3F) != (pduOut.adr1 & 0x3F)) + { + cntWrong++; + radio->cont(txmRead); + return; + } + + radio->disable(txmRead); + curSlave->cntNakEP++; + cntAllNaks++; + adr++; + slaveIdx = adr; + if(adr > maxAdr) + next(smEndEP); + else + next(smReqEadr); + } + radio->getStatistics(&statistic); +} + +void BlePoll::smEndComE() +{ + if(pollStop || pollStopped) + { + pollStopped = true; + return; + } + // Von vorne (zur Zeit, Test) + // + adr = 1; + slaveIdx = adr; + next(smReqEadr); +} + + +// S S S S S S S S S S S S S S S S S S S S S S S S S S S S S S S S S S S S S S +// ---------------------------------------------------------------------------- +// Datenübertragung Slave M a s t e r < - > S l a v e +// ---------------------------------------------------------------------------- +// + +// S S S S S S S S S S S S S S S S S S S S S S S S S S S S S S S S S S S S S S +// Vorbereitungen für den Empfang (Polling durch Master) +// ---------------------------------------------------------------------------- +// +void BlePoll::smStartComES() +{ + bool newValues; + bool newCtrl; + byte lenValues; + byte appId; + + bleState = 1310; + smStartComESCnt++; + + if(recStop || recStopped) + { + recStopped = true; + return; + } + + // Wenn keine Daten von der Anwendung zur Verfügung gestellt werden, + // dann macht der Betrieb hier keinen Sinn und der Slave geht in IDLE + // + if(cbData == NULL) + { + next(smIdle); + return; + } + + // Falls der Sender noch nicht ausgeschaltet ist, muss gewartet werden + // + if(!radio->disabled(txmResp)) + { + radio->disable(txmResp); + cntWaitDisabled++; + return; + } + + // Vorbereiten des erwarteten Inhalts beim Polling durch den Master + // + nak = true; + eadr = true; + setPduAddress(&pduIn); + pduIn.len = 6; + + + // Vorbereiten des zu sendenden Inhalts als Antwort auf das Polling + // + nak = false; + eadr = false; + setPduAddress(&pduOut); + + // Eintragen der Messwerte in das Sendetelegramm + // + if(lenBeacon == 0) // Wenn noch kein Empfangszyklus vorliegt + appId = valuePdu.appId; // dann wird der voreingestellte Satz gewählt + else + appId = recBeacon.data[2]; // ansonsten der speziell angeforderte + + newValues = getValues(&pduOut, (PlpType) appId); + + if((appId == plptMeas9Ctrl4) && (cbCtrl != NULL)) + getCtrls(&pduOut, (PlpType) appId); + + radio->setChannel(chn); + radio->send(&pduIn, &pduOut, txmResp, newValues); + + setTimeOut(wdTimeOut); + next(smWaitComES); +} + +// S S S S S S S S S S S S S S S S S S S S S S S S S S S S S S S S S S S S S S +void BlePoll::smWaitComES() +{ + bleState = 1320; + + radio->getStatistics(&statistic); + if(timeOut()) + { + next(smStartComES); + return; + } + + if(!radio->fin(txmResp, &crcError)) return; + // + // Übertragung beendet, Daten empfangen (polling) und versendet (response) + // + //lenBeacon = radio->getRecData(&recBeacon, txmResp, sizeof(recBeacon)); + next(smStartComES); +} + +// -------------------------------------------------------------------------- +// Anwenderfunktionen +// -------------------------------------------------------------------------- +// + +// neue Steuerungsdaten für einen Slave + +void BlePoll::updControl(int adr, byte *ctrlList, int nr) +{ + if(adr <= 0) return; + if(adr >= MAXSLAVE) return; + if(nr <= 1) return; + if(nr > 27) return; + + SlavePtr slavePtr = &slaveList[adr]; + PlpCtrl27Ptr ctrlPtr = (PlpCtrl27Ptr) &slavePtr->control; + for(int i = 0; i < nr; i++) + ctrlPtr->ctrl[i] = ctrlList[i]; + ctrlPtr->ctrlCnt++; + slavePtr->rspOk = false; +} + +// Feststellenn, ob Übertragung der Steuerungsdaten erfolgt ist + +bool BlePoll::ackTrans(int adr) +{ + if(adr <= 0) return(false); + if(adr >= MAXSLAVE) return(false); + + SlavePtr slavePtr = &slaveList[adr]; + return(slavePtr->rspOk); +} + +// Feststellen, ob Steuerungsdaten beim Slave verarbeitet sind + +bool BlePoll::ackControl(int adr) +{ + if(adr <= 0) return(false); + if(adr >= MAXSLAVE) return(false); + + SlavePtr slavePtr = &slaveList[adr]; + PlpCtrl27Ptr ctrlPtr = (PlpCtrl27Ptr) &slavePtr->control; + if(ctrlPtr->ctrlCnt == slavePtr->rspCtrlCount) + return(true); + else + return(false); +} + +// ---------------------------------------------------------------------------- +// Zugriff auf Slavedaten über die Adresse +// ---------------------------------------------------------------------------- +// + +// Feststellen, ob ein Slave neue Messwerte hat +// +bool BlePoll::measAvail(int slAdr) +{ + if(slAdr < 1) return(false); + if(slAdr >= MAXSLAVE) return(false); + + SlavePtr slavePtr = &slaveList[slAdr]; + + if(!slavePtr->newMeas) + return(false); + + slavePtr->newMeas = false; + return(true); +} + +// Auslesen der Netzwerk-Area +// +int BlePoll::getArea(int slAdr) +{ + if(slAdr < 1) return(false); + if(slAdr >= MAXSLAVE) return(false); + + SlavePtr slavePtr = &slaveList[slAdr]; + + return(slavePtr->area); +} + +// Auslesen der AppId aus Sicht der Klasse BlePoll +// +PlpType BlePoll::getAppId(int slAdr) +{ + if(slAdr < 1) return(plptError); + if(slAdr >= MAXSLAVE) return(plptError); + + SlavePtr slavePtr = &slaveList[slAdr]; + + return((PlpType) slavePtr->result.plData[0]); +} + +// Auslesen der Messwerte +// +int BlePoll::getMeas(int slAdr, byte *dest) +{ + int anzByte; + PlpType appId; + + if(slAdr < 1) return(false); + if(slAdr >= MAXSLAVE) return(false); + + SlavePtr slavePtr = &slaveList[slAdr]; + + appId = (PlpType) slavePtr->result.plData[0]; + + switch(appId) + { + case plptMeas6: + anzByte = 12; + break; + + case plptMeas9: + anzByte = 18; + break; + + case plptMeas9Ctrl4: + anzByte = 22; + break; + + case plptMeas13: + anzByte = 26; + break; + + default: + anzByte = 18; + break; + } + + for (int i = 0; i < anzByte; i++) + { + dest[i] = slavePtr->result.plData[i+2]; + } + + return(anzByte); +} + +int BlePoll::getCtrlM(int slAdr, byte *dest){ + int anzByte; + PlpType appId; + + if(slAdr < 1) return(false); + if(slAdr >= MAXSLAVE) return(false); + + + SlavePtr slavePtr = &slaveList[slAdr]; + appId = (PlpType) slavePtr->result.plData[0]; + + switch(appId) + { + case plptMeas6: + anzByte = 0; + break; + + case plptMeas9: + anzByte = 0; + break; + + case plptMeas9Ctrl4: + anzByte = 4; + break; + + case plptMeas13: + anzByte = 0; + break; + + default: + anzByte = 0; + break; + } + + for (int i = 0; i < anzByte; i++) + { + dest[i] = slavePtr->result.plData[i+20]; + } + + return(anzByte); +} + + +// -------------------------------------------------------------------------- +// Debugging +// -------------------------------------------------------------------------- +// +dword BlePoll::debGetDword(int idx) +{ + dword retv = 0; + + switch(idx) + { + case 0: + retv = plMode; + break; + + case 1: + retv = cntAllRecs; + break; + + case 2: + retv = cntAllNaks; + break; + + case 3: + retv = cntAllTo; + break; + + case 4: + retv = cntAlien; + break; + + case 5: + retv = cntWrong; + break; + + case 6: + retv = statistic.pollAcks; + break; + + case 7: + retv = statistic.pollNaks; + break; + + case 8: + retv = bleState; + break; + + case 9: + retv = radio->getState(); + break; + } + + return(retv); +} + +dword BlePoll::getStatistics(TxStatisticsPtr dest) +{ + *dest = statistic; + return(bleState); +} + + +SlavePtr BlePoll::getSlavePtr(int idx) +{ + return(&slaveList[idx]); +} + +PollStatePtr BlePoll::getPollPtr(int idx) +{ + return(&pollList[idx]); +} + + + + + + + diff --git a/sketches/_PIO_Sketches/Karger/SoaapBleSlave_Test_2/src/BlePoll/BlePoll.h b/sketches/_PIO_Sketches/Karger/SoaapBleSlave_Test_2/src/BlePoll/BlePoll.h new file mode 100644 index 0000000000000000000000000000000000000000..721d22c5c1b2fd65fc1415d7707fb2d93383e036 --- /dev/null +++ b/sketches/_PIO_Sketches/Karger/SoaapBleSlave_Test_2/src/BlePoll/BlePoll.h @@ -0,0 +1,513 @@ +//----------------------------------------------------------------------------- +// Thema: Social Manufacturing Network / Development Environment +// Datei: BlePoll.h +// Editor: Robert Patzke +// URI/URL: www.mfp-portal.de +//----------------------------------------------------------------------------- +// Lizenz: CC-BY-SA (wikipedia: Creative Commons) +// Datum: 1. September 2021 +// +// Diese Bibliothek (Klassse) enthält diverse Ressourcen zur Kommunikation +// über BLE-Funkmodule auf niedriger Ebene, also dem direkten Telegrammaustausch. +// Darauf aufbauend sollen mehrkanalige Messeinrichtungen mit möglichst +// geringen Latenzzeiten entwickelt werden. +// + +#ifndef BlePoll_h +#define BlePoll_h +// ---------------------------------------------------------------------------- + +#include "stddef.h" +#include "string.h" +#include "arduinoDefs.h" +#include "bleSpec.h" +#include "IntrfRadio.h" + +#define MAXSLAVE 100 + +// Betriebsmodus (Polling und Slave) +// +typedef enum _PlMode +{ + plmIdle, // Ruhezustand, Gerät nicht im Netz aktiv + plmTest, // Low Level Tests + plmEmpty, // Leeres Polling (Aufbau Adressliste) + plmScan, // Daten aller aktiven Teilnehmer holen (Master) + plmSoaapM, // Vollständiger Betrieb SOAAP (Master) + plmSoaapS, // Vollständiger Betrieb SOAAP (Slave) + plmXchg // Daten übertragen (Slave, beide Richtungen) +} PlMode; + +// Grundsätzliche Datenstruktur für die Nutzdaten (ohne 6 Bytes Adresse) +// +typedef struct _PlPduBase // maximale Länge Beacon = 31 Bytes +{ + byte counter; // zyklischer Telegrammmzähler + byte type; // Kennzeichnung der Datenstruktur (AppType) + byte plData[29]; // weitere spezifische Nutzdaten +} PlPduBase, *PlPduBasePtr; + +// Grundsätzliche Datenstruktur für Messwerte (ohne 6 Bytes Adresse) +// +typedef struct _PlPduMeas // maximale Länge Beacon = 31 Bytes +{ + byte counter; // zyklischer Telegrammmzähler + byte type; // Kennzeichnung der Datenstruktur (AppType) + byte appId; // Kennzeichnung für Dateninhalte (PlpType) + byte measCnt; // Zähler für Messwertaktualisierung + byte plData[27]; // weitere spezifische Nutzdaten +} PlPduMeas, *PlPduMeasPtr; + +// Erweiterte Datenstruktur für die Nutzdaten (ohne 6 Bytes Adresse) +// zur Zeit noch nicht genutzt +// +typedef struct _PlPduExtd // grundsätzliche maximale Länge = 249 Bytes +{ + byte counter; // zyklischer Telegrammmzähler + byte type; // Kennzeichnung der Datenstruktur (AppType) + byte plData[247]; // weitere spezifische Nutzdaten +} PlPduExtd, *PlPduExtdPtr; + +// Datentypen (appId in plPduBase) +// +typedef enum _PlpType +{ + plptError, // Fehler erkannt + plptEmpty, // Leeres Telegramm (nur adresse) + plptBasic, // Grundlegende Bytestruktur + plptFullMeas, // Maximale Belegung mit 16-Bit Messwerten (word) + plptMeas3, // 3 Messwerte (1 Raumsensor) + plptMeas6, // 6 Messwerte (2 Raumsensoren) + plptMeas9, // 9 Messwerte (3 Raumsensoren) + plptMeas9Ctrl4, // 9 Messwerte + 4 Byte Steuerung + plptMeas10Ctrl4, // 10 Messwerte + 4 Byte Steuerung + plptMeas12, // 12 Messwerte (9 + 6 Byte Extradaten) + plptMeas13, // 13 Messwerte (9 + 8 Byte Extradaten) + plptMeasX, // Variable Anzahl Messwerte + plptCtrl0, // Keine Steuerung + plptCtrl2, // 2 Byte Steuerung + plptCtrl27, // 27 Byte Steuerung + plptCtrlX, // Variable Anzahl Steuerbytes + plptMsg // (Quittierte) Meldung an Slave +} PlpType, *PlpTypePtr; + +// Spezifische Datenstrukturen +// +typedef struct _PlpFullMeas // Ausnahme für vordefinierte Spezialfälle +{ + byte counter; // zyklischer Telegrammmzähler + byte type; // Kennzeichnung der Datenstruktur (AppType) + word meas[14]; // Liste von 14 Messwerten + byte appId; // Kennzeichnung für Dateninhalte (PlpType) + byte align; // Wird nicht gesendet, kennzeichnet Alignement +} PlpFullMeas, *PlpFullMeasPtr; + +typedef struct _PlpMeas3 // Länge 10 (+ 6 Bytes Adresse) +{ + byte counter; // zyklischer Telegrammmzähler + byte type; // Kennzeichnung der Datenstruktur (AppType) + byte appId; // Kennzeichnung für Dateninhalte (PlpType) + byte measCnt; // Zähler für Messwertaktualisierung + word meas[3]; // Liste von 3 Messwerten +} PlpMeas3, *PlpMeas3Ptr; + +typedef struct _PlpMeas6 // Länge 16 (+ 6 Bytes Adresse) +{ + byte counter; // zyklischer Telegrammmzähler + byte type; // Kennzeichnung der Datenstruktur (AppType) + byte appId; // Kennzeichnung für Dateninhalte (PlpType) + byte measCnt; // Zähler für Messwertaktualisierung + word meas[6]; // Liste von 6 Messwerten +} PlpMeas6, *PlpMeas6Ptr; + +typedef struct _PlpMeas9 // Länge 22 (+ 6 Bytes Adresse) +{ + byte counter; // zyklischer Telegrammmzähler + byte type; // Kennzeichnung der Datenstruktur (AppType) + byte appId; // Kennzeichnung für Dateninhalte (PlpType) + byte measCnt; // Zähler für Messwertaktualisierung + word meas[9]; // Liste von 9 Messwerten +} PlpMeas9, *PlpMeas9Ptr; + +typedef struct _PlpM9C4 // Länge 26 (+ 6 Bytes Adresse) +{ + byte counter; // zyklischer Telegrammmzähler + byte type; // Kennzeichnung der Datenstruktur (AppType) + byte appId; // Kennzeichnung für Dateninhalte (PlpType) + byte measCnt; // Zähler für Messwertaktualisierung + word meas[9]; // Liste von 9 Messwerten + byte ctrlPath; // Steuerungspfad (für Verzweigungen/Funktionen) + byte procCnt; // Prozesszähler + byte ctrl[2]; // Steuerungsdaten +} PlpM9C4, *PlpM9C4Ptr; + +typedef struct _PlpMeas12 // Länge 28 (+ 6 Bytes Adresse) +{ + byte counter; // zyklischer Telegrammmzähler + byte type; // Kennzeichnung der Datenstruktur (AppType) + byte appId; // Kennzeichnung für Dateninhalte (PlpType) + byte measCnt; // Zähler für Messwertaktualisierung + word meas[12]; // Liste von 12 Messwerten +} PlpMeas12, *PlpMeas12Ptr; + +typedef struct _PlpMeas13 // Länge 30 (+ 6 Bytes Adresse) +{ + byte counter; // zyklischer Telegrammmzähler + byte type; // Kennzeichnung der Datenstruktur (AppType) + byte appId; // Kennzeichnung für Dateninhalte (PlpType) + byte measCnt; // Zähler für Messwertaktualisierung + word meas[13]; // Liste von 13 Messwerten +} PlpMeas13, *PlpMeas13Ptr; + +typedef struct _PlpCtrl2 // Länge 7 (+ 6 Bytes Adresse) +{ + byte counter; // zyklischer Telegrammmzähler + byte type; // Kennzeichnung der Datenstruktur (AppType) + byte appId; // Kennzeichnung für Dateninhalte (PlpType) + byte ctrlCnt; // Zähler für Kommandoaktualisierung + byte procCnt; // Zähler für Prozessaktualisierung + byte ctrl[2]; // Liste von 2 Steuerbytes +} PlpCtrl2, *PlpCtrl2Ptr; + +typedef struct _PlpCtrl27 // Länge 31 (+ 6 Bytes Adresse) +{ + byte counter; // zyklischer Telegrammmzähler + byte type; // Kennzeichnung der Datenstruktur (AppType) + byte appId; // Kennzeichnung für Dateninhalte (PlpType) + byte ctrlCnt; // Zähler für Kommandoaktualisierung + byte procCnt; // Zähler für Prozessaktualisierung + byte ctrl[26]; // Liste von bis zu 26 Steuerbytes +} PlpCtrl27, *PlpCtrl27Ptr; + +// Identifikator für die Art der Daten +// +typedef enum _MeasId +{ + app // Gestaltung/Bedeutung der Daten aus Anwendung +} MeasId, *MeasIdPtr; + +typedef struct _Slave +{ + dword timeOut; // Wartezeit beim Polling in Mikrosekunden + dword cntTo; // Zähler für ausbleibende Antworten + dword cntErrCrc; // Zähler für CRC-Fehler bei der Übertragung + dword cntNakEP; // Zähler für NAK-Antworten beim Empty-Polling + dword cntAckDP; // Zähler für ACK-Antworten beim Data-Polling + dword cntLostPdu; // Zähler für verlorene Telegramme + dword cntLostMeas; // Zähler für verlorene Messwerte + dword delayCnt; // Verzögerung (Polldurchläufe) vor Fehlerzählung + byte adr; // Adresse (Nummer) des Slave (1-255) + byte area; // Einsatzgebiet des Slave (Adresserweiterung) + byte chn; // Aktueller Übertragungskanal (0-39) + byte pIdx; // Index in der aktuellen Pollingliste + word prioSet; // Anfangspriorität (rel. Häufigkeit) beim Polling + word minPrio; // Minimale Priorität (maximale Prioritätszahl) + PlPduBase result; // Daten vom Slave + PlPduBase control; // Daten zum Slave + bool newPdu; // Kennzeichnung für neues Telegramm + bool rspOk; // Rücksetz-Kennnzeichnung für neues Telegramm + bool newMeas; // Kennzeichnung für neuen Messwert + byte oldPduCount; // Merker für die Telegrammüberwachung + byte oldMeasCount; // Merker für die Messwertüberwachung + byte rspCtrlCount; // Merker für Steuerungsüberwachung +} Slave, *SlavePtr; + + +typedef struct _PollInfo +{ + dword aliens; // Anzahl der netzfremden Aktivitäten + dword wrongs; // Anzahl ungewünschter Netzaktivitäten +} PollInfo, *PollInfoPtr; + + +typedef struct _PollState +{ + byte slIdx; // Index in der Slave-Liste + byte status; // Zustand + word prioCnt; // Prioritätszähler +} PollState, *PollStatePtr; + +typedef bool (*cbDataPtr)(PlpType dataType, byte *dest); +typedef bool (*cbCtrlPtr)(PlpType plpType, byte *dest, byte *src, int sSize); + +#define psSlaveWasPresent 0x01 +#define psSlaveIsPresent 0x02 + +// ---------------------------------------------------------------------------- +// B l e P o l l +// ---------------------------------------------------------------------------- +class BlePoll +{ +public: + // ------------------------------------------------------------------------- + // Öffentliche Datentypen + // ------------------------------------------------------------------------- + // + typedef enum _ComType + { + ctMASTER, + ctSLAVE, + ctHybrid + } ComType; + + // Identifikator für die Anwendung + // + typedef enum _AppType + { + atDefault, // Standard-Default-Anwendung + atTestSend, // einfacher Sendetest (Soaap) + atSOAAP, // Steuerung optischer und akustischer Ausgaben für Performance-Künstler + atDevSOAAP, // Entwicklerbetrieb für SOAAP + atDHA // Dezentrale Hausautomatisierung + } AppType; + + // -------------------------------------------------------------------------- + // Öffentliche Daten + // -------------------------------------------------------------------------- + // + bool DataExchange; + +private: + // ------------------------------------------------------------------------- + // Private Datentypen + // ------------------------------------------------------------------------- + // + + typedef void (BlePoll::*cbVector)(void); + typedef dword (*MicsecFuPtr)(void); + + // -------------------------------------------------------------------------- + // Lokale Daten + // -------------------------------------------------------------------------- + // + IntrfRadio *radio; + bcPdu pduOut; + bcPdu pduIn; + cbVector nextState; + MicsecFuPtr micSec; + cbDataPtr cbData; + cbCtrlPtr cbCtrl; + dword toSet; + dword toValue; + dword cycleMics; + dword cycleCnt; + dword wdTimeOut; + + int chn; + int adr; + int area; + bool master; + bool eadr; + bool nak; + bool crcError; + + PlMode plMode; + PlMode oldPlMode; + PlpType plpType; + + Slave slaveList[MAXSLAVE+1]; + SlavePtr curSlave; + int slaveIdx; // ist z.Zt. identisch mit Slaveadresse adr + PollState pollList[MAXSLAVE+1]; + PollStatePtr curPoll; + int pollIdx; + int pollNr; + int pollMaxNr; + + int maxAdr; + dword cntPolling; + dword cntAllRecs; + dword cntAllTo; + bool pollStop; + bool pollStopped; + + dword cntAllNaks; + dword cntAlien; + dword cntWrong; + dword cntWaitDisabled; + + dword bleState; + dword runCounter; + bool recStop; + bool recStopped; + + TxStatistics statistic; + PlPduMeas valuePdu; + PlpCtrl27 ctrlPdu; + bool newValue; + bool newCtrl; + + // Einstellungen für den Anwendungsbetrieb + // + bool fullCycle; // Vollständige Anwendung (EP & Data) + int epCycleTotal; // Anzahl der leeren Pollings gesamt + int epCycleRun; // Anzahl der leeren Pollings nach Kontakt + dword epTimeOut; // Time-Out in Mikrosekunden + + + // -------------------------------------------------------------------------- + // Lokale Funktionen + // -------------------------------------------------------------------------- + // + void setPduAddress(); + void setPduAddress(bcPduPtr pduPtr); + void setTimeOut(dword value); + bool timeOut(); + bool getValues(bcPduPtr pduPtr, PlpType appId); + bool getCtrls(bcPduPtr pduPtr, PlpType appId); + + + // Zustandsmaschine + // ----------------------------- + void smInit(); + void smIdle(); + + // Leeres Polling Master + // + void smStartEP(); + void smReqEadr(); + void smWaitNak(); + void smEndEP(); + + // Leeres Polling Slave + // + void smWaitEadr(); + void smEvalPoll(); + + // Datenübertragung + // + void smStartCom(); + + // Master: Master -> Slave + // + void smReqComE(); + void smWaitAckComE(); + void smEndComE(); + + // Master: Slave -> Master + // + void smReqComS(); + void smWaitAckComS(); + void smEndComS(); + + // Slave: Master <-> Slave + // + void smStartComES(); + void smWaitComES(); + void smEvalComES(); + + // Test + // + void smStartTest(); + void smWaitTest(); + void smLoopTest(); + + +public: + // -------------------------------------------------------------------------- + // Initialisierungen + // -------------------------------------------------------------------------- + BlePoll(IntrfRadio *refRadio, dword inCycleMics); + BlePoll(IntrfRadio *refRadio, MicsecFuPtr inMicroFu); + void init(IntrfRadio *refRadio, dword inCycleMics, MicsecFuPtr inMicroFu); + + void begin(ComType typeIn, int adrIn, AppType appType, dword watchDog); + void setCbDataPtr(cbDataPtr cbPtr); + void setCbCtrlPtr(cbCtrlPtr cbPtr); + + // -------------------------------------------------------------------------- + // Konfiguration + // -------------------------------------------------------------------------- + // + void setPollAddress(int chnIn, int adrIn, int areaIn, bool masterIn, bool eadrIn, bool nakIn); + void setEmptyPollParams(int cycleTotal, int cycleRun, dword timeOut); + void setDataPollParams(int slAdr, int prio, int minPrio, dword timeOut); + + // -------------------------------------------------------------------------- + // Steuerung des Telegrammaustausches (Polling) + // -------------------------------------------------------------------------- + // + void run(); // Ablaufsteuerung (CPU-Übergabe) dieses Moduls +/** + * @brief Sendet neue Steuerungsdaten an einen Slave + * + * @param adr Addresse d. zu Steuernden Slaves + * @param ctrlList Liste mit Bytes zum Austausch der Steuerbytes + * @param nr Anzahl d. Steuerbytes + */ + void updControl(int adr, byte *ctrlList, int nr); // neue Steuerungsdaten + // +/** + * @brief Prüft ob Steuerungsdaten übertragen wurden + * + * @param adr Adresse d. Slaves + * @return true Erfolgreiche übertragung + * @return false Fehler in Übertragung / Falsche Adresse + */ + bool ackTrans(int adr); // Bestätigung Steuerungsdaten übertragen + /** + * @brief Überprüft ob Steuerungsdaten korrekt übertragen wurden + * + * @param adr Adresse d. Slavrs + * @return true Daten erfolgreich verarbeitet + * @return false Fehler in Übertragung + */ + bool ackControl(int adr); // Bestätigung Steuerung ausgeführt + + + // Test + // + + // Leeres Polling + // + void stopEP(); + void resumeEP(); + bool stoppedEP(); + + // Empfangsbetrieb beim Slave + // + void stopSR(); + void resumeSR(); + bool stoppedSR(); + + // Laufender Betrieb + // + void start(PlMode inPlMode); + + + + // -------------------------------------------------------------------------- + // Zugriff auf Polling-Informationen + // -------------------------------------------------------------------------- + // + int getSlaveList(byte *dest, int maxByte); + void resetPollCounters(); + + // -------------------------------------------------------------------------- + // Zugriff auf Slavedaten + // -------------------------------------------------------------------------- + // Der Index wird von 0 an ausgewertet. Allerdings ist [0] in der Slave-Liste + // auf den Index [1] abzubilden, weil Slave[0] für besondere Aufgaben + // reserviert und für den Anwender nicht zugänglich ist. + // + bool measAvail(int slIdx); // Feststellen, ob neue Messwerte da sind + int getArea(int slIdx); // Wert der Area auslesen + PlpType getAppId(int slIdx); // Wert der AppId (BlePoll) auslesen + int getMeas(int slIdx, byte *dest); // Messwerte übergeben + int getCtrlM(int slIdx, byte *dest); + + + // -------------------------------------------------------------------------- + // Debugging + // -------------------------------------------------------------------------- + // + dword debGetDword(int idx); + dword getStatistics(TxStatisticsPtr dest); + + SlavePtr getSlavePtr(int idx); + PollStatePtr getPollPtr(int idx); +}; + + +// ---------------------------------------------------------------------------- +#endif // BlePoll_h diff --git a/sketches/_PIO_Sketches/Karger/SoaapBleSlave_Test_2/src/BlePoll/library.json b/sketches/_PIO_Sketches/Karger/SoaapBleSlave_Test_2/src/BlePoll/library.json new file mode 100644 index 0000000000000000000000000000000000000000..477225b9ff50f19fdf4a1ffb19f791f80efa4870 --- /dev/null +++ b/sketches/_PIO_Sketches/Karger/SoaapBleSlave_Test_2/src/BlePoll/library.json @@ -0,0 +1,4 @@ +{ + "name": "BlePoll", + "version": "0.0.0+20220804174235" + } \ No newline at end of file diff --git a/sketches/_PIO_Sketches/Karger/SoaapBleSlave_Test_2/src/ComRingBuf/ComRingBuf.cpp b/sketches/_PIO_Sketches/Karger/SoaapBleSlave_Test_2/src/ComRingBuf/ComRingBuf.cpp new file mode 100644 index 0000000000000000000000000000000000000000..66a9784b5507d680cc700b0f7fe5e68379da7e3e --- /dev/null +++ b/sketches/_PIO_Sketches/Karger/SoaapBleSlave_Test_2/src/ComRingBuf/ComRingBuf.cpp @@ -0,0 +1,782 @@ +//----------------------------------------------------------------------------- +// Thema: Social Manufacturing Network / Development Environment +// Datei: ComRingBuf.cpp +// Editor: Robert Patzke +// URI/URL: www.mfp-portal.de +//----------------------------------------------------------------------------- +// Lizenz: CC-BY-SA (wikipedia: Creative Commons) +// Datum: 21. November 2021 +// +// Der Inhalt dieser Datei sind Festlegungen zur Gestaltung eines Ringpuffers. +// + +#include "ComRingBuf.h" + + // -------------------------------------------------------------------------- + // Initialisierungen + // -------------------------------------------------------------------------- + + ComRingBuf::ComRingBuf() + { + rbReadIdx = 0; + rbWriteIdx = 0; + sbReadIdx = 0; + sbWriteIdx = 0; + newLineMode = NewLineModeNL; + } + + void ComRingBuf::begin(IntrfSerial *ser) + { + serIf = ser; + } + + // -------------------------------------------------------------------------- + // Konfiguration + // -------------------------------------------------------------------------- + // + void ComRingBuf::setNewLineMode(byte nlMode) + { + newLineMode = nlMode; + } + + + // -------------------------------------------------------------------------- + // Schnittstellen + // -------------------------------------------------------------------------- + // + // Byte aus dem Sendepuffer lesen + // + bool ComRingBuf::getByteSnd(byte *dest) + { + if(sbReadIdx == sbWriteIdx) return(false); + + *dest = sndBuffer[sbReadIdx]; + sbReadIdx++; + if(sbReadIdx >= sbSize) + sbReadIdx = 0; + return(true); + } + + // Byte in den Empfangspuffer schreiben + // + void ComRingBuf::putByteRec(byte b) + { + int space = rbReadIdx - rbWriteIdx - 1; + if(space == 0) return; + } + + +// ---------------------------------------------------------------------------- +// Writing and reading data via circular buffer (default usage) +// ---------------------------------------------------------------------------- +// + +// ---------------------------------------------------------------------------- +// Lesen (Empfangsvorgänge) +// ---------------------------------------------------------------------------- + +void ComRingBuf::setReadBuffer(int size, byte *bufPtr) +{ + recBuffer = bufPtr; + rbSize = size; + rbReadIdx = 0; + rbWriteIdx = 0; +} + +int ComRingBuf::getChr() +{ + int retv; + + if(rbReadIdx == rbWriteIdx) + return(EOF); + + retv = recBuffer[rbReadIdx]; + rbReadIdx++; + if(rbReadIdx >= rbSize) + rbReadIdx = 0; + return(retv); +} + +void ComRingBuf::clrRecBuf() +{ + rbReadIdx = 0; + rbWriteIdx = 0; +} + +int ComRingBuf::getAll(byte *buffer) +{ + int count, i; + int tmpInt; + + if(rbReadIdx == rbWriteIdx) + return(EOF); + + tmpInt = rbWriteIdx - rbReadIdx; + if(tmpInt < 0) + count = tmpInt + rbSize; + else + count = tmpInt; + + for(i = 0; i < count; i++) + { + buffer[i] = recBuffer[rbReadIdx]; + rbReadIdx++; + if(rbReadIdx >= rbSize) + rbReadIdx = 0; + } + + return(count); +} + +int ComRingBuf::getCount(int len, byte *buffer) +{ + int count, i; + int tmpInt; + + if(rbReadIdx == rbWriteIdx) + return(0); + + tmpInt = rbWriteIdx - rbReadIdx; + if(tmpInt < 0) + count = tmpInt + rbSize; + else + count = tmpInt; + + if(len > count) + len = count; + + for(i = 0; i < len; i++) + { + buffer[i] = recBuffer[rbReadIdx]; + rbReadIdx++; + if(rbReadIdx >= rbSize) + rbReadIdx = 0; + } + + return(len); +} + +int ComRingBuf::getCountStr(int len, char *buffer) +{ + int nrChar; + + nrChar = getCount(len, (uint8_t *) buffer); + if(nrChar == EOF) return(EOF); + + buffer[nrChar] = 0; + return(nrChar); +} + +int ComRingBuf::getLine(char *buffer) +{ + bool eol; + int count, i; + int tmpInt; + + if(rbReadIdx == rbWriteIdx) + return(0); + + tmpInt = rbWriteIdx - rbReadIdx; + if(tmpInt < 0) + count = tmpInt + rbSize; + else + count = tmpInt; + + eol = false; + + for(i = 0; i < count; i++) + { + buffer[i] = recBuffer[rbReadIdx]; + if(!eol) + { + if(buffer[i] == '\r' || buffer[i] == '\n') + eol = true; + } + else + { + if(buffer[i] != '\r' && buffer[i] != '\n') + break; + } + rbReadIdx++; + if(rbReadIdx >= rbSize) + rbReadIdx = 0; + } + + if(!eol) return(0); + + buffer[i] = 0; + return(i); +} + +int ComRingBuf::getLineDec(int *intValue) +{ + bool eol, inVal; + int count, i, j; + int tmpInt; + char c; + char buffer[32]; + + if(rbReadIdx == rbWriteIdx) + return(0); + + tmpInt = rbWriteIdx - rbReadIdx; + if(tmpInt < 0) + count = tmpInt + rbSize; + else + count = tmpInt; + + if(count > 30) + count = 30; + + eol = false; + + j = 0; + inVal = false; + + for(i = 0; i < count; i++) + { + c = recBuffer[rbReadIdx]; + if(!inVal) + { + if(c > '9') + { + rbReadIdx++; + if(rbReadIdx >= rbSize) + rbReadIdx = 0; + continue; + } + inVal = true; + } + + if(!eol) + { + if(c == '\r' || c == '\n') + eol = true; + } + else + { + if(c != '\r' && c != '\n') + break; + } + rbReadIdx++; + if(rbReadIdx >= rbSize) + rbReadIdx = 0; + buffer[j++] = c; + } + + if(!eol) return(0); + + buffer[j] = 0; + *intValue = atoi(buffer); + return(i); +} + +char ComRingBuf::getC() +{ + char retC; + + if(rbReadIdx == rbWriteIdx) + return(0); + + retC = recBuffer[rbReadIdx]; + rbReadIdx++; + if(rbReadIdx >= rbSize) + rbReadIdx = 0; + + return(retC); +} + + +int ComRingBuf::waitLine(int waitLoop, char *buffer) +{ + char inChar; + bool eol; + + if(loopCount == 0) + { + tmpIdx = 0; + } + + tmpVal = inCount(); + if(tmpVal < 1) + { + loopCount++; + if(loopCount < waitLoop) + return(0); + else + { + loopCount = 0; + return(EOF); + } + } + + eol = false; + + for(int i = 0; i < tmpVal; i++) + { + inChar = getC(); + buffer[tmpIdx++] = inChar; + if(inChar == '\r' || inChar == '\n') + { + eol = true; + break; + } + } + + if(eol) + { + buffer[tmpIdx] = 0; + loopCount = 0; + return(tmpIdx); + } + + return(0); +} + +//int ComRingBuf::waitLineDec(int waitLoop, int *intValue) +//{ +//}; + +int ComRingBuf::chkLine(char *rsp) +{ + int i,chkVal; + char chkChar; + + chkVal = inCount(); + if(chkVal <= strlen(rsp)) + return(0); + + chkVal = 0; + + for(i = 0; i < strlen(rsp); i++) + { + chkChar = getC(); + if(rsp[i] != chkChar) + { + chkVal = -100000; + break; + } + else + chkVal++; + } + + if(chkVal < 0) chkVal = EOF; + + while( (recBuffer[rbReadIdx] == '\r' || recBuffer[rbReadIdx] == '\n' ) + && (rbReadIdx != rbWriteIdx)) + { + rbReadIdx++; + if(rbReadIdx >= rbSize) + rbReadIdx = 0; + } + + return(chkVal); +} + +int ComRingBuf::chkBuf(char *rsp) +{ + int i,chkVal; + char chkChar; + + chkVal = inCount(); + if(chkVal < strlen(rsp)) + return(0); + + chkVal = 0; + + for(i = 0; i < strlen(rsp); i++) + { + chkChar = getC(); + if(rsp[i] != chkChar) + chkVal = -100; + else + chkVal++; + } + + return(chkVal); +} + +int ComRingBuf::waitAll(int waitLoop, byte *buffer) +{ +} + +int ComRingBuf::waitChkBuf(int waitLoop, char *rsp) +{ + int i; + int chkVal; + char chkChar; + + if(loopCount == 0) + { + tmpVal = strlen(rsp); + } + + chkVal = inCount(); + if(chkVal < tmpVal) + { + loopCount++; + if(loopCount < waitLoop) + return(0); + else + { + loopCount = 0; + return(-10); + } + } + + chkChar = getC(); + + if(rsp[0] != chkChar) + return(0); + + if(tmpVal == 1) + { + loopCount = 0; + return(1); + } + + chkVal = 1; + + for(i = 1; i < tmpVal; i++) + { + chkChar = getC(); + if(rsp[i] != chkChar) + return(0); + else + chkVal++; + } + + loopCount = 0; + return(chkVal); +} + +int ComRingBuf::inCount(void) +{ + int count = rbWriteIdx - rbReadIdx; + if(count < 0) + count += rbSize; + return(count); +} + +int ComRingBuf::getRestChar(byte tagChr, int len, byte *buffer) +{ + int count, i, j; + byte inChr; + int tmpInt; + bool tagged; + + if(rbReadIdx == rbWriteIdx) + return(0); + + tmpInt = rbWriteIdx - rbReadIdx; + if(tmpInt < 0) + count = tmpInt + rbSize; + else + count = tmpInt; + + if(len > count) + len = count; + + tagged = false; + j = 0; + + for(i = 0; i < len; i++) + { + inChr = recBuffer[rbReadIdx]; + rbReadIdx++; + if(rbReadIdx >= rbSize) + rbReadIdx = 0; + + if(!tagged) + { + if(inChr != tagChr) + continue; + + tagged = true; + continue; + } + + buffer[j++] = inChr; + } + + if(!tagged) j = -1; + + return(j); +} + +int ComRingBuf::getRestStr(char *tagStr, int len, byte *buffer) +{ + int count, i, j, tmpIdx; + byte inChr; + int tmpInt; + bool tagged; + int tagLen; + int tagIdx; + + if(rbReadIdx == rbWriteIdx) + return(0); + + tmpIdx = rbReadIdx; + tmpInt = rbWriteIdx - tmpIdx; + + if(tmpInt < 0) + count = tmpInt + rbSize; + else + count = tmpInt; + + if(len > count) + len = count; + + tagged = false; + j = 0; + + tagLen = (int) strlen(tagStr); + tagIdx = 0; + + if(len < tagLen) + return(0); + + for(i = 0; i < len; i++) + { + inChr = recBuffer[tmpIdx]; + tmpIdx++; + if(tmpIdx >= rbSize) + tmpIdx = 0; + + if(!tagged) + { + if(inChr != tagStr[tagIdx]) + { + tagIdx = 0; + continue; + } + + tagIdx++; + + if(tagIdx == tagLen) + tagged = true; + continue; + } + + buffer[j++] = inChr; + } + + if(!tagged) return(EOF); + else + { + rbReadIdx = tmpIdx; + return(j); + } +} + +int ComRingBuf::reqChkLine(char *req, char *rsp) +{ + int i; + int chkVal; + char chkChar; + + switch(reqChkState) + { + case 0: + rbReadIdx = 0; + rbWriteIdx = 0; + chkVal = putLine(req); + if(chkVal <= 0) + return(EOF); + tmpVal = strlen(rsp); + reqChkState = 1; + return(0); + + case 1: + chkVal = inCount(); + if(chkVal <= tmpVal) + return(0); + chkVal = 0; + + for(i = 0; i < tmpVal; i++) + { + chkChar = getC(); + if(rsp[i] != chkChar) + chkVal = -100; + else + chkVal++; + } + + while( (recBuffer[rbReadIdx] == '\r' || recBuffer[rbReadIdx] == '\n') + && (rbReadIdx != rbWriteIdx) ) + { + rbReadIdx++; + if(rbReadIdx >= rbSize) + rbReadIdx = 0; + } + + reqChkState = 0; + return(chkVal); + } + + return(-1000); // internal error with <reqChkState> +} + +// ---------------------------------------------------------------------------- +// Schreiben (Sendevorgänge) +// ---------------------------------------------------------------------------- + +void ComRingBuf::setWriteBuffer(int size, byte *bufPtr) +{ + sndBuffer = bufPtr; + sbSize = size; + sbReadIdx = 0; + sbWriteIdx = 0; +} + +int ComRingBuf::putChr(int chr) +{ + int space; + bool txDone; + + if(sndBuffer == NULL) return(EOF); + if(serIf == NULL) return(EOF); + + space = getSpace(); + + if(space == 0) + { + // Wenn der Sendepuffer voll ist, dann kann der Entlader feststecken + serIf->resuSend(); + return(EOF); + } + + if(sbReadIdx == sbWriteIdx) + { + // Wenn der Sendepuffer leer ist, dann kann das Zeichen evt. + // direkt gesendet werden. + txDone = serIf->condSend(chr); + if(txDone) return(chr); + } + + putBufB(chr); + return(chr); +} + +int ComRingBuf::putStr(char *msg) +{ + int sIdx = 0; + + if(sndBuffer == NULL) return(EOF); + if(serIf == NULL) return(EOF); + + int space = getSpace(); + int len = strlen(msg); + if(space < len) + { + serIf->resuSend(); + return(EOF); + } + + if(sbReadIdx == sbWriteIdx) + { + // Wenn der Sendepuffer leer ist, dann kann das erste Zeichen evt. + // direkt gesendet werden. + if(serIf->condSend(msg[0])) + sIdx = 1; + } + + for (int i = sIdx; i < len; i++) + { + sndBuffer[sbWriteIdx] = msg[i]; + sbWriteIdx++; + if(sbWriteIdx >= sbSize) + sbWriteIdx = 0; + } + + return(len); +} + +int ComRingBuf::putSeq(byte *msg, int n) +{ + int sIdx = 0; + + if(sndBuffer == NULL) return(EOF); + if(serIf == NULL) return(EOF); + + int space = getSpace(); + + if(space < n) + { + serIf->resuSend(); + return(EOF); + } + + if(sbReadIdx == sbWriteIdx) + { + // Wenn der Sendepuffer leer ist, dann kann das erste Zeichen evt. + // direkt gesendet werden. + if(serIf->condSend(msg[0])) + sIdx = 1; + } + + for (int i = sIdx; i < n; i++) + { + sndBuffer[sbWriteIdx] = msg[i]; + sbWriteIdx++; + if(sbWriteIdx >= sbSize) + sbWriteIdx = 0; + } + + return(n); + +} + +int ComRingBuf::putNL() +{ + int retv = 0; + + if(newLineMode & NewLineModeCR) + { + putBufB('\r'); + retv++; + } + + if(newLineMode & NewLineModeNL) + { + putBufB('\n'); + retv++; + } + + return(retv); +} + +int ComRingBuf::putLine(char *msg) +{ + int retv, nl; + + retv = putStr(msg); + if(retv < 0) + return(retv); + + nl = putNL(); + return(retv); +} + +//int ComRingBuf::putLine(char *msg, char c) +//{ +//} + +//int ComRingBuf::putLine(char *msg, int n) +//{ +//} + + + // -------------------------------------------------------------------------- + // Debugging + // -------------------------------------------------------------------------- + // + + + + + + + + + diff --git a/sketches/_PIO_Sketches/Karger/SoaapBleSlave_Test_2/src/ComRingBuf/ComRingBuf.h b/sketches/_PIO_Sketches/Karger/SoaapBleSlave_Test_2/src/ComRingBuf/ComRingBuf.h new file mode 100644 index 0000000000000000000000000000000000000000..bd8ee0c8e604ac8ca5a6c344ca9966bb856f365b --- /dev/null +++ b/sketches/_PIO_Sketches/Karger/SoaapBleSlave_Test_2/src/ComRingBuf/ComRingBuf.h @@ -0,0 +1,227 @@ +//----------------------------------------------------------------------------- +// Thema: Social Manufacturing Network / Development Environment +// Datei: ComRingBuf.h +// Editor: Robert Patzke +// URI/URL: www.mfp-portal.de +//----------------------------------------------------------------------------- +// Lizenz: CC-BY-SA (wikipedia: Creative Commons) +// Datum: 21. November 2021 +// +// Der Inhalt dieser Datei sind Festlegungen zur Gestaltung eines Ringpuffers. +// + +#ifndef ComRingBuf_h +#define ComRingBuf_h +// ---------------------------------------------------------------------------- + +#include "stddef.h" +#include "stdio.h" +#include "stdlib.h" +#include "string.h" +#include "arduinoDefs.h" +#include "IntrfBuf.h" +#include "IntrfSerial.h" + +#define NewLineModeCR 0x01 +#define NewLineModeNL 0x02 + +// ---------------------------------------------------------------------------- +// C o m R i n g B u f +// ---------------------------------------------------------------------------- +class ComRingBuf : IntrfBuf +{ +private: + // -------------------------------------------------------------------------- + // Lokale Daten + // -------------------------------------------------------------------------- + // + // Zugang zur Peripherie + // + IntrfSerial *serIf; + + // Lesen und Schreiben von Zeichen (Bytes) + // + byte *ptrSend; // Der (veraenderliche) Sendezeiger + byte *ptrRec; // Der (veraenderliche) Empfangszeiger + int maxRec; // Maximale Anzahl zu empfangender Bytes + byte endChrRec; // Abschlusszeichen beim Empfang + byte condMaskCom; // Bedingungen fuer den Datenaustausch + byte newLineMode; // Art für eine neue Zeile (CR/LF) + + byte *recBuffer; // Receive ring buffer start address + word rbReadIdx; // Read index + word rbWriteIdx; // Write index + word rbSize; // Buffer size + + byte *sndBuffer; // Transmit ring buffer start address + word sbReadIdx; // Read index + word sbWriteIdx; // Write index + word sbSize; // Buffer size + + int loopCount; // For internal time out checking + int reqChkState; // State of request/check procedure + int tmpVal; // Variable for temporary data storage + int tmpIdx; // Variable for temporary array index + + + // -------------------------------------------------------------------------- + // Lokale Funktionen + // -------------------------------------------------------------------------- + // + char getC(); + int putNL(); + + // -------------------------------------------------------------------------- + // Inline-Funktionen + // -------------------------------------------------------------------------- + // + void putBufB(byte b) + { + sndBuffer[sbWriteIdx] = b; + sbWriteIdx++; + if(sbWriteIdx >= sbSize) + sbWriteIdx = 0; + } + + int getSpace() + { + int space = sbReadIdx - sbWriteIdx - 1; + if(space < 0) space += sbSize; + return(space); + } + + +public: + // -------------------------------------------------------------------------- + // Initialisierungen + // -------------------------------------------------------------------------- + ComRingBuf(); + + void begin(IntrfSerial *ser); + + // -------------------------------------------------------------------------- + // Konfiguration + // -------------------------------------------------------------------------- + // + void setNewLineMode(byte nlMode); + + // -------------------------------------------------------------------------- + // Schnittstellen + // -------------------------------------------------------------------------- + // + bool getByteSnd(byte *dest); + void putByteRec(byte b); // Byte vom Empfang an Puffer geben + + + // Zuweisen eines Speichers (*bufPtr) der Größe size für den Lesepuffer + // + void setReadBuffer(int size, byte *bufPtr); + + + // -------------------------------------------------------------------------- + // Steuerung + // -------------------------------------------------------------------------- + // + + // ---------------------------------------------- + // Ein einzelnes Zeichen aus dem Ringpuffer lesen + // ---------------------------------------------- + // Rückgabe EOF (-1), wenn kein Zeichen vorhanden + // sonst das älteste Zeichen aus dem Ringpuffer + // + int getChr(); + + // ---------------------------------------------- + // Löschen des Emmpfangspuffers + // ---------------------------------------------- + // + void clrRecBuf(); + + // -------------------------------------------------- + // Alle empfangenen Zeichen aus dem Ringpuffer lesen + // -------------------------------------------------- + // Rückgabe EOF (-1), wenn kein Zeichen vorhanden + // sonst die Anzahl der empfangenen Zeichen + // + int getAll(byte *buffer); + + // ---------------------------------------------------------- + // Begrenzte Anzahl empfangener Zeichen aus Ringpuffer lesen + // ---------------------------------------------------------- + // Rückgabe EOF (-1), wenn kein Zeichen vorhanden + // sonst die Anzahl der ausgelesenen Zeichen + // + int getCount(int count, byte *buffer); + + // ------------------------------------------------------------------------ + // Begrenzte Anzahl Zeichen als 0-terminierten String aus Ringpuffer lesen + // ------------------------------------------------------------------------ + // Rückgabe EOF (-1), wenn kein Zeichen vorhanden + // sonst die Anzahl der ausgelesenen Zeichen + // + int getCountStr(int count, char *buffer); + + // --------------------------------------------------------- + // Die nächste Zeile (Zeichen bis CR und/oder LF) als String + // --------------------------------------------------------- + // Rückgabe EOF (-1), wenn kein Zeichen vorhanden + // sonst die Anzahl der ausgelesenen Zeichen + // + int getLine(char *buffer); + + // ----------------------------------------------- + // Die nächste im Puffer enthaltene Zeile auslesen + // und die darin enthaltene Dezimalzahl übergeben + // ----------------------------------------------- + // Rückgabe EOF (-1), wenn kein Zeichen vorhanden + // sonst die Anzahl der ausgelesenen Zeichen + // oder 0, wenn keine Dezimalzahl enthalten war + // + int getLineDec(int *intValue); + + // --------------------------------------------------------- + // Warten auf Zeile (Zeichen bis CR und/oder LF) als String + // --------------------------------------------------------- + // Rückgabe EOF (-1), wenn Wartezyklen verstrichen + // Rückgabe 0, solange kein Zeilenende gelesen + // sonst die Anzahl der ausgelesenen Zeichen + // + int waitLine(int waitLoop, char *buffer); + + //int waitLineDec(int waitLoop, int *intValue); + + // --------------------------------------------------------- + // Testen der Zeile im Puffer + // --------------------------------------------------------- + // Rückgabe 0, wenn Teststring (noch) nicht enthalten + // sonst die Länge des Teststring + // EOF, wenn Zeile im Puffer (gelöscht) nicht passte + // + int chkLine(char *rsp); + + int chkBuf(char *rsp); + int waitAll(int waitLoop, byte *buffer); + int waitChkBuf(int waitLoop, char *rsp); + int inCount(void); + int getRestChar(byte tagChr, int len, byte *buffer); + int getRestStr(char *tagStr, int len, byte *buffer); + int reqChkLine(char *req, char *rsp); + + void setWriteBuffer(int size, byte *bufPtr); + int putChr(int chr); + int putStr(char *msg); + int putSeq(byte *msg, int n); + int putLine(char *msg); + //int putLine(char *msg, char c); + //int putLine(char *msg, int n); + + // -------------------------------------------------------------------------- + // Debugging + // -------------------------------------------------------------------------- + // + +}; + + +// ---------------------------------------------------------------------------- +#endif // beacon_h diff --git a/sketches/_PIO_Sketches/Karger/SoaapBleSlave_Test_2/src/ComRingBuf/library.json b/sketches/_PIO_Sketches/Karger/SoaapBleSlave_Test_2/src/ComRingBuf/library.json new file mode 100644 index 0000000000000000000000000000000000000000..054f2c8c3093791dc7ce4f7de879b26a019e900b --- /dev/null +++ b/sketches/_PIO_Sketches/Karger/SoaapBleSlave_Test_2/src/ComRingBuf/library.json @@ -0,0 +1,4 @@ +{ + "name": "BlePoll", + "version": "0.0.0+20220804174235" +} \ No newline at end of file diff --git a/sketches/_PIO_Sketches/Karger/SoaapBleSlave_Test_2/src/LoopCheck/LoopCheck.cpp b/sketches/_PIO_Sketches/Karger/SoaapBleSlave_Test_2/src/LoopCheck/LoopCheck.cpp new file mode 100644 index 0000000000000000000000000000000000000000..b01795b4f033ebb0286340840a3b1507c6ef0302 --- /dev/null +++ b/sketches/_PIO_Sketches/Karger/SoaapBleSlave_Test_2/src/LoopCheck/LoopCheck.cpp @@ -0,0 +1,838 @@ +//----------------------------------------------------------------------------- +// Thema: Social Manufacturing Network / Software Loop Checking and Timing +// Datei: LoopCheck.cpp +// Editor: Robert Patzke +// URI/URL: www.mfp-portal.de +//----------------------------------------------------------------------------- +// Lizenz: CC-BY-SA (siehe Wikipedia: Creative Commons) +// + +#include "LoopCheck.h" + + + // ------------------------------------------------------------------------- + // Konstruktoren und Initialisierungen + // ------------------------------------------------------------------------- + // + LoopCheck::LoopCheck() + { + firstLoop = true; + taskHappened = false; + toggleMilli = true; + + initStatistics(); + initTasks(); + initClock(); + } + + void LoopCheck::initStatistics() + { + backgroundMicros = 0; + loopMicros = 0; + loopStartMicros = 0; + loopEndMicros = 0; + backgroundMaxMicros = 0; + backgroundMinMicros = (unsigned long) -1; + backgroundAvgMicros = 0; + loopMaxMicros = 0; + loopMinMicros = (unsigned long) -1; + loopAvgMicros = 0; + loopCounter = 0; + periodFailCount = 0; + periodMaxMicros = 0; + periodMinMicros = (unsigned int) -1; + periodMicros = 0; + periodFailAlarm = false; + + year = 0; + day = 0; + hour = 0; + min = 0; + sec = 0; + msec = 0; + + measureRuntime = 0; + + calcAvgCounter = 0; + } + + void LoopCheck::initTasks() + { + for (int i = 0; i < NrOfTimerTasks; i++) + { + timerTaskList[i].counterStarted = false; + timerTaskList[i].finished = false; + timerTaskList[i].firstRun = true; + timerTaskList[i].runCounter = 0; + } + + for( int i = 0; i < NrOfOnceTasks; i++) + { + onceTaskList[i].finished = false; + onceTaskList[i].firstRun = true; + onceTaskList[i].waitCounter = 0; + } + } + + void LoopCheck::initClock() + { + strcpy(dateTimeStr,"2017-12-07T17:11:35.456+00:00"); + dtYear = 2017; + dtMonth = 12; + dtDay = 7; + dtHour = 17; + dtMin = 11; + dtSec = 35; + dtmSec = 456; + } + + // ------------------------------------------------------------------------- + // Anwenderfunktionen + // ------------------------------------------------------------------------- + // + + void LoopCheck::begin() + { + unsigned int cycleMillis; + unsigned int restMicros; + unsigned int tmpInt; + unsigned int tmpInt100, tmpInt10, tmpInt1; + div_t divResult; + + loopStartMicros = SYSMICSEC; + clockCycleMicros = loopStartMicros - lastClockMicros + lastRestMicros; + // + // Zeit seit dem letzten Aufruf von begin() + + + // + if(firstLoop == true) + { + clockCycleMicros = 0; + lastClockMicros = loopStartMicros; + } + + // Aufteilen in Millisekunden und Mikrosekunden + // + divResult = DIV((int) clockCycleMicros, 1000); + + restMicros = divResult.rem; + cycleMillis = divResult.quot; + + if(cycleMillis > 0) + { + lastRestMicros = restMicros; + lastClockMicros = loopStartMicros; + msec += cycleMillis; + dtmSec += cycleMillis; + + // Betriebsstundenzähler + // + if(msec >= 1000) + { + msec -= 1000; + sec++; + measureRuntime++; + + if(sec == 60) + { + sec = 0; + min++; + if(min == 60) + { + min = 0; + hour++; + if(hour == 24) + { + hour = 0; + day++; + if(day == 365) + { + day = 0; + year++; + } + } + } + } + } + + // Software-Uhr + // + if(dtmSec >= 1000) + { + dtmSec -= 1000; + + dtSec++; + dateTimeStr[20] = '0'; + dateTimeStr[21] = '0'; + dateTimeStr[22] = '0'; + + if(dtSec == 60) + { + dtSec = 0; + dtMin++; + dateTimeStr[17] = '0'; + dateTimeStr[18] = '0'; + + if(dtMin == 60) + { + dtMin = 0; + dtHour++; + dateTimeStr[14] = '0'; + dateTimeStr[15] = '0'; + + if(dtHour == 24) + { + dtHour = 0; + dtDay++; + dateTimeStr[11] = '0'; + dateTimeStr[12] = '0'; + + if ( + (dtDay == (febLen + 1) && dtMonth == 2) + || (dtDay == 31 && (dtMonth == 4 || + dtMonth == 6 || + dtMonth == 9 || + dtMonth == 11)) + || dtDay == 32 + ) + { + dtDay = 1; + dtMonth++; + dateTimeStr[8] = '0'; + dateTimeStr[9] = '1'; + + if(dtMonth == 13) + { + dtMonth = 1; + dtYear++; + tmpInt = dtYear - 2000; + if((tmpInt % 4) == 0) + febLen = 29; + else + febLen = 28; + dateTimeStr[5] = '0'; + dateTimeStr[6] = '1'; + + divResult = DIV(tmpInt,100); + tmpInt100 = divResult.quot; + tmpInt = divResult.rem; + + divResult = DIV(tmpInt,10); + tmpInt10 = divResult.quot; + tmpInt1 = divResult.rem; + + dateTimeStr[1] = (char) (tmpInt100 | 0x30); + dateTimeStr[2] = (char) (tmpInt10 | 0x30); + dateTimeStr[3] = (char) (tmpInt1 | 0x30); + } + else + { + divResult = DIV(dtMonth,10); + dateTimeStr[5] = (char) (divResult.quot | 0x30); + dateTimeStr[6] = (char) (divResult.rem | 0x30); + } + } + else + { + divResult = DIV(dtDay,10); + dateTimeStr[8] = (char) (divResult.quot | 0x30); + dateTimeStr[9] = (char) (divResult.rem | 0x30); + } + } + else + { + divResult = DIV(dtHour,10); + dateTimeStr[11] = (char) (divResult.quot | 0x30); + dateTimeStr[12] = (char) (divResult.rem | 0x30); + } + } + else + { + divResult = DIV(dtMin,10); + dateTimeStr[14] = (char) (divResult.quot | 0x30); + dateTimeStr[15] = (char) (divResult.rem | 0x30); + } + } + else + { + divResult = DIV(dtSec,10); + dateTimeStr[17] = (char) (divResult.quot | 0x30); + dateTimeStr[18] = (char) (divResult.rem | 0x30); + } + } + else + { + divResult = DIV(dtmSec,100); + tmpInt100 = divResult.quot; + tmpInt = divResult.rem; + + divResult = DIV(tmpInt,10); + tmpInt10 = divResult.quot; + tmpInt1 = divResult.rem; + + dateTimeStr[20] = (char) (tmpInt100 | 0x30); + dateTimeStr[21] = (char) (tmpInt10 | 0x30); + dateTimeStr[22] = (char) (tmpInt1 | 0x30); + } + + } + + if(firstLoop == false) + { + backgroundMicros = loopStartMicros - loopEndMicros; + if(backgroundMicros > backgroundMaxMicros) + backgroundMaxMicros = backgroundMicros; + if(backgroundMicros < backgroundMinMicros) + backgroundMinMicros = backgroundMicros; + periodMicros = loopStartMicros - lastStartMicros; + if(periodMicros > periodMaxMicros) + periodMaxMicros = periodMicros; + periodSumMicros += periodMicros; + if(periodMicros < periodMinMicros) + periodMinMicros = periodMicros; + if(periodMicros > PeriodMinTime) + { + periodFailAlarm = true; + periodFailCount++; + } + + divResult = DIV(periodMicros, 1000); + if(divResult.quot > 0) + { + if(divResult.quot >= LoopScreeningGrades) + ++loopScreening[LoopScreeningGrades - 1]; + else + ++loopScreening[divResult.quot -1]; + } + } // if() + + lastStartMicros = loopStartMicros; + + } + + + unsigned int LoopCheck::done() + { + return(SYSMICSEC - loopStartMicros); + } + + void LoopCheck::end() + { + loopEndMicros = SYSMICSEC; + loopMicros = loopEndMicros - loopStartMicros; + if(loopMicros > loopMaxMicros) + loopMaxMicros = loopMicros; + if(loopMicros < loopMinMicros) + loopMinMicros = loopMicros; + + if(firstLoop == false) + { + loopSumMicros += loopMicros; + backgroundSumMicros += backgroundMicros; + calcAvgCounter++; + if(calcAvgCounter == CalcAverageDepth) + { + loopAvgMicros = loopSumMicros / CalcAverageDepth; + backgroundAvgMicros = backgroundSumMicros / CalcAverageDepth; + periodAvgMicros = periodSumMicros / CalcAverageDepth; + calcAvgCounter = 0; + loopSumMicros = 0; + backgroundSumMicros = 0; + periodSumMicros = 0; + } + } + else + { + loopAvgMicros = loopMicros; + backgroundAvgMicros = backgroundMicros; + } + + loopCounter++; + firstLoop = false; + taskHappened = false; + } + + bool LoopCheck::timerMicro + (int taskIdx, unsigned long repeatTime, unsigned int repetitions, unsigned long delay) + { + TimerTask *ctrlPtr; + unsigned long calcMics; + + // Test the limit of enabled timers + // + if(taskIdx < 0) return(false); + if(taskIdx >= NrOfTimerTasks) return(false); + + // Get the reference to timer data for the selected timer + // + ctrlPtr = &timerTaskList[taskIdx]; + + // If the timer task has finished, we are ready here + // + if(ctrlPtr->finished == true) return(false); + + // If it is the first run (initialisation 1) + // + if(ctrlPtr->firstRun == true) + { + ctrlPtr->firstRun = false; + ctrlPtr->repCounter = repetitions; + ctrlPtr->delayCounter = delay; + } + + // If counting is not started yet (initialisation 2) + // + if(ctrlPtr->counterStarted == false) + { + ctrlPtr->startCount = loopStartMicros; + ctrlPtr->counterStarted = true; + return(false); + } + + // If another count task has happened in this loop, we have to wait + // + if(taskHappened == true) return(false); + + // Calculate the number of microseconds since the start of the counter + // + calcMics = loopStartMicros - ctrlPtr->startCount; + ctrlPtr->ticks = calcMics; + + // If there is a delay, wait the delay time + // + if(ctrlPtr->delayCounter > 0) + { + if(calcMics < ctrlPtr->delayCounter) + return(false); + else + { + ctrlPtr->delayCounter = 0; // delay finished + ctrlPtr->startCount = loopStartMicros; // reset counter + } + return(false); + } + + // There is no delay (or delay is finished) + // If repeatTime is not passed, leave with FALSE + // + if(calcMics < repeatTime) + { + return(false); + } + + // One counter period finished + // + taskHappened = true; // disable other timers in this loop + ctrlPtr->counterStarted = false; // prepare resetting the counter + ctrlPtr->runCounter++; // count the timer events + + // If the number of periods is limited finish in time + // + if(ctrlPtr->repCounter > 0) + { + ctrlPtr->repCounter--; + if(ctrlPtr->repCounter == 0) + ctrlPtr->finished = true; + } + + return(true); + } + + bool LoopCheck::timerMicro + (int taskIdx, unsigned long repeatTime, unsigned int repetitions) + { + return(timerMicro(taskIdx, repeatTime, repetitions, 0)); + } + + + bool LoopCheck::timerMilli + (int taskIdx, unsigned long repeatTime, unsigned int repetitions, unsigned long delay) + { + return(timerMicro(taskIdx, repeatTime * 1000, repetitions, delay * 1000)); + } + + bool LoopCheck::timerMilli + (int taskIdx, unsigned long repeatTime, unsigned int repetitions) + { + return(timerMicro(taskIdx,repeatTime * 1000,repetitions,0)); + } + + bool LoopCheck::once(int taskIdx) + { + if(taskIdx < 0) return(false); + if(taskIdx >= NrOfOnceTasks) return(false); + + if(onceTaskList[taskIdx].finished == true) return(false); + onceTaskList[taskIdx].finished = true; + return(true); + } + + bool LoopCheck::once(int taskIdx, unsigned int nrOfLoops) + { + if(taskIdx < 0) return(false); + if(taskIdx >= NrOfOnceTasks) return(false); + + if(onceTaskList[taskIdx].finished == true) return(false); + if(nrOfLoops <= 1) + { + onceTaskList[taskIdx].finished = true; + return(true); + } + + if(onceTaskList[taskIdx].firstRun == true) + { + onceTaskList[taskIdx].firstRun = false; + onceTaskList[taskIdx].waitCounter = nrOfLoops; + } + + onceTaskList[taskIdx].waitCounter--; + if(onceTaskList[taskIdx].waitCounter > 0) + return(false); + + onceTaskList[taskIdx].finished = true; + return(true); + } + + bool LoopCheck::onceDelayed(int taskIdx, unsigned long delay) + { + if(taskIdx < 0) return(false); + if(taskIdx >= NrOfOnceTasks) return(false); + + if(onceTaskList[taskIdx].finished == true) return(false); + + if(onceTaskList[taskIdx].firstRun == true) + { + onceTaskList[taskIdx].firstRun = false; + onceTaskList[taskIdx].startCount = loopStartMicros; + } + + if(loopStartMicros - onceTaskList[taskIdx].startCount < delay) + return(false); + + onceTaskList[taskIdx].finished = true; + return(true); + } + + bool LoopCheck::toggle(int taskIdx) + { + bool toggleBit; + + if(taskIdx < 0) return(false); + if(taskIdx >= NrOfToggleTasks) return(false); + toggleBit = toggleTaskList[taskIdx]; + toggleTaskList[taskIdx] = !toggleBit; + return(toggleBit); + } + + unsigned long LoopCheck::timerCycle(int taskIdx) + { + if(taskIdx < 0) return(0); + if(taskIdx >= NrOfTimerTasks) return(0); + return(timerTaskList[taskIdx].runCounter); + } + + bool LoopCheck::timerCycleMod(int taskIdx, int modulo) + { + div_t divResult; + + if(taskIdx < 0) return(0); + if(taskIdx >= NrOfTimerTasks) return(0); + divResult = DIV(timerTaskList[taskIdx].runCounter,modulo); + if(divResult.rem == 0) + return(true); + else + return(false); + } + + unsigned long LoopCheck::tick(int taskIdx) + { + if(taskIdx < 0) return(0); + if(taskIdx >= NrOfTimerTasks) return(0); + return(timerTaskList[taskIdx].ticks); + } + + unsigned long LoopCheck::operationTime(OpHourMeter *opHourMeter) + { + opHourMeter->Milliseconds = msec; + opHourMeter->Seconds = sec; + opHourMeter->Minutes = min; + opHourMeter->Hours = hour; + opHourMeter->Days = day; + opHourMeter->Years = year; + return(loopStartMicros); + } + + unsigned long LoopCheck::getStatistics(LoopStatistics *statistics) + { + statistics->loopTime = (unsigned int) loopMicros; + statistics->loopMaxTime = (unsigned int) loopMaxMicros; + statistics->loopMinTime = (unsigned int) loopMinMicros; + statistics->loopAvgTime = (unsigned int) loopAvgMicros; + + statistics->bgTime = (unsigned int) backgroundMicros; + statistics->bgMaxTime = (unsigned int) backgroundMaxMicros; + statistics->bgMinTime = (unsigned int) backgroundMinMicros; + statistics->bgAvgTime = (unsigned int) backgroundAvgMicros; + + statistics->alarmCount = periodFailCount; + statistics->periodAlarm = periodFailAlarm; + periodFailAlarm = false; + + statistics->loopPeriod = periodMicros; + statistics->maxPeriod = periodMaxMicros; + statistics->minPeriod = periodMinMicros; + statistics->avgPeriod = periodAvgMicros; + + for (int i = 0; i < LoopScreeningGrades; i++) + statistics->rtScreening[i] = loopScreening[i]; + + return(loopCounter); + } + + void LoopCheck::resetStatistics() + { + backgroundMicros = 0; + loopMicros = 0; + + backgroundMaxMicros = 0; + backgroundMinMicros = (unsigned long) -1; + backgroundAvgMicros = 0; + + loopMaxMicros = 0; + loopMinMicros = (unsigned long) -1; + loopAvgMicros = 0; + loopCounter = 0; + + periodFailCount = 0; + periodMaxMicros = 0; + periodMinMicros = (unsigned int) -1; + periodAvgMicros = 0; + periodMicros = 0; + periodFailAlarm = false; + + for (int i = 0; i < LoopScreeningGrades; i++) + loopScreening[i] = 0; + + calcAvgCounter = 0; + } + + bool LoopCheck::setDateTime(const char *dtStr) + { + int tmpInt; + + if(strlen(dtStr) < 23) return(false); + strcpy(dateTimeStr,dtStr); + dtYear = (dateTimeStr[0] & 0x0F) * 1000 + + (dateTimeStr[1] & 0x0F) * 100 + + (dateTimeStr[2] & 0x0F) * 10 + + (dateTimeStr[3] & 0x0F); + + tmpInt = dtYear - 2000; + if((tmpInt % 4) == 0) + febLen = 29; + else + febLen = 28; + + + dtMonth = (dateTimeStr[5] & 0x0F) * 10 + + (dateTimeStr[6] & 0x0F); + + dtDay = (dateTimeStr[8] & 0x0F) * 10 + + (dateTimeStr[9] & 0x0F); + + dtHour = (dateTimeStr[11] & 0x0F) * 10 + + (dateTimeStr[12] & 0x0F); + + dtMin = (dateTimeStr[14] & 0x0F) * 10 + + (dateTimeStr[15] & 0x0F); + + dtSec = (dateTimeStr[17] & 0x0F) * 10 + + (dateTimeStr[18] & 0x0F); + + dtmSec = (dateTimeStr[20] & 0x0F) * 10 + + (dateTimeStr[21] & 0x0F) * 10 + + (dateTimeStr[22] & 0x0F); + + return(true); + } + + bool LoopCheck::setDateTime(lcDateTime dt) + { + div_t divResult; + int tmpInt; + + dtYear = dt.Year; + + tmpInt = dtYear - 2000; + if((tmpInt % 4) == 0) + febLen = 29; + else + febLen = 28; + + + divResult = DIV(dtYear,1000); + dateTimeStr[0] = (char) (0x30 + divResult.quot); + + divResult = DIV(divResult.rem,100); + dateTimeStr[1] = (char) (0x30 + divResult.quot); + + divResult = DIV(divResult.rem,10); + dateTimeStr[2] = (char) (0x30 + divResult.quot); + dateTimeStr[3] = (char) (0x30 + divResult.rem); + + dtMonth = dt.Month; + divResult = DIV(dtMonth,10); + dateTimeStr[5] = (char) (0x30 + divResult.quot); + dateTimeStr[6] = (char) (0x30 + divResult.rem); + + dtDay = dt.Day; + divResult = DIV(dtDay,10); + dateTimeStr[8] = (char) (0x30 + divResult.quot); + dateTimeStr[9] = (char) (0x30 + divResult.rem); + + dtHour = dt.Hour; + divResult = DIV(dtHour,10); + dateTimeStr[11] = (char) (0x30 + divResult.quot); + dateTimeStr[12] = (char) (0x30 + divResult.rem); + + dtMin = dt.Minute; + divResult = DIV(dtMin,10); + dateTimeStr[14] = (char) (0x30 + divResult.quot); + dateTimeStr[15] = (char) (0x30 + divResult.rem); + + dtSec = dt.Second; + divResult = DIV(dtSec,10); + dateTimeStr[17] = (char) (0x30 + divResult.quot); + dateTimeStr[18] = (char) (0x30 + divResult.rem); + + dtmSec = dt.Millisecond; + divResult = DIV(dtmSec, 100); + dateTimeStr[20] = (char) (0x30 + divResult.quot); + divResult = DIV(divResult.rem, 10); + dateTimeStr[21] = (char) (0x30 + divResult.quot); + dateTimeStr[22] = (char) (0x30 + divResult.rem); + + return(true); + } + + bool LoopCheck::getDateTime(lcDateTime *dt) + { + dt->Year = dtYear; + dt->Month = dtMonth; + dt->Day = dtDay; + dt->Hour = dtHour; + dt->Minute = dtMin; + dt->Second = dtSec; + dt->Millisecond = dtmSec; + return(true); + } + + const char * LoopCheck::refDateTime() + { + return(dateTimeStr); + } + + unsigned long LoopCheck::locMicros() + { +#ifdef smnSimLinux + struct timespec clockTime; + unsigned long retv; + + clock_gettime(CLOCK_MONOTONIC, &clockTime); + retv = clockTime.tv_nsec / 1000; + return(retv); +#endif + +#ifdef smnSimWindows + LARGE_INTEGER countValue, frequency, result; + + QueryPerformanceCounter(&countValue); + QueryPerformanceFrequency(&frequency); + + result.QuadPart = (countValue.QuadPart * 1000000) / frequency.QuadPart; + return((unsigned long) result.QuadPart); +#endif + +#ifdef smnSloeber + return(micros()); +#endif + } + +#ifdef smnESP8266 + div_t LoopCheck::locDiv(int numer, int denom) + { + div_t retv; + + retv.quot = numer / denom; + retv.rem = numer % denom; + + return(retv); + } +#endif + + void LoopCheck::startTimeMeasure() + { + measureTimeSet = SYSMICSEC; + } + + unsigned long LoopCheck::getTimeMeasure() + { + return(SYSMICSEC - measureTimeSet); + } + + unsigned long LoopCheck::getRuntime() + { + return(measureRuntime); + } + + void LoopCheck::hexAsc(char * dest, byte val) + { + char cv; + + cv = val >> 4; + if(cv < 10) + cv += 0x30; + else + cv += 0x37; + dest[0] = cv; + + cv = val & 0x0F; + if(cv < 10) + cv += 0x30; + else + cv += 0x37; + dest[1] = cv; + + dest[2] = '\0'; + } + + + // ------------------------------------------------------------------------- + // Debug-Funktionen + // ------------------------------------------------------------------------- + // +#ifdef smnLoopCheckDebug + + void LoopCheck::dbgGetStatistics(char *buffer, int idxItem) + { + switch(idxItem) + { + case 0: + sprintf(buffer,"lT=%d, lMaxT=%d, lMinT=%d, lAvgT=%d", + loopMicros,loopMaxMicros,loopMinMicros,loopAvgMicros); + break; + + case 1: + sprintf(buffer,"bT=%d, bMaxT=%d, bMinT=%d, bAvgT=%d", + backgroundMicros,backgroundMaxMicros,backgroundMinMicros,backgroundAvgMicros); + break; + + case 2: + sprintf(buffer,"rtAlCnt=%d, lCnt=%d, Scr=%d,%d,%d,%d,%d,%d", + periodFailCount, loopCounter, loopScreening[0],loopScreening[1],loopScreening[2],loopScreening[3],loopScreening[4],loopScreening[5]); + break; + } + } + +#endif diff --git a/sketches/_PIO_Sketches/Karger/SoaapBleSlave_Test_2/src/LoopCheck/LoopCheck.h b/sketches/_PIO_Sketches/Karger/SoaapBleSlave_Test_2/src/LoopCheck/LoopCheck.h new file mode 100644 index 0000000000000000000000000000000000000000..9588f3e56dc3ebe52890b772533793e533aad05d --- /dev/null +++ b/sketches/_PIO_Sketches/Karger/SoaapBleSlave_Test_2/src/LoopCheck/LoopCheck.h @@ -0,0 +1,343 @@ +//----------------------------------------------------------------------------- +// Thema: Social Manufacturing Network / Development Environment +// Datei: LoopCheck.h +// Editor: Robert Patzke +// URI/URL: www.mfp-portal.de +//----------------------------------------------------------------------------- +// Lizenz: CC-BY-SA (siehe Wikipedia: Creative Commons) +// +#ifndef _LoopCheck_h +#define _LoopCheck_h +//----------------------------------------------------------------------------- + +#define PeriodMinTime 5000 +// Wenn der Aufrufzyklus der Loop diese Zeit (in Mikrosekunden) überschreitet, +// dann wird ein Alarmbit gesetzt und ein Alarmzähler inkrementiert + +#ifndef LoopScreeningGrades + #define LoopScreeningGrades 6 +#endif + +#define NrOfTimerTasks 10 + +#define lcTimer0 0 +#define lcTimer1 1 +#define lcTimer2 2 +#define lcTimer3 3 +#define lcTimer4 4 +#define lcTimer5 5 +#define lcTimer6 6 +#define lcTimer7 7 +#define lcTimer8 8 +#define lcTimer9 9 + + +#define NrOfOnceTasks 4 + +#define lcOnce0 0 +#define lcOnce1 1 +#define lcOnce2 2 +#define lcOnce3 3 + +#define NrOfToggleTasks 4 + +#define lcToggle0 0 +#define lcToggle1 1 +#define lcToggle2 2 +#define lcToggle3 3 + +#define CalcAverageDepth 32 + +#ifdef UseGithubPath + #include "../environment/environment.h" +#else + #include "environment.h" +#endif + +#if defined(smnSimLinux) || defined(smnSimWindows) + #include <stdlib.h> + #include <string.h> + #include <time.h> + #define SYSMICSEC locMicros() +#endif + +#ifdef smnSimWindows +#include <Windows.h> +#endif + +#ifdef smnSloeber + #include "Arduino.h" + #define SYSMICSEC micros() +#endif + +#ifdef smnESP8266 + #define DIV(x,y) locDiv(x,y) +#else + #define DIV(x,y) div(x,y) +#endif + +typedef struct _OpHourMeter +{ + int Years; + int Days; + int Hours; + int Minutes; + int Seconds; + int Milliseconds; +} OpHourMeter; + +typedef struct _lcDateTime +{ + int Year; + int Month; + int Day; + int Hour; + int Minute; + int Second; + int Millisecond; +} lcDateTime; + +typedef struct _LoopStatistics +{ + unsigned int loopTime; // Schleifenzeit in Mikrosekunden + unsigned int loopMaxTime; // Maximale Schleifenzeit + unsigned int loopMinTime; // Minimale Schleifenzeit + unsigned int loopAvgTime; // Mittlere Schleifenzeit + + unsigned int bgTime; // Zeit außerhalb der Schleife + unsigned int bgMaxTime; // Maximale Außenzeit + unsigned int bgMinTime; // Minimale Außenzeit + unsigned int bgAvgTime; // Mittlere Außenzeit + + unsigned int loopPeriod; // Zeit zwischen loop-Aufrufen + unsigned int maxPeriod; // Maximale Aufrufdistanz + unsigned int minPeriod; // Minimale Aufrufdistanz + unsigned int avgPeriod; // Mittlere Aufrufdistanz + + bool periodAlarm; // Aufrufdistanz > PeriodMinTime + unsigned int alarmCount; // Anzahl der Überschreitungen + + unsigned int rtScreening[LoopScreeningGrades]; + // Echtzeitüberwachung (Klassierung der ms Überschreitungen) +} LoopStatistics; + + +// --------------------------------------------------------------------------- +// class LoopCheck +// --------------------------------------------------------------------------- +// +class LoopCheck +{ + // ------------------------------------------------------------------------- + // Klassenspezifische Datentypen + // ------------------------------------------------------------------------- + // + typedef struct _TimerTask + { + bool counterStarted; + bool finished; + bool firstRun; + unsigned long startCount; + unsigned long runCounter; + unsigned long delayCounter; + unsigned long ticks; + unsigned int repCounter; + } TimerTask; + + typedef struct _OnceTask + { + bool finished; + bool firstRun; + unsigned int waitCounter; + unsigned long startCount; + } OnceTask; + +private: + // ------------------------------------------------------------------------- + // Lokale Variablen + // ------------------------------------------------------------------------- + // + unsigned long checkStartMicros; // Zeit des ersten Aufrufs von begin() + + unsigned long backgroundMicros; // Zeit, die außerhalb von loop() + // verstrichen ist (in Mikrosekunden) + unsigned long loopMicros; // Zeit, die innerhalb von loop() + // verstrichen ist (in Mikrosekunden) + unsigned long loopStartMicros; // Loop-Startzeit (us seit CPU-Start) + unsigned long lastClockMicros; + unsigned long lastStartMicros; + unsigned long lastRestMicros; + + unsigned long loopEndMicros; // Loop-Endezeit (us seit CPU-Start) + unsigned long clockCycleMicros; // Abstand zwischen zwei clock ticks + unsigned long mainStartMicros; // Zählerstand bei Programmstart + + unsigned long backgroundMaxMicros; // Maximale Zeit außerhalb loop() + unsigned long backgroundMinMicros; // Minimale Zeit außerhalb loop() + unsigned long backgroundAvgMicros; // Mittlere Zeit außerhal loop() {32} + unsigned long backgroundSumMicros; // Summe für Mittelwertberechnung + + unsigned long loopMaxMicros; // Maximale Zeit innerhalb loop() + unsigned long loopMinMicros; // Minimale Zeit innerhalb loop() + unsigned long loopAvgMicros; // Mittlere Zeit innerhalb loop() + unsigned long loopSumMicros; // Summe für Mittelwertberechnung + + unsigned long loopCounter; // Anzahl der loop()-Durchläufe + + unsigned int loopScreening[LoopScreeningGrades]; + + int calcAvgCounter; // Zähler für die Mittelwertbildung + bool firstLoop; // Spezielle Kennzeichnung erste loop() + bool taskHappened; // Kennzeichnung: Es lief ein LoopTask + + TimerTask timerTaskList[NrOfTimerTasks]; // Steuerung der zyklischen + // Tasks (Timer-Ersatz in loop()) + OnceTask onceTaskList[NrOfOnceTasks]; + bool toggleTaskList[NrOfToggleTasks]; + + int year; // Betriebsstundenzähler gesamt + int day; + int hour; + int min; + int sec; + int msec; + bool toggleMilli; + + int dtYear; // Zeit / Uhr + int dtMonth; + int dtDay; + int dtHour; + int dtMin; + int dtSec; + int dtmSec; + int febLen; + char dateTimeStr[30]; + + unsigned int periodMicros; // Zeit zwischen zwei loop-Aufrufen + unsigned int periodMinMicros; + unsigned int periodMaxMicros; + unsigned int periodAvgMicros; + unsigned int periodSumMicros; + + bool periodFailAlarm; // periodMicros > Millisekunde + unsigned int periodFailCount; // Anzahl der Überschreitungen + + unsigned long measureTimeSet; // Mikrosekunden-Offset Zeitmessung + + unsigned long measureRuntime; // Laufzeit seit Start in Sekunden + +private: + // ------------------------------------------------------------------------- + // Lokale Funktionen + // ------------------------------------------------------------------------- + // + void initTasks(); + void initStatistics(); + void initClock(); + unsigned long locMicros(); +#ifdef smnESP8266 + div_t locDiv(int numer, int denom); +#endif + +public: + // ------------------------------------------------------------------------- + // Konstruktoren und Initialisierungen + // ------------------------------------------------------------------------- + // + LoopCheck(); + + // ------------------------------------------------------------------------- + // Anwenderfunktionen + // ------------------------------------------------------------------------- + // + void begin(); // Diese Funktion muss am Anfang der Schleife aufgerufen + // werden. + + unsigned int done(); // Diese Funktion kann vor dem Aufruf von end() + // genutzt werden und liefert die Laufzeit bis dahin + + void end(); // Diese Funktion muss am Ende der Schleife aufgerufen + // werden. + + bool timerMicro(int taskIdx, unsigned long repeatTime, unsigned int repetitions); + bool timerMicro(int taskIdx, unsigned long repeatTime, unsigned int repetitions, unsigned long delay); + // Diese Funktion muss als Bedingung (if) aufgerufen werden, um den + // nachfolgenden Block {} mit der Wiederholzeit <repeatTime> auszuführen + // Für jede Taskschleife muss ein anderer Index <taskIdx> aus dem Bereich + // 0 <= taskIdx < MaxNrOfLoopTasks angegeben werden. + // Mit <repetitions> wird angegeben, wie oft der Durchlauf überhaupt erfolgt. + // Der Wert 0 gibt an, dass der Task für immer läuft + + bool timerMilli(int taskIdx, unsigned long repeatTime, unsigned int repetitions); + bool timerMilli(int taskIdx, unsigned long repeatTime, unsigned int repetitions, unsigned long delay); + + bool once(int taskIdx); + // Diese Funktion liefert nur einmal den Wert <true> + + bool once(int taskIdx, unsigned int nrOfLoops); + // Diese Funktion liefert nur einmal den Wert <true> + // nach Ablauf von nrOfLoops Aufrufen + + bool onceDelayed(int taskIdx, unsigned long delay); + // Diese Funktion liefert nur einmal den Wert <true> + // nach Ablauf von <delay> Mikrosekunden + + bool toggle(int taskIdx); + // Diese Funktion liefert abwechselnd die Werte <true> oder <false> + + unsigned long timerCycle(int taskIdx); + // Rückgabe des aktuellen Timerablaufes (startet ab 0). + + bool timerCycleMod(int taskIdx, int modulo); + // Liefert alle <modulo> Timerabläufe den Wert <true> + + unsigned long tick(int taskIdx); + // Rückgabe des aktuellen Zählwertes in Mikrosekunden + + unsigned long operationTime(OpHourMeter *opHourMeter); + // Die Zeit ab Start der CPU + + unsigned long getStatistics(LoopStatistics *statistics); + // Statistik über Ablaufzeiten + + void resetStatistics(); + // Rücksetzen der Statistikdaten + + bool setDateTime(const char *dtStr); + // Setzen der Uhr über standardisierten String + + bool setDateTime(lcDateTime dt); + // Setzen der Uhr über lokal definierte Struktur + + bool getDateTime(lcDateTime *dt); + // Abfragen der Uhr über lokal definierte Struktur + + const char * refDateTime(); + // Zeiger auf Datum/Uhrzeit holen + + void startTimeMeasure(); + // Zeitmessung starten + + unsigned long getTimeMeasure(); + // Zeitmesswert holen + + unsigned long getRuntime(); + // Laufzeit in Sekunden + + void hexAsc(char * dest, byte val); + // Umwandlung byte in Hex-ASCII + + // ------------------------------------------------------------------------- + // Debug-Funtionen + // ------------------------------------------------------------------------- + // + +#ifdef smnLoopCheckDebug + void dbgGetStatistics(char *buffer, int idxItem); +#endif + +}; + +//----------------------------------------------------------------------------- +#endif + diff --git a/sketches/_PIO_Sketches/Karger/SoaapBleSlave_Test_2/src/LoopCheck/ReadMe.md b/sketches/_PIO_Sketches/Karger/SoaapBleSlave_Test_2/src/LoopCheck/ReadMe.md new file mode 100644 index 0000000000000000000000000000000000000000..7701d9d3347942f8c88807f2f8342bade47ace46 --- /dev/null +++ b/sketches/_PIO_Sketches/Karger/SoaapBleSlave_Test_2/src/LoopCheck/ReadMe.md @@ -0,0 +1,20 @@ +# Tools for cyclic called procedures +Arduino Sketches are build on two basic functions. +*void setup()* is called once when the CPU is reset and programmers place their initialisation code here. +*void loop()* is called in an endless loop, i.e. a cyclic entered function. +But the cycle time is not determined, it depends on the speed of the CPU and the used resources. +Many examples for Arduino use the function *delay(milliseconds)* to organise a kind of timing. +But this function is really freezing your program for the given number of milliseconds. +Using a real timer is a good solution, but some CPUs have only less timers +and they sometimes are already used for some libraries. + +The tools presented with LoopCheck-library give You the features of (many) timers inside *loop()* +based on the Arduino-function *micros()* which is called with the macro SYSMICSEC, +defined in *LoopCheck.h*. + +You will find, that there is another file included: *environment.h*, which you can find here: +https://github.com/RobertPatzke/homeautomation/blob/developer/libraries/environment/environment.h +*environment.h* defines the IDE you are using, the CPU and specific development boards. +Code is in several parts conditional, depending on the definitions you make in *environment.h*. +You will see, that this library is not fixed to Arduino, it may be used for any environment +where cyclic called functions happen. diff --git a/sketches/_PIO_Sketches/Karger/SoaapBleSlave_Test_2/src/LoopCheck/library.json b/sketches/_PIO_Sketches/Karger/SoaapBleSlave_Test_2/src/LoopCheck/library.json new file mode 100644 index 0000000000000000000000000000000000000000..3af69246689b448266e74521f4ff1d792450456f --- /dev/null +++ b/sketches/_PIO_Sketches/Karger/SoaapBleSlave_Test_2/src/LoopCheck/library.json @@ -0,0 +1,4 @@ +{ + "name": "LoopCheck", + "version": "0.0.0+20220823165932" +} \ No newline at end of file diff --git a/sketches/_PIO_Sketches/Karger/SoaapBleSlave_Test_2/src/MidiNotes/MidiNotes.cpp b/sketches/_PIO_Sketches/Karger/SoaapBleSlave_Test_2/src/MidiNotes/MidiNotes.cpp new file mode 100644 index 0000000000000000000000000000000000000000..ec91464f7411b1f25f33b3b536faf3b8dc1e8dcd --- /dev/null +++ b/sketches/_PIO_Sketches/Karger/SoaapBleSlave_Test_2/src/MidiNotes/MidiNotes.cpp @@ -0,0 +1,405 @@ +//----------------------------------------------------------------------------- +// Thema: Social Manufacturing Network / Development Environment +// Datei: Midi.cpp +// Editor: Robert Patzke +// URI/URL: www.mfp-portal.de +//----------------------------------------------------------------------------- +// Lizenz: CC-BY-SA (wikipedia: Creative Commons) +// Datum: 27. November 2021 +// +// Der Inhalt dieser Datei sind Festlegungen für steuerbare Midi-Controller. +// +// + +#include "MidiNotes.h" + +// ---------------------------------------------------------------------------- +// Initialisierungen +// ---------------------------------------------------------------------------- +// + +void MidiNotes::begin(int inBpm, NoteDiv inRes, int inMidiCycle, IntrfBuf *inCRB) +{ + dword stdNoteMicroTick; + + crb = inCRB; // Zeiger auf Ringpuffer + midiCycle = inMidiCycle; // Zuklus der ZM in Mikrosekunden + bpm = inBpm; // Beats Per Minute (Metronom) + stdNoteMicroTick = 60000000 / bpm; // Viertelnotenlänge in Mikrosekunden + stdNoteCount = stdNoteMicroTick / inMidiCycle; // " in Zyklen der ZM + stdNoteTick = 60000 / bpm; // Viertelnotenlänge in Millisekunden + minNoteTick = stdNoteTick / inRes; // Zu erwartende kürzeste Note (ms) + + typeList[nti0].length = 8 * stdNoteCount; + setNoteType(nti0); + + typeList[nti1].length = 4 * stdNoteCount; + setNoteType(nti1); + + typeList[nti2p].length = 3 * stdNoteCount; + setNoteType(nti2p); + + typeList[nti2].length = 2 * stdNoteCount; + setNoteType(nti2); + + typeList[nti4p].length = stdNoteCount + stdNoteCount / 2; + setNoteType(nti4p); + + // Standard-Note = Viertelnote ( + typeList[nti4].length = stdNoteCount; + setNoteType(nti4); + + typeList[nti8].length = stdNoteCount / 2; + setNoteType(nti8); + + typeList[nti8p].length = stdNoteCount / 2 + stdNoteCount / 4; + setNoteType(nti8p); + + typeList[nti16].length = stdNoteCount / 4; + setNoteType(nti16); + + typeList[nti16p].length = stdNoteCount / 4 + stdNoteCount / 8; + setNoteType(nti16p); + + typeList[nti32].length = stdNoteCount / 8; + setNoteType(nti32); + + typeList[nti32p].length = stdNoteCount / 8 + stdNoteCount / 16; + setNoteType(nti32p); + + typeList[nti64].length = stdNoteCount / 16; + setNoteType(nti64); + + typeList[nti64p].length = stdNoteCount / 16 + stdNoteCount / 32; + setNoteType(nti64p); + + opMode = momIdle; + setChannel(1); + stopRun = false; + stoppedRun = false; + next(smInit); +} + + +// ---------------------------------------------------------------------------- +// Konfiguration +// ---------------------------------------------------------------------------- +// +void MidiNotes::setNoteType(NoteTypeIdx nt) +{ + NoteTypePtr typePtr; + + typePtr = &typeList[nt]; + typePtr->attack = 0; + typePtr->decay = 0; + typePtr->sustain = typePtr->length; + typePtr->release = 0; + typePtr->pause = (typePtr->length * 20) / 100; + + typePtr->deltaAttack = 0; + typePtr->deltaDecay = 0; + typePtr->percentSustain = 70; + typePtr->deltaRelease = 0; +} + + +void MidiNotes::setNoteType(NoteTypeIdx nt, byte pAttL, byte pDecL, byte pSusL, byte pRelL, + byte pPauL, byte dAtt, byte dDec, byte pSusV, byte dRel) +{ + NoteTypePtr typePtr; + + typePtr = &typeList[nt]; + typePtr->attack = (typePtr->length * pAttL) / 100; + typePtr->decay = (typePtr->length * pDecL) / 100; + typePtr->sustain = (typePtr->length * pSusL) / 100; + typePtr->release = (typePtr->length * pRelL) / 100; + typePtr->pause = (typePtr->length * pPauL) / 100; + + typePtr->deltaAttack = dAtt; + typePtr->deltaDecay = dDec; + typePtr->percentSustain = pSusV; + typePtr->deltaRelease = dRel; +} + +int MidiNotes::addChordNote(NoteTypeIdx nti, byte val, byte vel) +{ + NotePtr notePtr; + int i; + + for(i = 0; i < MaxNrNoteSim; i++) + { + notePtr = &chord[i]; + if(notePtr->mode == NoteModeEmpty) + { + notePtr->mode = NoteModeRun; + notePtr->typeIdx = nti; + notePtr->value = val; + notePtr->veloc = vel; + break; + } + } + return(i); +} + +void MidiNotes::setChannel(int chnVal) +{ + if(chnVal < 1) chnVal = 1; + if(chnVal > 16) chnVal = 16; + chn = chnVal - 1; +} + +// ---------------------------------------------------------------------------- +// Betrieb +// ---------------------------------------------------------------------------- +// +void MidiNotes::setOpMode(MidiOpMode mom) +{ + opMode = mom; +} + + +void MidiNotes::setChordNote(int idx, NoteTypeIdx nti, int val, int vel) +{ + if(idx < 0) return; + if(idx >= MaxNrNoteSim) return; + + if(nti >= 0 && nti < ntiNr) + newNote[idx].typeIdx = nti; + + if(val >= 0 && val <= 127) + newNote[idx].value = val; + + if(vel >= 0 && vel <= 127) + newNote[idx].veloc = vel; + + newNote[idx].newVal = true; +} + + +// ---------------------------------------------------------------------------- +// Steuerung, Zustandsmaschine +// ---------------------------------------------------------------------------- +// + +void MidiNotes::stop() +{ + stopRun = true; +} + +void MidiNotes::resume() +{ + stopRun = false; + stoppedRun = false; +} + +void MidiNotes::run() +{ + runCounter++; + if(cycleCnt > 0) cycleCnt--; + + if(nextState != NULL) + (this->*nextState)(); +} + +void MidiNotes::smInit() +{ + next(smIdle); +} + +void MidiNotes::smIdle() +{ + switch(opMode) + { + case momIdle: + break; + + case momSequence: + next(smNoteOn); + break; + + case momRunDelta: + break; + } +} + +void MidiNotes::smNoteOn() +{ + int i, j, tIdx; + bool doAttack; + dword attack, sustain; + + if(stopRun || stoppedRun) // Unterbrechen/Stoppen des Ablaufs + { // vor dem Einschalten einer Note + stoppedRun = true; + return; + } + + if(crb == NULL) // Ohne Ausgabepuffer in Wartezustand + { + next(smIdle); + return; + } + + doAttack = false; // Voreinstellung kein Aufklingen + + // Auslesen der Noten aus dem Akkordspeicher + // + j = 0; + for(i = 0; i < MaxNrNoteSim; i++) + { + notePtr = &chord[i]; + + if(i == 0) // erste Note + { + if(notePtr->mode == NoteModeEmpty) // Wenn die erste Note leer ist + { // dann in den Wartezustand + next(smIdle); + return; + } + noteSeq[j++] = 0x90 | chn; // ansonsten startet die Notenfolge ** + } + else // weitere Noten + { + if(notePtr->mode == NoteModeEmpty) // bei leerer Note Schleife beendet + break; + } + + // Die Noten im Akkordspeicher können durch aktuelle Noten + // ersetzt werden. + + if(newNote[i].newVal) // wenn neue Note vorliegt + { + newNote[i].newVal = false; // neue Note quittieren + notePtr->typeIdx = newNote[i].typeIdx; // und Inhalte im + notePtr->value = newNote[i].value; // Akkordspeicher + notePtr->veloc = newNote[i].veloc; // überschreiben + } + + noteSeq[j++] = notePtr->value; // Notenwert in Sequenz eintragen ** + + // Daten für die Note aus der Typenliste holen + // + tIdx = notePtr->typeIdx; + typePtr = &typeList[tIdx]; + notePtr->cntAttack = typePtr->attack; // Aufklingzeit in Zähler + notePtr->cntDecay = typePtr->decay; // Abklingzeit in Zähler + notePtr->cntSustain = typePtr->sustain; // Klingzeit in Zähler + notePtr->cntRelease = typePtr->release; // Ausklingzeit in Zähler + notePtr->cntPause = typePtr->pause; // Pausenzeit in Zähler + + if(notePtr->cntAttack != 0) // Wenn ein Attack-Wert gegeben ist + { + doAttack = true; // dann attack markieren + attack = // und den Wert auf den erste Schritt setzen + (typePtr->deltaAttack * notePtr->veloc) / 100; + if(attack > 127) attack = 127; + noteSeq[j++] = attack; // Lautstärke in Sequenz eintragen ** + } + else // ohne Attack-Wert geht es hier gleich in Sustain weiter + { + sustain = (typePtr->percentSustain * notePtr->veloc) / 100; + if(sustain > 127) sustain = 127; + noteSeq[j++] = sustain; // Lautstärke in Sequenz eintragen ** + } + } + + crb->putSeq(noteSeq, j); // Sequenz an Puffer übergeben ***** + + if(doAttack) + next(smAttack); + else + next(smSustain); +} + +void MidiNotes::smAttack() +{ + +} + +void MidiNotes::smDecay() +{ + +} + +// TODO +// Es können noch nicht Noten unterschiedlicher Länge in einem Akkord +// verarbeitet werden. Bei mehreren eingetragenen Noten würde die +// kürzeste Note den Ablauf bestimmen. + +void MidiNotes::smSustain() +{ + int i; + bool sustFin; + + sustFin = false; + for(i = 0; i < MaxNrNoteSim; i++) + { + notePtr = &chord[i]; + if(notePtr->mode == NoteModeEmpty) + break; + + if(notePtr->cntSustain > 0) // Die Sustain-Zeit in diesem Zustand verweilen + notePtr->cntSustain--; + else + sustFin = true; + } + + if(sustFin) + next(smNoteOff); +} + +void MidiNotes::smRelease() +{ + +} + +void MidiNotes::smNoteOff() +{ + int i,j; + + j = 0; + for(i = 0; i < MaxNrNoteSim; i++) // Alle Noten im Akkord bearbeiten + { + notePtr = &chord[i]; + if(notePtr->mode == NoteModeEmpty) + break; + + if(i == 0) + { + noteSeq[j++] = 0x80 | chn; // Erste Note bestimmt den Befehl AUS ** + absPause = notePtr->cntPause; + } + + noteSeq[j++] = notePtr->value; //Erste und weitere Noten liefern Liste ** + noteSeq[j++] = 0; + } + + crb->putSeq(noteSeq, j); // Sequenz an Puffer übergeben ***** + + next(smPause); +} + +void MidiNotes::smPause() +{ + if(absPause > 0) + { + absPause--; + return; + } + + next(smNoteOn); +} + +// ---------------------------------------------------------------------------- +// Debugging +// ---------------------------------------------------------------------------- +// + + + + + + + + + diff --git a/sketches/_PIO_Sketches/Karger/SoaapBleSlave_Test_2/src/MidiNotes/MidiNotes.h b/sketches/_PIO_Sketches/Karger/SoaapBleSlave_Test_2/src/MidiNotes/MidiNotes.h new file mode 100644 index 0000000000000000000000000000000000000000..0f09fccd7d1a19c3c9171b0cf96c8320f5ad0b44 --- /dev/null +++ b/sketches/_PIO_Sketches/Karger/SoaapBleSlave_Test_2/src/MidiNotes/MidiNotes.h @@ -0,0 +1,226 @@ +//----------------------------------------------------------------------------- +// Thema: Social Manufacturing Network / Development Environment +// Datei: MidiNotes.h +// Editor: Robert Patzke +// URI/URL: www.mfp-portal.de +//----------------------------------------------------------------------------- +// Lizenz: CC-BY-SA (wikipedia: Creative Commons) +// Datum: 27. November 2021 +// +// Der Inhalt dieser Datei sind Festlegungen für steuerbare Midi-Controller +// + +#ifndef MidiNotes_h +#define MidiNotes_h +// ---------------------------------------------------------------------------- + +#include "arduinoDefs.h" +#include "ComRingBuf.h" + +#define MaxNrNoteSim 4 +#define MaxMidiSeq (2 * MaxNrNoteSim + 1) + +// Definierte Noten +// +#define SchlossC 60 +#define Kammerton 69 + +typedef enum _NoteDiv +{ + nd4 = 1, + nd8 = 2, + nd16 = 4, + nd32 = 8, + nd64 = 16 +} NoteDiv; + +typedef enum _MidiOpMode +{ + momIdle, + momSequence, + momRunDelta +} MidiOpMode; + + +// ---------------------------------------------------------------------------- +// M i d i N o t e s +// ---------------------------------------------------------------------------- +// +class MidiNotes +{ +#define next(x) nextState = &MidiNotes::x + +public: + // ------------------------------------------------------------------------- + // Öffentliche Datentypen + // ------------------------------------------------------------------------- + // + typedef enum _NoteTypeIdx + { + nti0 = 0, + nti1, + nti2p, + nti2, + nti4p, + nti4, + nti8p, + nti8, + nti16p, + nti16, + nti32p, + nti32, + nti64p, + nti64, + ntiNr + } NoteTypeIdx; + + +private: + // ------------------------------------------------------------------------- + // Private Datentypen + // ------------------------------------------------------------------------- + // + typedef void (MidiNotes::*cbVector)(void); + + typedef struct _NoteType + { + dword length; + dword attack; + dword decay; + dword sustain; + dword release; + dword pause; + byte deltaAttack; + byte deltaDecay; + byte percentSustain; + byte deltaRelease; + } NoteType, *NoteTypePtr; + + typedef struct _Note + { + byte mode; + byte typeIdx; + byte value; + byte veloc; + int state; + dword cntAttack; + dword cntDecay; + dword cntSustain; + dword cntRelease; + dword cntPause; + } Note, *NotePtr; + + typedef struct _NewNote + { + bool newVal; + byte typeIdx; + byte value; + byte veloc; + }NewNote; + +#define NoteModeEmpty 0x00 +#define NoteModeRun 0x01 +#define NoteModeDoChange 0x02 + + // -------------------------------------------------------------------------- + // Lokale Daten + // -------------------------------------------------------------------------- + // + IntrfBuf *crb; + cbVector nextState; + + MidiOpMode opMode; + + dword runCounter; + dword cycleCnt; + + dword midiCycle; // Zustandstakt in Mikrosekunden + dword minNoteTick; // minimale Notendauer in Millisekunden + dword bpm; // Beats per Minute (Metronom) + dword stdNoteTick; // Dauer einer Viertelnote in Millisekunden + dword stdNoteCount; // Viertelnote in Zyklen der Zustandsmaschine + + Note chord[MaxNrNoteSim]; // Liste der simultanen Noten (Akkord) + NoteType typeList[ntiNr]; // Liste der Notentypen + byte chn; // Aktueller Kanal + byte noteSeq[MaxMidiSeq]; // Lokaler Telegrammaufbau + + NotePtr notePtr; // Temporäre Notendaten + NoteTypePtr typePtr; // Temporärer Notentyp + + dword absPause; // Pause für den zyklischen Ablauf + NewNote newNote[MaxNrNoteSim]; // Übergabe neuer Noten + + bool stopRun; // Anhalten der Midi-Schleife + bool stoppedRun; // Midi-Schleife angehalten + + + // -------------------------------------------------------------------------- + // Lokale Funktionen + // -------------------------------------------------------------------------- + // + + // Zustandsmaschine + // ----------------------------- + void smInit(); + void smIdle(); + + void smNoteOn(); + void smAttack(); + void smDecay(); + void smSustain(); + void smRelease(); + void smNoteOff(); + void smPause(); + + + // -------------------------------------------------------------------------- + // Inline-Funktionen + // -------------------------------------------------------------------------- + // + +public: + // -------------------------------------------------------------------------- + // Initialisierungen + // -------------------------------------------------------------------------- + void begin(int inBpm, NoteDiv inRes, int inMidiCycle, IntrfBuf *inCRB); + + + // -------------------------------------------------------------------------- + // Konfiguration + // -------------------------------------------------------------------------- + // + void setNoteType(NoteTypeIdx nt); + + void setNoteType(NoteTypeIdx nt, byte pAttL, byte pDecL, byte pSusL, byte pRelL, + byte dAtt, byte dDec, byte pSusV, byte dRel, byte pPauL); + + int addChordNote(NoteTypeIdx nti, byte val, byte vel); + + void setChannel(int chnVal); + + // -------------------------------------------------------------------------- + // Betrieb + // -------------------------------------------------------------------------- + // + void setOpMode(MidiOpMode mom); + void setChordNote(int idx, NoteTypeIdx nti, int val, int vel); + + // -------------------------------------------------------------------------- + // Steuerung, Zustandsmaschine + // -------------------------------------------------------------------------- + // + void run(); + void stop(); + void resume(); + + // -------------------------------------------------------------------------- + // Debugging + // -------------------------------------------------------------------------- + // + +}; + + +// ---------------------------------------------------------------------------- +#endif // MidiNotes_h diff --git a/sketches/_PIO_Sketches/Karger/SoaapBleSlave_Test_2/src/MidiNotes/library.json b/sketches/_PIO_Sketches/Karger/SoaapBleSlave_Test_2/src/MidiNotes/library.json new file mode 100644 index 0000000000000000000000000000000000000000..a95d68926746af5b6e20d30d2a29ea5b513110ad --- /dev/null +++ b/sketches/_PIO_Sketches/Karger/SoaapBleSlave_Test_2/src/MidiNotes/library.json @@ -0,0 +1,4 @@ +{ + "name": "MidiNotes", + "version": "0.0.0+20220823165932" +} \ No newline at end of file diff --git a/sketches/_PIO_Sketches/Karger/SoaapBleSlave_Test_2/src/Monitor/Monitor.cpp b/sketches/_PIO_Sketches/Karger/SoaapBleSlave_Test_2/src/Monitor/Monitor.cpp new file mode 100644 index 0000000000000000000000000000000000000000..9c30d24b20011e8d22623c261a295ccfb42fe1ea --- /dev/null +++ b/sketches/_PIO_Sketches/Karger/SoaapBleSlave_Test_2/src/Monitor/Monitor.cpp @@ -0,0 +1,1165 @@ +//----------------------------------------------------------------------------- +// Thema: Social Manufacturing Network / Development Environment +// Datei: Monitor.cpp +// Editor: Robert Patzke +// URI/URL: www.mfp-portal.de +//----------------------------------------------------------------------------- +// Lizenz: CC-BY-SA (wikipedia: Creative Commons) +// Datum: 15. Mai 2021 +// +// Der Monitor dient zum direkten Zugriff auf die Ressourcen eines +// Mikrocontrollers über die serielle Schnittstelle. +// ACHTUNG! +// Er ist nicht für die Anwendung des "Serial Monitor" aus der Arduino-IDE +// bzw. aus Eclipse/Sloeber gedacht, sondern für ein typisches "Terminal". +// Verwendet wurde bei der Entwicklung unter Linux das GtkTerm. +// + +#include "Monitor.h" + +//----------------------------------------------------------------------------- +// Initialisierungen +//----------------------------------------------------------------------------- + +void Monitor::init(int inMode, int inCpu, LoopCheck *inLcPtr, IntrfTw *inTwPtr) +{ + mode = inMode; + cpu = inCpu; + wrIdx = 0; + rdIdx = 0; + blkOut = false; + blkIn = false; + inIdx = 0; + info = NULL; + readOffsAddr = 0; + doReadReg = false; + extraIn = false; + lcPtr = inLcPtr; + twiPtr = inTwPtr; + nrOfChnChar = '@'; + +#ifdef smnNANOBLE33 + + microTicValPtr = (dword *) 0x40009548; + microTicCapPtr = (dword *) 0x40009048; + +#endif + + nextState = + &Monitor::waitEnter; +} + + +Monitor::Monitor(int inMode, int inCpu) +{ + init(inMode, inCpu, NULL, NULL); +} + +Monitor::Monitor(int inMode, int inCpu, LoopCheck *inLcPtr) +{ + init(inMode, inCpu, inLcPtr, NULL); +} + +Monitor::Monitor(int inMode, int inCpu, LoopCheck *inLcPtr, IntrfTw *inTwiPtr) +{ + init(inMode, inCpu, inLcPtr, inTwiPtr); +} + +//----------------------------------------------------------------------------- +// Konfiguration, Hilfsfunktionen +//----------------------------------------------------------------------------- +// +int Monitor::putBuf(char c) +{ + if(blkIn) return(-1); + + int free = rdIdx - wrIdx - 1; + if(free < 0) free += BufSize; + if(free < 1) return(0); + buffer[wrIdx++] = c; + if(wrIdx == BufSize) + wrIdx = 0; + return(1); +} + +int Monitor::putBuf(char *txt) +{ + if(blkIn) return(-1); + + int free = rdIdx - wrIdx - 1; + int size = strlen(txt); + if(free < 0) free += BufSize; + if(free < size) return(0); + for(int i = 0; i < size; i++) + { + buffer[wrIdx++] = txt[i]; + if(wrIdx == BufSize) + wrIdx = 0; + } + return(size); +} + +char Monitor::getBuf() +{ + int num = wrIdx - rdIdx; + if(num == 0) return('\0'); + char c = buffer[rdIdx++]; + if(rdIdx == BufSize) + rdIdx = 0; + return(c); +} + +void Monitor::clrBuf() +{ + wrIdx = 0; + rdIdx = 0; +} + +void Monitor::sendConfig() +{ + int nrChn = nrOfChnChar & 0x3F; + int bufIdx = 0; + CfgMeasChnPtr cfgPtr; + + // Visualisierungskanäle (Anzahl) anfordern + outChar[bufIdx++] = '&'; + outChar[bufIdx++] = '@'; // Kanalnummer + outChar[bufIdx++] = '@'; // Typ + outChar[bufIdx++] = nrOfChnChar; + outChar[bufIdx++] = '$'; + + for(int i = 0; i < nrChn; i++) + { + cfgPtr = &cfgChnArr[i]; + outChar[bufIdx++] = '&'; + outChar[bufIdx++] = (i+1) | 0x40; + outChar[bufIdx++] = cfgPtr->type; + hexWord(&outChar[bufIdx], cfgPtr->maxVal); + bufIdx += 4; + hexWord(&outChar[bufIdx], cfgPtr->minVal); + bufIdx += 4; + if(cfgPtr->name != NULL) + { + bufIdx += cpyStr(&outChar[bufIdx], cfgPtr->name); + } + outChar[bufIdx++] = '$'; + } + outChar[bufIdx] = '\0'; + out(outChar); +} + +//----------------------------------------------------------------------------- +// Lokale Abläufe +//----------------------------------------------------------------------------- +// + +volatile dword calcTest1, calcTest2, calcTest3; + +void Monitor::waitEnter() +{ + char c; + + busy = false; + + if(!keyHit()) return; + c = keyIn(); + if(c != '\r' && c != '\n') + { + lastKeyIn = c; + return; + } + + busy = true; + + blkIn = true; + blkOut = true; + GoPrm +} + +void doSomeCode() +{ + for(int i = 0; i < 500; i++) + { + calcTest1++; + calcTest1++; + calcTest1++; + calcTest1++; + calcTest1++; + calcTest1++; + calcTest1++; + calcTest1++; + calcTest1++; + calcTest1++; + calcTest1++; + calcTest1++; + calcTest1++; + calcTest1++; + calcTest1++; + calcTest1++; + calcTest1++; + calcTest1++; + calcTest1++; + calcTest1++; + } +} + +volatile dword micTime; + +void Monitor::getKey() +{ + char cin,c1,c0; + + if(!keyHit()) return; + cin = keyIn(); + if(mode & modeEcho) + out(cin); + + c0 = c1 = '\0'; + + if(inIdx == 0) + c0 = cin; + else if(inIdx == 1) + { + c0 = inChar[0]; + c1 = cin; + } + else if(inIdx == 2) + { + c0 = inChar[0]; + c1 = inChar[1]; + } + + switch(c0) + { + case '\r': + out("\r\n"); + blkIn = false; + blkOut = false; + GoWt + break; + + case 'c': + case 'C': + if(inIdx == 0) + { + inChar[inIdx] = cin; + inIdx++; + } + else if(inIdx == 1) + { + + if(cin >= '0' && cin <= '9') + { + inIdx = 0; + out('='); + int cIdx = cin - 0x30; + if(cFlag[cIdx]) + { + cFlag[cIdx] = false; + out('0'); + } + else + { + cFlag[cIdx] = true; + out('1'); + } + GoPrm + } + + else if(cin == 'f' || cin == 'F') + { + inChar[inIdx] = cin; + inIdx++; + } + } + + else if(inIdx == 2) + { + inIdx = 0; + if(cin == 'g' || cin == 'G') + { + sendConfig(); + GoPrm + } + } + else + GoPrm + break; + + case 'i': + case 'I': + if(inIdx == 0) + { + inChar[inIdx] = cin; + inIdx++; + } + else if(inIdx == 1) + { + inIdx = 0; + out(' '); + if(cin == 'a' || cin == 'A') + nextState = &Monitor::getTwiAdr; + else if(cin == 'l' || cin == 'L') + nextState = &Monitor::readTwiList; + else if(cin == 'r' || cin == 'R') + nextState = &Monitor::readTwiByte; + else if(cin == 'w' || cin == 'W') + nextState = &Monitor::writeTwiByte; + } + break; + + case 'r': + case 'R': + if(inIdx == 0) + { + inChar[inIdx] = cin; + inIdx++; + } + else if(inIdx == 1) + { + inIdx = 0; + out(' '); + if(cin == 'o' || cin == 'O') + nextState = &Monitor::getRdOffsAdr; + else if(cin == 'r' || cin == 'R') + nextState = &Monitor::readRegVal; + } + break; + + // ------------------------------------------------------------------------ + case 't': // Zeitmessungen + case 'T': // + // ------------------------------------------------------------------------ + if(inIdx == 0) + { + inChar[inIdx] = cin; + inIdx++; + } + else if(inIdx == 1) + { + inIdx = 0; + nextState = &Monitor::getTiming; + if(cin == 'l' || cin == 'L') + { + cmdMode1 = 'L'; + } + else if(cin == 'b' || cin == 'B') + { + cmdMode1 = 'B'; + } + else if(cin == 'c' || cin == 'C') + { + cmdMode1 = 'C'; + } +#ifdef smnNANOBLE33 + else if(cin == 'p' || cin == 'P') + { + micTime = micsecs(); + doSomeCode(); + micTime = (micsecs() - micTime - 11) / 10; + out(' '); + out(micTime); + GoPrm + } +#endif + else if(cin == 'r' || cin == 'R') + { + if(lcPtr != NULL) + { + lcPtr->resetStatistics(); + out(' '); + } + GoPrm + } + else if(cin == 't' || cin == 'T') + { + dword micTime = micros(); + calcTest2 = micros(); + calcTest2 = micros(); + calcTest2 = micros(); + calcTest2 = micros(); + calcTest2 = micros(); + calcTest2 = micros(); + calcTest2 = micros(); + calcTest2 = micros(); + calcTest2 = micros(); + calcTest2 = micros(); + calcTest2 = micros(); + calcTest2 = micros(); + calcTest2 = micros(); + calcTest2 = micros(); + calcTest2 = micros(); + calcTest2 = micros(); + calcTest2 = micros(); + calcTest2 = micros(); + calcTest2 = micros(); + micTime = (micros() - micTime) / 20; + out(' '); + out(micTime); + GoPrm + } + else + { + GoPrm + } + } + break; + + case 'V': + case 'v': + out(' '); + nextState = &Monitor::version; + break; + + } +} + +void Monitor::prompt() +{ + if(mode & modeNl) + out('\n'); + + out("\rM>"); + GoInp +} + +void Monitor::version() +{ + out("Monitor: Version 0.1, May 16, 2021"); + GoPrm +} + +void Monitor::getRdOffsAdr() +{ + char cin; + dword val; + int valIdx; + + if(!keyHit()) return; + cin = keyIn(); + readOffsAddr = 0; + + if(cin != '\r') + { + if(cin >= '0' && cin <= '9') + inChar[inIdx] = cin - 0x30; + else if(cin >= 'A' && cin <= 'F') + inChar[inIdx] = cin - 0x37; + else if(cin >= 'a' && cin <= 'f') + inChar[inIdx] = cin - 0x57; + else + return; + + out(cin); + if(inIdx < 16) + inIdx++; + else + out((char) 0x08); + } + else + { + valIdx = 0; + inIdx--; + while(inIdx >= 0) + { + val = inChar[inIdx]; + readOffsAddr |= val << valIdx * 4; + inIdx--; + valIdx++; + } + + // TEST + //out(" = "); + //out(readOffsAddr); + inIdx = 0; + GoPrm + } +} + +void Monitor::readRegVal() +{ + char cin; + dword val,adr; + int valIdx; + + dword *regPtr; + + if(!keyHit()) return; + cin = keyIn(); + adr = 0; + + if(cin != '\r') + { + if(cin >= '0' && cin <= '9') + inChar[inIdx] = cin - 0x30; + else if(cin >= 'A' && cin <= 'F') + inChar[inIdx] = cin - 0x37; + else if(cin >= 'a' && cin <= 'f') + inChar[inIdx] = cin - 0x57; + else + return; + + out(cin); + if(inIdx < 16) + inIdx++; + else + out((char) 0x08); + } + else + { + valIdx = 0; + inIdx--; + while(inIdx >= 0) + { + val = inChar[inIdx]; + adr |= val << valIdx * 4; + inIdx--; + valIdx++; + } + + regPtr = (dword *) (readOffsAddr + adr); + val = *regPtr; + + out(": "); + hexDword(outChar, val); + out(outChar); + inIdx = 0; + GoPrm + } +} + +void Monitor::getTiming() +{ + LoopStatistics lStat; + unsigned int maxVal; + unsigned int minVal; + unsigned int avgVal; + char cin; + + if(lcPtr == NULL) + { + outl("Kein LoopCheck."); + GoPrm + return; + } + + if(!keyHit()) return; + cin = keyIn(); + if(mode & modeEcho) + out(cin); + + if(cin == 'r' || cin == 'R') + { + out(' '); + lcPtr->getStatistics(&lStat); + if(cmdMode1 == 'L') + { + maxVal = lStat.loopMaxTime; + minVal = lStat.loopMinTime; + avgVal = lStat.loopAvgTime; + } + else if(cmdMode1 == 'B') + { + maxVal = lStat.bgMaxTime; + minVal = lStat.bgMinTime; + avgVal = lStat.bgAvgTime; + } + else if(cmdMode1 == 'C') + { + maxVal = lStat.maxPeriod; + minVal = lStat.minPeriod; + avgVal = lStat.avgPeriod; + } + else + { + maxVal = 0; + minVal = 0; + avgVal = 0; + } + + out(maxVal); out("/"); out(minVal); out("/"); out(avgVal); out("\r"); + GoPrm + } + else if(cin == 'm' || cin == 'M') + { + lcPtr->resetStatistics(); + lcPtr->startTimeMeasure(); + nextState = &Monitor::getLoopMeasure; + } + +} + +void Monitor::getLoopMeasure() +{ + LoopStatistics lStat; + unsigned int maxVal; + unsigned int minVal; + unsigned int avgVal; + + if(lcPtr->getTimeMeasure() < 1000000) + return; + + out(' '); + lcPtr->getStatistics(&lStat); + if(cmdMode1 == 'L') + { + maxVal = lStat.loopMaxTime; + minVal = lStat.loopMinTime; + avgVal = lStat.loopAvgTime; + } + else if(cmdMode1 == 'B') + { + maxVal = lStat.bgMaxTime; + minVal = lStat.bgMinTime; + avgVal = lStat.bgAvgTime; + } + else if(cmdMode1 == 'C') + { + maxVal = lStat.maxPeriod; + minVal = lStat.minPeriod; + avgVal = lStat.avgPeriod; + } + else + { + maxVal = 0; + minVal = 0; + avgVal = 0; + } + + out(maxVal); out("/"); out(minVal); out("/"); out(avgVal); out("\r"); + GoPrm +} + + +void Monitor::getTwiAdr() +{ + char cin; + + if(!keyHit()) return; + cin = keyIn(); + twiAdr = 0; + + if(cin != '\r') + { + if(cin >= '0' && cin <= '9') + inChar[inIdx] = cin - 0x30; + else if(cin >= 'A' && cin <= 'F') + inChar[inIdx] = cin - 0x37; + else if(cin >= 'a' && cin <= 'f') + inChar[inIdx] = cin - 0x57; + else + return; + + out(cin); + if(inIdx < 2) + inIdx++; + else + out((char) 0x08); + } + else + { + twiAdr = (inChar[0] << 4) | inChar[1]; + + out(" = "); + out(twiAdr); + + inIdx = 0; + GoPrm + } +} + +void Monitor::readTwiList() +{ + char cin; + int reg; + int anz; + + char tmpOut[3]; + + TwiStatus twiStatus; + + if(twiPtr == NULL) + { + out("no Twi"); + inIdx = 0; + GoPrm + } + + if(!keyHit()) return; + cin = keyIn(); + + if(cin != '\r') + { + if(cin >= '0' && cin <= '9') + inChar[inIdx] = cin - 0x30; + else if(cin >= 'A' && cin <= 'F') + inChar[inIdx] = cin - 0x37; + else if(cin >= 'a' && cin <= 'f') + inChar[inIdx] = cin - 0x57; + else + return; + + out(cin); + if(inIdx == 1) + out(" "); + + if(inIdx < 4) + inIdx++; + else + out((char) 0x08); + } + else + { + reg = (inChar[0] << 4) | inChar[1]; + anz = (inChar[2] << 4) | inChar[3]; + + twiByteSeq.len = anz; + twiByteSeq.valueRef = byteArray; + + twiStatus = twiPtr->readByteRegSeq(twiAdr, reg, &twiByteSeq); + + out(" ["); + out((int) twiStatus); + out("] "); + + if((int) twiStatus == 128) + { + for(int i = 0; i < anz; i++) + { + hexByte(tmpOut, byteArray[i]); + out(tmpOut); + if(i != (anz-1)) out(':'); + } + } + + inIdx = 0; + GoPrm + } +} + +void Monitor::readTwiByte() +{ + char cin; + int reg; + byte val; + + if(twiPtr == NULL) + { + out("no Twi"); + inIdx = 0; + GoPrm + } + + if(!keyHit()) return; + cin = keyIn(); + + if(cin != '\r') + { + if(cin >= '0' && cin <= '9') + inChar[inIdx] = cin - 0x30; + else if(cin >= 'A' && cin <= 'F') + inChar[inIdx] = cin - 0x37; + else if(cin >= 'a' && cin <= 'f') + inChar[inIdx] = cin - 0x57; + else + return; + + out(cin); + if(inIdx < 2) + inIdx++; + else + out((char) 0x08); + } + else + { + reg = (inChar[0] << 4) | inChar[1]; + + val = twiPtr->readByteReg(twiAdr, reg); + + out(" = "); + binByte(outChar, val); + out(outChar); + + inIdx = 0; + GoPrm + } +} + +void Monitor::writeTwiByte() +{ + char cin; + int reg; + int val; + + TwiStatus twiStatus; + + if(twiPtr == NULL) + { + out("no Twi"); + inIdx = 0; + GoPrm + } + + if(!keyHit()) return; + cin = keyIn(); + + if(cin != '\r') + { + if(cin >= '0' && cin <= '9') + inChar[inIdx] = cin - 0x30; + else if(cin >= 'A' && cin <= 'F') + inChar[inIdx] = cin - 0x37; + else if(cin >= 'a' && cin <= 'f') + inChar[inIdx] = cin - 0x57; + else + return; + + out(cin); + if(inIdx == 1) + out(" "); + + if(inIdx < 4) + inIdx++; + else + out((char) 0x08); + } + else + { + reg = (inChar[0] << 4) | inChar[1]; + val = (inChar[2] << 4) | inChar[3]; + + twiStatus = twiPtr->writeByteReg(twiAdr, reg, val); + + out(" : "); + out((int) twiStatus); + + inIdx = 0; + GoPrm + } +} + +//----------------------------------------------------------------------------- +// Lokale Schnittstelle +//----------------------------------------------------------------------------- +// +void Monitor::print(char c, int eol) +{ + putBuf(c); + if(eol & eolCR) + putBuf('\r'); + if(eol & eolLF) + putBuf('\n'); +} + +void Monitor::print(char *txt, int eol) +{ + if(txt != NULL) + putBuf(txt); + if(eol & eolCR) + putBuf('\r'); + if(eol & eolLF) + putBuf('\n'); +} + +void Monitor::print(byte *hex, int nr, char fill, int eol) +{ + if(hex == NULL) return; + + for(int i = 0; i < nr; i++) + { + hexByte(tmpChar,hex[i]); + tmpChar[2] = fill; + tmpChar[3] = '\0'; + putBuf(tmpChar); + } + + if(eol & eolCR) + putBuf('\r'); + if(eol & eolLF) + putBuf('\n'); +} + +void Monitor::print(unsigned int iVal, int eol) +{ + char iBuf[16]; + + itoa(iVal, iBuf, 10); + putBuf(iBuf); + if(eol & eolCR) + putBuf('\r'); + if(eol & eolLF) + putBuf('\n'); +} + +void Monitor::prints(int iVal, int eol) +{ + char iBuf[16]; + + itoa(iVal, iBuf, 10); + putBuf(iBuf); + if(eol & eolCR) + putBuf('\r'); + if(eol & eolLF) + putBuf('\n'); +} + +//----------------------------------------------------------------------------- +// Datenaufbereitung +//----------------------------------------------------------------------------- +// +void Monitor::hexByte(char * dest, byte val) +{ + char cv; + + cv = val >> 4; + if(cv < 10) + cv += 0x30; + else + cv += 0x37; + dest[0] = cv; + + cv = val & 0x0F; + if(cv < 10) + cv += 0x30; + else + cv += 0x37; + dest[1] = cv; + + dest[2] = '\0'; +} + +void Monitor::binByte(char * dest, byte val) +{ + byte mask; + + mask = 0x80; + + for(int i = 0; i < 8; i++) + { + if((val & mask) != 0) + dest[i] = '1'; + else + dest[i] = '0'; + mask >>= 1; + } + + dest[8] = '\0'; +} + +int Monitor::cpyStr(char *dest, char *src) +{ + int i = 0; + + while((dest[i] = src[i]) != '\0') i++; + return(i); +} + +void Monitor::binDword(char *dest, dword dwVal) +{ + int idx = 0; + byte bVal; + + bVal = dwVal >> 24; + binByte(&dest[idx], bVal); + idx += 8; + dest[idx++] = ' '; + + bVal = dwVal >> 16; + binByte(&dest[idx], bVal); + idx += 8; + dest[idx++] = ' '; + + bVal = dwVal >> 8; + binByte(&dest[idx], bVal); + idx += 8; + dest[idx++] = ' '; + + bVal = dwVal; + binByte(&dest[idx], bVal); + idx += 8; + + dest[idx] = '\0'; +} + +void Monitor::hexDword(char *dest, dword dwVal) +{ + int idx = 0; + byte bVal; + + bVal = dwVal >> 24; + hexByte(&dest[idx], bVal); + idx += 2; + + bVal = dwVal >> 16; + hexByte(&dest[idx], bVal); + idx += 2; + + bVal = dwVal >> 8; + hexByte(&dest[idx], bVal); + idx += 2; + + bVal = dwVal; + hexByte(&dest[idx], bVal); + idx += 2; + + dest[idx] = '\0'; +} + +void Monitor::binWord(char *dest, word wVal) +{ + int idx = 0; + byte bVal; + + bVal = wVal >> 8; + binByte(&dest[idx], bVal); + idx += 8; + dest[idx++] = ' '; + + bVal = wVal; + binByte(&dest[idx], bVal); + idx += 8; + + dest[idx] = '\0'; +} + +void Monitor::hexWord(char *dest, word wVal) +{ + int idx = 0; + byte bVal; + + bVal = wVal >> 8; + hexByte(&dest[idx], bVal); + idx += 2; + + bVal = wVal; + hexByte(&dest[idx], bVal); + idx += 2; + + dest[idx] = '\0'; +} + + + +//----------------------------------------------------------------------------- +// Anwenderschnittstelle +//----------------------------------------------------------------------------- +// + +void Monitor::run() +{ + char c; + + if(!blkOut) + { + c = getBuf(); + if(c != '\0') + smnSerial.print(c); + } + (this->*nextState)(); +} + +void Monitor::cprint(char c) +{ + print(c, 0); +} + +void Monitor::cprintln(char c) +{ + print(c, eolCR | eolLF); +} + +void Monitor::cprintcr(char c) +{ + print(c, eolCR); +} + +void Monitor::print(char *txt) +{ + print(txt, 0); +} + +void Monitor::println(char *txt) +{ + print(txt, eolCR | eolLF); +} + +void Monitor::println() +{ + print((char *) NULL, eolCR | eolLF); +} + +void Monitor::printcr(char *txt) +{ + print(txt, eolCR); +} + +void Monitor::printcr() +{ + print((char *) NULL, eolCR); +} + +void Monitor::print(unsigned int iVal) +{ + print(iVal, 0); +} + +void Monitor::prints(int iVal) +{ + prints(iVal, 0); +} + +void Monitor::println(unsigned int iVal) +{ + print(iVal, eolCR | eolLF); +} + +void Monitor::printcr(unsigned int iVal) +{ + print(iVal, eolCR); +} + +void Monitor::print(byte *iVal, int nr, char fill) +{ + print(iVal, nr, fill, 0); +} + +void Monitor::printcr(byte *iVal, int nr, char fill) +{ + print(iVal, nr, fill, eolCR); +} + +void Monitor::println(byte *iVal, int nr, char fill) +{ + print(iVal, nr, fill, eolCR | eolLF); +} + +void Monitor::setInfo(char *txt) +{ + info = txt; +} + +void Monitor::config(int inNrOfChn) +{ + if(inNrOfChn < 0) return; + + if(inNrOfChn > MaxChn) + inNrOfChn = MaxChn; + + nrOfChnChar = inNrOfChn | 0x40; +} + +void Monitor::config(int inChn, char inType, word inMax, word inMin, char *inName) +{ + if(inChn < 1) return; + + if(inChn > MaxChn) + inChn = MaxChn; + + CfgMeasChnPtr chnPtr = &cfgChnArr[inChn-1]; + chnPtr->maxVal = inMax; + chnPtr->minVal = inMin; + chnPtr->name = inName; + chnPtr->type = inType; +} + + diff --git a/sketches/_PIO_Sketches/Karger/SoaapBleSlave_Test_2/src/Monitor/Monitor.h b/sketches/_PIO_Sketches/Karger/SoaapBleSlave_Test_2/src/Monitor/Monitor.h new file mode 100644 index 0000000000000000000000000000000000000000..1ee2bb11830c716703e5489655355c93a039d131 --- /dev/null +++ b/sketches/_PIO_Sketches/Karger/SoaapBleSlave_Test_2/src/Monitor/Monitor.h @@ -0,0 +1,211 @@ +//----------------------------------------------------------------------------- +// Thema: Social Manufacturing Network / Development Environment +// Datei: Monitor.h +// Editor: Robert Patzke +// URI/URL: www.mfp-portal.de +//----------------------------------------------------------------------------- +// Lizenz: CC-BY-SA (wikipedia: Creative Commons) +// Datum: 15. Mai 2021 +// +// Der Monitor dient zum direkten Zugriff auf die Ressourcen eines +// Mikrocontrollers über die serielle Schnittstelle. +// + +#include "Arduino.h" +#include "environment.h" +#include "arduinoDefs.h" +#include "LoopCheck.h" +#include "IntrfTw.h" + +#ifndef Monitor_h +#define Monitor_h +// ---------------------------------------------------------------------------- + +#define keyHit() smnSerial.available() +#define keyIn() smnSerial.read() +#define out(x) smnSerial.print(x) +#define outl(x) smnSerial.println(x) +#define GoInp nextState = &Monitor::getKey; +#define GoPrm nextState = &Monitor::prompt; +#define GoWt nextState = &Monitor::waitEnter; + +#define modeEcho 0x01 +#define modeNl 0x02 + +#define eolCR 0x01 +#define eolLF 0x02 +#define eolNL 0x03 + +#define BufSize 512 +#define MaxChn 32 + +class Monitor +{ + // ------------------------------------------------------------------------- + // class specific data types + // ------------------------------------------------------------------------- + // + typedef void (Monitor::*StatePtr)(void); + typedef struct _ConfMeasChannel + { + word maxVal; + word minVal; + char *name; + char type; + } CfgMeasChn, *CfgMeasChnPtr; + +private: + // -------------------------------------------------------------------------- + // Lokale Daten + // -------------------------------------------------------------------------- + // + int cpu; + int mode; + +#ifdef smnNANOBLE33 + dword *microTicValPtr; + dword *microTicCapPtr; +#endif + + char buffer[BufSize]; + int wrIdx; + int rdIdx; + bool blkOut; + bool blkIn; + + char inChar[16]; + char outChar[128]; + char tmpChar[8]; + int inIdx; + bool extraIn; + + char cmdMode1; + char cmdMode2; + + char *info; + + StatePtr nextState; + LoopCheck *lcPtr; + + IntrfTw *twiPtr; + int twiAdr; + TwiByteSeq twiByteSeq; + byte byteArray[32]; + + dword readOffsAddr; + bool doReadReg; + + CfgMeasChn cfgChnArr[MaxChn]; + char nrOfChnChar; + + // -------------------------------------------------------------------------- + // Lokale Funktionen + // -------------------------------------------------------------------------- + // + void init(int mode, int cpu); + void init(int mode, int cpu, LoopCheck *inLcPtr); + void init(int mode, int cpu, LoopCheck *inLcPtr, IntrfTw *inTwPtr); + + void waitEnter(); + void prompt(); + void getKey(); + void version(); + void getRdOffsAdr(); + void readRegVal(); + void getTiming(); + void getLoopMeasure(); + + void getTwiAdr(); + void readTwiList(); + void readTwiByte(); + void writeTwiByte(); + + void print(char c, int eol); + void print(char *txt, int eol); + void print(byte *hex, int nr, char fill, int eol); + void print(unsigned int iVal, int eol); + void prints(int iVal, int eol); + +#ifdef smnNANOBLE33 + + dword micsecs() + { + *microTicCapPtr = 1; + return(*microTicValPtr); + } + +#endif + + // -------------------------------------------------------------------------- + // Datenaufbereitung + // -------------------------------------------------------------------------- + // + void hexByte(char *dest, byte val); + void binByte(char *dest, byte val); + void hexWord(char *dest, word val); + void binWord(char *dest, word val); + void hexDword(char *dest, dword val); + void binDword(char *dest, dword val); + int cpyStr(char *dest, char *src); + +public: + // -------------------------------------------------------------------------- + // Initialisierungen + // -------------------------------------------------------------------------- + + Monitor(int mode, int cpu); + Monitor(int mode, int cpu, LoopCheck *inLcPtr); + Monitor(int mode, int cpu, LoopCheck *inLcPtr, IntrfTw *inTwiPtr); + + // -------------------------------------------------------------------------- + // Konfiguration und Hilfsfunktionen + // -------------------------------------------------------------------------- + // + void setInfo(char *txt); + int putBuf(char c); + int putBuf(char *txt); + char getBuf(); + void clrBuf(); + void sendConfig(); + + + // -------------------------------------------------------------------------- + // Anwenderschnittstelle + // -------------------------------------------------------------------------- + // + + // Funktionen + // + void run(); + void cprint(char c); + void print(char *txt); + void print(unsigned int iVal); + void prints(int iVal); + void print(byte *iVal, int nr, char fill); + void printcr(); + void cprintcr(char c); + void printcr(char *txt); + void printcr(unsigned int iVal); + void printcr(byte *iVal, int nr, char fill); + void println(); + void cprintln(char c); + void println(char *txt); + void println(unsigned int iVal); + void println(byte *iVal, int nr, char fill); + + void config(int inNrOfChn); + void config(int inChn, char inType, word inMax, word inMin, char *inName); + + + // Zustände (Variablen) + // + bool busy; + char lastKeyIn; + + // Steuerbits (Kommandobits) + // + bool cFlag[10]; + }; + +// ---------------------------------------------------------------------------- +#endif // Monitor_h diff --git a/sketches/_PIO_Sketches/Karger/SoaapBleSlave_Test_2/src/Monitor/library.json b/sketches/_PIO_Sketches/Karger/SoaapBleSlave_Test_2/src/Monitor/library.json new file mode 100644 index 0000000000000000000000000000000000000000..a9b281138760d16aa71d51ecec1518e22188a30f --- /dev/null +++ b/sketches/_PIO_Sketches/Karger/SoaapBleSlave_Test_2/src/Monitor/library.json @@ -0,0 +1,4 @@ +{ + "name": "Monitor", + "version": "0.0.0+20220823165932" +} \ No newline at end of file diff --git a/sketches/_PIO_Sketches/Karger/SoaapBleSlave_Test_2/src/SensorLSM9DS1/SensorLSM9DS1.cpp b/sketches/_PIO_Sketches/Karger/SoaapBleSlave_Test_2/src/SensorLSM9DS1/SensorLSM9DS1.cpp new file mode 100644 index 0000000000000000000000000000000000000000..5a57198a5bb3b3c340ffa5a725f7f7c009725d9a --- /dev/null +++ b/sketches/_PIO_Sketches/Karger/SoaapBleSlave_Test_2/src/SensorLSM9DS1/SensorLSM9DS1.cpp @@ -0,0 +1,875 @@ +//----------------------------------------------------------------------------- +// Thema: Social Manufacturing Network / Development Environment +// Datei: SensorLSM9DS1.cpp +// Editor: Robert Patzke +// URI/URL: www.mfp-portal.de +//----------------------------------------------------------------------------- +// Lizenz: CC-BY-SA (wikipedia: Creative Commons) +// + +#include "SensorLSM9DS1.h" +#include <string.h> + +// ---------------------------------------------------------------------------- +// Initialisierungen +// ---------------------------------------------------------------------------- + +SensorLSM9DS1::SensorLSM9DS1(IntrfTw *refI2C, int inRunCycle) +{ + TwiParams twiParams; + + twPtr = refI2C; + runState = rsInit; + twiByteSeq.len = 12; + twiByteSeq.valueRef = byteArray; + runCycle = inRunCycle; + + fullScaleA = 4; + fullScaleG = 2000; + fullScaleM = 4; + + newValueAG = false; + newValueM = false; + + avgSetAG = 0; + avgCntAG = 0; + avgSetM = 0; + avgCntM = 0; + + errorCntAdrNakAG = 0; + errorCntDataNakAG = 0; + errorCntOverAG = 0; + + errorCntAdrNakM = 0; + errorCntDataNakM = 0; + errorCntOverM = 0; + + timeOutTwiStatus = 0; + timeOutTwiDataAG = 0; + timeOutTwiDataM = 0; + + timeOutStatusAG = 0; + toValueStatusAG = 0; + timeOutStatusM = 0; + toValueStatusM = 0; + + toCntTwiStatusAG = 0; + toCntTwiStatusM = 0; + toCntTwiDataAG = 0; + toCntTwiDataM = 0; + toCntStatusAG = 0; + toCntStatusM = 0; + + sumA.x = sumA.y = sumA.z = sumG.x = sumG.y = sumG.z = 0; + waitCnt = 2; + + refI2C->getParams(&twiParams); + switch(twiParams.speed) + { + case Twi100k: + twiCycle = 10; + break; + + case Twi250k: + twiCycle = 4; + break; + + case Twi400k: + twiCycle = 2; + break; + } + + twiStatusCycle = 40 * twiCycle; + twiDataCycleAG = 160 * twiCycle; + twiDataCycleM = 100 * twiCycle; + + enableMeasAG = false; + enableMeasM = false; + + runStateCntTotal = 0; +} + +// ---------------------------------------------------------------------------- +// Konfiguration +// ---------------------------------------------------------------------------- +// +int SensorLSM9DS1::resetAG() +{ + twPtr->writeByteReg(AG_Adr, AG_Ctrl8, 0x05); + + // Get ID + return(twPtr->readByteReg(AG_Adr, AG_Id)); +} + +int SensorLSM9DS1::resetM() +{ + twPtr->writeByteReg(M_Adr, M_Ctrl2, 0x0C); + + // Get ID + return(twPtr->readByteReg(M_Adr, M_Id)); +} + +int SensorLSM9DS1::reset() +{ + int retv; + + twPtr->writeByteReg(AG_Adr, AG_Ctrl8, 0x05); + twPtr->writeByteReg(M_Adr, M_Ctrl2, 0x0C); + + retv = twPtr->readByteReg(AG_Adr, AG_Id); + retv += twPtr->readByteReg(M_Adr, M_Id); + return(retv); +} + +void SensorLSM9DS1::setScanAG(byte scValueAG, byte scValueA, byte scValueG) +{ + twPtr->writeByteReg(AG_Adr, AG_Ctrl6, scValueAG | scValueA); + twPtr->writeByteReg(AG_Adr, AG_Ctrl1, scValueAG | scValueG); +} + +void SensorLSM9DS1::setScanM(byte scValue1, byte scValue2, byte scValue3, byte scValue4) +{ + twPtr->writeByteReg(M_Adr, M_Ctrl1, scValue1); + twPtr->writeByteReg(M_Adr, M_Ctrl2, scValue2); + twPtr->writeByteReg(M_Adr, M_Ctrl3, scValue3); + twPtr->writeByteReg(M_Adr, M_Ctrl4, scValue4); +} + +void SensorLSM9DS1::setTimeOutValues(FreqAG fAG, FreqM fM) +{ + int freqA = 1190, freqM = 40000; + int cycleA, cycleM; + + enableMeasAG = true; + + switch(fAG) + { + case FreqAG14_9: + freqA = 149; + break; + + case FreqAG59_5: + freqA = 595; + break; + + case FreqAG119: + freqA = 1190; + break; + + case FreqAG238: + freqA = 2380; + break; + + case FreqAG476: + freqA = 4760; + break; + + case FreqAG952: + freqA = 9520; + break; + + case FreqAG_OFF: + freqA = 1190; + enableMeasAG = false; + break; + } + + cycleA = (freqA * runCycle) / 10; // Zyklusfrequenz + toValueStatusAG = 1200000 / cycleA; // Mikrosekunden + 20% Verlängerung + + // Test + //toValueStatusAG += 2; + + enableMeasM = true; + + switch(fM) + { + case FreqM0_625: + freqM = 625; + break; + + case FreqM1_25: + freqM = 1250; + break; + + case FreqM2_5: + freqM = 2500; + break; + + case FreqM5: + freqM = 5000; + break; + + case FreqM10: + freqM = 10000; + break; + + case FreqM20: + freqM = 20000; + break; + + case FreqM40: + freqM = 40000; + break; + + case FreqM80: + freqM = 80000; + break; + + case FreqM_OFF: + freqM = 40000; + enableMeasM = false; + break; + } + + cycleM = (freqM * runCycle) / 1000; // Zyklusfrequenz + toValueStatusM = 1200000 / cycleM; // Mikrosekunden + 20% Verlängerung + + // Test + //toValueStatusM += 3; + +} + +void SensorLSM9DS1::begin(FreqAG freqAG, int avgAG, MaxA maxA, MaxG maxG, FreqM freqM, int avgM, MaxM maxM) +{ + setScanAG((byte) freqAG, (byte) maxA | A_LpAuto, (byte) maxG | G_LpHH); + setScanM((byte) freqM | Mxy_PmMed | M_TmpOn, (byte) maxM, M_Contin, Mz_PmMed); + + setTimeOutValues(freqAG, freqM); + + if(avgAG == 1) + { + avgSetAG = 0; + avgCntAG = 0; + } + else + { + avgSetAG = avgAG; + avgCntAG = avgAG; + } + + if(avgM == 1) + { + avgSetM = 0; + avgCntM = 0; + } + else + { + avgSetM = avgM; + avgCntM = avgM; + } + + delay(10); +} + +void SensorLSM9DS1::begin() +{ + //reset(); + + delay(10); + + setScanAG(AG_Odr119, A_Fs4g | A_LpAuto, G_Fs2000 | G_LpHH); + setScanM(M_Odr40 | Mxy_PmMed | M_TmpOn, M_Fs4G, M_Contin, Mz_PmMed); + + avgSetAG = 6; + avgCntAG = 6; + + avgSetM = 0; + avgCntM = 0; + + + delay(10); +} + +// ---------------------------------------------------------------------------- +// Steuerfunktionen, gezielte Prozessorzugriffe und Hilfsfunktionen +// ---------------------------------------------------------------------------- +// +/* +void SensorLSM9DS1::run0() +{ + switch(runState) + { + case rsInit: + runState = rsScanAGReq; + break; + + // ------------ Accel & Gyro ------------ + + case rsScanAGReq: + twPtr->recByteReg(AG_Adr, AG_Status, &twiByte); + runState = rsScanAGChk; + break; + + case rsScanAGChk: + if(twiByte.twiStatus != TwStFin) + break; + + if((twiByte.value & 0x03) == 0) + { + waitCnt = 2; + runState = rsWaitAG; + break; + } + + twiByteSeq.len = 12; + twPtr->recByteRegSeq(AG_Adr, G_Out, &twiByteSeq); + runState = rsFetchAG; + break; + + case rsWaitAG: + if(waitCnt > 0) + { + waitCnt--; + break; + } + else + { + runState = rsScanAGReq; + } + break; + + case rsFetchAG: + if(twiByte.twiStatus != TwStFin) + break; + + for(int i = 0; i < 12; i++) + tmpDataAG.byteArray[i] = byteArray[i]; + + if(avgSetAG > 0) + { + sumA.x += (int) tmpDataAG.valueAG.A.x; + sumA.y += (int) tmpDataAG.valueAG.A.y; + sumA.z += (int) tmpDataAG.valueAG.A.z; + sumG.x += (int) tmpDataAG.valueAG.G.x; + sumG.y += (int) tmpDataAG.valueAG.G.y; + sumG.z += (int) tmpDataAG.valueAG.G.z; + avgCntAG--; + + if(avgCntAG == 0) + { + rawDataAG.valueAG.A.x = short (sumA.x / avgSetAG); + rawDataAG.valueAG.A.y = short (sumA.y / avgSetAG); + rawDataAG.valueAG.A.z = short (sumA.z / avgSetAG); + rawDataAG.valueAG.G.x = short (sumG.x / avgSetAG); + rawDataAG.valueAG.G.y = short (sumG.y / avgSetAG); + rawDataAG.valueAG.G.z = short (sumG.z / avgSetAG); + + sumA.x = sumA.y = sumA.z = sumG.x = sumG.y = sumG.z = 0; + avgCntAG = avgSetAG; + + newValueAG = true; + } + } + else + { + rawDataAG.valueAG.A.x = tmpDataAG.valueAG.A.x; + rawDataAG.valueAG.A.y = tmpDataAG.valueAG.A.x; + rawDataAG.valueAG.A.z = tmpDataAG.valueAG.A.x; + rawDataAG.valueAG.G.x = tmpDataAG.valueAG.A.x; + rawDataAG.valueAG.G.y = tmpDataAG.valueAG.A.x; + rawDataAG.valueAG.G.z = tmpDataAG.valueAG.A.x; + newValueAG = true; + } + + runState = rsScanAGReq; + break; + } +} + +void SensorLSM9DS1::run1() +{ + switch(runState) + { + case rsInit: + runState = rsScanAGReq; + break; + + // ------------ Accel & Gyro ------------ + + case rsScanAGReq: + twPtr->recByteReg(AG_Adr, AG_Status, &twiByte); + runState = rsScanAGChk; + break; + + case rsScanAGChk: + if(twiByte.twiStatus != TwStFin) + break; + + if((twiByte.value & 0x03) == 0) + { + waitCnt = 2; + runState = rsWaitAG; + break; + } + + twiByteSeq.len = 12; + twPtr->recByteRegSeq(AG_Adr, G_Out, &twiByteSeq); + runState = rsFetchAG; + break; + + case rsWaitAG: + if(waitCnt > 0) + { + waitCnt--; + break; + } + else + { + runState = rsScanAGReq; + } + break; + + case rsFetchAG: + if(twiByteSeq.twiStatus != TwStFin) + break; + + for(int i = 0; i < 12; i++) + rawDataAG.byteArray[i] = byteArray[i]; + + newValueAG = true; + + runState = rsScanAGReq; + break; + } +} + +*/ + +void SensorLSM9DS1::stop() +{ + enableMeasAG = false; + enableMeasM = false; +} + +void SensorLSM9DS1::resume() +{ + enableMeasAG = true; + enableMeasM = true; +} + +void SensorLSM9DS1::run() +{ + runStateCntTotal++; + + switch(runState) + { + // ------------------------------------------------------------------------ + case rsInit: + // ------------------------------------------------------------------------ + runStateCntArray[rsInit]++; + runState = rsScanAGReq; + timeOutStatusAG = toValueStatusAG; + timeOutStatusM = toValueStatusM; + break; + + // ------------ Accel & Gyro ------------ + + // ------------------------------------------------------------------------ + case rsScanAGReq: + // ------------------------------------------------------------------------ + runStateCntArray[rsScanAGReq]++; + if(!enableMeasAG) + { + runState = rsScanMReq; + break; + } + + twPtr->recByteReg(AG_Adr, AG_Status, &twiByte); + timeOutTwiStatus = twiStatusCycle / runCycle + 1; + runState = rsScanAGChk; + break; + + // ------------------------------------------------------------------------ + case rsWaitAG: + // ------------------------------------------------------------------------ + runStateCntArray[rsWaitAG]++; + break; + + // ------------------------------------------------------------------------ + case rsScanAGChk: + // ------------------------------------------------------------------------ + runStateCntArray[rsScanAGChk]++; + if((twiByte.twiStatus != TwStFin) && ((twiByte.twiStatus & TwStError) == 0)) + { + if(timeOutTwiStatus > 0) + timeOutTwiStatus--; + else + { + toCntTwiStatusAG++; + runState = rsScanAGReq; + } + break; + } + + if((twiByte.twiStatus & TwStError) != 0) + { + if(twiByte.twiStatus == TwStAdrNak) + errorCntAdrNakAG++; + else if(twiByte.twiStatus == TwStDataNak) + errorCntDataNakAG++; + else + errorCntOverAG++; + + runState = rsScanAGReq; + break; + } + + if((twiByte.value & 0x03) == 0) + { + if(timeOutStatusAG > 0) + timeOutStatusAG--; + else + { + timeOutStatusAG = toValueStatusAG; + toCntStatusAG++; + } + runState = rsScanMReq; // -> Magnet + break; + } + + timeOutStatusAG = toValueStatusAG; + twiByteSeq.len = 12; + twPtr->recByteRegSeq(AG_Adr, G_Out, &twiByteSeq); + timeOutTwiDataAG = twiDataCycleAG / runCycle + 1; + runState = rsFetchAG; + break; + + // ------------------------------------------------------------------------ + case rsFetchAG: + // ------------------------------------------------------------------------ + runStateCntArray[rsFetchAG]++; + if((twiByteSeq.twiStatus != TwStFin) && ((twiByte.twiStatus & TwStError) == 0)) + { + if(timeOutTwiDataAG > 0) + { + timeOutTwiDataAG--; + break; + } + } + + if(((twiByteSeq.twiStatus & TwStError) != 0) || (timeOutTwiDataAG == 0)) + { + if(twiByteSeq.twiStatus == TwStAdrNak) + errorCntAdrNakAG++; + else if(twiByteSeq.twiStatus == TwStDataNak) + errorCntDataNakAG++; + else if(twiByteSeq.twiStatus == TwStOverrun) + errorCntOverAG++; + else + toCntTwiDataAG++; + + twiByteSeq.len = 12; + twPtr->recByteRegSeq(AG_Adr, G_Out, &twiByteSeq); + timeOutTwiDataAG = twiDataCycleAG / runCycle + 1; + break; + } + + for(int i = 0; i < 12; i++) + comDataAG.byteArray[i] = byteArray[i]; + + if(avgSetAG > 0) + { + sumA.x += comDataAG.valueAG.A.x; + sumA.y += comDataAG.valueAG.A.y; + sumA.z += comDataAG.valueAG.A.z; + sumG.x += comDataAG.valueAG.G.x; + sumG.y += comDataAG.valueAG.G.y; + sumG.z += comDataAG.valueAG.G.z; + avgCntAG--; + + if(avgCntAG == 0) + { + rawDataAG.valueAG.A.x = sumA.x / avgSetAG; + rawDataAG.valueAG.A.y = sumA.y / avgSetAG; + rawDataAG.valueAG.A.z = sumA.z / avgSetAG; + rawDataAG.valueAG.G.x = sumG.x / avgSetAG; + rawDataAG.valueAG.G.y = sumG.y / avgSetAG; + rawDataAG.valueAG.G.z = sumG.z / avgSetAG; + sumA.x = sumA.y = sumA.z = sumG.x = sumG.y = sumG.z = 0; + avgCntAG = avgSetAG; + newValueAG = true; + } + } + else + { + rawDataAG.valueAG.A.x = comDataAG.valueAG.A.x; + rawDataAG.valueAG.A.y = comDataAG.valueAG.A.y; + rawDataAG.valueAG.A.z = comDataAG.valueAG.A.z; + rawDataAG.valueAG.G.x = comDataAG.valueAG.G.x; + rawDataAG.valueAG.G.y = comDataAG.valueAG.G.y; + rawDataAG.valueAG.G.z = comDataAG.valueAG.G.z; + newValueAG = true; + } + + runState = rsScanAGReq; + break; + + // ------------ Magnet ------------ + + // ------------------------------------------------------------------------ + case rsScanMReq: + // ------------------------------------------------------------------------ + runStateCntArray[rsScanMReq]++; + if(!enableMeasM) + { + runState = rsScanAGReq; + break; + } + + twPtr->recByteReg(M_Adr, M_Status, &twiByte); + timeOutTwiStatus = twiStatusCycle / runCycle + 1; + runState = rsScanMChk; + break; + + // ------------------------------------------------------------------------ + case rsScanMChk: + // ------------------------------------------------------------------------ + runStateCntArray[rsScanMChk]++; + if((twiByte.twiStatus != TwStFin) && ((twiByte.twiStatus & TwStError) == 0)) + { + if(timeOutTwiStatus > 0) + timeOutTwiStatus--; + else + { + toCntTwiStatusM++; + runState = rsScanMReq; + } + break; + } + + if((twiByte.twiStatus & TwStError) != 0) + { + if(twiByte.twiStatus == TwStAdrNak) + errorCntAdrNakM++; + else if(twiByte.twiStatus == TwStDataNak) + errorCntDataNakM++; + else + errorCntOverM++; + + runState = rsScanAGReq; + break; + } + + if((twiByte.value & 0x08) == 0) + { + if(timeOutStatusM > 0) + timeOutStatusM--; + else + { + timeOutStatusM = toValueStatusM; + toCntStatusM++; + } + runState = rsScanAGReq; // -> Accel,Gyro + break; + } + + timeOutStatusM = toValueStatusM; + twiByteSeq.len = 6; + twPtr->recByteRegSeq(M_Adr, M_Out, &twiByteSeq); + timeOutTwiDataM = twiDataCycleM / runCycle + 1; + runState = rsFetchM; + break; + + // ------------------------------------------------------------------------ + case rsFetchM: + // ------------------------------------------------------------------------ + runStateCntArray[rsFetchM]++; + if((twiByteSeq.twiStatus != TwStFin) && ((twiByte.twiStatus & TwStError) == 0)) + { + if(timeOutTwiDataM > 0) + { + timeOutTwiDataM--; + break; + } + } + + if( ((twiByteSeq.twiStatus & TwStError) != 0) || (timeOutTwiDataM == 0) ) + { + if(twiByteSeq.twiStatus == TwStAdrNak) + errorCntAdrNakM++; + else if(twiByteSeq.twiStatus == TwStDataNak) + errorCntDataNakM++; + else if(twiByteSeq.twiStatus == TwStOverrun) + errorCntOverM++; + else + toCntTwiDataM++; + + twiByteSeq.len = 6; + twPtr->recByteRegSeq(AG_Adr, M_Out, &twiByteSeq); + timeOutTwiDataM = twiDataCycleM / runCycle + 1; + break; + } + + for(int i = 0; i < 6; i++) + rawDataM.byteArray[i] = byteArray[i]; + + if(avgSetM > 0) + { + sumM.x += rawDataM.valueM.x; + sumM.y += rawDataM.valueM.y; + sumM.z += rawDataM.valueM.z; + avgCntM--; + + if(avgCntM == 0) + { + rawDataM.valueM.x = sumM.x / avgSetM; + rawDataM.valueM.y = sumM.y / avgSetM; + rawDataM.valueM.z = sumM.z / avgSetM; + sumM.x = sumM.y = sumM.z = 0; + avgCntM = avgSetM; + newValueM = true; + } + } + else + { + newValueM = true; + } + + runState = rsScanAGReq; + break; + } +} + +void SensorLSM9DS1::syncValuesM() +{ + newValueM = false; +} + +bool SensorLSM9DS1::getValuesM(RawDataMPtr rdptr) +{ + if(!newValueM) return(false); + for(int i = 0; i < 6; i++) + rdptr->byteArray[i] = rawDataM.byteArray[i]; + newValueM = false; + return(true); +} + +bool SensorLSM9DS1::getValuesM(CalValuePtr calPtr) +{ + if(!newValueM) return(false); + + calPtr->x = (float) fullScaleM * (float) rawDataM.valueM.x / (float) 32767; + calPtr->y = (float) fullScaleM * (float) rawDataM.valueM.y / (float) 32767; + calPtr->z = (float) fullScaleM * (float) rawDataM.valueM.z / (float) 32767; + + newValueM = false; + return(true); +} + +void SensorLSM9DS1::syncValuesAG() +{ + newValueAG = false; +} + +bool SensorLSM9DS1::getValuesAG(RawDataAGPtr rdptr) +{ + if(!newValueAG) return(false); + for(int i = 0; i < 12; i++) + rdptr->byteArray[i] = rawDataAG.byteArray[i]; + newValueAG = false; + return(true); +} + +bool SensorLSM9DS1::getValuesAG(CalValueAGPtr calPtr) +{ + if(!newValueAG) return(false); + + calPtr->G.x = (float) fullScaleG * (float) rawDataAG.valueAG.G.x / (float) 32767; + calPtr->G.y = (float) fullScaleG * (float) rawDataAG.valueAG.G.y / (float) 32767; + calPtr->G.z = (float) fullScaleG * (float) rawDataAG.valueAG.G.z / (float) 32767; + + calPtr->A.x = (float) fullScaleA * (float) rawDataAG.valueAG.A.x / (float) 32767; + calPtr->A.y = (float) fullScaleA * (float) rawDataAG.valueAG.A.y / (float) 32767; + calPtr->A.z = (float) fullScaleA * (float) rawDataAG.valueAG.A.z / (float) 32767; + + newValueAG = false; + return(true); +} + +bool SensorLSM9DS1::getAvgValuesAG(CalValueAGPtr calPtr) +{ + if(!newValueAG) return(false); + newValueAG = false; + + if(avgSetAG > 0) + { + sumA.x += rawDataAG.valueAG.A.x; + sumA.y += rawDataAG.valueAG.A.y; + sumA.z += rawDataAG.valueAG.A.z; + sumG.x += rawDataAG.valueAG.G.x; + sumG.y += rawDataAG.valueAG.G.y; + sumG.z += rawDataAG.valueAG.G.z; + avgCntAG--; + + if(avgCntAG > 0) return(false); + + calPtr->G.x = (float) fullScaleG * (float) (sumG.x / avgSetAG) / (float) 32767; + calPtr->G.y = (float) fullScaleG * (float) (sumG.y / avgSetAG) / (float) 32767; + calPtr->G.z = (float) fullScaleG * (float) (sumG.z / avgSetAG) / (float) 32767; + + calPtr->A.x = (float) fullScaleA * (float) (sumA.x / avgSetAG) / (float) 32767; + calPtr->A.y = (float) fullScaleA * (float) (sumA.y / avgSetAG) / (float) 32767; + calPtr->A.z = (float) fullScaleA * (float) (sumA.z / avgSetAG) / (float) 32767; + + avgCntAG = avgSetAG; + return(true); + } + + calPtr->G.x = (float) fullScaleG * (float) rawDataAG.valueAG.G.x / (float) 32767; + calPtr->G.y = (float) fullScaleG * (float) rawDataAG.valueAG.G.y / (float) 32767; + calPtr->G.z = (float) fullScaleG * (float) rawDataAG.valueAG.G.z / (float) 32767; + + calPtr->A.x = (float) fullScaleA * (float) rawDataAG.valueAG.A.x / (float) 32767; + calPtr->A.y = (float) fullScaleA * (float) rawDataAG.valueAG.A.y / (float) 32767; + calPtr->A.z = (float) fullScaleA * (float) rawDataAG.valueAG.A.z / (float) 32767; + + return(true); +} + + + + +// ---------------------------------------------------------------------------- +// Ereignisbearbeitung und Interrupts +// ---------------------------------------------------------------------------- +// + +// ---------------------------------------------------------------------------- +// D e b u g - H i l f e n +// ---------------------------------------------------------------------------- +// +dword SensorLSM9DS1::debGetDword(int code) +{ + dword retv; + + + switch(code) + { + case 1: + retv = toValueStatusAG; + break; + + case 2: + retv = toValueStatusM; + break; + + default: + retv = 0; + break; + } + return(retv); +} + + +dword SensorLSM9DS1::debGetRunState(int code) +{ + if(0 <= code < 9) + return(runStateCntArray[code]); + else + return(0); +} + + + + diff --git a/sketches/_PIO_Sketches/Karger/SoaapBleSlave_Test_2/src/SensorLSM9DS1/SensorLSM9DS1.h b/sketches/_PIO_Sketches/Karger/SoaapBleSlave_Test_2/src/SensorLSM9DS1/SensorLSM9DS1.h new file mode 100644 index 0000000000000000000000000000000000000000..63cb831c96688b30a85397927a14a52dcb6a15f2 --- /dev/null +++ b/sketches/_PIO_Sketches/Karger/SoaapBleSlave_Test_2/src/SensorLSM9DS1/SensorLSM9DS1.h @@ -0,0 +1,363 @@ +//----------------------------------------------------------------------------- +// Thema: Social Manufacturing Network / Development Environment +// Datei: SensorLSM9DS1.h +// Editor: Robert Patzke +// URI/URL: www.mfp-portal.de +//----------------------------------------------------------------------------- +// Lizenz: CC-BY-SA (wikipedia: Creative Commons) +// + +#ifndef SENSORLSM9DS1_H +#define SENSORLSM9DS1_H + +#include "Arduino.h" +#include "arduinoDefs.h" +#include "IntrfTw.h" + +// ---------------------------------------------------------------------------- + +// ------------------------ Acceleration and Gyroscope ------- +#define AG_Adr 0x6B +// ------------------------ Acceleration and Gyroscope ------- +#define AG_Id 0x0F +#define AG_Ctrl1 0x10 +#define G_Out 0x18 +#define AG_Ctrl6 0x20 +#define AG_Ctrl8 0x22 +#define AG_Status 0x27 + +#define AG_Rate(x) (x << 5) +#define AG_Odr14_9 0x20 +#define AG_Odr59_5 0x40 +#define AG_Odr119 0x60 +#define AG_Odr238 0x80 +#define AG_Odr476 0xA0 +#define AG_Odr952 0xC0 + +typedef enum _FreqAG +{ + FreqAG_OFF = 0xFF, + FreqAG14_9 = AG_Odr14_9, + FreqAG59_5 = AG_Odr59_5, + FreqAG119 = AG_Odr119, + FreqAG238 = AG_Odr238, + FreqAG476 = AG_Odr476, + FreqAG952 = AG_Odr952 +} FreqAG; + +#define AG_FullScale(x) (x << 3) +#define A_Fs2g 0x00 +#define A_Fs4g 0x10 +#define A_Fs8g 0x18 +#define A_Fs16g 0x08 +#define G_Fs245 0x00 +#define G_Fs2000 0x18 +#define G_Fs500 0x08 + +typedef enum _MaxA +{ + MaxAcc2g = A_Fs2g, + MaxAcc4g = A_Fs4g, + MaxAcc8g = A_Fs8g, + MaxAcc16g = A_Fs16g +} MaxA; + +typedef enum _MaxG +{ + MaxGyro245dps = G_Fs245, + MaxGyro500dps = G_Fs500, + MaxGyro2000dps = G_Fs2000 +} MaxG; + +#define AG_LowPass(x) (x) +#define A_LpAuto 0x00 +#define A_Lp50 0x07 +#define A_Lp105 0x06 +#define A_Lp211 0x05 +#define A_Lp408 0x04 +#define G_LpLL 0x00 +#define G_LpLH 0x01 +#define G_LpHL 0x02 +#define G_LpHH 0x03 + +// ------------------------ Magnetic Field ------- +#define M_Adr 0x1E +// ------------------------ Magnetic Field ------- +#define M_Id 0x0F +#define M_Ctrl1 0x20 +#define M_Ctrl2 0x21 +#define M_Ctrl3 0x22 +#define M_Ctrl4 0x23 +#define M_Ctrl5 0x24 +#define M_Status 0x27 +#define M_Out 0x28 + +// Control 1 +#define M_Rate(x) (x << 2) +#define M_Odr0_625 0x00 +#define M_Odr1_25 0x04 +#define M_Odr2_5 0x08 +#define M_Odr5 0x0C +#define M_Odr10 0x10 +#define M_Odr20 0x14 +#define M_Odr40 0x18 +#define M_Odr80 0x1C + +typedef enum _FreqM +{ + FreqM_OFF = 0xFF, + FreqM0_625 = M_Odr0_625, + FreqM1_25 = M_Odr1_25, + FreqM2_5 = M_Odr2_5, + FreqM5 = M_Odr5, + FreqM10 = M_Odr10, + FreqM20 = M_Odr20, + FreqM40 = M_Odr40, + FreqM80 = M_Odr80 +} FreqM; + +#define M_Temp(x) (x << 7) +#define M_TmpOn 0x80 +#define M_TmpOff 0x00 + +#define Mxy_Power(x) (x << 6) +#define Mxy_PmLow 0x00 +#define Mxy_PmMed 0x20 +#define Mxy_PmHigh 0x40 +#define Mxy_PmUhigh 0x60 + +// Control 2 +#define M_FullScale(x) (x << 5) +#define M_Fs4G 0x00 +#define M_Fs8G 0x20 +#define M_Fs12G 0x40 +#define M_Fs16G 0x60 + +typedef enum _MaxM +{ + MaxMag4G = M_Fs4G, + MaxMag8G = M_Fs8G, + MaxMag12G = M_Fs12G, + MaxMag16G = M_Fs16G +} MaxM; + + +// Control 3 +#define M_OpMode(x) (x) +#define M_Contin 0x00 +#define M_Single 0x01 +#define M_Down 0x10 + +// Control 4 +#define Mz_Power(x) (x << 2) +#define Mz_PmLow 0x00 +#define Mz_PmMed 0x04 +#define Mz_PmHigh 0x08 +#define Mz_PmUhigh 0x0C + + +typedef enum _RunState +{ + rsInit, + rsScanAGReq, + rsWaitAG, + rsScanAGChk, + rsFetchAG, + rsScanMReq, + rsScanMChk, + rsFetchM +} RunState; + +#define NrOfRunStates 8 + +typedef struct _RawValue +{ + short int x; + short int y; + short int z; +} RawValue; + +typedef struct _SumValue +{ + int x; + int y; + int z; +} SumValue, *SumValuePtr; + +typedef struct _RawValueAG +{ + RawValue G; + RawValue A; +} RawValueAG; + +typedef union _RawDataAG +{ + byte byteArray[12]; + RawValueAG valueAG; +} RawDataAG, *RawDataAGPtr; + +typedef union _RawDataM +{ + byte byteArray[6]; + RawValue valueM; +} RawDataM, *RawDataMPtr; + +typedef struct _CalValue +{ + float x; + float y; + float z; +} CalValue, *CalValuePtr; + +typedef struct _CalValueAG +{ + CalValue G; + CalValue A; +} CalValueAG, *CalValueAGPtr; + +typedef struct _SensorErrors +{ + +} SensorErrors, *SensorErrorsPtr; + +class SensorLSM9DS1 +{ +private: + // -------------------------------------------------------------------------- + // Lokale Daten und Funktionen + // -------------------------------------------------------------------------- + // + IntrfTw *twPtr; + TwiByte twiByte; + TwiByteSeq twiByteSeq; + byte byteArray[12]; + + bool enableMeasAG; + bool newValueAG; + RawDataAG rawDataAG; + RawDataAG comDataAG; + + bool enableMeasM; + bool newValueM; + RawDataM rawDataM; + + int fullScaleA; + int fullScaleG; + int fullScaleM; + + SumValue sumA; + SumValue sumG; + int avgSetAG; + int avgCntAG; + + SumValue sumM; + int avgSetM; + int avgCntM; + + dword timeOutTwiStatus; + dword timeOutTwiDataAG; + dword timeOutTwiDataM; + + dword timeOutStatusAG; + dword toValueStatusAG; + dword timeOutStatusM; + dword toValueStatusM; + + int twiCycle; + int twiStatusCycle; + int twiDataCycleAG; + int twiDataCycleM; + + RunState runState; + int waitCnt; + int runCycle; + + void setTimeOutValues(FreqAG fAG, FreqM fM); + +public: + // -------------------------------------------------------------------------- + // Initialisierungen der Basis-Klasse + // -------------------------------------------------------------------------- + + SensorLSM9DS1(IntrfTw *refI2C, int inRunCycle); + + // -------------------------------------------------------------------------- + // Konfigurationen + // -------------------------------------------------------------------------- + // + int resetAG(); + int resetM(); + int reset(); + + void setScanAG(byte scValueAG, byte scValueA, byte scValueG); + // Messparameter für Accel und Gyro + // scValueAG = Abtastrate + // scValueA = Vollausschlag und Tiefpass für Beschleunigung + // scValueB = Vollausschlag und Tiefpass für Gyrometer + + void setScanM(byte scValue1, byte scValue2, byte scValue3, byte scValue4); + // Messparameter für Magnetfeld + // scValue1 = Abtastrate, Temperaturkompensation und XY-Powermode + // scValue2 = Vollausschlag + // scValue3 = Betriebsart + // scValue4 = Z-Powermode + + + void begin(FreqAG freqAG, int avgAG, MaxA maxA, MaxG maxG, FreqM freqM, int avgM, MaxM maxM); + void begin(); + + // -------------------------------------------------------------------------- + // Steuerfunktionen + // -------------------------------------------------------------------------- + // + void run(); + void run0(); + void run1(); + void stop(); + void resume(); + + // -------------------------------------------------------------------------- + // Datenaustausch + // -------------------------------------------------------------------------- + // + dword errorCntOverAG; + dword errorCntAdrNakAG; + dword errorCntDataNakAG; + + dword errorCntOverM; + dword errorCntAdrNakM; + dword errorCntDataNakM; + + dword toCntTwiStatusAG; + dword toCntTwiStatusM; + dword toCntTwiDataAG; + dword toCntTwiDataM; + dword toCntStatusAG; + dword toCntStatusM; + + void syncValuesAG(); + bool getValuesAG(RawDataAGPtr rdptr); + bool getValuesAG(CalValueAGPtr calPtr); + bool getAvgValuesAG(CalValueAGPtr calPtr); + void syncValuesM(); + bool getValuesM(RawDataMPtr rdptr); + bool getValuesM(CalValuePtr calPtr); + + // ---------------------------------------------------------------------------- + // Ereignisbearbeitung und Interrupts + // ---------------------------------------------------------------------------- + // + + // ---------------------------------------------------------------------------- + // D e b u g - H i l f e n + // ---------------------------------------------------------------------------- + // + dword runStateCntArray[NrOfRunStates]; + dword runStateCntTotal; + dword debGetDword(int code); + dword debGetRunState(int code); + +}; + +#endif // SENSORLSM9DS1_H + diff --git a/sketches/_PIO_Sketches/Karger/SoaapBleSlave_Test_2/src/SensorLSM9DS1/library.json b/sketches/_PIO_Sketches/Karger/SoaapBleSlave_Test_2/src/SensorLSM9DS1/library.json new file mode 100644 index 0000000000000000000000000000000000000000..6432e5ccb8930ce40504aa4f03e463f2df00fac0 --- /dev/null +++ b/sketches/_PIO_Sketches/Karger/SoaapBleSlave_Test_2/src/SensorLSM9DS1/library.json @@ -0,0 +1,4 @@ +{ + "name": "SensorLSM9DS1", + "version": "0.0.0+20220823165932" +} \ No newline at end of file diff --git a/sketches/_PIO_Sketches/Karger/SoaapBleSlave_Test_2/src/SoaapComDue/SoaapComDue.cpp b/sketches/_PIO_Sketches/Karger/SoaapBleSlave_Test_2/src/SoaapComDue/SoaapComDue.cpp new file mode 100644 index 0000000000000000000000000000000000000000..b24e6f4f90c3ecc1588b5af5dde88b4b922e8ee7 --- /dev/null +++ b/sketches/_PIO_Sketches/Karger/SoaapBleSlave_Test_2/src/SoaapComDue/SoaapComDue.cpp @@ -0,0 +1,212 @@ +//----------------------------------------------------------------------------- +// Thema: Steuerung optischer und akustischer Ausgaben für Perfomer +// Datei: SoaapComDue.cpp +// Editor: Robert Patzke +// URI/URL: www.hs-hannover.de +//----------------------------------------------------------------------------- +// Lizenz: CC-BY-SA (wikipedia: Creative Commons) +// Datum: 01.April 2022 +// +// Diese Bibliothek (Klassse) enthält diverse Ressourcen zum Zugriff auf den +// SOAAP-Master über eine serielle Schnittstelle des Arduino DUE. +// + +#include "SoaapComDue.h" + +#define next(x) nextState = &SoaapComDue::x + +// ---------------------------------------------------------------------------- +// Konstruktoren und Initialisierungen +// ---------------------------------------------------------------------------- +// +SoaapComDue::SoaapComDue(USARTClass *serial, SoaapMsg *soaMsg) +{ + pCom = serial; + pMsg = soaMsg; + nextState = &SoaapComDue::runInit; + + nrBytesIn = 0; + serInIdx = 0; + serInChar = 0; + serInCount = 0; + slaveAdr = 0; + slaveArea = 0; + appId = (SoaapApId) 0; + + measIdx = 0; + nrMeas = 0; + resMeas = 0; + slaveIdx = 0; + anyNewVal = false; +} + +// -------------------------------------------------------------------------- +// lokale Methoden (Zustandsmaschine) +// -------------------------------------------------------------------------- +// +void SoaapComDue::runInit() +{ + next(runWaitMsg); +} + +void SoaapComDue::runWaitMsg() +{ + nrBytesIn = pCom->available(); + // Anzahl der über <serial> eingetroffenen Bytes (Zeichen) + + if(nrBytesIn < 1) return; + // Beim nächsten Takt wieder in diesen Zustand, wenn kein Zeichen da + + for(serInIdx = 0; serInIdx < nrBytesIn; serInIdx++) + { // Suchen nach Startzeichen + serInChar = pCom->read(); + if(serInChar < 0x20) break; + } + + if(serInIdx == nrBytesIn) return; + // Beim nächsten Takt wieder in diesen Zustand, wenn Startzeichen nicht dabei + + slaveArea = serInChar & 0x1F; // Bereich auskodieren + + serInIdx = 0; // Index neu setzen für Inhaltszuordnung + next(runHeader); + // Beim nächsten Takt zum Zustand <runHeader> + +} + +void SoaapComDue::runHeader() +{ + nrBytesIn = pCom->available(); + // Anzahl der über Serial1 eingetroffenen Bytes (Zeichen) + + if(nrBytesIn < 1) return; + // Beim nächsten Takt wieder in diesen Zustand, wenn kein Zeichen da + + serInChar = pCom->read(); + // einzelnes Zeichen lesen + + if(serInIdx == 0) // nach der Area folgt die Slaveadresse + { + slaveAdr = serInChar & 0x1F; // 1 - 31 + slaveIdx = slaveAdr; // vorläufig lineare Adress/Index-Zuordnung + serInIdx++; + // Beim nächsten Takt wieder in diesen Zustand + } + else // und dann die Anwendungskennung + { + appId = (SoaapApId) serInChar; + measIdx = 0; // Index für Messwertunterscheidung + serInIdx = 0; // Index für Messwertaufbau + nrMeas = pMsg->measCnt(appId); // Anzahl Messwerte im Telegramm + resMeas = pMsg->measRes(appId); // Auflösung der Messwerte in Zeichen + next(runValues); + // Beim nächsten Takt zum Zustand <runValues> + } +} + +void SoaapComDue::runValues() +{ + int i; + + do + { + nrBytesIn = pCom->available(); + // Anzahl der über Serial1 eingetroffenen Bytes (Zeichen) + + if(nrBytesIn < 1) return; + // Beim nächsten Takt wieder in diesen Zustand, wenn kein Zeichen da + + for(i = 0; i < nrBytesIn; i++) + { + tmpBuffer[serInIdx++] = pCom->read(); + // einzelnes Zeichen lesen + + if(serInIdx == resMeas) break; + // Alle Zeichen vom Messwert da, also raus + } + + if(serInIdx < resMeas) return; + // Wenn noch nicht ale Zeichen vom Messwert erfasst, dann von vorn + + slValList[slaveIdx].measList[measIdx++] = pMsg->asc2meas(tmpBuffer); + // Zeichenkette in Messwert wandeln und speichern + + if(measIdx == nrMeas) break; + // Falls mehr als ein Telegramm eingetroffen ist + // muss hier ein Ausstieg erfolgen + + serInIdx = 0; // Nächste Zeichenfolge + } + while (pCom->available() > 0); + // Die Taktzeit der Zustandsmaschine ist größer, als die + // Übertragungszeit von einem Zeichen. + // Deshalb werden in einem Zustandstakt alle inzwischen eingetroffenen + // Zeichen bearbeitet. + + if(measIdx < nrMeas) return; + // Im Zustand bleiben, bis alle Messwerte gewandelt sind + + slValList[slaveIdx].newVal = true; + anyNewVal = true; + + next(runWaitMsg); +} + +// -------------------------------------------------------------------------- +// lokale Methoden (Hilfsfunktionen) +// -------------------------------------------------------------------------- +// + +// Erster Slave (kleinste Adresse) mit Daten +// +int SoaapComDue::getSlDataAvail() +{ + for(int i = 1; i <= ScdNrOfSlaves; i++) + if(slValList[i].newVal) + return(i); + return(0); +} + +// ---------------------------------------------------------------------------- +// Anwenderschnittstelle (Funktionen/Methoden) +// ---------------------------------------------------------------------------- +// + +// (zyklischer) Aufruf zum Ablauf +// +void SoaapComDue::run() +{ + if(nextState != NULL) + (this->*nextState)(); +} + +// Daten von irgendeinem Slave verfügbar +// +int SoaapComDue::anyDataAvail() +{ + if(!anyNewVal) return(0); + else return(getSlDataAvail()); +} + +// Daten von bestimmtem Slave verfügbar +// +bool SoaapComDue::slDataAvail(int slAdr) +{ + return(slValList[getSlIdxAdr(slAdr)].newVal); +} + +// Daten von einem bestimmten Slave abholen +// +int SoaapComDue::getData(int slAdr, pMeasValues pMeas) +{ + int slIdx = getSlIdxAdr(slAdr); + for(int i = 0; i < 8; i++) + pMeas->defShort[i] = slValList[slIdx].measList[i]; + slValList[slIdx].newVal = false; + anyNewVal = false; + for(int i = 1; i <= ScdNrOfSlaves; i++) + if(slValList[i].newVal) anyNewVal = true; + return(0); +} + + diff --git a/sketches/_PIO_Sketches/Karger/SoaapBleSlave_Test_2/src/SoaapComDue/SoaapComDue.h b/sketches/_PIO_Sketches/Karger/SoaapBleSlave_Test_2/src/SoaapComDue/SoaapComDue.h new file mode 100644 index 0000000000000000000000000000000000000000..990faa3710733dedfd4819f254c11b8900f15d65 --- /dev/null +++ b/sketches/_PIO_Sketches/Karger/SoaapBleSlave_Test_2/src/SoaapComDue/SoaapComDue.h @@ -0,0 +1,132 @@ +//----------------------------------------------------------------------------- +// Thema: Steuerung optischer und akustischer Ausgaben für Perfomer +// Datei: SoaapComDue.h +// Editor: Robert Patzke +// URI/URL: www.hs-hannover.de +//----------------------------------------------------------------------------- +// Lizenz: CC-BY-SA (wikipedia: Creative Commons) +// Datum: 01.April 2022 +// +// Diese Bibliothek (Klassse) enthält diverse Ressourcen zum Zugriff auf den +// SOAAP-BLE-Master über eine serielle Schnittstelle des Arduino DUE. +// + +#ifndef SoaapComDue_h +#define SoaapComDue_h + +#define ScdNrOfSlaves 6 + +#include "USARTClass.h" +#include "SoaapMsg.h" + +#ifndef byte +#define byte unsigned char +#endif + + +class SoaapComDue +{ +public: + // -------------------------------------------------------------------------- + // Konstruktoren und Initialisierungen + // -------------------------------------------------------------------------- + // + SoaapComDue(USARTClass *serial, SoaapMsg *soaMsg); + + // -------------------------------------------------------------------------- + // öffentliche Datentypen + // -------------------------------------------------------------------------- + // + typedef union + { + short defShort[9]; + short maxShort[13]; + float maxFloat[6]; + } MeasValues, *pMeasValues; + +private: + // -------------------------------------------------------------------------- + // lokale Datentypen + // -------------------------------------------------------------------------- + // + + typedef void (SoaapComDue::*CbVector)(void); + typedef struct + { + int slaveArea; + int slaveAdr; + SoaapApId apId; + bool newVal; + short measList[13]; + } SlaveValues, *pSlaveValues; + +private: + // -------------------------------------------------------------------------- + // lokale Variablen + // -------------------------------------------------------------------------- + // + USARTClass *pCom; + SoaapMsg *pMsg; + CbVector nextState; + + int nrBytesIn; // Antahl aktuell empfangener Zeichen + int serInCount; // Zähler für empfangene Zeichen + int serInIdx; // Index für besonderes Zeichen + byte serInChar; // Einzelnes empfangenes Zeichen + int slaveAdr; // Adresse des Soaap-Slave + int slaveArea; // Quellennetzwerk-Info, Bereich, o.ä. + SoaapApId appId; // Anwendungskennung, Datentyp, o.ä. + + int measIdx; // Index für den aktuellen Messwert + int nrMeas; // Anzahl der Messwerte im Telegramm + int resMeas; // Auflösung der Messwerte in Zeichen + bool anyNewVal; // Neuer Wert von beliebigem Slave + + SlaveValues slValList[ScdNrOfSlaves + 1]; // Vorläufige Liste aller Messwerte + int slaveIdx; // Index für lokale Slaveverwaltung + + byte tmpBuffer[128]; // Zwischenspeicher für empfangene Zeichen + + // -------------------------------------------------------------------------- + // Inline-Methoden + // -------------------------------------------------------------------------- + // + + // Index von Slave best. Adresse für Datenliste + // + int getSlIdxAdr(int slAdr) + { + // Zur Zeit sind Index und Slaveadresse identisch (1-6) + // Das wir später bei freier Zuordnung angepasst + return(slAdr); + } + + // -------------------------------------------------------------------------- + // lokale Methoden (Zustandsmaschine) + // -------------------------------------------------------------------------- + // + void runInit(); + void runWaitMsg(); + void runHeader(); + void runValues(); + + // -------------------------------------------------------------------------- + // lokale Methoden (Hilfsfunktionen) + // -------------------------------------------------------------------------- + // + int getSlDataAvail(); + +public: + // -------------------------------------------------------------------------- + // Anwenderschnittstelle (Funktionen) + // -------------------------------------------------------------------------- + // + void run(); // (zyklischer) Aufruf zum Ablauf + int anyDataAvail(); // Daten von irgendeinem Slave verfügbar + bool slDataAvail(int slAdr); // Daten von bestimmtem Slave verfügbar + int getData(int slAdr, pMeasValues pMeas); + // Daten von einem bestimmten Slave abholen + +}; + +#endif // SoaapComDue_h diff --git a/sketches/_PIO_Sketches/Karger/SoaapBleSlave_Test_2/src/SoaapComDue/library.json b/sketches/_PIO_Sketches/Karger/SoaapBleSlave_Test_2/src/SoaapComDue/library.json new file mode 100644 index 0000000000000000000000000000000000000000..d2cf1518adba3b9cb3a57d0eca8963fbceca345c --- /dev/null +++ b/sketches/_PIO_Sketches/Karger/SoaapBleSlave_Test_2/src/SoaapComDue/library.json @@ -0,0 +1,4 @@ +{ + "name": "SoaapComDue", + "version": "0.0.0+20220804174235" + } \ No newline at end of file diff --git a/sketches/_PIO_Sketches/Karger/SoaapBleSlave_Test_2/src/SoaapMsg/SoaapMsg.cpp b/sketches/_PIO_Sketches/Karger/SoaapBleSlave_Test_2/src/SoaapMsg/SoaapMsg.cpp new file mode 100644 index 0000000000000000000000000000000000000000..0f3f29704b3b1d5e02528071b0527804940435bd --- /dev/null +++ b/sketches/_PIO_Sketches/Karger/SoaapBleSlave_Test_2/src/SoaapMsg/SoaapMsg.cpp @@ -0,0 +1,159 @@ +//----------------------------------------------------------------------------- +// Thema: Steuerung optischer und akustischer Ausgaben für Perfomer +// Datei: SoaapMsg.h +// Editor: Robert Patzke +// URI/URL: www.hs-hannover.de +//----------------------------------------------------------------------------- +// Lizenz: CC-BY-SA (wikipedia: Creative Commons) +// Datum: 18. März 2022 +// +// Diese Bibliothek (Klassse) enthält diverse Ressourcen zur Generierung +// von Meldungen und Telegrammen, die im Rahmen des SOAAP-Projektes +// eingesetzt werden. +// + +#include "SoaapMsg.h" + +// ---------------------------------------------------------------------------- +// Konstruktoren und Initialisierungen +// ---------------------------------------------------------------------------- +// +SoaapMsg::SoaapMsg() +{ + +} + +// ---------------------------------------------------------------------------- +// Anwenderschnittstelle (Funktionen) +// ---------------------------------------------------------------------------- +// + +// Erstellen eines ASCII-Telegramms zum Übertragen der Messwerte +// +int SoaapMsg::getMsgA(int area, int slvNr, SoaapApId appId, char *dest, byte *meas) +{ + int msgIdx = 0; + int measIdx; + int measLen; + byte measByte; + char measChar; + + dest[msgIdx++] = (char) (area | 0x10); + dest[msgIdx++] = (char) (slvNr | 0x60); + dest[msgIdx++] = (char) (appId); + + switch(appId) + { + case saiDefaultMeas: + measLen = 18; + break; + + case saiDefaultMeasCtrl: + measLen = 18; + break; + + case saiMaximalMeas: + measLen = 26; + break; + } + + for(measIdx = 0; measIdx < measLen; measIdx++) + { + measByte = meas[measIdx]; + + // Erst das niederwertige Nibble als Hex-Ascii eintragen + // + measChar = (measByte & 0x0F) | 0x30; + if (measChar > 0x39) measChar += 7; + dest[msgIdx++] = measChar; + + // dann das höherwertige Nibble + // + measChar = (measByte >> 4) | 0x30; + if (measChar > 0x39) measChar += 7; + dest[msgIdx++] = measChar; + } + + if(appId == saiDefaultMeasCtrl) + { + measByte = meas[20]; + + // Erst das niederwertige Nibble als Hex-Ascii eintragen + // + measChar = (measByte & 0x0F) | 0x30; + if (measChar > 0x39) measChar += 7; + dest[msgIdx++] = measChar; + + // dann das höherwertige Nibble + // + measChar = (measByte >> 4) | 0x30; + if (measChar > 0x39) measChar += 7; + dest[msgIdx++] = measChar; + } + + dest[msgIdx] = '\0'; + return(msgIdx); +} + +// Umwandeln eines Messwert aus ASCII-Telegramm in Integer +// +short SoaapMsg::asc2meas(byte *ascList) +{ + unsigned short retv; + + retv = getVal(ascList[0]); + retv += getVal(ascList[1]) << 4; + retv += getVal(ascList[2]) << 8; + retv += getVal(ascList[3]) << 12; + + return((short) retv); +} + +// Auflösung der Messwerte in Zeichen (Bytes) +// +int SoaapMsg::measRes(SoaapApId appId) +{ + int retv = 0; + + switch(appId) + { + case saiDefaultMeas: + retv = 4; + break; + + case saiDefaultMeasCtrl: + retv = 4; + break; + + case saiMaximalMeas: + retv = 4; + break; + } + + return(retv); +} + +// Anzahl der Messwerte im Telegramm +// +int SoaapMsg::measCnt(SoaapApId appId) +{ + int retv = 0; + + switch(appId) + { + case saiDefaultMeas: + retv = 9; + break; + + case saiDefaultMeasCtrl: + retv = 9; + break; + + case saiMaximalMeas: + retv = 13; + break; + } + + return(retv); +} + diff --git a/sketches/_PIO_Sketches/Karger/SoaapBleSlave_Test_2/src/SoaapMsg/SoaapMsg.h b/sketches/_PIO_Sketches/Karger/SoaapBleSlave_Test_2/src/SoaapMsg/SoaapMsg.h new file mode 100644 index 0000000000000000000000000000000000000000..20df5732381c353181e02ce74cf3cf193789c5a0 --- /dev/null +++ b/sketches/_PIO_Sketches/Karger/SoaapBleSlave_Test_2/src/SoaapMsg/SoaapMsg.h @@ -0,0 +1,73 @@ +//----------------------------------------------------------------------------- +// Thema: Steuerung optischer und akustischer Ausgaben für Perfomer +// Datei: SoaapMsg.h +// Editor: Robert Patzke +// URI/URL: www.hs-hannover.de +//----------------------------------------------------------------------------- +// Lizenz: CC-BY-SA (wikipedia: Creative Commons) +// Datum: 18. März 2022 +// +// Diese Bibliothek (Klassse) enthält diverse Ressourcen zur Generierung +// von Meldungen und Telegrammen, die im Rahmen des SOAAP-Projektes +// eingesetzt werden. +// + +#ifndef SoaapMsg_h +#define SoaapMsg_h + +#include "arduinoDefs.h" + +typedef enum +{ + saiDefaultMeas = 0x68, + saiMaximalMeas = 0x69, + saiDefaultMeasCtrl = 0x6A +} SoaapApId; + +class SoaapMsg +{ +public: + // -------------------------------------------------------------------------- + // Konstruktoren und Initialisierungen + // -------------------------------------------------------------------------- + // + SoaapMsg(); + +private: + // -------------------------------------------------------------------------- + // lokale Variablen + // -------------------------------------------------------------------------- + // + + // -------------------------------------------------------------------------- + // Inline-Methoden + // -------------------------------------------------------------------------- + // + int getVal(char hexAsc) + { + if(hexAsc < 0x39) return(hexAsc - 0x30); + else return(hexAsc - 0x37); + } + + +public: + // -------------------------------------------------------------------------- + // Anwenderschnittstelle (Funktionen) + // -------------------------------------------------------------------------- + // + + int getMsgA(int area, int slvNr, SoaapApId appId, char *dest, byte *meas); + // Erstellen eines ASCII-Telegramms zum Übertragen der Messwerte + + short asc2meas(byte *ascList); + // Umwandeln eines Messwert aus ASCII-Telegramm in Integer + + int measRes(SoaapApId appId); + // Auflösung der Messwerte in Zeichen (Bytes) + + int measCnt(SoaapApId appId); + // Anzahl der Messwerte + +}; + +#endif // SoaapMsg_h diff --git a/sketches/_PIO_Sketches/Karger/SoaapBleSlave_Test_2/src/SoaapMsg/library.json b/sketches/_PIO_Sketches/Karger/SoaapBleSlave_Test_2/src/SoaapMsg/library.json new file mode 100644 index 0000000000000000000000000000000000000000..86be2b961f0f6f6dae95ed22fadc55f7a1c58826 --- /dev/null +++ b/sketches/_PIO_Sketches/Karger/SoaapBleSlave_Test_2/src/SoaapMsg/library.json @@ -0,0 +1,4 @@ +{ + "name": "SoaapMsg", + "version": "0.0.0+20220823165932" +} \ No newline at end of file diff --git a/sketches/_PIO_Sketches/Karger/SoaapBleSlave_Test_2/src/StateMachine/StateMachine.cpp b/sketches/_PIO_Sketches/Karger/SoaapBleSlave_Test_2/src/StateMachine/StateMachine.cpp new file mode 100644 index 0000000000000000000000000000000000000000..9c1f78d3b83eabbc30463d78e693b470e345e140 --- /dev/null +++ b/sketches/_PIO_Sketches/Karger/SoaapBleSlave_Test_2/src/StateMachine/StateMachine.cpp @@ -0,0 +1,480 @@ +// --------------------------------------------------------------------------- +// File: StateMachine.cpp +// Editors: Robert Patzke, +// Start: 07. February 2018 +// Last change: 22. February 2021 +// URI/URL: www.mfp-portal.de, homeautomation.x-api.de +// Licence: Creative Commons CC-BY-SA +// --------------------------------------------------------------------------- +// + +#include "StateMachine.h" + +// --------------------------------------------------------------------------- +// Constructors and initialisations +// --------------------------------------------------------------------------- +// + +int StateMachine::StateMachine_InstCounter; + +StateMachine::StateMachine(){;} // @suppress("Class members should be properly initialized") + +StateMachine::StateMachine(StatePtr firstState, StatePtr anyState, int cycle) +{ + begin(firstState, anyState, cycle); +} + +StateMachine::StateMachine(StatePtr firstState, StatePtr anyState, int cycle, MicsecFuPtr micsecFu) +{ + begin(firstState, anyState, cycle, micsecFu); +} + +void StateMachine::begin(StatePtr firstState, StatePtr anyState, int cycle) +{ + begin(firstState, anyState, cycle, NULL); +} + +void StateMachine::begin(StatePtr firstState, StatePtr anyState, int cycle, MicsecFuPtr micsecFu) +{ + nextState = firstState; + doAlways = anyState; + cycleTime = cycle; + frequency = 1000 / cycle; + delay = 0; + delaySet = 0; + repeatDelay = false; + userStatus = 0; + + StateMachine_InstCounter++; + instNumber = StateMachine_InstCounter; + micsFuPtr = micsecFu; +} + +// --------------------------------------------------------------------------- +// run State enter function, has to be cyclic called +// --------------------------------------------------------------------------- +// +void StateMachine::run() +{ + unsigned long startMics = 0, diffMics; + + runCounter++; + + if(timeOutCounter > 0) + timeOutCounter--; + + if(timeMeasureOn) + timeMeasureCounter++; + + if(doAlways != NULL) + doAlways(); + + if(delay > 0) + { + delay--; + return; + } + + if(repeatDelay) + delay = delaySet; + + if(useProgList) + { + if(progIndex == progEndIdx) + { + if(loopProgList) + { + progIndex = 0; + nextState = progList[progIndex]; + progIndex++; + } + else + { + useProgList = false; + nextState = finProgState; + } + } + else + { + nextState = progList[progIndex]; + progIndex++; + } + } + + if(nextState != NULL) + { + if(micsFuPtr != NULL) + startMics = micsFuPtr(); + + nextState(); + + if(micsFuPtr != NULL) + { + diffMics = micsFuPtr() - startMics; + curStateRuntime = diffMics; + + if(diffMics > maxStateRuntime[0]) + { + maxStateRuntime[0] = diffMics; + maxRuntimeNumber[0] = curStateNumber; + } + else if(diffMics > maxStateRuntime[1]) + { + if(curStateNumber != maxRuntimeNumber[0]) + { + maxStateRuntime[1] = diffMics; + maxRuntimeNumber[1] = curStateNumber; + } + } + else if(diffMics > maxStateRuntime[2]) + { + if(curStateNumber != maxRuntimeNumber[1]) + { + maxStateRuntime[2] = diffMics; + maxRuntimeNumber[2] = curStateNumber; + } + } + else if(diffMics > maxStateRuntime[3]) + { + if(curStateNumber != maxRuntimeNumber[2]) + { + maxStateRuntime[3] = diffMics; + maxRuntimeNumber[3] = curStateNumber; + } + } + } + } + else + noStateCounter++; + +} + +// --------------------------------------------------------------------------- +// service functions/methods for manipulating the state machine +// --------------------------------------------------------------------------- +// + +// checking a state for staying (not enter new state) +// +bool StateMachine::stayHere() +{ + if(repeatState > 0) + { + repeatState--; + if(repeatState == 0) + { + repeatDelay = false; + } + return(true); + } + + firstEnterToggle = true; + return(false); +} + +// setting delay before next state +// +void StateMachine::setDelay(int delayTime) +{ + delay = (delayTime * frequency) / 1000; + repeatDelay = false; +} + +// setting internal speed of the state machine +// can only be slower than the calling frequency +// +void StateMachine::setSpeed(int freq) +{ + delaySet = delay = frequency / freq; + repeatDelay = true; +} + +// setting future state to be called by run +// +void StateMachine::enter() +{ + if(stayHere()) return; + + pastState = nextState; + nextState = futureState; +} + +// setting next state to be called by run +// +void StateMachine::enter(StatePtr next) +{ + if(stayHere()) return; + + pastState = nextState; + nextState = next; +} + +// setting next state with delay (before) +// +void StateMachine::enter(StatePtr next, int delayTime) +{ + if(stayHere()) return; + + delay = (delayTime * frequency) / 1000; + repeatDelay = false; + + pastState = nextState; + nextState = next; +} + +// setting next state with repetition +// +void StateMachine::enterRep(StatePtr next, int count) +{ + if(stayHere()) return; + + repeatState = count; + pastState = nextState; + nextState = next; +} + +// setting next state with repetition and delay +// +void StateMachine::enterRep(StatePtr next, int count, int delayTime) +{ + if(stayHere()) return; + + delaySet = delay = (delayTime * frequency) / 1000; + repeatDelay = true; + + repeatState = count; + pastState = nextState; + nextState = next; +} + +// setting state and state after +// +void StateMachine::enterVia(StatePtr next, StatePtr then) +{ + if(stayHere()) return; + + pastState = nextState; + nextState = next; + futureState = then; +} + +// calling state +// +void StateMachine::call(StatePtr next) +{ + if(stayHere()) return; + + pastState = nextState; + futureState = nextState; + nextState = next; +} + +// setting state and state after with delay +// +void StateMachine::enterVia(StatePtr next, StatePtr after, int delayTime) +{ + if(stayHere()) return; + + delay = (delayTime * frequency) / 1000; + repeatDelay = false; + + pastState = nextState; + nextState = next; + futureState = after; +} + +// calling state +// +void StateMachine::call(StatePtr next, int delayTime) +{ + if(stayHere()) return; + + delay = (delayTime * frequency) / 1000; + repeatDelay = false; + + pastState = nextState; + futureState = nextState; + nextState = next; +} + + +// setting state to state list (program) +// +void StateMachine::enterList(StatePtr fin) +{ + if(stayHere()) return; + + pastState = nextState; + useProgList = true; + progIndex = 0; + finProgState = fin; +} + +// setting state to state list (program)and delay +// +void StateMachine::enterList(StatePtr fin, int delayTime) +{ + if(stayHere()) return; + + delay = (delayTime * frequency) / 1000; + repeatDelay = false; + + pastState = nextState; + useProgList = true; + progIndex = 0; + finProgState = fin; +} + +// setting state to state list (program) at a position +// +void StateMachine::enterListAt(StatePtr fin, int index) +{ + if(stayHere()) return; + + pastState = nextState; + useProgList = true; + progIndex = index; + finProgState = fin; +} + +// setting state to state list (program)at a position and delay +// +void StateMachine::enterListAt(StatePtr fin, int index, int delayTime) +{ + if(stayHere()) return; + + delay = (delayTime * frequency) / 1000; + repeatDelay = false; + + pastState = nextState; + useProgList = true; + progIndex = index; + finProgState = fin; +} + +// detecting the first call of a state +// +bool StateMachine::firstEnter() +{ + if(!firstEnterToggle) + return(false); + firstEnterToggle = false; + return(true); +} + +// reset first enter detector +// +void StateMachine::resetEnter() +{ + firstEnterToggle = true; +} + +// counting local cycles +// +bool StateMachine::cycle(int cnt) +{ + if(callCycleCnt <= 0) + { + callCycleCnt = cnt; + return(true); + } + callCycleCnt--; + return(false); +} +// +bool StateMachine::cycleSec() +{ + if(callCycleCnt <= 0) + { + callCycleCnt = frequency; + return(true); + } + callCycleCnt--; + return(false); +} + +// Alternativly returning true and false +// +bool StateMachine::toggle() +{ + markToggle = !markToggle; + return(markToggle); +} + +// Doing only once +// +bool StateMachine::oneShot() +{ + if(!markOneShot) return(false); + + markOneShot = false; + return (true); +} + +void StateMachine::setOneShot() +{ + markOneShot = true; +} + + +// Setable number of returning TRUE +// +void StateMachine::setCondCounter(unsigned int condVal) +{ + condCounter = condVal; +} + +bool StateMachine::condOpen() +{ + if(condCounter == 0) + return(false); + condCounter--; + return(true); +} + +// set the time-out value (milliseconds) +// +void StateMachine::setTimeOut(int toValue) +{ + timeOutCounter = (toValue * frequency) / 1000; +} + +// check the time-out counter +// +bool StateMachine::timeOut() +{ + if(timeOutCounter > 0) + return(false); + return(true); +} + +// start time measurement +// +void StateMachine::startTimeMeasure() +{ + timeMeasureCounter = 0; + timeMeasureOn = true; +} + +int StateMachine::getTimeMeasure(bool stop) +{ + if(stop) + timeMeasureOn = false; + return(cycleTime * timeMeasureCounter); +} + +unsigned long StateMachine::getExtTimeMeasure(bool stop) +{ + if(stop) + timeMeasureOn = false; + return(cycleTime * timeMeasureCounter); +} + +// --------------------------------------------------------------------------- +// Debug and statistic functions/methods +// --------------------------------------------------------------------------- +// +int StateMachine::getDelay() +{ + return(delay); +} diff --git a/sketches/_PIO_Sketches/Karger/SoaapBleSlave_Test_2/src/StateMachine/StateMachine.h b/sketches/_PIO_Sketches/Karger/SoaapBleSlave_Test_2/src/StateMachine/StateMachine.h new file mode 100644 index 0000000000000000000000000000000000000000..b5a6ecea89a1a4a81795bf2992e52dd58bb350d2 --- /dev/null +++ b/sketches/_PIO_Sketches/Karger/SoaapBleSlave_Test_2/src/StateMachine/StateMachine.h @@ -0,0 +1,171 @@ +// --------------------------------------------------------------------------- +// File: StateMachine.cpp +// Editors: Robert Patzke, +// Start: 07. February 2018 +// Last change: 07. February 2018 +// URI/URL: www.mfp-portal.de, homeautomation.x-api.de +// Licence: Creative Commons CC-BY-SA +// --------------------------------------------------------------------------- +// + +#include "stdlib.h" + + +#ifndef _StateMachine_h +#define _StateMachine_h +// --------------------------------------------------------------------------- + +#define NrOfSteps 32 + +#define AUTBREAK(x,y) { x.enter(y); return; } + +// --------------------------------------------------------------------------- +// class StateMachine +// --------------------------------------------------------------------------- +// + +class StateMachine +{ + // ------------------------------------------------------------------------- + // class specific data types + // ------------------------------------------------------------------------- + // + typedef void (*StatePtr)(void); + typedef unsigned long (*MicsecFuPtr)(void); + +private: + // ------------------------------------------------------------------------- + // local variables + // ------------------------------------------------------------------------- + // + int delay; // Setting of delay for next state + int delaySet; // Setup value for repeated delays + bool repeatDelay; // If true, every state is delayed (speed set) + int repeatState; // Controlled repeating a state + bool useVarState; // breaking the fixed sequence of states by + // using a variable state (in futureState) + + bool useProgList; // control progList usage + bool loopProgList; // looping proglist + StatePtr progList[NrOfSteps]; // dynamically created state run list + int progIndex; // Program counter (index to next state) + int progEndIdx; // Index to next empty progList entry + StatePtr finProgState; // State after using state list + MicsecFuPtr micsFuPtr; // Pointer to micsec function + + bool firstEnterToggle; // Is set to true when state changes + int timeOutCounter; // automatic decremented counter + + bool timeMeasureOn; // control of the measurement counter + unsigned long timeMeasureCounter; // triggered automatic incremented counter + + int callCycleCnt; // For cycles inside a state + bool markToggle; // For bit complements + bool markOneShot; // for doing only one time + + unsigned int condCounter; // Counter for questionable conditions + + // ------------------------------------------------------------------------- + // local functions/methods + // ------------------------------------------------------------------------- + // + bool stayHere(); + +public: + // ------------------------------------------------------------------------- + // public variables + // ------------------------------------------------------------------------- + // + StatePtr nextState; // Pointer for indirect calling next state + StatePtr pastState; // Pointer of the past state + StatePtr futureState; // Pointer to a future state (see useVarState) + StatePtr doAlways; // Pointer to a always called state + int cycleTime; // Cycle time in milliseconds + int frequency; // Frequency in Hertz (1/s) + int userStatus; // A number presenting the visible state + + // statistic information + // + static int StateMachine_InstCounter; + + unsigned int noStateCounter; // Counter for empty running of state machine + unsigned int instNumber; // Number of this instance + unsigned int runCounter; // Counter for running states + unsigned int curStateNumber; // Number of current state + + unsigned long curStateRuntime; // run time of latest state + unsigned long maxStateRuntime[4]; // Maximum run time of a state + unsigned long maxRuntimeNumber[4]; // Number of the state of maximum runtime + + // error and debug support + // + int userError; + + // ------------------------------------------------------------------------- + // constructors and initialisations + // ------------------------------------------------------------------------- + // + StateMachine(); + StateMachine(StatePtr firstState, StatePtr anyState, int cycle); + void begin(StatePtr firstState, StatePtr anyState, int cycle); + StateMachine(StatePtr firstState, StatePtr anyState, int cycle, MicsecFuPtr micsecFu); + void begin(StatePtr firstState, StatePtr anyState, int cycle, MicsecFuPtr micsecFu); + + // ------------------------------------------------------------------------- + // user functions + // ------------------------------------------------------------------------- + // + void run(); // has to be cyclic called + void setDelay(int delayTime); // delay before next state + void setSpeed(int freq); // internal run frequency + + void enter(); // set next to future state + void enter(StatePtr state); // set next state to run + void enter(StatePtr state, int delayTime); // ... delayed + + void enterRep(StatePtr state, int count); // repeat next state + void enterRep(StatePtr state, int count, int delayTime); + + void call(StatePtr state); // set next state and return + void call(StatePtr state, int delayTime); // ... delayed + + void enterVia(StatePtr next, StatePtr future); // next and then + void enterVia(StatePtr next, StatePtr future, int delayTime); + + void enterList(StatePtr fin); + void enterList(StatePtr fin, int delayTime); + + void enterListAt(StatePtr fin, int index); + void enterListAt(StatePtr fin, int index, int delayTime); + + bool firstEnter(); // true only, if the state is first entered + void resetEnter(); // reset first enter mark + bool cycle(int cnt); // true only, if called <cnt> times + bool cycleSec(); // true only, if a second passed + bool toggle(); // alternating return true and false + bool oneShot(); // only one time true for a call + void setOneShot(); // preparing oneShot to be true + + void setTimeOut(int toValue); // Set time-out counter + bool timeOut(); // Check time-out counter + void startTimeMeasure(); // Start time measurement + int getTimeMeasure(bool stop); // Time in milliseconds + + unsigned long getExtTimeMeasure(bool stop); // Time in milliseconds + + void setCondCounter(unsigned int cntVal); // Set condition counter + bool condOpen(); // Ask for open conditions + + // ------------------------------------------------------------------------- + // debug functions + // ------------------------------------------------------------------------- + // + int getDelay(); + +}; + + + + +// --------------------------------------------------------------------------- +#endif diff --git a/sketches/_PIO_Sketches/Karger/SoaapBleSlave_Test_2/src/StateMachine/library.json b/sketches/_PIO_Sketches/Karger/SoaapBleSlave_Test_2/src/StateMachine/library.json new file mode 100644 index 0000000000000000000000000000000000000000..4dbee447df0f4ef48684a8d78288826ff419108f --- /dev/null +++ b/sketches/_PIO_Sketches/Karger/SoaapBleSlave_Test_2/src/StateMachine/library.json @@ -0,0 +1,4 @@ +{ + "name": "StateMachine", + "version": "0.0.0+20220823165932" +} \ No newline at end of file diff --git a/sketches/_PIO_Sketches/Karger/SoaapBleSlave_Test_2/src/environment/IntrfBuf.h b/sketches/_PIO_Sketches/Karger/SoaapBleSlave_Test_2/src/environment/IntrfBuf.h new file mode 100644 index 0000000000000000000000000000000000000000..c2f41d77dacb2618fee37685820740222e70b8b3 --- /dev/null +++ b/sketches/_PIO_Sketches/Karger/SoaapBleSlave_Test_2/src/environment/IntrfBuf.h @@ -0,0 +1,48 @@ +//----------------------------------------------------------------------------- +// Thema: Social Manufacturing Network / Development Environment +// Datei: IntrfBuf.h +// Editor: Robert Patzke +// URI/URL: www.mfp-portal.de +//----------------------------------------------------------------------------- +// Lizenz: CC-BY-SA (wikipedia: Creative Commons) +// Datum: 22. November 2021 +// +// Eine Schnittstelle zu Puffern (speziell Ringpuffer für Kommunikation) +// + +#ifndef IntrfBuf_h +#define IntrfBuf_h +// ---------------------------------------------------------------------------- + +#include "arduinoDefs.h" + + +class IntrfBuf +{ +public: + // -------------------------------------------------------------------------- + // Konfigurationen + // -------------------------------------------------------------------------- + // + + // -------------------------------------------------------------------------- + // Steuerfunktionen + // -------------------------------------------------------------------------- + // + + + // -------------------------------------------------------------------------- + // Datenzugriffe + // -------------------------------------------------------------------------- + // + virtual bool getByteSnd(byte *dest); // Byte aus Puffer zum Senden holen + // Rückgabe FALSE: Puffer leer + + virtual void putByteRec(byte b); // Byte vom Empfang an Puffer geben + + virtual int putSeq(byte *msg, int n); // Bytefolge an Puffer übergeben + +}; + +// ---------------------------------------------------------------------------- +#endif // IntrfBuf_h diff --git a/sketches/_PIO_Sketches/Karger/SoaapBleSlave_Test_2/src/environment/IntrfGpio.h b/sketches/_PIO_Sketches/Karger/SoaapBleSlave_Test_2/src/environment/IntrfGpio.h new file mode 100644 index 0000000000000000000000000000000000000000..d37fdf6765d077ac1bc20944080dc257f55e0a8a --- /dev/null +++ b/sketches/_PIO_Sketches/Karger/SoaapBleSlave_Test_2/src/environment/IntrfGpio.h @@ -0,0 +1,122 @@ +//----------------------------------------------------------------------------- +// Thema: Social Manufacturing Network / Development Environment +// Datei: IntrfGpio.h +// Editor: Robert Patzke +// URI/URL: www.mfp-portal.de +//----------------------------------------------------------------------------- +// Lizenz: CC-BY-SA (wikipedia: Creative Commons) +// Datum: 04. April 2022 +// +// Eine Schnittstelle zu den unterschiedlichen Ports in Mikrocontrollern +// + +#ifndef IntrfGpio_h +#define IntrfGpio_h +// ---------------------------------------------------------------------------- + +#include "arduinoDefs.h" + +typedef enum _ifPortNumber +{ + ifPort0, + ifPort1, + ifPort2, + ifPort3, + ifPort4, + ifPort5, + ifPort6, + ifPort7, + ifPort8, + ifPort9 +} ifPortNumber; + +typedef enum +{ + GEnoError, + GEcdictPar +} GpioError; + +typedef struct _GpioMask +{ + dword port; + dword pins; +} GpioMask, *GpioMaskPtr; + +typedef struct _GpioExtMask +{ + dword port; + dword pins; + _GpioExtMask *next; +} GpioExtMask, *GpioExtMaskPtr; + +typedef struct _GpioRef +{ + dword *ioPtr; + dword pins; +} GpioRef, *GpioRefPtr; + +typedef struct _GpioExtRef +{ + dword *ioPtr; + dword pins; + _GpioExtRef *next; +} GpioExtRef, *GpioExtRefPtr; + +typedef struct _GpioExtVal +{ + dword value; + _GpioExtVal *next; +} GpioExtVal, *GpioExtValPtr; + +// Spezifikation der Schnittstellentreiber +// +#define IfDrvInput 0x0000 +#define IfDrvOutput 0x0001 +#define IfDrvStrongHigh 0x0002 +#define IfDrvStrongLow 0x0004 +#define IfDrvOpenDrain 0x0008 +#define IfDrvOpenSource 0x0010 +#define IfDrvPullUp 0x0020 +#define IfDrvPullDown 0x0040 +#define IfDrvPullStrong 0x0080 + +typedef enum +{ + ArdD2D5, + ArdA0A3, + ArdA4A5, + ArdA0A5, + ArdA4A7, + ArdA0A7 +} ArdMask; + +class IntrfGpio +{ +public: + + //virtual ~IntrfGpio(); + + // -------------------------------------------------------------------------- + // Konfigurationen + // -------------------------------------------------------------------------- + // + virtual GpioError config(int nr, unsigned int cnfBits, GpioExtRefPtr refPtr); + virtual GpioError config(int nrFrom, int nrTo, unsigned int cnfBits, GpioExtRefPtr refPtr); + virtual GpioError config(GpioExtMask mask, unsigned int cnfBits, GpioExtRefPtr refPtr); + virtual GpioError configArd(ArdMask ardMask, unsigned int cnfBits); + + // -------------------------------------------------------------------------- + // Anwendungsfunktionen + // -------------------------------------------------------------------------- + // + virtual void read(GpioExtRefPtr refPtr, GpioExtValPtr valPtr); + virtual dword readArd(ArdMask ardMask); + + virtual void write(GpioExtRefPtr refPtr, GpioExtValPtr valPtr); + virtual void writeArd(ArdMask ardMask, dword value); + virtual void set(GpioExtRefPtr refPtr); + virtual void clr(GpioExtRefPtr refPtr); +}; + +// ---------------------------------------------------------------------------- +#endif //IntrfGpio_h diff --git a/sketches/_PIO_Sketches/Karger/SoaapBleSlave_Test_2/src/environment/IntrfRadio.h b/sketches/_PIO_Sketches/Karger/SoaapBleSlave_Test_2/src/environment/IntrfRadio.h new file mode 100644 index 0000000000000000000000000000000000000000..470277ab4f365581507365d1f412a47683463662 --- /dev/null +++ b/sketches/_PIO_Sketches/Karger/SoaapBleSlave_Test_2/src/environment/IntrfRadio.h @@ -0,0 +1,154 @@ +//----------------------------------------------------------------------------- +// Thema: Social Manufacturing Network / Development Environment +// Datei: IntrfRadio.h +// Editor: Robert Patzke +// URI/URL: www.mfp-portal.de +//----------------------------------------------------------------------------- +// Lizenz: CC-BY-SA (wikipedia: Creative Commons) +// Datum: 9. Mai 2021 +// +// Eine Schnittstelle zu den unterschiedlichen Transceivern in Mikrocontrollern +// oder Boards mit Mikrocontrollern und Radio-Transceivern +// + +#ifndef IntrfRadio_h +#define IntrfRadio_h +// ---------------------------------------------------------------------------- + +#include "arduinoDefs.h" +#include "bleSpec.h" + +typedef struct _TxState +{ + unsigned int prgLoopPrep; + unsigned int evtLoopRampUp; + unsigned int evtLoopTrans; + byte * txBufferPtr; +} TxState, *TxStatePtr; + +typedef struct _Channel +{ + int idx; + int freq; +} Channel, *ChannelPtr; + +// Zustand des Datenempfangs (Bit) +// +#define RECSTAT_ADDRESS 0x0001 +#define RECSTAT_PAYLOAD 0x0002 +#define RECSTAT_END 0x0004 +#define RECSTAT_DISABLED 0x0008 +#define RECSTAT_CRCOK 0x0010 + +// Modi für das Senden von Telegrammen +// +typedef enum _TxMode +{ + txmBase, // Einzelne Sendung, Endezustand DISABLED + txmRepStart, // Wiederholte Sendung Start, Endezustand END + txmRepCont, // Wiederholte Sendung Fortsetzung, Endezustand END + txmRepEnd, // Wiederholte Sendung Ende, Endezustand DISABLED + txmReadPrep, // Einzelne Sendung mit Empfangsvorbereitung, Endezustand READY + txmRead, // Einzelne Sendung und Empfang, Endezustand END + txmPoll, // Einzelne Sendung und Empfang, Endezustand DISABLED + txmReadS, // Einzelne sendung und Empfang mit Daten, Endezustand END + txmRespE, // Empfang für spezifische Antwort (leeres Polling) + txmResp // Empfang für spezifische Antwort (Datenübertragung) +} TxMode; +// +#define NrOfTxModes 10 + +// Protokollspezifische Adresseninhalte und Festlegungen +// +#define PollPduSize 8 +#define PollAdrSize 6 + +// len = PduMem[1] +#define BLE_LEN pduMem[1] +// Adr[1] = PduMem[3] +#define BLE_ADR1 pduMem[3] + +#define SOAAP_NAK 0x40 +#define SOAAP_EADR 0x80 + +// Modeabhängige Statistikdaten +// +typedef struct _TxStatistics +{ + TxMode mode; + dword interrupts; + dword recs; + dword sendings; + dword aliens; + dword wrongs; + dword pollAcks; + dword pollNaks; + dword crcErrors; + dword intErrors; + byte memDumpRec[16]; + byte memDumpSnd[16]; +} TxStatistics, *TxStatisticsPtr; + +class IntrfRadio +{ +public: + // Kanalfrequenzen (Offsets zur Basisfrequenz) und Whitening-Preset + // Die ersten 3 Kanäle sind Bewerbungskanäle. + // Daran anschließend sind die Kanäle grob nach Frequenz einsortiert. + // Diese Liste kann zur Laufzeit an Störungen angepasst werden und wird aufsteigend angewendet + // + Channel channelList[40] = + { + {37, 2} , {38,26} , {39,80} , { 1, 6} , { 3,10} , { 5,14} , { 7,18} , { 9,22} , + {12,30} , {14,34} , {16,38} , {18,42} , {20,46} , {22,50} , {24,54} , {26,58} , + {28,62} , {30,66} , {32,70} , {34,74} , {35,76} , { 2, 8} , { 4,12} , { 6,16} , + { 8,20} , {33,72} , {31,68} , {13,32} , {15,36} , {17,40} , {19,44} , {21,48} , + {23,52} , {25,56} , {27,60} , {29,64} , {11,28} , {10,24} , { 0, 4} , {36,78} + }; + + //virtual ~IntrfRadio(); + + // -------------------------------------------------------------------------- + // Konfigurationen + // -------------------------------------------------------------------------- + // + virtual void begin(); + virtual void setAccessAddress(dword addr); + virtual void setPacketParms(blePduType type); + + // -------------------------------------------------------------------------- + // Steuerfunktionen + // -------------------------------------------------------------------------- + // + virtual void setChannel(int chnr); // Schalten physikalischer Kanal + virtual int sendSync(bcPduPtr inPduPtr, TxStatePtr refState); + + virtual void send(bcPduPtr inPduPtr, TxMode txMode); + virtual void send(bcPduPtr inPduPtrE, bcPduPtr inPduPtrS, TxMode txMode, bool newValues); + // Senden (und/oder Empfang) eines Telegramms in einem festgelegten Modus + + virtual void disable(TxMode txMode); // Funk AUS für Betriebswechsel + virtual bool disabled(TxMode txMode); // Abfrage, ob ausgeschaltet + virtual void cont(TxMode txMode); // aktuellen Vorgang fortsetzen + virtual bool fin(TxMode txMode, bool *err); // Abfrage ob aktueller Vorgang beendet +// virtual int getRecData(bcPduPtr data, TxMode txMode, int max); // Lennard: Deaktiviert + + virtual int startRec(); // Datenempfang starten + virtual int contRec(); // Datenempfang fortsetzen + virtual int endRec(); // Datenempfang beenden + virtual int checkRec(); // Zustand Datenempfang feststellen + virtual int getRecData(bcPduPtr data, int max); // Empfangene Daten lesen + + virtual void setPower(int DBm); // Leistung des Senders in DBm + + // -------------------------------------------------------------------------- + // Datenzugriffe + // -------------------------------------------------------------------------- + // + virtual int getStatistics(TxStatisticsPtr dest); + virtual int getState(); // Chip-abhängiger Funk-Status + +}; + +// ---------------------------------------------------------------------------- +#endif // IntrfRadio_h diff --git a/sketches/_PIO_Sketches/Karger/SoaapBleSlave_Test_2/src/environment/IntrfSerial.h b/sketches/_PIO_Sketches/Karger/SoaapBleSlave_Test_2/src/environment/IntrfSerial.h new file mode 100644 index 0000000000000000000000000000000000000000..909a810a3282ef0e1ee36e79286bd5c4df0bb929 --- /dev/null +++ b/sketches/_PIO_Sketches/Karger/SoaapBleSlave_Test_2/src/environment/IntrfSerial.h @@ -0,0 +1,101 @@ +//----------------------------------------------------------------------------- +// Thema: Social Manufacturing Network / Development Environment +// Datei: IntrfSerial.h +// Editor: Robert Patzke +// URI/URL: www.mfp-portal.de +//----------------------------------------------------------------------------- +// Lizenz: CC-BY-SA (wikipedia: Creative Commons) +// Datum: 17. November 2021 +// +// Eine Schnittstelle zu den seriellen Schnittstellen in Mikrocontrollern +// oder Boards mit Mikrocontrollern und seriellen schnittstellen +// + +#ifndef IntrfSerial_h +#define IntrfSerial_h +// ---------------------------------------------------------------------------- + +#include "arduinoDefs.h" +#include "IntrfBuf.h" + +typedef enum _SerSpeed +{ + Baud1200, + Baud2400, + Baud4800, + Baud9600, + Baud14400, + Baud19200, + Baud28800, + Baud31250, + Baud38400, + Baud56000, + Baud57600, + Baud76800, + Baud115200, + Baud230400, + Baud250000, + Baud460800, + Baud921600, + Baud1Meg +} SerSpeed; + +typedef enum _SerType +{ + stStd, // Typischer Ausgang ca. 2 mA + stPow, // Starker Ausgang ca. 10 mA + stCur // Open Collector/Drain ca. 10 mA Stromschleife +} SerType; + +typedef struct _SerParams +{ + int inst; // Nummer (Index) der Ser-Instanz + int txdPort; // Nummer (Index) des Port fuer TX + int txdPin; // Nummer (Index) des Pin fuer TX + int rxdPort; // Nummer (Index) des Port fuer RX + int rxdPin; // Nummer (Index) des Pin fuer RX + SerSpeed speed; // Bitrate (Baud) + SerType type; // Ausgang +} SerParams, *SerParamsPtr; + +typedef enum _SerError +{ + SEnoError +} SerError; + + +class IntrfSerial +{ +public: + // -------------------------------------------------------------------------- + // Konfigurationen + // -------------------------------------------------------------------------- + // + virtual void begin(SerParamsPtr serParPtr, IntrfBuf * bufferIf); + + // -------------------------------------------------------------------------- + // Steuerfunktionen + // -------------------------------------------------------------------------- + // + virtual void resuSend(); // Fortsetzen des Interrupt-Sendebetriebs + virtual void startSend(); // Starten des Sendebetriebs + virtual void stopSend(); // Anhalten des Sendebetriebs + + virtual void startRec(); // Starten des Empfangsbetriebs + virtual void stopRec(); // Anhalten des Empfangsbetriebs + + + // -------------------------------------------------------------------------- + // Datenzugriffe + // -------------------------------------------------------------------------- + // + virtual bool condSend(byte c); // Bedingtes Senden eines Zeichens + + virtual int getLastError(); // Letzten Fehler lesen (Bits) + virtual int getAnyError(); // Alle vorgekommenen Fehlerbits + virtual dword getErrCount(); // Anzahl der Fehler lesen + +}; + +// ---------------------------------------------------------------------------- +#endif // IntrfRadio_h diff --git a/sketches/_PIO_Sketches/Karger/SoaapBleSlave_Test_2/src/environment/IntrfTimer.h b/sketches/_PIO_Sketches/Karger/SoaapBleSlave_Test_2/src/environment/IntrfTimer.h new file mode 100644 index 0000000000000000000000000000000000000000..2777f5ba7b80b1116baa9030c452037dc4507952 --- /dev/null +++ b/sketches/_PIO_Sketches/Karger/SoaapBleSlave_Test_2/src/environment/IntrfTimer.h @@ -0,0 +1,55 @@ +//----------------------------------------------------------------------------- +// Thema: Social Manufacturing Network / Development Environment +// Datei: IntrfTimer.h +// Editor: Robert Patzke +// URI/URL: www.mfp-portal.de +//----------------------------------------------------------------------------- +// Lizenz: CC-BY-SA (wikipedia: Creative Commons) +// Datum: 29. Juni 2021 +// +// Eine Schnittstelle zu den unterschiedlichen Timern in Mikrocontrollern +// + +#ifndef IntrfTimer_h +#define IntrfTimer_h +// ---------------------------------------------------------------------------- + +#include "arduinoDefs.h" + +typedef enum _ifTimerNumber +{ + ifTimer0, + ifTimer1, + ifTimer2, + ifTimer3, + ifTimer4, + ifTimer5, + ifTimer6, + ifTimer7, + ifTimer8, + ifTimer9 +} ifTimerNumber; + +class IntrfTimer +{ +public: + + //virtual ~IntrfTimer(); + + // -------------------------------------------------------------------------- + // Konfigurationen + // -------------------------------------------------------------------------- + // + virtual void setMilli(ifTimerNumber timNr, int milliSec, int repeat); + //virtual void setMilli(ifTimerNumber timNr, int milliSec, int repeat, dword ISR); + + // -------------------------------------------------------------------------- + // Steuerfunktionen + // -------------------------------------------------------------------------- + // + virtual bool milli(); // Abfrage des Timer, <true> wenn abgelaufen + +}; + +// ---------------------------------------------------------------------------- +#endif //IntrfTimer_h diff --git a/sketches/_PIO_Sketches/Karger/SoaapBleSlave_Test_2/src/environment/IntrfTw.h b/sketches/_PIO_Sketches/Karger/SoaapBleSlave_Test_2/src/environment/IntrfTw.h new file mode 100644 index 0000000000000000000000000000000000000000..f0d97b622e98f8f48ee8f066912caf1b4723bc89 --- /dev/null +++ b/sketches/_PIO_Sketches/Karger/SoaapBleSlave_Test_2/src/environment/IntrfTw.h @@ -0,0 +1,125 @@ +//----------------------------------------------------------------------------- +// Thema: Social Manufacturing Network / Development Environment +// Datei: IntrfTw.h +// Editor: Robert Patzke +// URI/URL: www.mfp-portal.de +//----------------------------------------------------------------------------- +// Lizenz: CC-BY-SA (wikipedia: Creative Commons) +// Datum: 3. Juni 2021 +// +// Eine Schnittstelle zu den unterschiedlichen I2C Schnittstellen +// oder Boards mit geeigneten Mikrocontrollern +// + +#ifndef IntrfTw_h +#define IntrfTw_h +// ---------------------------------------------------------------------------- + +#include "arduinoDefs.h" + +typedef enum _TwiDevType +{ + TwiMaster, + TwiSlave +} TwiDevType; + +typedef enum _TwiSpeed +{ + Twi100k, // Standard, sollte unterstützt werden + Twi250k, + Twi400k // Schnell, sollte unterstützt werden +} TwiSpeed; + +typedef struct _TwiParams +{ + int inst; // Nummer (Index) der Twi-Instanz + TwiDevType type; // Auswahl Master/Slave + int clkPort; // Nummer (Index) des Port fuer Takt + int clkPin; // Nummer (Index) des Pin fuer Takt + int dataPort; // Nummer (Index) des Port fuer Daten + int dataPin; // Nummer (Index) des Pin fuer Daten + TwiSpeed speed; +} TwiParams, *TwiParamsPtr; + +typedef enum _TwiError +{ + TEnoError +} TwiError; + +typedef enum _TwiStatus +{ + TwStUnborn, + TwStRdReq, + TwStWrReq, + TwStSent, + TwStRecvd, + TwStFin = 0x0080, + TwStError = 0x0100, + TwStOverrun = 0x0101, + TwStAdrNak = 0x0102, + TwStDataNak = 0x0104 +} TwiStatus; + +typedef struct _TwiByte +{ + TwiStatus twiStatus; + byte value; +} TwiByte, *TwiBytePtr; + +typedef struct _TwiWord +{ + TwiStatus twiStatus; + word value; +} TwiWord, *TwiWordPtr; + +typedef struct _TwiByteSeq +{ + TwiStatus twiStatus; + int len; + byte *valueRef; +} TwiByteSeq, *TwiByteSeqPtr; + + +class IntrfTw +{ +public: + // -------------------------------------------------------------------------- + // Konstruktoren und Initialisierungen + // -------------------------------------------------------------------------- + // + virtual TwiError begin(TwiParamsPtr inParPtr); + + //virtual ~IntrfTw(); + + // -------------------------------------------------------------------------- + // Konfigurationen + // -------------------------------------------------------------------------- + // + virtual void getParams(TwiParamsPtr parPtr); + + // -------------------------------------------------------------------------- + // Steuerfunktionen + // -------------------------------------------------------------------------- + // + + // -------------------------------------------------------------------------- + // Datenaustausch + // -------------------------------------------------------------------------- + // + // asynchrone Kommunikation, Zustand in TwiByte.twiStatus + // + virtual TwiError sendByte(int adr, TwiBytePtr refByte); + virtual TwiError sendByteReg(int adr, int reg, TwiBytePtr refByte); + virtual TwiError recByteReg(int adr, int reg, TwiBytePtr refByte); + virtual TwiError recByteRegSeq(int adr, int reg, TwiByteSeqPtr refByteSeq); + + // synchrone Kommunikation + // + virtual TwiStatus writeByteReg(int adr, int reg, byte value); + virtual int readByteReg(int adr, int reg); + virtual TwiStatus readByteRegSeq(int adr, int reg, TwiByteSeqPtr refByteSeq); + +}; + +// ---------------------------------------------------------------------------- +#endif // IntrfTw_h diff --git a/sketches/_PIO_Sketches/Karger/SoaapBleSlave_Test_2/src/environment/SoaapBleMaster.h b/sketches/_PIO_Sketches/Karger/SoaapBleSlave_Test_2/src/environment/SoaapBleMaster.h new file mode 100644 index 0000000000000000000000000000000000000000..98bd22eb99c0839cf9f5ad554dd116b21c0afd81 --- /dev/null +++ b/sketches/_PIO_Sketches/Karger/SoaapBleSlave_Test_2/src/environment/SoaapBleMaster.h @@ -0,0 +1,63 @@ +// ---------------------------------------------------------------------------- +// SoaapBleMaster.h +// Beispielhafte Anwendung SOAAP / Steuerung optischer und akustischer Ausgaben +// Kommunikation über BLE-Funkanäle mit Bewerbungstelegrammen +// P o l l i n g - M a s t e r +// ---------------------------------------------------------------------------- +// Editor: Robert Patzke +// URI/URL: www.mfp-portal.de +//----------------------------------------------------------------------------- +// Lizenz: CC-BY-SA (wikipedia: Creative Commons) +// Datum: 1. November 2021 +// Letzte Bearbeitung: 15. März 2022 +// + +#ifndef SoaapBleMaster_h +#define SoaapBleMaster_h + +// Vordefinitionen, Festlegungen zur Kompilierung +// +#define DebugTerminal +// Mit dieser Definition werden die Klasse Monitor und weitere Testmethoden +// eingebunden, womit ein anwendungsorientiertes Debugging möglich ist + +//#define TEST001 +// Ausgaben an serielle schnittstelle zur Prüfung der ap-Zustandsmaschine + +#include "LoopCheck.h" +#include "StateMachine.h" +#include "nRF52840Radio.h" +#include "BlePoll.h" +#include "ComRingBuf.h" +#include "nRF52840Ser.h" +#include "SoaapMsg.h" +#include "Monitor.h" + +// ---------------------------------------------------------------------------- +// Vorwärtsreferenzen +// ---------------------------------------------------------------------------- +// +void ctrlIdle(); +void ctrlInit(); +void sendCtrl(); +void checkCtrl(); + +void apInit(); +void apWaitDE(); +void apWaitMeas(); +void apProcMeas(); + + +#ifdef DebugTerminal +// ---------------------- +void smInit() ; +void smCheckJobs() ; +void smDebDword() ; +void smCtrlPolling() ; +void smWaitPolling() ; +void smReadPollValues() ; +void smCheckSer(); +// ---------------------- +#endif + +#endif /* SoaapBleMaster_h */ diff --git a/sketches/_PIO_Sketches/Karger/SoaapBleSlave_Test_2/src/environment/SoaapBleSlave.h b/sketches/_PIO_Sketches/Karger/SoaapBleSlave_Test_2/src/environment/SoaapBleSlave.h new file mode 100644 index 0000000000000000000000000000000000000000..f3ae7f7500126e35f19524b4188a3044d43dfaf4 --- /dev/null +++ b/sketches/_PIO_Sketches/Karger/SoaapBleSlave_Test_2/src/environment/SoaapBleSlave.h @@ -0,0 +1,43 @@ +#ifndef SoaapBleSlave_h +#define SoaapBleSlave_h + +#include "LoopCheck.h" +#include "StateMachine.h" +#include "nRF52840Radio.h" +#include "BlePoll.h" +#include "ComRingBuf.h" +#include "nRF52840Ser.h" +#include "SoaapMsg.h" +#include "Monitor.h" +#include "nRF52840Twi.h" +#include "SensorLSM9DS1.h" +#include "nRF52840Gpio.h" + +//#define SlaveACM1 +bool sendData(PlpType plpType, byte *dest); +bool getValues(PlpType plpType, byte *dest); +void smInit(); +void smCheckJobs(); +void smCheckSens(); + +void smDebDword(); +void smCtrlPolling(); +void smWaitPolling(); +void smSensReset1(); +void smSensReset2(); + +void smSensGetValues1(); +void smSensGetValues2(); +void smSensGetValues3(); +void smSensGetValues4(); +void smSensGetValues5(); +void smSensGetValues6(); +void smSensGetValues7(); + +void smSensGetSoaapValues(); +void smSensDebugValues(); + +void smSensGetErrors(); +void smSensGetTimeOuts(); +void smSensGetRunCounts(); +#endif \ No newline at end of file diff --git a/sketches/_PIO_Sketches/Karger/SoaapBleSlave_Test_2/src/environment/arduinoDefs.h b/sketches/_PIO_Sketches/Karger/SoaapBleSlave_Test_2/src/environment/arduinoDefs.h new file mode 100644 index 0000000000000000000000000000000000000000..4830c5d860683336800903c177b10c53fcb73736 --- /dev/null +++ b/sketches/_PIO_Sketches/Karger/SoaapBleSlave_Test_2/src/environment/arduinoDefs.h @@ -0,0 +1,53 @@ +//----------------------------------------------------------------------------- +// Thema: Social Manufacturing Network / Definitions instead Arduino +// Datei: arduinoDefs.h +// Editor: Robert Patzke +// URI/URL: www.mfp-portal.de +//----------------------------------------------------------------------------- +// Lizenz: CC-BY-SA (wikipedia: Creative Commons) +// +// These definitions shall encapsulate the Arduino environment +// The file should be included instead of Arduino.h for arbitrary environments +// + +#ifndef _arduinoDefs_h +#define _arduinoDefs_h + +// --------------------------------------------------------------------------- +// Simple type definitions and settings +// --------------------------------------------------------------------------- +// +#undef byte +#undef word +#undef dword + +#define byte unsigned char +#define word unsigned short +#define dword unsigned long + +#ifdef smnLinGcc64 + +#undef byte +#undef word +#undef dword + +#define byte unsigned char +#define word unsigned short +#define dword unsigned int + +#endif + +// --------------------------------------------------------------------------- +// Complex type definitions +// --------------------------------------------------------------------------- +// The following types are more complex definitions with Arduino. +// But here simple types are used if possible, because we only care for the +// environment that is needed by Social Manufacturing Network +// + +#ifndef IPAddress + #define IPAddress byte * +#endif + + +#endif // _arduinoDefs_h diff --git a/sketches/_PIO_Sketches/Karger/SoaapBleSlave_Test_2/src/environment/bleSpec.h b/sketches/_PIO_Sketches/Karger/SoaapBleSlave_Test_2/src/environment/bleSpec.h new file mode 100644 index 0000000000000000000000000000000000000000..a4993a39fee05fa5162fc888acf0804e5fc59254 --- /dev/null +++ b/sketches/_PIO_Sketches/Karger/SoaapBleSlave_Test_2/src/environment/bleSpec.h @@ -0,0 +1,86 @@ +//----------------------------------------------------------------------------- +// Thema: Social Manufacturing Network / Development Environment +// Datei: bleSpec.h +// Editor: Robert Patzke +// URI/URL: www.mfp-portal.de +//----------------------------------------------------------------------------- +// Lizenz: CC-BY-SA (wikipedia: Creative Commons) +// Datum: 8. Mai 2021 +// +// Der Inhalt dieser Datei ist der Blootooth Spezifikation 5.2 entnommen +// bzw. daran angelehnt. +// Insbesondere dem Teil 6, Low Energy Controller +// + +#ifndef bleSpec_h +#define bleSpec_h +// ---------------------------------------------------------------------------- + +#ifndef octet +typedef unsigned char octet; +#endif + +#define VersionBTS 52 +#define TypeBTS BLE + +// ---------------------------------------------------------------------------- +// Festlegungen für die Bewerbungskanäle (Advertizing Physical Channels) +// ---------------------------------------------------------------------------- + +// Basisfrequenz in MHz +#define BaseFrequency 2400 + +// Zugriffsadresse (Access Address) +#define AdvAccAddr 0x8E89BED6 + +// CRC-Polynom +#define PolynomCRC 0x0100065B + +// CRC-Startwert +#define AdvStartCRC 0x555555 + +// Geräteadresse +typedef octet BD_ADR[6]; + +// Telegrammtypen (PDU Types) +#define ADV_IND 0x0 +#define ADV_DIRECT_IND 0x1 +#define ADV_NONCONN_IND 0x2 +#define SCAN_REQ 0x3 +#define SCAN_RSP 0x4 +#define CONNECT_IND 0x5 +#define ADV_SCAN_IND 0x6 + +// Kennzeichnung Art der Geräteadresse (Device Address Mark, TxAdd = 1, random) +#define DevAdrType 0x2 + +// Telegrammkopf ohne Längenbyte +#define HeadS0B ((ADV_NONCONN_IND << 4) | DevAdrType) +#define HeadS0BS ((ADV_SCAN_IND << 4) | DevAdrType) + +// Datenstruktur für das zu sendende Telegramm +// bei der Bewerbung (Advertising) +// +typedef struct _bcPdu // Beacon - PDU +{ + byte head; // Header = PDU-Typ und Adresskennung (S0 bei nRF52840) + byte len; // Länge des Telegramms inkl. Adresse (LENGTH bei nRF52840) + byte adr0; // niedrigstwertiges Adressbyte (S1 bei nRF52840) + byte adr1; // + byte adr2; // Das ist die Geräteadresse, die hier wahlfrei ist + byte adr3; // Sie wird zur Identifikation des Gerätes verwendet + byte adr4; // + byte adr5; // höchstwertiges Addressbyte + byte data[31]; // Nutzdaten (maximale Anzahl nach BLE-Spez.) +} bcPdu, *bcPduPtr; + +// Telegrammtypen +// +typedef enum _blePduType +{ + bptAdv, // Standard-Bewerbungstelegramm + bptAux +} blePduType; + +// ---------------------------------------------------------------------------- +#endif // bleSpec_h diff --git a/sketches/_PIO_Sketches/Karger/SoaapBleSlave_Test_2/src/environment/environment.h b/sketches/_PIO_Sketches/Karger/SoaapBleSlave_Test_2/src/environment/environment.h new file mode 100644 index 0000000000000000000000000000000000000000..311c3331bd39a97884ba12b85375b08a418813d0 --- /dev/null +++ b/sketches/_PIO_Sketches/Karger/SoaapBleSlave_Test_2/src/environment/environment.h @@ -0,0 +1,126 @@ +//----------------------------------------------------------------------------- +// Thema: Social Manufacturing Network / Development Environment +// Datei: environment.h +// Editor: Robert Patzke +// URI/URL: www.mfp-portal.de +//----------------------------------------------------------------------------- +// Lizenz: CC-BY-SA (wikipedia: Creative Commons) +// + +#ifndef _environment_h +#define _environment_h + +#ifdef smnDEFBYBUILD + +// Alternative Festlegungen durch Settings in der Build-Umgebung der IDE +// Das erspart die Verwaltung mehrerer/unterschiedlicher environment.h Dateien +// in den Projekten +// + #ifdef smnUBUNTU_ECLIPSE + // Meine Entwicklungs- und Testumgebung auf dem Notebook unter UBUNTU + // für Sketche, die auf dem PC laufen (u.a. zum Debuggen) + + #define smnSimLinux + #define smnNotebook + #define smnLINUX + #define smnDebugLinuxConsole + + #endif + + #ifdef smnWIN32_VS + // Meine Entwicklungs- und Testumgebung auf dem Notebook unter Windows + // für Sketche, die auf dem PC laufen (u.a. zum Debuggen) + + #define smnSimWindows + #define smnNotebook + #define smnWIN32 + #define smnDebugWindowsConsole + + #endif + + #ifdef smnSLOELIN + // Mit Sloeber auf Ubuntu/Linux für Entwicklungen zum ESP32 + // + + #define smnDebugArduino + #define smnSloeber + #define smnESP32_DEV + #define smnESP32 + #define smnSerial Serial + #endif + + #ifdef smnSLOEDUE + // Mit Sloeber auf Ubuntu/Linux für Entwicklungen zum Arduino Due + // + + #define smnDebugArduino + #define smnSloeber + #define smnArduinoDUE + #define smnArduinoShieldEth + #define smnSAM3X + #define smnSerial Serial + #endif + + #ifdef smnNANOBLE33 + #define smnDebugArduino + #define smnSloeber + #define smnArduinoNanoBLE33 + #define smnNRF52840 + #define smnSerial Serial + #endif + + #ifdef smnSLOESAMD21 + #define smnDebugArduino + #define smnSloeber + #define smnArduinoZeroSamD21 + #define smnSAMD21G18 + #define smnSD21MINI + #define smnSerial SerialUSB + #endif + +#else + +// Die Definitionen werden hier in den meisten Fällen grundsetzlich ausgewertet, +// nicht über spezifische Werte. +// Die Abfrage geschieht also mit #ifdef +// Daraus folgt hier eine Liste der Möglichkeiten, die beliebig erweitert werden kann. +// Die Auswahl erfolgt schließlich über aus- bzw. einkommentieren. +// + +// Übergeordnete Festlegungen +// --------------------------------------------------------------------------- +// +#define smnDebugArduino +//#define smnDebugLinuxConsole +// + +// IDE, Editor, etc. +// --------------------------------------------------------------------------- +// +//#define smnSimLinux +#define smnSloeber +//#define smnArduinoIDE +//#define smnPlatformIO + +// Hardware, Boards, etc. +// --------------------------------------------------------------------------- +// +//#define smnNotebook +//#define smnESP32_DEV +#define smnNodeMCU10 +//#define smnArduinoDUE +//#define smnArduinoShieldEth +//#define smnArduinoShieldWiFi +#define smnSerial Serial + +// Prozessoren, Microcontroller, Betriebssysteme, etc. +// --------------------------------------------------------------------------- +// +//#define smnLINUX +//#define smnESP32 +#define smnESP8266 +//#define smnSAM3X + +#endif // smnDEFBYBUILD + +#endif // _environment_h diff --git a/sketches/_PIO_Sketches/Karger/SoaapBleSlave_Test_2/src/environment/library.json b/sketches/_PIO_Sketches/Karger/SoaapBleSlave_Test_2/src/environment/library.json new file mode 100644 index 0000000000000000000000000000000000000000..9e3641f6fb0e38c5e74b3c3cee96651efbb2fdaa --- /dev/null +++ b/sketches/_PIO_Sketches/Karger/SoaapBleSlave_Test_2/src/environment/library.json @@ -0,0 +1,4 @@ +{ + "name": "environment", + "version": "0.0.0+20220823165932" +} \ No newline at end of file diff --git a/sketches/_PIO_Sketches/Karger/SoaapBleSlave_Test_2/src/environment/socManNetUser.h b/sketches/_PIO_Sketches/Karger/SoaapBleSlave_Test_2/src/environment/socManNetUser.h new file mode 100644 index 0000000000000000000000000000000000000000..4809a3b98de3da0b84f1f25ba7cda8af91bb2672 --- /dev/null +++ b/sketches/_PIO_Sketches/Karger/SoaapBleSlave_Test_2/src/environment/socManNetUser.h @@ -0,0 +1,315 @@ +//----------------------------------------------------------------------------- +// Thema: Social Manufacturing Network / Broadcast Socket Interface +// Datei: socManNetUser.h +// Editor: Igor Farber, Robert Patzke +// URI/URL: www.mfp-portal.de +//----------------------------------------------------------------------------- +// Lizenz: CC-BY-SA (wikipedia: Creative Commons) +// + +#ifndef _socManNetUser_h +#define _socManNetUser_h + +#define smnMULTIBOARDS + +#define smnBOARD001 +//#define smnBOARD002 +//#define smnBOARD003 +//#define smnBOARD004 +//#define smnBOARD005 +//#define smnBOARD006 + + + +#ifndef smnMyNet +// *************************************************************************** +// define smnMyNet in project properties (Arduino) with -DsmnMyNet +// to use your own network definition file included at the end of this file + + +//---------------------------------------------------------------------------// +//------------------------------------------------------------------------- +// MAC-Adresse des Ethernet-Shield +//------------------------------------------------------------------------- +#ifdef smnMULTIBOARDS + + #ifdef smnBOARD001 + #define LOCAL_MAC_ADR_B0 0x90 + #define LOCAL_MAC_ADR_B1 0xa2 + #define LOCAL_MAC_ADR_B2 0xda + #define LOCAL_MAC_ADR_B3 0x0f + #define LOCAL_MAC_ADR_B4 0x1b + #define LOCAL_MAC_ADR_B5 0x84 + // MAC-Adresse + + #define LOCAL_MAC_ADR_STR (char *) "90-a2-da-0f-1b-84" + // MAC-Adresse als String + #endif + + #ifdef smnBOARD002 + #define LOCAL_MAC_ADR_B0 0x90 + #define LOCAL_MAC_ADR_B1 0xa2 + #define LOCAL_MAC_ADR_B2 0xda + #define LOCAL_MAC_ADR_B3 0x0f + #define LOCAL_MAC_ADR_B4 0x63 + #define LOCAL_MAC_ADR_B5 0xb0 + // MAC-Adresse + + #define LOCAL_MAC_ADR_STR (char *) "90-a2-da-0f-63-b0" + // MAC-Adresse als String + #endif + + #ifdef smnBOARD003 + #define LOCAL_MAC_ADR_B0 0x90 + #define LOCAL_MAC_ADR_B1 0xa2 + #define LOCAL_MAC_ADR_B2 0xda + #define LOCAL_MAC_ADR_B3 0x0f + #define LOCAL_MAC_ADR_B4 0x5b + #define LOCAL_MAC_ADR_B5 0xe1 + // MAC-Adresse + + #define LOCAL_MAC_ADR_STR (char *) "90-a2-da-0f-5b-e1" + // MAC-Adresse als String + #endif + + #ifdef smnBOARD004 + #define LOCAL_MAC_ADR_B0 0x90 + #define LOCAL_MAC_ADR_B1 0xa2 + #define LOCAL_MAC_ADR_B2 0xda + #define LOCAL_MAC_ADR_B3 0x0f + #define LOCAL_MAC_ADR_B4 0x5b + #define LOCAL_MAC_ADR_B5 0x8f + // MAC-Adresse + + #define LOCAL_MAC_ADR_STR (char *) "90-a2-da-0f-62-d0" + // MAC-Adresse als String + #endif + + #ifdef smnBOARD005 + #define LOCAL_MAC_ADR_B0 0x90 + #define LOCAL_MAC_ADR_B1 0xa2 + #define LOCAL_MAC_ADR_B2 0xda + #define LOCAL_MAC_ADR_B3 0x0f + #define LOCAL_MAC_ADR_B4 0x62 + #define LOCAL_MAC_ADR_B5 0xd0 + // MAC-Adresse + + #define LOCAL_MAC_ADR_STR (char *) "90-a2-da-0f-62-d0" + // MAC-Adresse als String + #endif + + #ifdef smnBOARD006 + #define LOCAL_MAC_ADR_B0 0x90 + #define LOCAL_MAC_ADR_B1 0xa2 + #define LOCAL_MAC_ADR_B2 0xda + #define LOCAL_MAC_ADR_B3 0x0f + #define LOCAL_MAC_ADR_B4 0x62 + #define LOCAL_MAC_ADR_B5 0xd0 + // MAC-Adresse + + #define LOCAL_MAC_ADR_STR (char *) "90-a2-da-0f-62-d0" + // MAC-Adresse als String + #endif + +#else + #define LOCAL_MAC_ADR_B0 0x90 + #define LOCAL_MAC_ADR_B1 0xa2 + #define LOCAL_MAC_ADR_B2 0xda + #define LOCAL_MAC_ADR_B3 0x0f + #define LOCAL_MAC_ADR_B4 0x62 + #define LOCAL_MAC_ADR_B5 0xd0 + // MAC-Adresse + + #define LOCAL_MAC_ADR_STR (char *) "90-a2-da-0f-62-d0" + // MAC-Adresse als String +#endif + +#define LOCAL_PORT 4100 +// Portnummer lokal + +#define BROADCAST_PORT 4100 +// Portnummer Rundruf + +#define CONFIG_PORT 4001 + +//------------------------------------------------------------------------- +// Sub-Netz-Maske +//------------------------------------------------------------------------- +#define SUB_NET_MASK_B0 255 +#define SUB_NET_MASK_B1 255 +#define SUB_NET_MASK_B2 255 +#define SUB_NET_MASK_B3 0 + +//---------------------------------------------------------------------------- +// IP-Adresse, ist auf das verwendete Netzwerk anzupassen (kein DHCP) +//---------------------------------------------------------------------------- + +// Das Netzwerk an sich +#define LOCAL_IP_B0 192 +#define LOCAL_IP_B1 168 +#define LOCAL_IP_B2 99 + +#define BROADCAST_IP_B0 192 +#define BROADCAST_IP_B1 168 +#define BROADCAST_IP_B2 99 +#define BROADCAST_IP_B3 255 + +#ifdef smnMULTIBOARDS + + #ifdef smnBOARD001 + + // IP-Lokal + // ---------------------------------------------- + // + #define LOCAL_IP_B3 201 + #define LOCAL_IP_ADR_STR (char *) "192.168.99.201" + + // IP-Broadcast + // ---------------------------------------------- + // + #define BROADCAST_IP_ADR_STR (char *) "192.168.99.255" + + #endif + + + #ifdef smnBOARD002 + + // IP-Lokal + // ---------------------------------------------- + // + #define LOCAL_IP_B3 202 + #define LOCAL_IP_ADR_STR (char *) "192.168.99.202" + + // IP-Broadcast + // ---------------------------------------------- + // + #define BROADCAST_IP_ADR_STR (char *) "192.168.99.255" + + #endif + + + #ifdef smnBOARD003 + + // IP-Lokal + // ---------------------------------------------- + // + #define LOCAL_IP_B3 203 + #define LOCAL_IP_ADR_STR (char *) "192.168.99.203" + + // IP-Broadcast + // ---------------------------------------------- + // + #define BROADCAST_IP_ADR_STR (char *) "192.168.99.255" + + #endif + + + #ifdef smnBOARD004 + + // IP-Lokal + // ---------------------------------------------- + // + #define LOCAL_IP_B3 204 + #define LOCAL_IP_ADR_STR (char *) "192.168.99.204" + + // IP-Broadcast + // ---------------------------------------------- + // + #define BROADCAST_IP_ADR_STR (char *) "192.168.99.255" + + #endif + + + #ifdef smnBOARD005 + + // IP-Lokal + // ---------------------------------------------- + // + #define LOCAL_IP_B3 205 + #define LOCAL_IP_ADR_STR (char *) "192.168.99.205" + + // IP-Broadcast + // ---------------------------------------------- + // + #define BROADCAST_IP_ADR_STR (char *) "192.168.99.255" + + #endif + + + #ifdef smnBOARD006 + + // IP-Lokal + // ---------------------------------------------- + // + #define LOCAL_IP_B3 206 + #define LOCAL_IP_ADR_STR (char *) "192.168.99.205" + + // IP-Broadcast + // ---------------------------------------------- + // + #define BROADCAST_IP_ADR_STR (char *) "192.168.99.255" + + #endif + + +#else + + // IP-Lokal + // ---------------------------------------------- + // + #define LOCAL_IP_B3 205 + #define LOCAL_IP_ADR_STR (char *) "192.168.99.205" + + // IP-Broadcast + // ---------------------------------------------- + // + #define BROADCAST_IP_B3 255 + #define BROADCAST_IP_ADR_STR (char *) "192.168.99.255" + +#endif + +// IP-Gateway +// ---------------------------------------------- +// +#define GATEWAY_IP_B0 192 +#define GATEWAY_IP_B1 168 +#define GATEWAY_IP_B2 99 +#define GATEWAY_IP_B3 1 + + +/****************************************************************************** + * Netzwerkname + * Passwort + */ +#define SMNSSID "MPZ-Labor" //Netzwerk Name +#define SMNPASS "MPZMPZMPZ" //Netzwerk Passwort + +// IP-primaryDNS +// ---------------------------------------------- +// +#define PRIMDNS_IP_B0 8 +#define PRIMDNS_IP_B1 8 +#define PRIMDNS_IP_B2 8 +#define PRIMDNS_IP_B3 8 + +// IP-secondaryDNS +// ---------------------------------------------- +// +#define SECDNS_IP_B0 8 +#define SECDNS_IP_B1 8 +#define SECDNS_IP_B2 4 +#define SECDNS_IP_B3 4 + +#else +// *************************************************************************** + #undef _socManNetUser_h + #include MyNetFile + // Define MyNetFile in Project-Properties with -DMyNetFile=\"xxxxx\" + // and xxxxx being your filename. + // Define also smnMyNet with -DsmnMyNet to enter this include directive + +#endif // smnMyNet +// *************************************************************************** + +//---------------------------------------------------------------------------// +#endif // _socManNetUser_h diff --git a/sketches/_PIO_Sketches/Karger/SoaapBleSlave_Test_2/src/main.cpp b/sketches/_PIO_Sketches/Karger/SoaapBleSlave_Test_2/src/main.cpp new file mode 100644 index 0000000000000000000000000000000000000000..dc884bde144955acdd20fe68907119e60539e262 --- /dev/null +++ b/sketches/_PIO_Sketches/Karger/SoaapBleSlave_Test_2/src/main.cpp @@ -0,0 +1,855 @@ +// ---------------------------------------------------------------------------- +// SoaapBleSlave.ino +// Beispielhafte Anwendung SOAAP / Steuerung optischer und akustischer Ausgaben +// Kommunikation über BLE-Funkanäle mit Bewerbungstelegrammen +// P o l l i n g - S l a v e +// ---------------------------------------------------------------------------- +// Editor: Robert Patzke +// URI/URL: www.mfp-portal.de +//----------------------------------------------------------------------------- +// Lizenz: CC-BY-SA (wikipedia: Creative Commons) +// Datum: 1. November 2021 +// Letzte Bearbeitung: 1. November 2021 +// +#include "Arduino.h" + +#include "SoaapBleSlave.h" + +#define SlaveADR1 +#define DebugTerminal + +#ifdef SlaveADR1 +#define SlaveADR 1 +#define StartMsg "%@TestBleSlave (Adr=1), Version 20220424 " +#endif + +#ifdef SlaveADR4 +#define SlaveADR 4 +#define StartMsg "%@TestBleSlave (Adr=4), Version 20220424 " +#endif + +LoopCheck lc; +// Eine statische Instanz der Klasse LoopCheck +// Darüber wird das Zeitverhalten gesteuert (Software-Timer) und geprüft + +#ifdef DebugTerminal +Monitor mon(modeEcho | modeNl,0,&lc); +// Eine statische Instanz (mit Konstruktordaten) der Klasse Monitor +// Darüber wird mit (direkten) Terminals (z.B. VT100) kommuniziert +// Unter Linux werden hier GtkTerm (siehe Internet) und +// ArduinoMonTerm (eigene Entwicklung mit grafischen Wertanzeigen) eingesetzt. +// Das in den IDEs integrierte Terminal ist dafür meistens nicht geeignet, +// weil damit keine direkte Kommunikation (getipptes Zeichen sofort gesendet) +// möglich ist. +// ----- Parameter ------------------------------------------------------------ +// <mode Echo> Alle eintreffenden Zeichen werden sofort zurückgesendet +// <mode NL> Vor der Ausgabe des Prompt (M>) erfolgt CR/LF +// <0> Für Speicherzugriffe wird von 32 Bit ARM ausgegangen +// <&lc> Für Zeitüberwachungen und entsprechende statisctische Daten +// greift die Monitor-Klasse auf die LoopCheck-Klasse zu +#endif + +nRF52840Radio bleCom; +// Eine statische Instanz der Klasse nRF52840Radio +// Darüber wird direkt die CPU (nRF52840) auf dem Arduino-Board zum Senden und +// Empfangen von BLE-Beacons angesprochen. + +#define bleCycle 250 +BlePoll blePoll((IntrfRadio *) &bleCom, micros); +// Eine statische Instanz der Klasse BlePoll +// Darüber werden das Polling des Masters als auch die Antworten der Slaves +// gesteuert. Es können Geräte entwickelt werden, die nur Master oder Slave +// sind und solche mit Doppelfunktion, wenn kein expliziter Master +// eingesetzt und das Netzwerk über Spontan-Master quasi dezentral +// betrieben werden soll. +// ----- Parameter ------------------------------------------------------------ +// <&bleCom> Die Klasse (vom angenommenen Typ IntrfRadio), die die Daten- +// übertragung abwickelt. Hier wird eine Instanz von nRF52840Radio +// angebunden. Für andere Hardware kann eine entsprechende Klasse +// verwendet werden, die von IntrfRadio abgeleitet wurde. +// <micros> Eine Funktion, die die verstrichene Zeit in Mikrosekunden gibt. +// Damit werden Zeiten (z.B. Time-Out) berechnet. +// Wird hier der Wert NULL übergeben, dann werden die Zeiten aus +// dem Aufrufzyklus (bleCycleTime) in Mikrosekunden berechnet, +// was hier einer Auflösung von 500 Mikrosekunden entspricht. + +#ifdef DebugTerminal +#define smCycleTime 5 +void smInit(); // Vorwärtsreferenz auf die weiter unten definierte Funktion +StateMachine sm(smInit, NULL, smCycleTime); +// Eine statische Instanz für die Zustandsmaschine, die hier für allgemeine +// Steuerungen, Überwachungen und zum Debugging verwendet wird +// ----- Parameter ------------------------------------------------------------ +// <smInit> Der zuerst aufgerufene Zustand (Funktion). Weitere Zustände +// werden in den weiteren Zustandsfunktionen eingesetzt. +// <NULL> Hier kann eine weitere Zustandsfunktion angegeben werden, +// die dann grundsätzlich vor dem Verzweigen in einen Zustand +// aufgerufen wird. +// <smCycleTime> Die Zukluszeit (Takt) der Zustandsmaschine in Millisekunden +#endif + +nRF52840Twi twi; +// Eine statische Instanz der Klasse nRF52840Twi +// Darüber wird direkt die CPU (nRF52840) auf dem Arduino-Board zum Senden und +// Empfangen von I2C (TWI) Botschaften aufgerufen. + + +#define SensorCycle 500 +SensorLSM9DS1 sens((IntrfTw *) &twi, SensorCycle); +// Eine statische Instanz der Klasse SensorLSM9DS1 zum Zugriff +// auf den Sensor LSM9DS1 über den I2C-Bus (TWI) +// ----- Parameter ------------------------------------------------------------ +// <&twi> Die Klasse (vom angenommenen Typ IntrfTw), die die Datenüber- +// tragung auf I2C abwickelt. Hier wird eine Instanz von nRF52840Twi +// angebunden. Für andere Hardware kann eine entsprechende Klasse +// verwendet werden, die von IntrfTw abgeleitet wurde. +// +// <SensorCycle> Der Zugriff auf den Sensor erfolgt mit einer Zustands- +// maschine, deren Takt über die Periodenzeit SensorCycle +// in Mikrosekunden definiert ist. Siehe dazu entsprechenden +// Timeraufruf in LOOP. + +nRF52840Gpio gpio; +// Zugriff auf die Anschlüsse des Board + +bool getValues(PlpType plpType, byte *dest); +// Vorwärtsreferenz für Datenübergabe + +bool xchgCtrl(PlpType plpType, byte *dest, byte *src, int sSize); +// Vorwärtsreferenz für Steuerungsaustausch + +void setup() +{ + TwiParams twiPar; // Parameter für den I2C-Bus + + gpio.configArd(ArdA0A3, IfDrvInput | IfDrvPullUp); + +#ifdef DebugTerminal + mon.config(6); // 6 Anzeigekanäle, die von ArduinoMonTerm aufgebaut werden + + for(int i = 0; i < 6; i++) + { + if(i < 3) + mon.config(i+1,'C',16000,-16000,NULL); // Kanalnummer, Typ, Maxwert, Minwert + else + mon.config(i+1,'C',4000,-4000,NULL); + } +#endif + + bleCom.begin(); // Initialisierung der Datenübertragung + //bleCom.setPower(0x008); // Maximale Sendeleistung bei nRF52840 + bleCom.setPower(0x0FC); // Reduzierte Sendeleistung beim Schreibtisch-Test + + blePoll.begin(BlePoll::ctSLAVE, SlaveADR, BlePoll::atSOAAP, 10000); + // Initialisierung des Polling mit folgenden Parametern: + // <BlePoll::ctSLAVE> Es wird ein Slave eingerichtet + // <SlaveADR> Adresse (Nummer) des Slave + // <BlePoll::atSOAAP> Spezielle Anwendung SOAAP + // <10000> INT-Watchdog-Timeout in Mikrosekunden + + blePoll.setCbDataPtr(getValues); + blePoll.setCbCtrlPtr(xchgCtrl); + // Callbacks für Datenübergabe setzen + + //blePoll.stopSR(); + // Kein Empfangsbetrieb + + // Spezifische Parameter für den I2C-Bus am Arduino Nano 33 BLE + // + twiPar.inst = 0; // 1. Instanz der I2C + twiPar.type = TwiMaster; // Auswahl Master/slave + twiPar.clkPort = 0; // Takt über Port 0 (P0) + twiPar.clkPin = 15; // Takt an Pin 15 (P0.15) + twiPar.dataPort = 0; // Daten über Port 0 (P0) + twiPar.dataPin = 14; // Daten an Pin 14 (P0.14) + twiPar.speed = Twi100k; // Taktfrequenz + + twi.begin(&twiPar); // Initialisierung des I2C-Bus + + sens.begin(FreqAG119, 12, MaxAcc4g, MaxGyro2000dps, FreqM20, 10, MaxMag16G); + // Initialisierung der Sensorabfrage mit folgenden Parametern + // + // <FreqAG119> Beschleunigungssensoren und Gyroskop mit 119 Hz abgefragt + // + // <12> Vor der Wertübergabe wird der Mittelwert über 12 Messungen + // gebildet. Die Messfrequenz beträgt daher ca. 10 Hz. + // + // <MaxAcc4g> Der Maximalausschlag der Beschleunigung ist 4g + // + // <MaxGyro2000dps> Maximalausschlag des Gyro ist 2000 Grad/s + // + // <FreqM40> Der Magnetfeldsensor wird mit 20 Hz abgetastet + // + // <8> Mittelwertbildung über 10 Messwerte, also 2 Hz + // + // <MaxMag16G> Der Maximalwert entspricht 16 Gauss + + sens.syncValuesAG(); + sens.syncValuesM(); + // Rücksetzen des Ready-Bit für Messwertübergabe +} + +#ifdef DebugTerminal +char runView[4] = {'|','/','-','\\'}; +int runViewIdx = 0; +#endif + +void loop() +{ + lc.begin(); + // -------------------------------------------------------------------------- + +#ifdef DebugTerminal + // Der Monitor wird ständig aufgerufen und stellt damit eine grundsätzliche + // Belastung dar. Das ist für die Entwicklung auch vorgesehen. + // Es entsteht dadurch eine Reserve für den produktiven Einsatz. + // + mon.run(); +#endif + + // Alle 500 Mikrosekunden erfolgt der Aufruf des Ble-Polling + // + if(lc.timerMicro(lcTimer0, bleCycle, 0)) + blePoll.run(); + // ----- Parameter der Software-Timer --------------------------------------- + // <lcTimer0> Id/Nummer des Timer, zur Zeit werden bis 10 Timer unterstützt + // lcTimer0 bis lcTimer9 (einstellbar in LoopCheck.h) + // <bleCycleTime> Ablaufzeit in Einheit des Timer-Typ (Micro/Milli) + // hier in Mikrosekunden (timerMicro) + // <0> Anzahl der Wiederholungen, 0 = unbegrenzt + + // Alle 500 Mikrosekunden erfolgt der Aufruf der Sensorzustandsmaschine + // + if(lc.timerMicro(lcTimer1, SensorCycle, 0)) + sens.run(); + +#ifdef DebugTerminal + // Alle 5 Millisekunden wird die Zustandsmaschine für + // betriebliche Abläufe aufgerufen + // + if(lc.timerMilli(lcTimer2, smCycleTime, 0)) + { + sm.run(); + } + + // Jede halbe Sekunde erfolgt die Ausgabe der Version + // + if(lc.timerMilli(lcTimer3, 500, 0)) + { + if(!mon.cFlag[0]) + { + mon.print((char *) StartMsg); + mon.cprintcr(runView[runViewIdx]); + runViewIdx++; + if(runViewIdx > 3) runViewIdx = 0; + } + } +#endif + // -------------------------------------------------------------------------- + lc.end(); +} + +// ---------------------------------------------------------------------------- +// Übergabe der Daten an die BLE-Kommunikation +// ---------------------------------------------------------------------------- +// +RawDataAG rawDataAG; +RawDataM rawDataM; + +bool getValues(PlpType plpType, byte *dest) +{ + bool newData; + int si,di; + + memset(rawDataAG.byteArray,0,12); + + newData = sens.getValuesAG(&rawDataAG); + + si = di = 0; + if(newData) + { + switch(plpType) + { + case plptMeas6: + for(si = 0; si < 12; si++) + dest[di++] = rawDataAG.byteArray[si]; + break; + + case plptMeas9Ctrl4: + sens.getValuesM(&rawDataM); + + for(si = 0; si < 12; si++) + dest[di++] = rawDataAG.byteArray[si]; + for(si = 0; si < 6; si++) + dest[di++] = rawDataM.byteArray[si]; + break; + } + } + return(newData); +} + +int procSize; +byte procData[32]; +byte procPath; +byte procCnt; + + +bool xchgCtrl(PlpType plpType, byte *dest, byte *src, int sSize) +{ + int si,di; + bool retv; + + si = di = 0; + retv = false; + + switch(plpType) + { + case plptMeas9Ctrl4: + for(si = 0; si < sSize; si++) + procData[si] = src[si]; + procSize = sSize; + dest[di++] = procPath; + dest[di++] = procCnt; + dest[di++] = (byte) (gpio.readArd(ArdA0A3) & 0x0F); + dest[di++] = 0xAB; + + retv = true; + break; + } + + return(retv); +} + +#ifdef DebugTerminal +// **************************************************************************** +// Z u s t a n d s m a s c h i n e +// **************************************************************************** +// + +dword debDword; +byte tmpByteArray[256]; +CalValueAG calData; +CalValue calValue; + + +void smInit() +{ + sm.enter(smCheckJobs); +} + +// ---------------------------------------------------------------------------- +// Abfrage der Monitorschalter +// ---------------------------------------------------------------------------- +// + +void smCheckJobs() +{ + if(mon.cFlag[1] && !mon.busy) + sm.enter(smDebDword); + else if(mon.cFlag[2] && !mon.busy) + sm.enter(smCtrlPolling); + else if(mon.cFlag[3] && !mon.busy) + sm.enter(smCheckSens); + /* + else if(mon.cFlag[4] && !mon.busy) + sm.enter(smCheckSens); + */ +} + + +// ---------------------------------------------------------------------------- +// Debug-Informationen +// ---------------------------------------------------------------------------- +// + +void smDebDword() +{ + int idx; + + if(sm.firstEnter()) + { + mon.print((char *) "DebDword["); + mon.lastKeyIn = ':'; + } + + if(mon.lastKeyIn == ':') return; + + if(mon.lastKeyIn >= 0x30 && mon.lastKeyIn <= 0x39) + { + idx = mon.lastKeyIn & 0x0F; + mon.print(idx); + mon.print((char *) "]="); + debDword = blePoll.debGetDword(idx); + mon.println(debDword); + sm.resetEnter(); + } + else + { + if(mon.lastKeyIn == ' ') + { + mon.cFlag[1] = false; + mon.print((char *) "-- Schleifenabbruch - drücke Enter"); + sm.enter(smCheckJobs); + } + } +} + +// ---------------------------------------------------------------------------- +// Steuern des Polling-Prozesses +// ---------------------------------------------------------------------------- +// Es ist sowohl die Master- als auch die Slave-Funktion vorgesehen +// + +TxStatistics txStatistics; + +void smCtrlPolling() +{ + if(sm.firstEnter()) + { + mon.print((char *) "polling "); + mon.lastKeyIn = ':'; + } + + if(mon.lastKeyIn == ':') return; + + // -------------------------------------------------------------------------- + if(mon.lastKeyIn == 'P' || mon.lastKeyIn == 'p') + { + if(blePoll.stoppedEP()) + { + blePoll.resumeEP(); + mon.println((char *) "fortgesetzt"); + sm.resetEnter(); + } + else + { + blePoll.stopEP(); + sm.enter(smWaitPolling); + } + } + + // -------------------------------------------------------------------------- + else if(mon.lastKeyIn == 'S' || mon.lastKeyIn == 's') + { + mon.print((char *) "Sendepuffer = "); + bleCom.getPduSent(tmpByteArray, 0, 10); + mon.println(tmpByteArray, 10, ' '); + sm.resetEnter(); + } + + // -------------------------------------------------------------------------- + else if(mon.lastKeyIn == 'R' || mon.lastKeyIn == 'r') + { + mon.print((char *) "Radiopuffer = "); + bleCom.getPduMem(tmpByteArray, 0, 10); + mon.println(tmpByteArray, 10, ' '); + sm.resetEnter(); + } + + // -------------------------------------------------------------------------- + else if(mon.lastKeyIn == 'T' || mon.lastKeyIn == 't') + { + mon.print((char *) "TxStat ["); + dword bleStat = blePoll.getStatistics(&txStatistics); + mon.print(bleStat); + mon.print((char *) "] "); + mon.print(txStatistics.mode); mon.cprint(' '); + mon.print(txStatistics.interrupts); mon.cprint(' '); + mon.print(txStatistics.recs); mon.cprint(' '); + mon.print(txStatistics.sendings); mon.cprint(' '); + mon.print(txStatistics.aliens); mon.cprint(' '); + mon.print(txStatistics.wrongs); mon.cprint(' '); + mon.print(txStatistics.pollAcks); mon.cprint(' '); + mon.print(txStatistics.pollNaks); mon.cprint(' '); + mon.print(txStatistics.crcErrors); mon.print(" r[ "); + mon.print(txStatistics.memDumpRec,8,' '); mon.print("] s[ "); + mon.print(txStatistics.memDumpSnd,16,' '); mon.cprintln(']'); + sm.resetEnter(); + } + + + else + { + if(mon.lastKeyIn == ' ') + { + mon.cFlag[2] = false; + mon.print((char *) "-- Schleifenabbruch - drücke Enter"); + sm.enter(smCheckJobs); + } + } +} + +void smWaitPolling() +{ + if(!blePoll.stoppedEP()) return; + + mon.println((char *) "angehalten"); + sm.enter(smCtrlPolling); +} + +// ---------------------------------------------------------------------------- +// (4) Testen der Sensorzugriffe +// ---------------------------------------------------------------------------- +// + +char charOut[2]; + +void smCheckSens() +{ + if(sm.firstEnter()) + { + mon.print((char *) "Sensorzugriff "); + mon.lastKeyIn = ':'; + } + + if(mon.lastKeyIn == ':') return; + + charOut[0] = mon.lastKeyIn; + charOut[1] = '\0'; + mon.println(charOut); + + if(mon.lastKeyIn == '0' || mon.lastKeyIn == ' ') + { + mon.cFlag[3] = false; + mon.print((char *) "-- Schleifenabbruch - drücke Enter"); + sm.enter(smCheckJobs); + } + else if(mon.lastKeyIn == '1') + sm.enter(smSensReset1); + else if(mon.lastKeyIn == '2') + sm.enter(smSensReset2); + else if(mon.lastKeyIn == '3') + sm.enter(smSensGetValues1); + else if(mon.lastKeyIn == '4') + sm.enter(smSensGetValues2); + else if(mon.lastKeyIn == '5') + sm.enter(smSensGetValues3); + else if(mon.lastKeyIn == '6') + sm.enter(smSensGetValues4); + else if(mon.lastKeyIn == '7') + sm.enter(smSensGetValues5); + else if(mon.lastKeyIn == '8') + sm.enter(smSensGetValues6); + else if(mon.lastKeyIn == 'c') + sm.enter(smSensDebugValues); + else if(mon.lastKeyIn == 'e') + sm.enter(smSensGetErrors); + else if(mon.lastKeyIn == 'r') + sm.enter(smSensGetRunCounts); + else if(mon.lastKeyIn == 's') + sm.enter(smSensGetSoaapValues); + else if(mon.lastKeyIn == 't') + sm.enter(smSensGetTimeOuts); + else + sm.resetEnter(); + mon.lastKeyIn = ':'; +} + +void smSensReset1() +{ + int retv = sens.resetAG(); + //int retv = twi.writeByteReg(0x6B, 0x22, 0x05); + mon.print((char *) "resetAG = "); + mon.println(retv); + sm.enter(smCheckSens); +} + +void smSensReset2() +{ + int retv = sens.resetM(); + //int retv = twi.writeByteReg(0x1E, 0x21, 0x0C); + mon.print((char *) "resetM = "); + mon.println(retv); + sm.enter(smCheckSens); +} + +void smSensGetValues1() +{ + if(sm.firstEnter()) + sens.syncValuesAG(); + + if(!sens.getValuesAG(&rawDataAG)) return; + + mon.print((char *) "ValueA = "); + mon.print(rawDataAG.valueAG.A.x); + mon.print((char *) " "); + mon.print(rawDataAG.valueAG.A.y); + mon.print((char *) " "); + mon.println(rawDataAG.valueAG.A.z); + sm.enter(smCheckSens); +} + +char outValue[64]; + +void smSensGetValues2() +{ + if(sm.firstEnter()) + sens.syncValuesAG(); + + if(!sens.getValuesAG(&calData)) return; + + mon.print((char *) "ValueA = "); + sprintf(outValue,"%f ",calData.A.x); + mon.print(outValue); + sprintf(outValue,"%f ",calData.A.y); + mon.print(outValue); + sprintf(outValue,"%f ",calData.A.z); + mon.println(outValue); + sm.enter(smCheckSens); +} + +void smSensGetValues3() +{ + if(sm.firstEnter()) + { + sens.syncValuesAG(); + mon.lastKeyIn = ':'; + } + + if(!sens.getValuesAG(&calData)) return; + + mon.print((char *) "Values A = "); + sprintf(outValue,"%+5.3f ",calData.A.x); + mon.print(outValue); + sprintf(outValue,"%+5.3f ",calData.A.y); + mon.print(outValue); + sprintf(outValue,"%+5.3f ",calData.A.z); + mon.println(outValue); + + if(mon.lastKeyIn == ' ') + sm.enter(smCheckSens); +} + +void smSensGetValues4() +{ + if(sm.firstEnter()) + { + sens.syncValuesAG(); + mon.lastKeyIn = ':'; + } + + if(!sens.getValuesAG(&calData)) return; + + mon.print((char *) "Values AG = "); + sprintf(outValue,"%+5.3f ",calData.A.x); + mon.print(outValue); + sprintf(outValue,"%+5.3f ",calData.A.y); + mon.print(outValue); + sprintf(outValue,"%+5.3f ",calData.A.z); + mon.print(outValue); + + sprintf(outValue,"%+5.1f ",calData.G.x); + mon.print(outValue); + sprintf(outValue,"%+5.1f ",calData.G.y); + mon.print(outValue); + sprintf(outValue,"%+5.1f ",calData.G.z); + mon.println(outValue); + + + if(mon.lastKeyIn == ' ') + sm.enter(smCheckSens); +} + +void smSensGetValues5() +{ + if(sm.firstEnter()) + { + sens.syncValuesAG(); + mon.lastKeyIn = ':'; + sm.setTimeOut(1000); + } + + if(sm.timeOut()) + { + mon.println((char *) " Time Out"); + sm.enter(smCheckSens); + return; + } + + if(!sens.getValuesAG(&calData)) return; + sm.setTimeOut(1000); + + mon.print((char *) "Values AGM = "); + + sprintf(outValue,"%+5.3f ",calData.A.x); + mon.print(outValue); + sprintf(outValue,"%+5.3f ",calData.A.y); + mon.print(outValue); + sprintf(outValue,"%+5.3f ",calData.A.z); + mon.print(outValue); + + sprintf(outValue,"%+5.1f ",calData.G.x); + mon.print(outValue); + sprintf(outValue,"%+5.1f ",calData.G.y); + mon.print(outValue); + sprintf(outValue,"%+5.1f ",calData.G.z); + mon.print(outValue); + + sens.getValuesM(&calValue); + + sprintf(outValue,"%+5.3f ",calValue.x); + mon.print(outValue); + sprintf(outValue,"%+5.3f ",calValue.y); + mon.print(outValue); + sprintf(outValue,"%+5.3f ",calValue.z); + mon.println(outValue); + + if(mon.lastKeyIn == ' ') + sm.enter(smCheckSens); +} + +void smSensGetValues6() +{ + if(sm.firstEnter()) + { + sens.syncValuesAG(); + mon.lastKeyIn = ':'; + sm.setTimeOut(1000); + } + + if(sm.timeOut()) + { + mon.println((char *) " Time Out"); + sm.enter(smCheckSens); + return; + } + + if(!sens.getValuesAG(&rawDataAG)) return; + sm.setTimeOut(1000); + + mon.print((char *) "Values AGM = "); + + sprintf(outValue,"%4X ",(unsigned short) rawDataAG.valueAG.A.x); + mon.print(outValue); + sprintf(outValue,"%4X ",(unsigned short) rawDataAG.valueAG.A.y); + mon.print(outValue); + sprintf(outValue,"%4X ",(unsigned short) rawDataAG.valueAG.A.z); + mon.print(outValue); + + sprintf(outValue,"%4X ",(unsigned short) rawDataAG.valueAG.G.x); + mon.print(outValue); + sprintf(outValue,"%4X ",(unsigned short) rawDataAG.valueAG.G.y); + mon.print(outValue); + sprintf(outValue,"%4X ",(unsigned short) rawDataAG.valueAG.G.z); + mon.println(outValue); + + /* + sens.getValuesM(&calValue); + + sprintf(outValue,"%+5.3f ",calValue.x); + mon.print(outValue); + sprintf(outValue,"%+5.3f ",calValue.y); + mon.print(outValue); + sprintf(outValue,"%+5.3f ",calValue.z); + mon.println(outValue); + */ + if(mon.lastKeyIn == ' ') + sm.enter(smCheckSens); +} + + +void smSensGetValues7() +{ + if(sm.firstEnter()) + { + sens.syncValuesAG(); + mon.lastKeyIn = ':'; + sm.setTimeOut(1000); + } + + if(sm.timeOut()) + { + mon.println((char *) " Time Out"); + sm.enter(smCheckSens); + return; + } + + if(!sens.getValuesAG(&rawDataAG)) return; + sm.setTimeOut(1000); + + mon.print((char *) "%~Values AGM = $"); + + sprintf(outValue,"#@%04X$",(unsigned short) rawDataAG.valueAG.A.x); + mon.print(outValue); + sprintf(outValue,"#A%04X$",(unsigned short) rawDataAG.valueAG.A.y); + mon.print(outValue); + sprintf(outValue,"#B%04X$",(unsigned short) rawDataAG.valueAG.A.z); + mon.print(outValue); + + sprintf(outValue,"#C%04X$",(unsigned short) rawDataAG.valueAG.G.x); + mon.print(outValue); + sprintf(outValue,"#D%04X$",(unsigned short) rawDataAG.valueAG.G.y); + mon.print(outValue); + sprintf(outValue,"#E%04X$",(unsigned short) rawDataAG.valueAG.G.z); + mon.print(outValue); + + if(mon.lastKeyIn == ' ') + sm.enter(smCheckSens); +} + + +void smSensGetSoaapValues() +{ + sm.enter(smSensGetValues7); +} + +void smSensDebugValues() +{ + mon.print((char *) "Werte: toValueStatusAG="); + mon.print(sens.debGetDword(1)); + mon.print((char *) " toValueStatusM="); + mon.println(sens.debGetDword(2)); + sm.enter(smCheckSens); +} + + +void smSensGetErrors() +{ + mon.print((char *) "Errors AG: AdrNak="); + mon.print(sens.errorCntAdrNakAG); + mon.print((char *) " DataNak="); + mon.print(sens.errorCntDataNakAG); + mon.print((char *) " Overrun="); + mon.print(sens.errorCntOverAG); + + mon.print((char *) " M: AdrNak="); + mon.print(sens.errorCntAdrNakM); + mon.print((char *) " DataNak="); + mon.print(sens.errorCntDataNakM); + mon.print((char *) " Overrun="); + mon.println(sens.errorCntOverM); + sm.enter(smCheckSens); +} + +void smSensGetTimeOuts() +{ + mon.print((char *) "TimeOuts AG: TwiStat="); + mon.print(sens.toCntTwiStatusAG); + mon.print((char *) " TwiData="); + mon.print(sens.toCntTwiDataAG); + mon.print((char *) " Status="); + mon.print(sens.toCntStatusAG); + + mon.print((char *) " M: TwiStat="); + mon.print(sens.toCntTwiStatusM); + mon.print((char *) " TwiData="); + mon.print(sens.toCntTwiDataM); + mon.print((char *) " Status="); + mon.println(sens.toCntStatusM); + sm.enter(smCheckSens); +} + +void smSensGetRunCounts() +{ + mon.print((char *) "RunCounts: "); + for(int i = 0; i < NrOfRunStates; i++) + { + mon.print((char *) " "); + mon.print(sens.runStateCntArray[i]); + } + mon.print((char *) " Total="); + mon.println(sens.runStateCntTotal); + sm.enter(smCheckSens); +} +#endif // DebugTerminal + diff --git a/sketches/_PIO_Sketches/Karger/SoaapBleSlave_Test_2/src/nRF52840Gpio/library.json b/sketches/_PIO_Sketches/Karger/SoaapBleSlave_Test_2/src/nRF52840Gpio/library.json new file mode 100644 index 0000000000000000000000000000000000000000..a099c0c6f9c5ede5584dbf9ab24da0199b348548 --- /dev/null +++ b/sketches/_PIO_Sketches/Karger/SoaapBleSlave_Test_2/src/nRF52840Gpio/library.json @@ -0,0 +1,4 @@ +{ + "name": "nRF52840Gpio", + "version": "0.0.0+20220823165932" +} \ No newline at end of file diff --git a/sketches/_PIO_Sketches/Karger/SoaapBleSlave_Test_2/src/nRF52840Gpio/nRF52840Gpio.cpp b/sketches/_PIO_Sketches/Karger/SoaapBleSlave_Test_2/src/nRF52840Gpio/nRF52840Gpio.cpp new file mode 100644 index 0000000000000000000000000000000000000000..47a25ddebcff11a2d9ef003cf83ddf1be250d057 --- /dev/null +++ b/sketches/_PIO_Sketches/Karger/SoaapBleSlave_Test_2/src/nRF52840Gpio/nRF52840Gpio.cpp @@ -0,0 +1,353 @@ +//----------------------------------------------------------------------------- +// Thema: Social Manufacturing Network / Development Environment +// Datei: nRF52840Gpio.cpp +// Editor: Robert Patzke +// URI/URL: www.mfp-portal.de +//----------------------------------------------------------------------------- +// Lizenz: CC-BY-SA (wikipedia: Creative Commons) +// Datum: 29. Juni 2021 +// + +#include "nRF52840Gpio.h" + + // -------------------------------------------------------------------------- + // Konstruktoren + // -------------------------------------------------------------------------- + // + nRF52840Gpio::nRF52840Gpio() + { + gpioPtr = NULL; + } + + + + // -------------------------------------------------------------------------- + // Konfigurationen + // -------------------------------------------------------------------------- + // + +dword nRF52840Gpio::getCnfValue(unsigned int cnfBits) +{ + dword tmpMask = 0; + + if(cnfBits & IfDrvPullUp) tmpMask |= GpioPinCnf_PULL(GpioPullUp); + if(cnfBits & IfDrvPullDown) tmpMask |= GpioPinCnf_PULL(GpioPullDown); + + if((cnfBits & IfDrvOutput)) // Ausgang ********************************** + { + tmpMask |= GpioPinCnf_DIR; + + if(cnfBits & IfDrvStrongHigh) // StrongHigh = H1 + { + if(cnfBits & IfDrvOpenSource) // OpenSource = D0 + tmpMask |= GpioPinCnf_DRIVE(GpioDriveD0H1); + else if(cnfBits & IfDrvStrongLow) // StrongLow = H0 + tmpMask |= GpioPinCnf_DRIVE(GpioDriveH0H1); + else + tmpMask |= GpioPinCnf_DRIVE(GpioDriveS0H1); + } + else if(cnfBits & IfDrvStrongLow) // StrongLow = H0 + { + if(cnfBits & IfDrvOpenDrain) // OpenDrain = D1 + tmpMask |= GpioPinCnf_DRIVE(GpioDriveH0D1); + else + tmpMask |= GpioPinCnf_DRIVE(GpioDriveH0S1); + } + else + { + if(cnfBits & IfDrvOpenSource) // OpenSource = D0 + tmpMask |= GpioPinCnf_DRIVE(GpioDriveD0S1); + else if(cnfBits & IfDrvOpenDrain) // OpenDrain = D1 + tmpMask |= GpioPinCnf_DRIVE(GpioDriveS0D1); + else + tmpMask |= GpioPinCnf_DRIVE(GpioDriveS0S1); + } + } + else // Eingang ********************************** + { + tmpMask &= 0xFFFFFFFC; + } + + return(tmpMask); +} + +GpioError nRF52840Gpio::config(int nrFrom, int nrTo, unsigned int cnfBits, GpioExtRefPtr refPtr) +{ + GpioError retv = GEnoError; + int portNum; + int pinNum; + dword tmpMask; + dword cnfValue; + + tmpMask = IfDrvOpenDrain | IfDrvOpenSource; + if((cnfBits & tmpMask) == tmpMask) return (GEcdictPar); + + tmpMask = IfDrvPullDown | IfDrvPullUp; + if((cnfBits & tmpMask) == tmpMask) return (GEcdictPar); + + cnfValue = getCnfValue(cnfBits); + tmpMask = 0; + + // Bedienen des angegebenen Bereiches + // + for(int i = nrFrom; i <= nrTo; i++) + { + portNum = (i & 0x0E0) >> 5; + pinNum = i & 0x01F; + + tmpMask |= (1 << i); + + if(portNum == 0) + gpioPtr = NrfGpioPtr0; + else + gpioPtr = NrfGpioPtr1; + + gpioPtr->PIN_CNF[pinNum] = cnfValue; + } + + refPtr->ioPtr = (dword *) gpioPtr; + refPtr->pins = tmpMask; + + return(retv); +} + +GpioError nRF52840Gpio::config(int nr, unsigned int cnfBits, GpioExtRefPtr refPtr) +{ + return(config(nr,nr,cnfBits, refPtr)); +} + +GpioError nRF52840Gpio::config(GpioExtMask mask, unsigned int cnfBits, GpioExtRefPtr refPtr) +{ + GpioError retv = GEnoError; + dword cnfVal; + + cnfVal = IfDrvOpenDrain | IfDrvOpenSource; + if((cnfBits & cnfVal) == cnfVal) return (GEcdictPar); + + cnfVal = IfDrvPullDown | IfDrvPullUp; + if((cnfBits & cnfVal) == cnfVal) return (GEcdictPar); + + cnfVal = getCnfValue(cnfBits); + + // Bedienen des angegebenen Bereiches + // + dword chkMask = 1; + + for(int i = 0; i < 32; i++) + { + if(mask.port == 0) + gpioPtr = NrfGpioPtr0; + else + gpioPtr = NrfGpioPtr1; + + if(mask.pins & chkMask) + gpioPtr->PIN_CNF[i] = cnfVal; + + chkMask <<= 1; + } + + if(refPtr != NULL) + { + refPtr->ioPtr = (dword *) gpioPtr; + refPtr->pins = mask.pins; + } + + return(retv); +} + +GpioError nRF52840Gpio::configArd(ArdMask ardMask, unsigned int cnfBits) +{ + GpioExtMask ioMask; + + switch(ardMask) + { + case ArdA0A3: + ioMask.port = 0; + ioMask.pins = ArdA0Mask | ArdA1Mask | ArdA2Mask | ArdA3Mask; + break; + + case ArdA4A7: + ioMask.port = 0; + ioMask.pins = ArdA4Mask | ArdA5Mask | ArdA6Mask | ArdA7Mask; + break; + + case ArdA0A7: + ioMask.port = 0; + ioMask.pins = ArdA0Mask | ArdA1Mask | ArdA2Mask | ArdA3Mask | + ArdA4Mask | ArdA5Mask | ArdA6Mask | ArdA7Mask; + break; + + case ArdD2D5: + ioMask.port = 1; + ioMask.pins = ArdD2Mask | ArdD3Mask | ArdD4Mask | ArdD5Mask; + break; + } + + return config(ioMask, cnfBits, NULL); +} + + + + // -------------------------------------------------------------------------- + // Anwendungsfunktionen + // -------------------------------------------------------------------------- + // +void nRF52840Gpio::read(GpioExtRefPtr ioRefPtr, GpioExtValPtr valPtr) +{ + gpioPtr = (nrfGpioPtr) ioRefPtr->ioPtr; + valPtr->value = gpioPtr->IN; +} + +dword nRF52840Gpio::readArd(ArdMask ardMask) +{ + dword inVal; + dword retVal; + + retVal = 0; + + switch(ardMask) + { + case ArdA0A3: + inVal = NrfGpioPtr0->IN; + if(inVal & ArdA0Mask) retVal |= 0x01; + if(inVal & ArdA1Mask) retVal |= 0x02; + if(inVal & ArdA2Mask) retVal |= 0x04; + if(inVal & ArdA3Mask) retVal |= 0x08; + break; + + case ArdA4A7: + inVal = NrfGpioPtr0->IN; + if(inVal & ArdA4Mask) retVal |= 0x01; + if(inVal & ArdA5Mask) retVal |= 0x02; + if(inVal & ArdA6Mask) retVal |= 0x04; + if(inVal & ArdA7Mask) retVal |= 0x08; + break; + + case ArdA0A7: + inVal = NrfGpioPtr0->IN; + if(inVal & ArdA0Mask) retVal |= 0x01; + if(inVal & ArdA1Mask) retVal |= 0x02; + if(inVal & ArdA2Mask) retVal |= 0x04; + if(inVal & ArdA3Mask) retVal |= 0x08; + if(inVal & ArdA4Mask) retVal |= 0x10; + if(inVal & ArdA5Mask) retVal |= 0x20; + if(inVal & ArdA6Mask) retVal |= 0x40; + if(inVal & ArdA7Mask) retVal |= 0x80; + break; + + case ArdD2D5: + inVal = NrfGpioPtr1->IN; + if(inVal & ArdD2Mask) retVal |= 0x01; + if(inVal & ArdD3Mask) retVal |= 0x02; + if(inVal & ArdD4Mask) retVal |= 0x04; + if(inVal & ArdD5Mask) retVal |= 0x08; + break; + } + + return(retVal); +} + + +void nRF52840Gpio::write(GpioExtRefPtr refPtr, GpioExtValPtr valPtr) +{ + ((nrfGpioPtr) refPtr->ioPtr)->OUTSET = valPtr->value & refPtr->pins; + ((nrfGpioPtr) refPtr->ioPtr)->OUTCLR = ~valPtr->value & refPtr->pins; + if(refPtr->next == NULL) return; + ((nrfGpioPtr) refPtr->next->ioPtr)->OUTSET = valPtr->next->value & refPtr->next->pins; + ((nrfGpioPtr) refPtr->next->ioPtr)->OUTCLR = ~valPtr->next->value & refPtr->next->pins; +} + +void nRF52840Gpio::set(GpioExtRefPtr refPtr) +{ + ((nrfGpioPtr) refPtr->ioPtr)->OUTSET = refPtr->pins; + if(refPtr->next == NULL) return; + ((nrfGpioPtr) refPtr->next->ioPtr)->OUTSET = refPtr->next->pins; +} + +void nRF52840Gpio::clr(GpioExtRefPtr refPtr) +{ + ((nrfGpioPtr) refPtr->ioPtr)->OUTCLR = refPtr->pins; + if(refPtr->next == NULL) return; + ((nrfGpioPtr) refPtr->next->ioPtr)->OUTCLR = refPtr->next->pins; +} + + + +void nRF52840Gpio::writeArd(ArdMask ardMask, dword value) +{ + dword set0 = 0, set1 = 0; + dword clr0 = 0, clr1 = 0; + + switch(ardMask) + { + case ArdA0A3: + if(value & 0x01) set0 |= ArdA0Mask; + else clr0 |= ArdA0Mask; + if(value & 0x02) set0 |= ArdA1Mask; + else clr0 |= ArdA1Mask; + if(value & 0x04) set0 |= ArdA2Mask; + else clr0 |= ArdA2Mask; + if(value & 0x08) set0 |= ArdA3Mask; + else clr0 |= ArdA3Mask; + + NrfGpioPtr0->OUTSET = set0; + NrfGpioPtr0->OUTCLR = clr0; + break; + + case ArdA4A7: + if(value & 0x01) set0 |= ArdA4Mask; + else clr0 |= ArdA4Mask; + if(value & 0x02) set0 |= ArdA5Mask; + else clr0 |= ArdA5Mask; + if(value & 0x04) set0 |= ArdA6Mask; + else clr0 |= ArdA6Mask; + if(value & 0x08) set0 |= ArdA7Mask; + else clr0 |= ArdA7Mask; + + NrfGpioPtr0->OUTSET = set0; + NrfGpioPtr0->OUTCLR = clr0; + break; + + case ArdA0A7: + if(value & 0x01) set0 |= ArdA0Mask; + else clr0 |= ArdA0Mask; + if(value & 0x02) set0 |= ArdA1Mask; + else clr0 |= ArdA1Mask; + if(value & 0x04) set0 |= ArdA2Mask; + else clr0 |= ArdA2Mask; + if(value & 0x08) set0 |= ArdA3Mask; + else clr0 |= ArdA3Mask; + if(value & 0x01) set0 |= ArdA4Mask; + else clr0 |= ArdA4Mask; + if(value & 0x02) set0 |= ArdA5Mask; + else clr0 |= ArdA5Mask; + if(value & 0x04) set0 |= ArdA6Mask; + else clr0 |= ArdA6Mask; + if(value & 0x08) set0 |= ArdA7Mask; + else clr0 |= ArdA7Mask; + + NrfGpioPtr0->OUTSET = set0; + NrfGpioPtr0->OUTCLR = clr0; + break; + + case ArdD2D5: + if(value & 0x01) set1 |= ArdD2Mask; + else clr1 |= ArdD2Mask; + if(value & 0x02) set1 |= ArdD3Mask; + else clr1 |= ArdD3Mask; + if(value & 0x04) set1 |= ArdD4Mask; + else clr1 |= ArdD4Mask; + if(value & 0x08) set1 |= ArdD5Mask; + else clr1 |= ArdD5Mask; + + NrfGpioPtr1->OUTSET = set1; + NrfGpioPtr1->OUTCLR = clr1; + break; + } +} + + + // ---------------------------------------------------------------------------- + // Ereignisbearbeitung und Interrupts + // ---------------------------------------------------------------------------- + // diff --git a/sketches/_PIO_Sketches/Karger/SoaapBleSlave_Test_2/src/nRF52840Gpio/nRF52840Gpio.h b/sketches/_PIO_Sketches/Karger/SoaapBleSlave_Test_2/src/nRF52840Gpio/nRF52840Gpio.h new file mode 100644 index 0000000000000000000000000000000000000000..addf5ad533ddfecabd2c540824238c278a117998 --- /dev/null +++ b/sketches/_PIO_Sketches/Karger/SoaapBleSlave_Test_2/src/nRF52840Gpio/nRF52840Gpio.h @@ -0,0 +1,181 @@ +//----------------------------------------------------------------------------- +// Thema: Social Manufacturing Network / Development Environment +// Datei: nRF52840Gpio.h +// Editor: Robert Patzke +// URI/URL: www.mfp-portal.de +//----------------------------------------------------------------------------- +// Lizenz: CC-BY-SA (wikipedia: Creative Commons) +// Datum: 29. Juni 2021 +// + +#ifndef NRF52840GPIO_H +#define NRF52840GPIO_H + +#include "Arduino.h" +#include "arduinoDefs.h" +#include "IntrfGpio.h" + +#ifndef nrfGpioDef +// ---------------------------------------------------------------------------- +typedef struct _nrfGpio +{ + volatile dword Reserve01; // 000 + volatile dword OUT; // 004 + volatile dword OUTSET; // 008 + volatile dword OUTCLR; // 00C + volatile dword IN; // 010 + volatile dword DIR; // 014 + volatile dword DIRSET; // 018 + volatile dword DIRCLR; // 01C + volatile dword LATCH; // 020 + volatile dword DETECTMODE; // 024 + volatile dword Reserve02[118]; // 026 + volatile dword PIN_CNF[32]; // 200 +} nrfGpio, *nrfGpioPtr; + +#define NrfGpioBase 0x50000000 +#define NrfGpioBase0 0x50000500 +#define NrfGpioPtr0 ((nrfGpioPtr) NrfGpioBase0) +#define NrfGpioBase1 0x50000800 +#define NrfGpioPtr1 ((nrfGpioPtr) NrfGpioBase1) + +#define GpioPinCnf_DIR ((dword) 0x00000001) + +#define GpioPinCnf_INPUT ((dword) 0x00000001 << 1) + +#define GpioPinCnf_PULL(x) ((dword) x << 2) +#define GpioPullDown 1 +#define GpioPullUp 3 + +#define GpioPinCnf_DRIVE(x) ((dword) x << 8) +#define GpioDriveS0S1 0 +#define GpioDriveH0S1 1 +#define GpioDriveS0H1 2 +#define GpioDriveH0H1 3 +#define GpioDriveD0S1 4 +#define GpioDriveD0H1 5 +#define GpioDriveS0D1 6 +#define GpioDriveH0D1 7 + +#define GpioPinCnf_SENSE(x) ((dword) x << 16) +#define GpioSenseHigh 2 +#define GpioSenseLow 3 + +#define nrfGpioDef +// ---------------------------------------------------------------------------- +#endif + +#define P0(x) (x) +#define P1(x) (32+x) + +#ifdef smnNANOBLE33 +// ---------------------------------------------------------------------------- +#define ArdA0Bit 4 +#define ArdA1Bit 5 +#define ArdA2Bit 30 +#define ArdA3Bit 29 +#define ArdA4Bit 31 +#define ArdA5Bit 2 +#define ArdA6Bit 28 +#define ArdA7Bit 3 + +#define ArdA0 P0(4) +#define ArdA1 P0(5) +#define ArdA2 P0(30) +#define ArdA3 P0(29) +#define ArdA4 P0(31) +#define ArdA5 P0(2) +#define ArdA6 P0(28) +#define ArdA7 P0(3) + +#define ArdA0Mask (1 << 4) +#define ArdA1Mask (1 << 5) +#define ArdA2Mask (1 << 30) +#define ArdA3Mask (1 << 29) +#define ArdA4Mask (1 << 31) +#define ArdA5Mask (1 << 2) +#define ArdA6Mask (1 << 28) +#define ArdA7Mask (1 << 3) + + +#define ArdD2 P1(11) +#define ArdD3 P1(12) +#define ArdD4 P1(15) +#define ArdD5 P1(13) +#define ArdD6 P0(14) +#define ArdD7 P0(23) +#define ArdD8 P1(21) +#define ArdD9 P0(27) +#define ArdD10 P1(2) +#define ArdD11 P1(1) +#define ArdD12 P1(8) +#define ArdD13 P0(13) + +#define ArdD2Mask (1 << 11) +#define ArdD3Mask (1 << 12) +#define ArdD4Mask (1 << 15) +#define ArdD5Mask (1 << 13) +#define ArdD6Mask (1 << 14) +#define ArdD7Mask (1 << 23) +#define ArdD8Mask (1 << 21) +#define ArdD9Mask (1 << 27) +#define ArdD10Mask (1 << 2) +#define ArdD11Mask (1 << 1) +#define ArdD12Mask (1 << 8) +#define ArdD13Mask (1 << 13) + +// ---------------------------------------------------------------------------- +#endif + +class nRF52840Gpio : IntrfGpio +{ +private: + // -------------------------------------------------------------------------- + // lokale Variablen + // -------------------------------------------------------------------------- + // + nrfGpioPtr gpioPtr; + +public: + // -------------------------------------------------------------------------- + // Konstruktoren + // -------------------------------------------------------------------------- + // + nRF52840Gpio(); + + // -------------------------------------------------------------------------- + // Konfigurationen + // -------------------------------------------------------------------------- + // + 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 configArd(ArdMask ardMask, unsigned int cnfBits); + + // -------------------------------------------------------------------------- + // Anwendungsfunktionen + // -------------------------------------------------------------------------- + // + void read(GpioExtRefPtr ioRef, GpioExtValPtr valPtr); + dword readArd(ArdMask ardMask); + + void write(GpioExtRefPtr refPtr, GpioExtValPtr valPtr); + void writeArd(ArdMask ardMask, dword value); + void set(GpioExtRefPtr refPtr); + void clr(GpioExtRefPtr refPtr); + + // ---------------------------------------------------------------------------- + // Ereignisbearbeitung und Interrupts + // ---------------------------------------------------------------------------- + // + + // -------------------------------------------------------------------------- + // Debugging und globale Variablen + // -------------------------------------------------------------------------- + // + +}; + +#endif //NRF52840GPIO_H diff --git a/sketches/_PIO_Sketches/Karger/SoaapBleSlave_Test_2/src/nRF52840Radio/library.json b/sketches/_PIO_Sketches/Karger/SoaapBleSlave_Test_2/src/nRF52840Radio/library.json new file mode 100644 index 0000000000000000000000000000000000000000..a18f8f0f08e3ee567cac8bd59e8774c14b3effe7 --- /dev/null +++ b/sketches/_PIO_Sketches/Karger/SoaapBleSlave_Test_2/src/nRF52840Radio/library.json @@ -0,0 +1,4 @@ +{ + "name": "nRF52840Radio", + "version": "0.0.0+20220823165932" +} \ No newline at end of file diff --git a/sketches/_PIO_Sketches/Karger/SoaapBleSlave_Test_2/src/nRF52840Radio/nRF52840Radio.cpp b/sketches/_PIO_Sketches/Karger/SoaapBleSlave_Test_2/src/nRF52840Radio/nRF52840Radio.cpp new file mode 100644 index 0000000000000000000000000000000000000000..5639480f98f812bc2170a24674d34534dd95d5e6 --- /dev/null +++ b/sketches/_PIO_Sketches/Karger/SoaapBleSlave_Test_2/src/nRF52840Radio/nRF52840Radio.cpp @@ -0,0 +1,943 @@ +//----------------------------------------------------------------------------- +// Thema: Social Manufacturing Network / Development Environment +// Datei: nRF52840Radio.h +// Editor: Robert Patzke +// URI/URL: www.mfp-portal.de +//----------------------------------------------------------------------------- +// Lizenz: CC-BY-SA (wikipedia: Creative Commons) +// + +#include "Arduino.h" +#include "nRF52840Radio.h" +#include <string.h> + +// ---------------------------------------------------------------------------- +// Initialisierungen +// ---------------------------------------------------------------------------- + +nRF52840Radio::nRF52840Radio() +{ + NrfRadioPtr->TASKS_DISABLE; // Sender/Empfänger abgeschaltet +#ifdef nrfPowerDCDCEN + *nrfPowerDCDCEN = 1; +#endif +#ifdef nrfClockTASKS_HFCLKSTART + *nrfClockTASKS_HFCLKSTART = 1; +#endif + NrfRadioPtr->POWER = 0; + NrfRadioPtr->POWER = 1; + + irqCounter = 0; + trfMode = txmBase; + statisticPtr = NULL; + recMode = true; + pmPtr = (bcPduPtr) pduMem; + psPtr = (bcPduPtr) pduSentS; + pePtr = (bcPduPtr) pduSentE; + eadM = false; + nakM = false; + comFin = false; + comError = false; + newValues = false; + + memset(statList,0,NrOfTxModes * sizeof(TxStatistics)); +} + +// ---------------------------------------------------------------------------- +// Konfiguration +// ---------------------------------------------------------------------------- + +// Allgemeine Vorbereitungen +// +void nRF52840Radio::begin() +{ + instPtr0 = this; // Verzweigung im statischen Bereich setzen + + NrfRadioPtr->INTENCLR = 0xFFFFFFFF; // Vorsichtshalber keine Interrupts + + // Interruptvektor setzen + // + __NVIC_SetVector((IRQn_Type) 1, (dword) nRF52840Radio::irqHandler0); + __NVIC_SetPriority((IRQn_Type) 1, 1); + __NVIC_EnableIRQ((IRQn_Type) 1); +} + +// Setzen der Zugriffsadresse +// +void nRF52840Radio::setAccessAddress(dword addr) +{ + dword prefix = addr >> 24; + dword base = addr << 8; + + cfgData.base0 = NrfRadioPtr->BASE0 = base; + cfgData.prefix0 = NrfRadioPtr->PREFIX0 = prefix; + cfgData.txAddr = NrfRadioPtr->TXADDRESS = 0; + cfgData.rxAddr = NrfRadioPtr->RXADDRESSES = 0x01; +} + +// Telegrammparameter setzen +// +void nRF52840Radio::setPacketParms(blePduType type) +{ + switch(type) + { + case bptAdv: + cfgData.pCnf0 = NrfRadioPtr->PCNF0 = PCNF0_LFLEN(8) | PCNF0_S0LEN(1) | PCNF0_S1LEN(0); + cfgData.pCnf1 = NrfRadioPtr->PCNF1 = PCNF1_MAXLEN(42) | PCNF1_BALEN(3) | PCNF1_WHITEEN(1); + cfgData.modeCnf0 = NrfRadioPtr->MODECNF0 = 1; + cfgData.crcCnf = NrfRadioPtr->CRCCNF = CRCCNF_LEN(3) | CRCCNF_SKIPADDR(1); + cfgData.crcPoly = NrfRadioPtr->CRCPOLY = PolynomCRC; + cfgData.crcInit = NrfRadioPtr->CRCINIT = AdvStartCRC; + cfgData.packetPtr = NrfRadioPtr->PACKETPTR = (dword) pduMem; + cfgData.mode = NrfRadioPtr->MODE = 3; + cfgData.dacnf = NrfRadioPtr->DACNF = 0x0FF00; + break; + + case bptAux: + break; + } +} + + +// ---------------------------------------------------------------------------- +// Steuerfunktionen und gezielte Prozessorzugriffe +// ---------------------------------------------------------------------------- + +// Schalten des Bewerbungskanals +// +void nRF52840Radio::setChannel(int nr) +{ + cfgData.frequency = NrfRadioPtr->FREQUENCY = channelList[nr].freq; + cfgData.whiteInit = NrfRadioPtr->DATAWHITEIV = channelList[nr].idx; +} + +// ---------------------------------------------------------------------------- +// S e n d e n +// ---------------------------------------------------------------------------- + +// Einstellen der Sendeleistung +// +void nRF52840Radio::setPower(int DBm) +{ + cfgData.txPower = NrfRadioPtr->TXPOWER = DBm; +} +// Senden eines Telegramms +// Es wird davon ausgeganen, das der Radio-Zustand = DISABLED ist +// +int nRF52840Radio::sendSync(bcPduPtr inPduPtr, TxStatePtr refState) +{ + int retv = 0; + NrfRadioPtr->INTENCLR = 0xFFFFFFFF; + NrfRadioPtr->EVENTS_READY = 0; + NrfRadioPtr->EVENTS_END = 0; + memcpy((void *)pduMem, (void *)inPduPtr, sizeof(bcPdu)); // Daten kopieren + if(refState != NULL) + refState->prgLoopPrep = retv = 3 + sizeof(bcPdu); + NrfRadioPtr->TASKS_TXEN = 1; // Starten des Anlaufes + while(NrfRadioPtr->EVENTS_READY != 1) retv++; // Warten bis angelaufen + if(refState != NULL) + refState->evtLoopRampUp = retv - 3; + NrfRadioPtr->TASKS_START = 1; // Starten des Sendevorgangs + while(NrfRadioPtr->EVENTS_END != 1) retv++; // Warten bis gesendet + NrfRadioPtr->TASKS_DISABLE = 1; // Sender abschalten + if(refState != NULL) + { + refState->evtLoopTrans = retv - refState->evtLoopRampUp; + refState->txBufferPtr = pduMem; + } + return(retv); +} + +void nRF52840Radio::send(bcPduPtr inPduPtr, TxMode txMode) +{ + send(inPduPtr, NULL, txMode, false); +} + +void nRF52840Radio::send(bcPduPtr inPduPtrE, bcPduPtr inPduPtrS, TxMode txMode, bool inNewValues) +{ + NrfRadioPtr->INTENCLR = 0xFFFFFFFF; + NrfRadioPtr->EVENTS_READY = 0; + NrfRadioPtr->EVENTS_END = 0; + NrfRadioPtr->EVENTS_DISABLED = 0; + NrfRadioPtr->EVENTS_RXREADY = 0; + NrfRadioPtr->EVENTS_TXREADY = 0; + NrfRadioPtr->EVENTS_ADDRESS = 0; + + // TODO + // Das muss Alles noch einmal überarbeitet werden. + // Hier stecken zu viele Redundanzen drin, Altlast aus diversen Tests mit der Hardware + + memcpy((void *)pduMem, (void *)inPduPtrE, sizeof(bcPdu)); // Daten in Funkpuffer kopieren + + memcpy((void *)pduSentE, (void *)inPduPtrE, sizeof(bcPdu)); // Daten in extra Puffer kopieren + // Die übergebenen Daten werden in einen Extrapuffer kopiert zur Entkopplung für eventuelle + // lokale Modifikationen + + if(inPduPtrS != NULL) // Falls Daten für eine Antwort gegeben sind + memcpy((void *)pduSentS, (void *)inPduPtrS, sizeof(bcPdu));// Daten in extra Puffer kopieren + // Die übergebenen Daten werden in einen Extrapuffer kopiert zur Entkopplung für eventuelle + // lokale Modifikationen + + comFin = false; + comError = false; + newValues = inNewValues; + + trfMode = txMode; + +#if (defined smnDEBUG && defined nRF52840RadioDEB) + statisticPtr = &statList[(int) txMode]; + statisticPtr->mode = txMode; + memset(statisticPtr->memDumpRec,0,16); + memset(statisticPtr->memDumpSnd,0,16); +#endif + + switch(txMode) + { + case txmPoll: + recMode = false; + NrfRadioPtr->SHORTS = NrfScTXREADY_START | NrfScEND_DISABLE | NrfScDISABLED_RXEN | NrfScRXREADY_START; + NrfRadioPtr->INTENSET = NrfIntRXREADY; + NrfRadioPtr->TASKS_TXEN = 1; + break; + + case txmResp: + case txmRespE: + recMode = true; + NrfRadioPtr->SHORTS = NrfScREADY_START; + NrfRadioPtr->INTENSET = NrfIntEND; + NrfRadioPtr->TASKS_RXEN = 1; + break; + + case txmBase: + NrfRadioPtr->SHORTS = NrfScREADY_START | NrfScEND_DISABLE; + NrfRadioPtr->TASKS_TXEN = 1; + break; + + case txmRepStart: + NrfRadioPtr->SHORTS = NrfScREADY_START; + NrfRadioPtr->TASKS_TXEN = 1; + break; + + case txmRepCont: + NrfRadioPtr->SHORTS = 0; + NrfRadioPtr->TASKS_START = 1; + break; + + case txmRepEnd: + NrfRadioPtr->SHORTS = NrfScEND_DISABLE; + NrfRadioPtr->TASKS_START = 1; + break; + + case txmReadPrep: + NrfRadioPtr->SHORTS = NrfScTXREADY_START | NrfScEND_DISABLE | NrfScDISABLED_RXEN; + NrfRadioPtr->TASKS_TXEN = 1; + break; + + case txmReadS: + NrfRadioPtr->SHORTS = NrfScTXREADY_START | NrfScEND_DISABLE | NrfScDISABLED_RXEN | NrfScRXREADY_START; + NrfRadioPtr->INTENSET = NrfIntADDRESS; + NrfRadioPtr->TASKS_TXEN = 1; + break; + + case txmRead: + NrfRadioPtr->SHORTS = NrfScTXREADY_START | NrfScEND_DISABLE | NrfScDISABLED_RXEN | NrfScRXREADY_START; + NrfRadioPtr->INTENSET = NrfIntADDRESS | NrfIntEND; + NrfRadioPtr->TASKS_TXEN = 1; + break; + } +} + +void nRF52840Radio::disable(TxMode txMode) +{ + switch(txMode) + { + case txmBase: + break; + + case txmRepStart: + break; + + case txmRepCont: + break; + + case txmRepEnd: + break; + + case txmReadPrep: + break; + + case txmRead: + NrfRadioPtr->TASKS_DISABLE = 1; + break; + + case txmPoll: + NrfRadioPtr->INTENCLR = 0xFFFFFFFF; + NrfRadioPtr->EVENTS_DISABLED = 0; + NrfRadioPtr->TASKS_DISABLE = 1; + break; + + case txmResp: + case txmRespE: + NrfRadioPtr->TASKS_DISABLE = 1; + break; + } + NrfRadioPtr->SHORTS = 0; +} + +bool nRF52840Radio::disabled(TxMode txMode) +{ + bool retv = false; + + switch(txMode) + { + case txmBase: + break; + + case txmRepStart: + break; + + case txmRepCont: + break; + + case txmRepEnd: + break; + + case txmReadPrep: + break; + + case txmRead: + case txmPoll: + if(NrfRadioPtr->EVENTS_DISABLED == 1) + { + NrfRadioPtr->EVENTS_DISABLED = 0; + retv = true; + } + else + { + if(NrfRadioPtr->STATE == NrfStDISABLED) + retv = true; + } + break; + + case txmResp: + case txmRespE: + if(NrfRadioPtr->EVENTS_DISABLED == 1) + { + NrfRadioPtr->EVENTS_DISABLED = 0; + retv = true; + } + else + { + if(NrfRadioPtr->STATE == NrfStDISABLED) + retv = true; + } + break; + } + return(retv); +} + +bool nRF52840Radio::fin(TxMode txMode, bool *crcErr) +{ + bool retv = false; + + *crcErr = comError; + + switch(txMode) + { + case txmBase: + break; + + case txmRepStart: + break; + + case txmRepCont: + break; + + case txmRepEnd: + break; + + case txmReadPrep: + break; + + case txmReadS: + retv = comFin; + break; + + case txmRead: + /* + if(NrfRadioPtr->EVENTS_END == 1) + { + NrfRadioPtr->EVENTS_END = 0; + retv = true; + } + else + { + if(NrfRadioPtr->STATE == NrfStRXIDLE) + retv = true; + } + */ + retv = comFin; + break; + + case txmPoll: + retv = comFin; + break; + + case txmResp: + retv = comFin; + break; + + case txmRespE: + if(NrfRadioPtr->STATE == NrfStDISABLED && !recMode) + retv = true; + break; + } + return(retv); +} + +void nRF52840Radio::cont(TxMode txMode) +{ + switch(txMode) + { + case txmBase: + break; + + case txmRepStart: + break; + + case txmRepCont: + break; + + case txmRepEnd: + break; + + case txmReadPrep: + break; + + case txmRead: + comFin = false; + NrfRadioPtr->TASKS_START = 1; + break; + } +} + +int nRF52840Radio::getRecData(bcPduPtr data, TxMode txMode, int max) +{ + byte *bPtr = (byte *) data; + int retv = 0; + + switch(txMode) + { + case txmResp: + data->head = pduSentE[0]; + retv = data->len = pduSentE[1]; + + for(int i = 2; i < (retv + 2); i++) + { + if(i == max) break; + bPtr[i] = pduSentE[i]; + } + + break; + + case txmBase: + break; + + case txmRepStart: + break; + + case txmRepCont: + break; + + case txmRepEnd: + break; + + case txmReadPrep: + break; + + case txmRead: + break; + } + + + return(retv); +} + + + +// ---------------------------------------------------------------------------- +// E m p f a n g e n +// ---------------------------------------------------------------------------- + +// Starten des Datenempfangs +// +int nRF52840Radio::startRec() +{ + int retv; + NrfRadioPtr->INTENCLR = 0xFFFFFFFF; + NrfRadioPtr->EVENTS_READY = 0; + NrfRadioPtr->EVENTS_END = 0; + NrfRadioPtr->EVENTS_ADDRESS = 0; + NrfRadioPtr->EVENTS_PAYLOAD = 0; + NrfRadioPtr->EVENTS_CRCOK = 0; + NrfRadioPtr->EVENTS_CRCERROR = 0; + NrfRadioPtr->TASKS_RXEN = 1; // Anlauf Empfänger starten + retv = 8; + while(NrfRadioPtr->EVENTS_READY != 1) retv++; // Warten bis angelaufen + NrfRadioPtr->TASKS_START = 1; // Starten des Empfangs + return(retv + 1); +} + +// Fortsetzen des Datenempfangs +// +int nRF52840Radio::contRec() +{ + NrfRadioPtr->EVENTS_END = 0; + NrfRadioPtr->EVENTS_ADDRESS = 0; + NrfRadioPtr->EVENTS_PAYLOAD = 0; + NrfRadioPtr->EVENTS_CRCOK = 0; + NrfRadioPtr->EVENTS_CRCERROR = 0; + NrfRadioPtr->TASKS_START = 1; // Starten des Empfangs + return(6); +} + +// Beenden des Datenempfangs +// +int nRF52840Radio::endRec() +{ + int retv; + NrfRadioPtr->EVENTS_DISABLED = 0; + NrfRadioPtr->EVENTS_END = 0; + NrfRadioPtr->EVENTS_ADDRESS = 0; + NrfRadioPtr->EVENTS_PAYLOAD = 0; + NrfRadioPtr->EVENTS_CRCOK = 0; + NrfRadioPtr->EVENTS_CRCERROR = 0; + NrfRadioPtr->TASKS_DISABLE = 1; // Anlauf Empfänger beenden + retv = 7; + while(NrfRadioPtr->EVENTS_DISABLED != 1) retv++; // Warten bis abgelaufen + return(retv); +} + +// Empfangszustand abfragen +// +int nRF52840Radio::checkRec() +{ + int retv = 0; + + if(NrfRadioPtr->EVENTS_ADDRESS != 0) + retv |= RECSTAT_ADDRESS; + + if(NrfRadioPtr->EVENTS_PAYLOAD != 0) + retv |= RECSTAT_PAYLOAD; + + if(NrfRadioPtr->EVENTS_END != 0) + retv |= RECSTAT_END; + + if(NrfRadioPtr->CRCSTATUS != 0) + retv |= RECSTAT_CRCOK; + + if(NrfRadioPtr->EVENTS_DISABLED != 0) + retv |= RECSTAT_DISABLED; + + return(retv); +} + +int nRF52840Radio::getRecData(bcPduPtr data, int max) +{ + int retv; + byte *bPtr = (byte *) data; + + data->head = pduMem[0]; + retv = data->len = pduMem[1]; + + for(int i = 2; i < (retv + 2); i++) + { + if(i == max) break; + bPtr[i] = pduMem[i]; + } + + return(retv); +} + +// ---------------------------------------------------------------------------- +// Interruptverarbeitung +// ---------------------------------------------------------------------------- +// + +nRF52840Radio *nRF52840Radio::instPtr0 = NULL; + +void nRF52840Radio::irqHandler0() +{ + if(instPtr0 == NULL) return; + instPtr0->irqCounter++; + instPtr0->irqHandler(); +} + +void nRF52840Radio::irqHandler() +{ + statisticPtr->interrupts++; + + switch(trfMode) + { + // ------------------------------------------------------------------------ + case txmRead: // Empty Polling für Master + // ------------------------------------------------------------------------ + + if((NrfRadioPtr->STATE & 0x08) != 0) // Noch im Sendemodus + { // -------------------------------------------------------------------- + if(NrfRadioPtr->EVENTS_ADDRESS == 1) // AC-Adr gesendet + { + NrfRadioPtr->EVENTS_ADDRESS = 0; // nur quittieren + } + + if(NrfRadioPtr->EVENTS_END == 1) // Senden fertig + { + NrfRadioPtr->EVENTS_END = 0; // nur quittieren + statisticPtr->sendings++; + memcpy(statisticPtr->memDumpSnd,pduMem,8); + } + } + else // im Empfangsmodus + { // -------------------------------------------------------------------- + if(NrfRadioPtr->EVENTS_ADDRESS == 1) // AC-Adr empfangen + { + NrfRadioPtr->EVENTS_ADDRESS = 0; // quittieren + NrfRadioPtr->SHORTS = 0; // Direktverbindungen löschen + } + + if(NrfRadioPtr->EVENTS_END == 1) // Empfang fertig + { + NrfRadioPtr->EVENTS_END = 0; // nur quittieren + comFin = true; + statisticPtr->recs++; + memcpy(statisticPtr->memDumpRec,pduMem,8); + } + } + + break; + + // ------------------------------------------------------------------------ + case txmPoll: // Empty Polling und Datenempfang für Master -> DISABLED + // ------------------------------------------------------------------------ + if(NrfRadioPtr->EVENTS_RXREADY == 1) // Empfang aktiviert + { + NrfRadioPtr->EVENTS_RXREADY = 0; // Int quittieren + +#if (defined smnDEBUG && defined nRF52840RadioDEB) + statisticPtr->sendings++; + memcpy(statisticPtr->memDumpSnd,pduMem,8); +#endif + NrfRadioPtr->EVENTS_DISABLED = 0; // Neu erwartet, zurücksetzen + NrfRadioPtr->SHORTS = NrfScEND_DISABLE | NrfScRXREADY_START; + NrfRadioPtr->INTENSET = NrfIntDISABLED; + recMode = true; + } + + if(NrfRadioPtr->EVENTS_DISABLED == 1) // Empfang beendet + { + NrfRadioPtr->EVENTS_DISABLED = 0; // Int quittieren + comFin = true; + if(NrfRadioPtr->CRCSTATUS == 0) + comError = true; + +#if (defined smnDEBUG && defined nRF52840RadioDEB) + statisticPtr->recs++; + if(comError) statisticPtr->crcErrors++; + memcpy(statisticPtr->memDumpRec,pduMem,16); + if(!recMode) + { + // Das darf nicht passieren, sonst neue Int-Verarbeitung erforderlich + statisticPtr->intErrors++; + } +#endif + } + break; + + // ------------------------------------------------------------------------ + case txmReadS: // Datenübertragung für Master (Slave->Master) + // ------------------------------------------------------------------------ + + if(NrfRadioPtr->EVENTS_ADDRESS == 1) // AC-Adr gesendet + { + NrfRadioPtr->EVENTS_ADDRESS = 0; // quittieren + + if((NrfRadioPtr->STATE & 0x08) != 0) // im Sendezustand + break; // nichts weiter + // -------------------------------------------------------------------- + else // Im Empfangszustand + { + NrfRadioPtr->SHORTS = NrfScEND_DISABLE; // automatisch abschalten + NrfRadioPtr->INTENCLR = 0xFFFFFFFF; // und nur noch DISABLED + NrfRadioPtr->INTENSET = NrfIntDISABLED; // Interrupt freischalten + } + } + + if(NrfRadioPtr->EVENTS_DISABLED == 1) // Übertragung fertig + { + NrfRadioPtr->EVENTS_DISABLED = 0; // quittieren + comFin = true; + } + + + break; + + // ---------------------------------------------------------------------- + case txmRespE: // Empty Polling für Slave + // ---------------------------------------------------------------------- + + // -------------------------------------------------------------------- + if(NrfRadioPtr->EVENTS_END == 1) // Übertragung beendet + // -------------------------------------------------------------------- + { + NrfRadioPtr->EVENTS_END = 0; // Event quittieren + + if(recMode) // im Empfangsmodus + { // ---------------------------------------------------------------- + NrfRadioPtr->SHORTS = 0; // keine direkte Kopplung mehr + + statisticPtr->recs++; + memcpy(statisticPtr->memDumpRec,pduMem,8); + + // ---------------------------------------------------------------- + // Reaktion + // ---------------------------------------------------------------- + // + if((pduSentE[5] == pduMem[5]) && (pduSentE[6] == pduMem[6]) && (pduSentE[7] == pduMem[7])) + { + // Die richtige Protokollumgebung (z.B. Soaap) + // + if(pduSentE[2] != pduMem[2]) + { + // aber die falsche Adresse + // Datenempfang fortsetzen + statisticPtr->wrongs++; + NrfRadioPtr->TASKS_START = 1; + } + else + { // richtige Adresse, Antwort schicken + // ------------------------------------------------------------ + statisticPtr->pollNaks++; + + // zunächst alle Funk-Interrupts sperren + NrfRadioPtr->INTENCLR = 0xFFFFFFFF; + + // Interrupt freigeben für "Abgeschaltet" + NrfRadioPtr->INTENSET = NrfIntDISABLED; + + // Empfangsbetrieb abschalten + NrfRadioPtr->TASKS_DISABLE = 1; + } + + } + else + { + // Fremde Umgebung (nicht akzeptierte PDU) + // Datenempfang fortsetzen + statisticPtr->aliens++; + NrfRadioPtr->TASKS_START = 1; + } + } + else // im Sendemodus + { // ---------------------------------------------------------------- + + + } + } + + // -------------------------------------------------------------------- + if(NrfRadioPtr->EVENTS_DISABLED == 1) // ausgeschaltet + // -------------------------------------------------------------------- + { + NrfRadioPtr->EVENTS_DISABLED = 0; // quittieren + + if(recMode) + { + // zunächst alle Funk-Interrupts sperren + NrfRadioPtr->INTENCLR = 0xFFFFFFFF; + + // Interrupt freigeben für "Abgeschaltet" + NrfRadioPtr->INTENSET = NrfIntDISABLED; + + // Kopplung automatisch starten und abschalten nach Ende + NrfRadioPtr->SHORTS = NrfScREADY_START | NrfScEND_DISABLE; + + NrfRadioPtr->TASKS_TXEN = 1; // Sender einschalten + recMode = false; + + // Daten in Funkpuffer kopieren + memcpy((void *)pduMem, (void *)pduSentE, sizeof(bcPdu)); + } + else + { + NrfRadioPtr->SHORTS = 0; + statisticPtr->sendings++; + } + } + + break; + + // ---------------------------------------------------------------------- + case txmResp: // Datenübertragung Slave + // ---------------------------------------------------------------------- + + // -------------------------------------------------------------------- + if(NrfRadioPtr->EVENTS_END == 1) // Übertragung beendet + // Polling-Daten empfangen + // -------------------------------------------------------------------- + { + NrfRadioPtr->EVENTS_END = 0; // Event quittieren + +#if (defined smnDEBUG && defined nRF52840RadioDEB) + statisticPtr->recs++; + memcpy(statisticPtr->memDumpRec,pduMem,8); +#endif + + if((pduSentE[5] != pduMem[5]) || (pduSentE[6] != pduMem[6]) || (pduSentE[7] != pduMem[7])) + { + // Das empfangene Telegramm gehört nicht zum eigenen Netzwerk + // +#if (defined smnDEBUG && defined nRF52840RadioDEB) + statisticPtr->aliens++; +#endif + NrfRadioPtr->SHORTS = 0; // Keine Direktverbindungen + NrfRadioPtr->TASKS_START = 1; // Datenempfang fortsetzen + break; + } + + if((pduSentE[2] != pduMem[2]) || ((pduSentE[3] & 0x3F) != (pduMem[3] & 0x3F))) + { + // Das empfangene Telegramm ist für einen anderen Slave oder Bereich + // +#if (defined smnDEBUG && defined nRF52840RadioDEB) + statisticPtr->wrongs++; +#endif + NrfRadioPtr->SHORTS = 0; // Keine Direktverbindungen + NrfRadioPtr->TASKS_START = 1; // Datenempfang fortsetzen + break; + // TODO + // Hier wird das Protokoll noch erweitert zum Belauschen anderer Slaves + } + + eadM = ((pduMem[3] & SOAAP_EADR) != 0); // Merker für Empfangspolling + nakM = ((pduMem[3] & SOAAP_NAK) != 0); // Merker für NAK-Polling + +#if (defined smnDEBUG && defined nRF52840RadioDEB) + if(nakM) + statisticPtr->pollNaks++; + else + statisticPtr->pollAcks++; +#endif + if(eadM) + { + // Empfangsaufforderung + // Eadr-Nak-Daten in Funkpuffer kopieren + // + memcpy((void *)pduMem, (void *)pduSentE, sizeof(bcPdu)); + } + else + { + // Sendeaufforderung + // Polling-Steuerdaten in Empfangspuffer und + // Sadr-Ack-Daten in Funkpuffer kopieren + // + memcpy((void *)pduSentE, (void *)pduMem, sizeof(bcPdu)); + memcpy((void *)pduMem, (void *)pduSentS, sizeof(bcPdu)); + } + + // Setzen der Direktverbinder auf vollständigen Durchlauf bis Ende der Sendung + // ACHTUNG! Freigegebene Interrupts treten auf, auch wenn sie zu einer + // Direktverbindung gehören. + // + NrfRadioPtr->SHORTS = NrfScDISABLED_TXEN | NrfScREADY_START | NrfScEND_DISABLE; + NrfRadioPtr->EVENTS_READY = 0; // Evt. hängendes Ereignis löschen + NrfRadioPtr->INTENSET = NrfIntREADY; // Int zur Vorbereitung des Sendeabschlusses + NrfRadioPtr->TASKS_DISABLE = 1; // Abschalten des Empfangsbetriebs + break; + } + + // -------------------------------------------------------------------- + if(NrfRadioPtr->EVENTS_READY == 1) // Bereit zum Senden + // -------------------------------------------------------------------- + { + NrfRadioPtr->EVENTS_READY = 0; // Event quittieren + + // Vorbereiten auf das Ende der Sendung mit Abschalten + // NrfScREADY_START | NrfScEND_DISABLE sind weiter wirksam + // + NrfRadioPtr->SHORTS = NrfScREADY_START | NrfScEND_DISABLE; + NrfRadioPtr->EVENTS_DISABLED = 0; // Evt. hängendes Ereignis löschen + recMode = false; + NrfRadioPtr->INTENSET = NrfIntDISABLED; // Int zum Sendeabschluss + break; + } + + // -------------------------------------------------------------------- + if(NrfRadioPtr->EVENTS_DISABLED == 1) // Sendevorgang beendet + // -------------------------------------------------------------------- + { + NrfRadioPtr->EVENTS_DISABLED = 0; // Event quittieren + comFin = true; +#if (defined smnDEBUG && defined nRF52840RadioDEB) + statisticPtr->sendings++; + memcpy(statisticPtr->memDumpSnd,pduMem,16); +#endif + } + + break; + + } +} + +// -------------------------------------------------------------------------- +// Datenzugriffe +// -------------------------------------------------------------------------- +// +int nRF52840Radio::getStatistics(TxStatisticsPtr dest) +{ + int retv = 0; + + *dest = *statisticPtr; + return(retv); +} + +int nRF52840Radio::getState() +{ + return(NrfRadioPtr->STATE); +} + +// ---------------------------------------------------------------------------- +// D e b u g - H i l f e n +// ---------------------------------------------------------------------------- +// +int nRF52840Radio::getPduMem(byte *dest, int start, int end) +{ + int i,j; + + j = 0; + + for(i = start; i < end; i++) + { + dest[j++] = pduMem[i]; + } + return(j); +} + +int nRF52840Radio::getPduSent(byte *dest, int start, int end) +{ + int i,j; + + j = 0; + + for(i = start; i < end; i++) + { + dest[j++] = pduSentE[i]; + } + return(j); +} + + + + + + + diff --git a/sketches/_PIO_Sketches/Karger/SoaapBleSlave_Test_2/src/nRF52840Radio/nRF52840Radio.h b/sketches/_PIO_Sketches/Karger/SoaapBleSlave_Test_2/src/nRF52840Radio/nRF52840Radio.h new file mode 100644 index 0000000000000000000000000000000000000000..0e61246043b8b3bd78928b3e33e31f81e180d011 --- /dev/null +++ b/sketches/_PIO_Sketches/Karger/SoaapBleSlave_Test_2/src/nRF52840Radio/nRF52840Radio.h @@ -0,0 +1,313 @@ +//----------------------------------------------------------------------------- +// Thema: Social Manufacturing Network / Development Environment +// Datei: nRF52840Radio.h +// Editor: Robert Patzke +// URI/URL: www.mfp-portal.de +//----------------------------------------------------------------------------- +// Lizenz: CC-BY-SA (wikipedia: Creative Commons) +// + +#ifndef NRF52840RADIO_H +#define NRF52840RADIO_H + +#include "arduinoDefs.h" +#include "bleSpec.h" +#include "IntrfRadio.h" + +#define nRF52840RadioDEB + +// ---------------------------------------------------------------------------- + +typedef struct _NRF_RADIO_Type +{ + volatile dword TASKS_TXEN; + volatile dword TASKS_RXEN; + volatile dword TASKS_START; + volatile dword TASKS_STOP; + volatile dword TASKS_DISABLE; + volatile dword TASKS_RSSISTART; + volatile dword TASKS_RSSISTOP; + volatile dword TASKS_BCSTART; + volatile dword TASKS_BCSTOP; + volatile dword TASKS_EDSTART; + volatile dword TASKS_EDSTOP; + volatile dword TASKS_CCASTART; + volatile dword TASKS_CCASTOP; + volatile dword RESERVED0[51]; + volatile dword EVENTS_READY; + volatile dword EVENTS_ADDRESS; + volatile dword EVENTS_PAYLOAD; + volatile dword EVENTS_END; + volatile dword EVENTS_DISABLED; + volatile dword EVENTS_DEVMATCH; + volatile dword EVENTS_DEVMISS; + volatile dword EVENTS_RSSIEND; + volatile dword RESERVED1[2]; + volatile dword EVENTS_BCMATCH; + volatile dword RESERVED2; + volatile dword EVENTS_CRCOK; + volatile dword EVENTS_CRCERROR; + volatile dword EVENTS_FRAMESTART; + volatile dword EVENTS_EDEND; + volatile dword EVENTS_EDSTOPPED; + volatile dword EVENTS_CCAIDLE; + volatile dword EVENTS_CCABUSY; + volatile dword EVENTS_CCASTOPPED; + volatile dword EVENTS_RATEBOOST; + volatile dword EVENTS_TXREADY; + volatile dword EVENTS_RXREADY; + volatile dword EVENTS_MHRMATCH; + volatile dword RESERVED3[2]; + volatile dword EVENTS_SYNC; + volatile dword EVENTS_PHYEND; + volatile dword RESERVED4[36]; + volatile dword SHORTS; + volatile dword RESERVED5[64]; + volatile dword INTENSET; + volatile dword INTENCLR; + volatile dword RESERVED6[61]; + volatile dword CRCSTATUS; + volatile dword RESERVED7; + volatile dword RXMATCH; + volatile dword RXCRC; + volatile dword DAI; + volatile dword PDUSTAT; + volatile dword RESERVED8[59]; + volatile dword PACKETPTR; + volatile dword FREQUENCY; + volatile dword TXPOWER; + volatile dword MODE; + volatile dword PCNF0; + volatile dword PCNF1; + volatile dword BASE0; + volatile dword BASE1; + volatile dword PREFIX0; + volatile dword PREFIX1; + volatile dword TXADDRESS; + volatile dword RXADDRESSES; + volatile dword CRCCNF; + volatile dword CRCPOLY; + volatile dword CRCINIT; + volatile dword RESERVED9; + volatile dword TIFS; + volatile dword RSSISAMPLE; + volatile dword RESERVED10; + volatile dword STATE; + volatile dword DATAWHITEIV; + volatile dword RESERVED11[2]; + volatile dword BCC; + volatile dword RESERVED12[39]; + volatile dword DAB[8]; + volatile dword DAP[8]; + volatile dword DACNF; + volatile dword MHRMATCHCONF; + volatile dword MHRMATCHMAS; + volatile dword RESERVED13; + volatile dword MODECNF0; + volatile dword RESERVED14[3]; + volatile dword SFD; + volatile dword EDCNT; + volatile dword EDSAMPLE; + volatile dword CCACTRL; + volatile dword RESERVED15[611]; + volatile dword POWER; +} *nrfRadioPtr; + + + +#define NrfRadioBase 0x40001000 +#define NrfRadioPtr ((nrfRadioPtr) NrfRadioBase) + +#ifndef NrfPowerBase +#define NrfPowerBase 0x40000000 +#define nrfPowerDCDCEN ((dword *) 0x40000578) +#endif + +#ifndef NrfClockBase +#define NrfClockBase 0x40000000 +#define nrfClockTASKS_HFCLKSTART ((dword *) 0x40000000) +#endif + +// Direktverbindungen (shortcuts) zwischen events und Tasks +// +#define NrfScREADY_START 0x00000001 +#define NrfScEND_DISABLE 0x00000002 +#define NrfScDISABLED_TXEN 0x00000004 +#define NrfScDISABLED_RXEN 0x00000008 +#define NrfScTXREADY_START 0x00040000 +#define NrfScRXREADY_START 0x00080000 + +// Interrupts +// +#define NrfIntREADY 0x00000001 +#define NrfIntADDRESS 0x00000002 +#define NrfIntPAYLOAD 0x00000004 +#define NrfIntEND 0x00000008 +#define NrfIntDISABLED 0x00000010 +#define NrfIntRSSIEND 0x00000080 +#define NrfIntTXREADY 0x00200000 +#define NrfIntRXREADY 0x00400000 + +// Zustände +// +#define NrfStDISABLED 0 +#define NrfStRXRU 1 +#define NrfStRXIDLE 2 +#define NrfStRX 3 +#define NrfStRXDISABLE 4 +#define NrfStTXRU 9 +#define NrfStTXIDLE 10 +#define NrfStTX 11 +#define NrfStTXDISABLE 12 + +// Festlegungen für die Paketkonfigurationsregister +// + +#define PCNF0_LFLEN(x) x +// Anzahl der Bits im Längenfeld (0-15) + +#define PCNF0_S0LEN(x) (x << 8) +// Länge des Header0 (S0) in Bytes (0 oder 1) + +#define PCNF0_S1LEN(x) (x << 16) +// Länge des S1-Feldes in Bit (0 bis 15) + +#define PCNF1_MAXLEN(x) x +// Maximale Telegrammlänge (0 bis 255) + +#define PCNF1_BALEN(x) (x << 16) +// Basislänge der Zugriffsadresse (Access Address, 2-4) + +#define PCNF1_WHITEEN(x) (x << 25) +// Whitening (Bitmischung) Ein/Aus (1/0) + +// Festlegungen für die CRC-Generierung +// + +#define CRCCNF_LEN(x) x +// Anzahl der Bytes für CRC (0-3) + +#define CRCCNF_SKIPADDR(x) (x << 8) +// Zugriffsadresse (Access Address) nicht im CRC (1), im CRC (0) + + +typedef struct _nrf52840Cfg +{ + dword pCnf0; + dword pCnf1; + dword whiteInit; + dword modeCnf0; + dword crcPoly; + dword crcInit; + dword crcCnf; + dword packetPtr; + dword frequency; + dword txPower; + dword mode; + dword dacnf; + dword rxAddrEn; + dword base0; + dword prefix0; + dword txAddr; + dword rxAddr; + +}nrf52840Cfg, *nrf52840CfgPtr; + +// ---------------------------------------------------------------------------- + +class nRF52840Radio : IntrfRadio +{ +private: + // -------------------------------------------------------------------------- + // Lokale Daten + // -------------------------------------------------------------------------- + // + byte pduMem[256]; + byte pduSentE[256]; + byte pduSentS[256]; + + bcPduPtr pmPtr; + bcPduPtr pePtr; + bcPduPtr psPtr; + + nrf52840Cfg cfgData; + + bool recMode; + bool eadM; + bool nakM; + bool comFin; + bool comError; + bool newValues; + + dword irqCounter; + TxMode trfMode; + + TxStatistics statList[NrOfTxModes]; + TxStatisticsPtr statisticPtr; + +public: + // -------------------------------------------------------------------------- + // Initialisierungen der Basis-Klasse + // -------------------------------------------------------------------------- + + nRF52840Radio(); + + // -------------------------------------------------------------------------- + // Konfigurationen + // -------------------------------------------------------------------------- + // + void begin(); + void setAccessAddress(dword addr); // Setzen der Zugriffsadresse + void setPacketParms(blePduType type); + + // -------------------------------------------------------------------------- + // Steuerfunktionen + // -------------------------------------------------------------------------- + // + void setChannel(int nr); // Schalten physikalischer Kanal + int sendSync(bcPduPtr inPduPtr, TxStatePtr refState); + + void send(bcPduPtr inPduPtr, TxMode txMode); + void send(bcPduPtr inPduPtrE, bcPduPtr inPduPtrS, TxMode txMode, bool newValues); + int getRecData(bcPduPtr data, TxMode txMode, int max); // Empfangene Daten lesen + + void disable(TxMode txMode); + bool disabled(TxMode txMode); // Abfrage, ob ausgeschaltet + void cont(TxMode txMode); + bool fin(TxMode txMode, bool *err); + // Senden eines Telegramms (und warten) + int startRec(); // Datenempfang starten + int contRec(); // Datenempfang fortsetzen + int endRec(); // Datenempfang beenden + int checkRec(); // Zustand Datenempfang feststellen + int getRecData(bcPduPtr data, int max); // Empfangene Daten lesen + + void setPower(int DBm); // Leistung des Senders in DBm + + void readCheckCfg(); // Konfigurationsdaten auslesen + + static nRF52840Radio *instPtr0; + static void irqHandler0(); + + void irqHandler(); + + // -------------------------------------------------------------------------- + // Datenzugriffe + // -------------------------------------------------------------------------- + // + int getStatistics(TxStatisticsPtr dest); + int getState(); + + // ---------------------------------------------------------------------------- + // D e b u g - H i l f e n + // ---------------------------------------------------------------------------- + // + int getPduMem(byte *dest, int start, int end); + int getPduSent(byte *dest, int start, int end); + + +}; + + +#endif // NRF52840RADIO_H + diff --git a/sketches/_PIO_Sketches/Karger/SoaapBleSlave_Test_2/src/nRF52840Ser/library.json b/sketches/_PIO_Sketches/Karger/SoaapBleSlave_Test_2/src/nRF52840Ser/library.json new file mode 100644 index 0000000000000000000000000000000000000000..fa5d17537ce11418ad11ee8b2689c1ae0ba6a20b --- /dev/null +++ b/sketches/_PIO_Sketches/Karger/SoaapBleSlave_Test_2/src/nRF52840Ser/library.json @@ -0,0 +1,4 @@ +{ + "name": "nRF52840Ser", + "version": "0.0.0+20220823165932" +} \ No newline at end of file diff --git a/sketches/_PIO_Sketches/Karger/SoaapBleSlave_Test_2/src/nRF52840Ser/nRF52840Ser.cpp b/sketches/_PIO_Sketches/Karger/SoaapBleSlave_Test_2/src/nRF52840Ser/nRF52840Ser.cpp new file mode 100644 index 0000000000000000000000000000000000000000..86b66bb6cd5ba3f8e3a58c8587d7df52eac240f5 --- /dev/null +++ b/sketches/_PIO_Sketches/Karger/SoaapBleSlave_Test_2/src/nRF52840Ser/nRF52840Ser.cpp @@ -0,0 +1,323 @@ +//----------------------------------------------------------------------------- +// Thema: Social Manufacturing Network / Development Environment +// Datei: nRF52840Ser.cpp +// Editor: Robert Patzke +// URI/URL: www.mfp-portal.de +//----------------------------------------------------------------------------- +// Lizenz: CC-BY-SA (wikipedia: Creative Commons) +// + +#include "nRF52840Ser.h" +#include <string.h> + +// ---------------------------------------------------------------------------- +// Initialisierungen +// ---------------------------------------------------------------------------- + +nRF52840Ser::nRF52840Ser() +{ + serPtr = NULL; + instPtr0 = NULL; + irqCounter = 0; + curIntEn = 0; + curIRQ = 0; + lastError = 0; + cntError = 0; +} + +dword speedArr[18] = +{ + 0x0004F000, 0x0009D000, 0x0013B000, + 0x00275000, 0x003B0000, 0x004EA000, + 0x0075F000, 0x00800000, 0x009D5000, + 0x00E50000, 0x00EBF000, 0x013A9000, + 0x01D7E000, 0x03AFB000, 0x04000000, + 0x075F7000, 0x0EBED000, 0x10000000 +}; + +// ---------------------------------------------------------------------------- +// Konfiguration +// ---------------------------------------------------------------------------- +// +void nRF52840Ser::begin(SerParamsPtr inParPtr, IntrfBuf *bufferIf) +{ + nrfGpioPtr gpioPtr; + dword regVal; + + // Setzen des Peripheriezeigers anhand der Instanz + // und Initialisieren weiterer Variablen/Zeiger + // + serPtr = NrfSerPtr0; + clrAllEvents(); + instPtr0 = this; + curIRQ = 2; + + // Interruptvektor setzen + // + __NVIC_SetVector((IRQn_Type) 2, (dword) nRF52840Ser::irqHandler0); + __NVIC_SetPriority((IRQn_Type) 2, 1); + __NVIC_EnableIRQ((IRQn_Type) 2); + + // Alternative Peripherie (gleiche ID, also Alles) abschalten + // + serPtr->ENABLE = SerDisable; + + + // TxD + // ------------------------------------------------- + // + // Pins zuweisen und initialisieren + // + if(inParPtr->txdPort == 1) + { + regVal = 32 + inParPtr->txdPin; + gpioPtr = NrfGpioPtr1; + } + else + { + regVal = inParPtr->txdPin; + gpioPtr = NrfGpioPtr0; + } + + + // Connect (hoechstwertiges Bit) beruecksichtigen + // + serPtr->PSEL_TXD = regVal | 0x7FFFFFC0; + + // Zugewiesenen Pin als Ausgang schalten und Treibermodus setzen + // Laut Datenblatt ist das entsprechende Bit im Konfigurationsregister + // mit dem DIR-Register physikalisch verbunden + // + if(inParPtr->type == stStd) + regVal = GpioPinCnf_DRIVE(GpioDriveS0S1); + else if(inParPtr->type == stPow) + regVal = GpioPinCnf_DRIVE(GpioDriveH0H1); + else + regVal = GpioPinCnf_DRIVE(GpioDriveH0D1); + + gpioPtr->PIN_CNF[inParPtr->txdPin] = regVal | GpioPinCnf_DIROUT; + + // RXD + // ------------------------------------------------- + // + if(inParPtr->rxdPort == 1) + { + regVal = 32 + inParPtr->rxdPin; + gpioPtr = NrfGpioPtr1; + } + else + { + regVal = inParPtr->rxdPin; + gpioPtr = NrfGpioPtr0; + } + + // Connect (hoechstwertiges Bit) beruecksichtigen + // + serPtr->PSEL_RXD = regVal | 0x7FFFFFC0; + + // Zugewiesenen Pin als Eingang schalten und Treibermodus setzen + // Laut Datenblatt ist das entsprechende Bit im Konfigurationsregister + // mit dem DIR-Register physikalisch verbunden + // + gpioPtr->PIN_CNF[inParPtr->rxdPin] = GpioPinCnf_PULL(GpioPullUp); + + // Bitrate einstellen + // + regVal = speedArr[inParPtr->speed]; + serPtr->BAUDRATE = regVal; + serPtr->SHORTS = 0; + + // Interrupts freischalten + // + curIntEn = (SerInt_TXDRDY | SerInt_RXDRDY | SerInt_ERROR); + serPtr->INTENSET = curIntEn; + + // Und bereit machen + // + serPtr->ENABLE = SerEnable; + txdFin = true; + + bufIf = bufferIf; + delay(10); +} + + +// ---------------------------------------------------------------------------- +// Steuerfunktionen, gezielte Prozessorzugriffe und Hilfsfunktionen +// ---------------------------------------------------------------------------- +// +void nRF52840Ser::clrAllEvents() +{ + serPtr->EVENTS_RXDRDY = 0; + serPtr->EVENTS_TXDRDY = 0; + serPtr->EVENTS_ERROR = 0; +} + +// Fortsetzen des Interrupt-Sendebetriebs +// +void nRF52840Ser::resuSend() +{ + byte td; + + if(!txdFin) return; + if(bufIf == NULL) return; + if(!bufIf->getByteSnd(&td)) return; + + txdFin = false; + serPtr->EVENTS_TXDRDY = 0; + serPtr->TXD = td; +} + +// Starten des Sendebetriebs +// +void nRF52840Ser::startSend() +{ + serPtr->TASKS_STARTTX = 1; +} + +// Anhalten des Sendebetriebs +// +void nRF52840Ser::stopSend() +{ + serPtr->TASKS_STOPTX = 1; +} + +// Starten des Empfangsbetriebs +// +void nRF52840Ser::startRec() +{ + serPtr->TASKS_STARTRX = 1; +} + +// Anhalten des Empfangsbetriebs +// +void nRF52840Ser::stopRec() +{ + serPtr->TASKS_STOPRX = 1; +} + + +// Bedingtes Ausgeben eines Zeichens +// +bool nRF52840Ser::condSend(byte c) +{ + if(!txdFin) return(false); + + txdFin = false; + serPtr->EVENTS_TXDRDY = 0; + serPtr->TXD = c; + return(true); +} + +// ---------------------------------------------------------------------------- +// Ereignisbearbeitung und Interrupts +// ---------------------------------------------------------------------------- +// +nRF52840Ser *nRF52840Ser::instPtr0 = NULL; + +void nRF52840Ser::irqHandler0() +{ + if(instPtr0 == NULL) return; + instPtr0->irqCounter++; + instPtr0->irqHandler(); +} + + + // -------------------------------------------------------------------------- + // Interrupts (Ereignisbehandlung) + // -------------------------------------------------------------------------- + // +void nRF52840Ser::irqHandler() +{ + byte b; + + if(serPtr->EVENTS_TXDRDY != 0) + { + serPtr->EVENTS_TXDRDY = 0; + if(bufIf == NULL) return; + + if(!bufIf->getByteSnd(&b)) + txdFin = true; + else + serPtr->TXD = b; + } + else if(serPtr->EVENTS_RXDRDY != 0) + { + serPtr->EVENTS_RXDRDY = 0; + b = serPtr->RXD; + if(bufIf == NULL) return; + bufIf->putByteRec(b); + } + else if(serPtr->EVENTS_ERROR != 0) + { + serPtr->EVENTS_ERROR = 0; + cntError++; + lastError = serPtr->ERRORSRC; + anyError |= lastError; + } +} + +// -------------------------------------------------------------------------- +// Datenzugriffe +// -------------------------------------------------------------------------- +// +// Letzten Fehler lesen (Bits) +// +int nRF52840Ser::getLastError() +{ + return(lastError); +} + +// Alle vorgekommenen Fehlerbits +// +int nRF52840Ser::getAnyError() +{ + return(anyError); +} + +// Anzahl der Fehler lesen +// +dword nRF52840Ser::getErrCount() +{ + return(cntError); +} + + + +// ---------------------------------------------------------------------------- +// D e b u g - H i l f e n +// ---------------------------------------------------------------------------- +// +dword nRF52840Ser::getIrqCount() +{ + return(irqCounter); +} + +void nRF52840Ser::resetIrqList() +{ + irqIdx = 0; + firstRead = true; + + for(int i = 0; i < 8; i++) + irqList[i] = 0; +} + +void nRF52840Ser::getIrqList(char *dest) +{ + int destIdx = 0; + + for(int i = 0; i < 8; i++) + { + if(irqList[i] == 0) break; + + dest[destIdx++] = ' '; + dest[destIdx++] = irqList[i] + 0x30; + } + + dest[destIdx] = '\0'; +} + + + + + diff --git a/sketches/_PIO_Sketches/Karger/SoaapBleSlave_Test_2/src/nRF52840Ser/nRF52840Ser.h b/sketches/_PIO_Sketches/Karger/SoaapBleSlave_Test_2/src/nRF52840Ser/nRF52840Ser.h new file mode 100644 index 0000000000000000000000000000000000000000..37fcae4b19bc8ec15a2a83040f6f086d35e68efd --- /dev/null +++ b/sketches/_PIO_Sketches/Karger/SoaapBleSlave_Test_2/src/nRF52840Ser/nRF52840Ser.h @@ -0,0 +1,234 @@ +//----------------------------------------------------------------------------- +// Thema: Social Manufacturing Network / Development Environment +// Datei: nRF52840Ser.h +// Editor: Robert Patzke +// URI/URL: www.mfp-portal.de +//----------------------------------------------------------------------------- +// Lizenz: CC-BY-SA (wikipedia: Creative Commons) +// + +#ifndef NRF52840SER_H +#define NRF52840SER_H + +#include "Arduino.h" +#include "arduinoDefs.h" +#include "IntrfBuf.h" +#include "IntrfSerial.h" + +// ---------------------------------------------------------------------------- + +typedef struct _nrfSer +{ + volatile dword TASKS_STARTRX; // 000 + volatile dword TASKS_STOPRX; // 004 + volatile dword TASKS_STARTTX; // 008 + volatile dword TASKS_STOPTX; // 00C + volatile dword Reserve01[3]; // 010 + volatile dword TASKS_SUSPEND; // 01C + volatile dword Reserve02[56]; // 020 + volatile dword EVENTS_CTS; // 100 + volatile dword EVENTS_NCTS; // 104 + volatile dword EVENTS_RXDRDY; // 108 + volatile dword Reserve03[4]; // 10C + volatile dword EVENTS_TXDRDY; // 11C + volatile dword Reserve04; // 120 + volatile dword EVENTS_ERROR; // 124 + volatile dword Reserve05[7]; // 128 + volatile dword EVENTS_RXTO; // 144 + volatile dword Reserve06[46]; // 148 + volatile dword SHORTS; // 200 + volatile dword Reserve07[64]; // 204 + volatile dword INTENSET; // 304 + volatile dword INTENCLR; // 308 + volatile dword Reserve08[93]; // 30C + volatile dword ERRORSRC; // 480 + volatile dword Reserve09[31]; // 484 + volatile dword ENABLE; // 500 + volatile dword Reserve10; // 504 + volatile dword PSEL_RTS; // 508 + volatile dword PSEL_TXD; // 50C + volatile dword PSEL_CTS; // 510 + volatile dword PSEL_RXD; // 514 + volatile dword RXD; // 518 + volatile dword TXD; // 51C + volatile dword Reserve11; // 520 + volatile dword BAUDRATE; // 524 + volatile dword Reserve12[17]; // 528 + volatile dword CONFIG; // 56C +} nrfSer, *nrfSerPtr; + +#define NrfSerBase0 0x40002000 +#define NrfSerPtr0 ((nrfSerPtr) NrfSerBase0) + +#ifndef nrfGpioDef + +typedef struct _nrfGpio +{ + volatile dword Reserve01; // 000 + volatile dword OUT; // 004 + volatile dword OUTSET; // 008 + volatile dword OUTCLR; // 00C + volatile dword IN; // 010 + volatile dword DIR; // 014 + volatile dword DIRSET; // 018 + volatile dword DIRCLR; // 01C + volatile dword LATCH; // 020 + volatile dword DETECTMODE; // 024 + volatile dword Reserve02[118]; // 026 + volatile dword PIN_CNF[32]; // 200 +} nrfGpio, *nrfGpioPtr; + +#define NrfGpioBase 0x50000000 +#define NrfGpioBase0 0x50000500 +#define NrfGpioPtr0 ((nrfGpioPtr) NrfGpioBase0) +#define NrfGpioBase1 0x50000800 +#define NrfGpioPtr1 ((nrfGpioPtr) NrfGpioBase1) + +#define GpioPinCnf_DIROUT ((dword) 0x00000001) + +#define GpioPinCnf_DISBUF ((dword) 0x00000002) + +#define GpioPinCnf_PULL(x) ((dword) x << 2) +#define GpioPullDown 1 +#define GpioPullUp 3 + +#define GpioPinCnf_DRIVE(x) ((dword) x << 8) +#define GpioDriveS0S1 0 +#define GpioDriveH0S1 1 +#define GpioDriveS0H1 2 +#define GpioDriveH0H1 3 +#define GpioDriveD0S1 4 +#define GpioDriveD0H1 5 +#define GpioDriveS0D1 6 +#define GpioDriveH0D1 7 + +#define GpioPinCnf_SENSE(x) ((dword) x << 16) +#define GpioSenseHigh 2 +#define GpioSenseLow 3 + +#define nrfGpioDef +#endif + +// Festlegungen für die Paketkonfigurationsregister +// + +#define SerInt_RXDRDY ((dword) 0x00000001 << 2) +// Interrupt für Event RXDRDY + +#define SerInt_TXDRDY ((dword) 0x00000001 << 7) +// Interrupt für Event TXDRDY + +#define SerInt_ERROR ((dword) 0x00000001 << 9) +// Interrupt für Event ERROR + + +#define SerEnable 4 +#define SerDisable 0 + +// Bit-Masken fuer Kommunikationsbedingungen +// +#define BM_REC_NOT_COND 0x00 +// Keine Bedingungen beim Empfang +#define BM_REC_END_CHR 0x01 +// Empfang Stoppen beim Eintreffen des vorgegebenen Zeichens +#define BM_REC_RINGBUF 0x02 +// Receive characters in ring buffer +#define BM_SND_RINGBUF 0x04 +// Transmit characters via ring buffer + + + +// ---------------------------------------------------------------------------- + +class nRF52840Ser : IntrfSerial +{ +private: + // -------------------------------------------------------------------------- + // Lokale Daten und Funktionen + // -------------------------------------------------------------------------- + // + nrfSerPtr serPtr; + dword irqCounter; + + int lastError; + int anyError; + dword cntError; + + int curIRQ; + dword curIntEn; + + IntrfBuf *bufIf; + bool txdFin; // TRUE = Sendevorgang beendet + + void clrAllEvents(); + +public: + // -------------------------------------------------------------------------- + // Initialisierungen der Basis-Klasse + // -------------------------------------------------------------------------- + + nRF52840Ser(); + + // -------------------------------------------------------------------------- + // Konfigurationen + // -------------------------------------------------------------------------- + // + void begin(SerParamsPtr serParPtr, IntrfBuf *bufferIf); + + + // -------------------------------------------------------------------------- + // Steuerfunktionen + // -------------------------------------------------------------------------- + // + void resuSend(); // Fortsetzen des Interrupt-Sendebetriebs + void startSend(); // Starten des Sendebetriebs + void stopSend(); // Anhalten des Sendebetriebs + + void startRec(); // Starten des Empfangsbetriebs + void stopRec(); // Anhalten des Empfangsbetriebs + + + // -------------------------------------------------------------------------- + // Datenzugriffe + // -------------------------------------------------------------------------- + // + bool condSend(byte c); // Bedingtes Senden eines Zeichens + + int getLastError(); // Letzten Fehler lesen (Bits) + int getAnyError(); // Alle vorgekommenen Fehlerbits + dword getErrCount(); // Anzahl der Fehler lesen + + + // ---------------------------------------------------------------------------- + // Ereignisbearbeitung und Interrupts + // ---------------------------------------------------------------------------- + // + static nRF52840Ser *instPtr0; + static void irqHandler0(); + + void irqHandler(); + + // -------------------------------------------------------------------------- + // lokale Variablen + // -------------------------------------------------------------------------- + // + + + // ---------------------------------------------------------------------------- + // D e b u g - H i l f e n + // ---------------------------------------------------------------------------- + // + int irqIdx; + int irqList[8]; + + byte extraValue; + bool firstRead; + + dword getIrqCount(); + void resetIrqList(); + void getIrqList(char *dest); + +}; + +#endif // NRF52840SER_H + diff --git a/sketches/_PIO_Sketches/Karger/SoaapBleSlave_Test_2/src/nRF52840Twi/library.json b/sketches/_PIO_Sketches/Karger/SoaapBleSlave_Test_2/src/nRF52840Twi/library.json new file mode 100644 index 0000000000000000000000000000000000000000..16ae3922cdc02214ba2709422d1f9acfa86d132d --- /dev/null +++ b/sketches/_PIO_Sketches/Karger/SoaapBleSlave_Test_2/src/nRF52840Twi/library.json @@ -0,0 +1,4 @@ +{ + "name": "nRF52840Twi", + "version": "0.0.0+20220823165932" +} \ No newline at end of file diff --git a/sketches/_PIO_Sketches/Karger/SoaapBleSlave_Test_2/src/nRF52840Twi/nRF52840Twi.cpp b/sketches/_PIO_Sketches/Karger/SoaapBleSlave_Test_2/src/nRF52840Twi/nRF52840Twi.cpp new file mode 100644 index 0000000000000000000000000000000000000000..81fdb263721b902935a3a21f952b214796e8c9d5 --- /dev/null +++ b/sketches/_PIO_Sketches/Karger/SoaapBleSlave_Test_2/src/nRF52840Twi/nRF52840Twi.cpp @@ -0,0 +1,586 @@ +//----------------------------------------------------------------------------- +// Thema: Social Manufacturing Network / Development Environment +// Datei: nRF52840Radio.cpp +// Editor: Robert Patzke +// URI/URL: www.mfp-portal.de +//----------------------------------------------------------------------------- +// Lizenz: CC-BY-SA (wikipedia: Creative Commons) +// + +#include "nRF52840Twi.h" +#include <string.h> + +// ---------------------------------------------------------------------------- +// Initialisierungen +// ---------------------------------------------------------------------------- + +nRF52840Twi::nRF52840Twi() +{ + twiPtr = NULL; + instPtr0 = NULL; + instPtr1 = NULL; + irqCounter = 0; +} + +// ---------------------------------------------------------------------------- +// Konfiguration +// ---------------------------------------------------------------------------- +// +TwiError nRF52840Twi::begin(TwiParamsPtr inParPtr) +{ + TwiError retv; + nrfGpioPtr gpioPtr; + dword regVal; + + retv = TEnoError; + + params = *inParPtr; + + // Setzen des Peripheriezeigers anhand der Instanz + // und Initialisieren weiterer Variablen/Zeiger + // + if(inParPtr->inst == 0) + { + twiPtr = NrfTwiPtr0; + clrAllEvents(); + instPtr0 = this; + curIRQ = 3; + + // Interruptvektor setzen + // + __NVIC_SetVector((IRQn_Type) 3, (dword) nRF52840Twi::irqHandler0); + __NVIC_SetPriority((IRQn_Type) 3, 1); + __NVIC_EnableIRQ((IRQn_Type) 3); + } + else + { + twiPtr = NrfTwiPtr1; + clrAllEvents(); + instPtr1 = this; + curIRQ = 4; + + // Interruptvektor setzen + // + __NVIC_SetVector((IRQn_Type) 4, (dword) nRF52840Twi::irqHandler1); + __NVIC_SetPriority((IRQn_Type) 4, 1); + __NVIC_EnableIRQ((IRQn_Type) 4); + } + + // Alternative Peripherie (gleiche ID, also Alles) abschalten + // + twiPtr->ENABLE = TwiDisable; + + + // Takt + // ------------------------------------------------- + // + // Pins zuweisen und initialisieren + // + if(inParPtr->clkPort == 1) + { + regVal = 32 + inParPtr->clkPin; + gpioPtr = NrfGpioPtr1; + } + else + { + regVal = inParPtr->clkPin; + gpioPtr = NrfGpioPtr0; + } + + // Connect (hoechstwertiges Bit) beruecksichtigen + // + twiPtr->PSEL_SCL = regVal | 0x7FFFFFC0; + + // Zugewiesenen Pin als Eingang schalten und Treibermodus setzen + // Laut Datenblatt ist das entsprechende Bit im Konfigurationsregister + // mit dem DIR-Register physikalisch verbunden + // + gpioPtr->PIN_CNF[inParPtr->clkPin] = GpioPinCnf_DRIVE(GpioDriveS0D1); + + // Daten + // ------------------------------------------------- + // + if(inParPtr->dataPort == 1) + { + regVal = 32 + inParPtr->dataPin; + gpioPtr = NrfGpioPtr1; + } + else + { + regVal = inParPtr->dataPin; + gpioPtr = NrfGpioPtr0; + } + + // Connect (hoechstwertiges Bit) beruecksichtigen + // + twiPtr->PSEL_SDA = regVal | 0x7FFFFFC0; + + // Zugewiesenen Pin als Eingang schalten und Treibermodus setzen + // Laut Datenblatt ist das entsprechende Bit im Konfigurationsregister + // mit dem DIR-Register physikalisch verbunden + // + gpioPtr->PIN_CNF[inParPtr->dataPin] = GpioPinCnf_DRIVE(GpioDriveS0D1); + + // Frequenz einstellen + // + if(inParPtr->speed == Twi100k) + regVal = NrfTwi100k; + else if(inParPtr->speed == Twi400k) + regVal = NrfTwi400k; + else + regVal = NrfTwi250k; + + twiPtr->FREQUENCY = regVal; + + twiPtr->SHORTS = 0; + + // Interrupts freischalten + // + curIntEn = (TwiInt_TXDSENT | TwiInt_RXDREADY | TwiInt_ERROR | TwiInt_STOPPED); + twiPtr->INTENSET = curIntEn; + + // Und bereit machen + // + twiPtr->ENABLE = TwiEnable; + + delay(10); + + return(retv); +} + + +void nRF52840Twi::getParams(TwiParamsPtr parPtr) +{ + *parPtr = params; +} + + +// ---------------------------------------------------------------------------- +// Steuerfunktionen, gezielte Prozessorzugriffe und Hilfsfunktionen +// ---------------------------------------------------------------------------- +// +void nRF52840Twi::clrAllEvents() +{ + twiPtr->EVENTS_STOPPED = 0; + twiPtr->EVENTS_RXDREADY = 0; + twiPtr->EVENTS_TXDSENT = 0; + twiPtr->EVENTS_SUSPENDED = 0; + twiPtr->EVENTS_BB = 0; + twiPtr->EVENTS_ERROR = 0; +} + +// ---------------------------------------------------------------------------- +// M a s t e r +// ---------------------------------------------------------------------------- +// + + // -------------------------------------------------------------------------- + // Datenaustausch + // -------------------------------------------------------------------------- + // +TwiError nRF52840Twi::sendByte(int adr, TwiBytePtr refByte) +{ + TwiError retv = TEnoError; + lastError = 0; + + resetIrqList(); + + byteStruPtr = refByte; + twiPtr->ADDRESS = adr; + + byteStruPtr->twiStatus = TwStWrReq; + trfMode = ttmWriteByte; + + twiPtr->TASKS_STARTTX = 1; + twiPtr->TXD = refByte->value; + + return(retv); +} + +TwiError nRF52840Twi::sendByteReg(int adr, int reg, TwiBytePtr refByte) +{ + TwiError retv = TEnoError; + + //dynHand = &nRF52840Twi::irqHandler; + + resetIrqList(); + + byteStruPtr = refByte; + twiPtr->ADDRESS = adr; + + byteStruPtr->twiStatus = TwStWrReq; + trfMode = ttmWriteByteReg; + comIdx = 1; + irqIdx = 0; + + twiPtr->TASKS_STARTTX = 1; + twiPtr->TXD = reg; + + return(retv); +} + +TwiStatus nRF52840Twi::writeByteReg(int adr, int reg, byte value) +{ + twiPtr->INTENCLR = curIntEn; + + tmpByte.value = value; + + sendByteReg(adr, reg, &tmpByte); + + while(tmpByte.twiStatus != TwStFin) + { + irqHandler(); + + if(tmpByte.twiStatus & TwStError) + break; + } + + twiPtr->INTENSET = curIntEn; + + return(tmpByte.twiStatus); +} + + +TwiError nRF52840Twi::recByteReg(int adr, int reg, TwiBytePtr refByte) +{ + TwiError retv = TEnoError; + + //dynHand = &nRF52840Twi::irqHandler; + + byteStruPtr = refByte; + twiPtr->ADDRESS = adr; + + resetIrqList(); + + byteStruPtr->twiStatus = TwStRdReq; + trfMode = ttmReadByteReg; + + twiPtr->TASKS_STARTTX = 1; + twiPtr->TXD = reg; + + return(retv); +} + +int nRF52840Twi::readByteReg(int adr, int reg) +{ + twiPtr->INTENCLR = curIntEn; + + recByteReg(adr, reg, &tmpByte); + + while(tmpByte.twiStatus != TwStFin) + { + irqHandler(); + + if(tmpByte.twiStatus & TwStError) + break; + } + + twiPtr->INTENSET = curIntEn; + + if(tmpByte.twiStatus == TwStFin) + return(tmpByte.value); + else + return(-1); +} + + +TwiError nRF52840Twi::recByteRegSeq(int adr, int reg, TwiByteSeqPtr refByteSeq) +{ + TwiError retv = TEnoError; + + byteSeqPtr = refByteSeq; + comIdx = 0; + twiPtr->ADDRESS = adr; + + byteSeqPtr->twiStatus = TwStRdReq; + trfMode = ttmReadByteRegSeq; + + twiPtr->TASKS_STARTTX = 1; + twiPtr->TXD = reg; + + return(retv); +} + +TwiStatus nRF52840Twi::readByteRegSeq(int adr, int reg, TwiByteSeqPtr refByteSeq) +{ + byteSeqPtr = refByteSeq; + comIdx = 0; + twiPtr->ADDRESS = adr; + + byteSeqPtr->twiStatus = TwStRdReq; + trfMode = ttmReadByteRegSeq; + + twiPtr->INTENCLR = curIntEn; + + twiPtr->TASKS_STARTTX = 1; + twiPtr->TXD = reg; + + while(byteSeqPtr->twiStatus != TwStFin) + { + irqHandler(); + + if(byteSeqPtr->twiStatus & TwStError) + break; + } + + twiPtr->INTENSET = curIntEn; + + return(byteSeqPtr->twiStatus); +} + +// ---------------------------------------------------------------------------- +// Ereignisbearbeitung und Interrupts +// ---------------------------------------------------------------------------- +// +nRF52840Twi *nRF52840Twi::instPtr0 = NULL; + +void nRF52840Twi::irqHandler0() +{ + if(instPtr0 == NULL) return; + instPtr0->irqCounter++; + instPtr0->irqHandler(); +} + +nRF52840Twi *nRF52840Twi::instPtr1 = NULL; + +void nRF52840Twi::irqHandler1() +{ + if(instPtr1 == NULL) return; + instPtr1->irqCounter++; + instPtr1->irqHandler(); +} + + + // -------------------------------------------------------------------------- + // Interrupts (Ereignisbehandlung) + // -------------------------------------------------------------------------- + // +void nRF52840Twi::irqHandler() +{ + switch(trfMode) + { + case ttmWriteByte: + // ------------------------------------------------------------------------ + + if(twiPtr->EVENTS_ERROR) + { + twiPtr->EVENTS_ERROR = 0; + lastError = twiPtr->ERRORSRC; + twiPtr->ERRORSRC = (lastError & 0x06); // Clear AdrNak/DataNak + byteStruPtr->twiStatus = (TwiStatus) ( (int) TwStError + lastError); + twiPtr->TASKS_STOP = 1; + + irqList[irqIdx++] = 8; + return; + } + + if(twiPtr->EVENTS_TXDSENT) + { + twiPtr->EVENTS_TXDSENT = 0; + byteStruPtr->twiStatus = TwStSent; + twiPtr->TASKS_STOP = 1; + + irqList[irqIdx++] = 1; + return; + } + + if(twiPtr->EVENTS_STOPPED) + { + twiPtr->EVENTS_STOPPED = 0; + if(lastError == 0) + byteStruPtr->twiStatus = TwStFin; + + irqList[irqIdx++] = 3; + return; + } + + break; + + case ttmWriteByteReg: + // ------------------------------------------------------------------------ + + if(twiPtr->EVENTS_ERROR) + { + twiPtr->EVENTS_ERROR = 0; + lastError = twiPtr->ERRORSRC; + twiPtr->ERRORSRC = (lastError & 0x06); // Clear AdrNak/DataNak + byteStruPtr->twiStatus = (TwiStatus) ( (int) TwStError + lastError); + twiPtr->TASKS_STOP = 1; + return; + } + + if(twiPtr->EVENTS_TXDSENT) + { + twiPtr->EVENTS_TXDSENT = 0; + byteStruPtr->twiStatus = TwStSent; + if(comIdx == 1) + { + comIdx = 0; + twiPtr->TXD = byteStruPtr->value; + } + else + twiPtr->TASKS_STOP = 1; + return; + } + + if(twiPtr->EVENTS_STOPPED) + { + twiPtr->EVENTS_STOPPED = 0; + if(lastError == 0) + byteStruPtr->twiStatus = TwStFin; + return; + } + + break; + + case ttmReadByteReg: + // ------------------------------------------------------------------------ + + if(twiPtr->EVENTS_ERROR) + { + twiPtr->EVENTS_ERROR = 0; + lastError = twiPtr->ERRORSRC; + twiPtr->ERRORSRC = (lastError & 0x06); // Clear AdrNak/DataNak + byteStruPtr->twiStatus = (TwiStatus) ( (int) TwStError + lastError); + twiPtr->TASKS_STOP = 1; + + irqList[irqIdx++] = 8; + return; + } + + if(twiPtr->EVENTS_TXDSENT) + { + twiPtr->EVENTS_TXDSENT = 0; + byteStruPtr->twiStatus = TwStSent; + twiPtr->TASKS_STARTRX = 1; + twiPtr->SHORTS = 2; + + irqList[irqIdx++] = 1; + return; + } + + if(twiPtr->EVENTS_STOPPED) + { + twiPtr->EVENTS_STOPPED = 0; + if(lastError == 0) + byteStruPtr->twiStatus = TwStFin; + + irqList[irqIdx++] = 3; + twiPtr->SHORTS = 0; + return; + } + + if(twiPtr->EVENTS_RXDREADY) + { + twiPtr->EVENTS_RXDREADY = 0; + byteStruPtr->twiStatus = TwStRecvd; + byteStruPtr->value = twiPtr->RXD; + + irqList[irqIdx++] = 2; + return; + } + + break; + + case ttmReadByteRegSeq: + // ------------------------------------------------------------------------ + + if(twiPtr->EVENTS_ERROR) + { + twiPtr->EVENTS_ERROR = 0; + lastError = twiPtr->ERRORSRC; + twiPtr->ERRORSRC = (lastError & 0x06); // Clear AdrNak/DataNak + byteSeqPtr->twiStatus = (TwiStatus) ( (int) TwStError + lastError); + twiPtr->TASKS_STOP = 1; + return; + } + + if(twiPtr->EVENTS_TXDSENT) + { + twiPtr->EVENTS_TXDSENT = 0; + byteSeqPtr->twiStatus = TwStSent; + twiPtr->TASKS_STARTRX = 1; + return; + } + + if(twiPtr->EVENTS_STOPPED) + { + twiPtr->EVENTS_STOPPED = 0; + if(lastError == 0) + byteSeqPtr->twiStatus = TwStFin; + twiPtr->SHORTS = 0; + return; + } + + if(twiPtr->EVENTS_RXDREADY) + { + twiPtr->EVENTS_RXDREADY = 0; + byteSeqPtr->twiStatus = TwStRecvd; + /* + if(comIdx == (byteSeqPtr->len - 2)) + twiPtr->SHORTS = 2; + byteSeqPtr->valueRef[comIdx] = twiPtr->RXD; + if(comIdx < (byteSeqPtr->len - 1)) + comIdx++; + */ + if(comIdx == (byteSeqPtr->len - 2)) + twiPtr->SHORTS = 2; + + lastIn = twiPtr->RXD; + + if(comIdx < (byteSeqPtr->len)) + byteSeqPtr->valueRef[comIdx] = lastIn; + + comIdx++; + return; + } + + break; + + } +} + +// ---------------------------------------------------------------------------- +// S l a v e +// ---------------------------------------------------------------------------- + +// Starten des Datenempfangs +// + +// ---------------------------------------------------------------------------- +// D e b u g - H i l f e n +// ---------------------------------------------------------------------------- +// +dword nRF52840Twi::getIrqCount() +{ + return(irqCounter); +} + +void nRF52840Twi::resetIrqList() +{ + irqIdx = 0; + firstRead = true; + + for(int i = 0; i < 8; i++) + irqList[i] = 0; +} + +void nRF52840Twi::getIrqList(char *dest) +{ + int destIdx = 0; + + for(int i = 0; i < 8; i++) + { + if(irqList[i] == 0) break; + + dest[destIdx++] = ' '; + dest[destIdx++] = irqList[i] + 0x30; + } + + dest[destIdx] = '\0'; +} + + + + + diff --git a/sketches/_PIO_Sketches/Karger/SoaapBleSlave_Test_2/src/nRF52840Twi/nRF52840Twi.h b/sketches/_PIO_Sketches/Karger/SoaapBleSlave_Test_2/src/nRF52840Twi/nRF52840Twi.h new file mode 100644 index 0000000000000000000000000000000000000000..e33ca74b72c254311a695ab5ea7fd3152a8ebf4d --- /dev/null +++ b/sketches/_PIO_Sketches/Karger/SoaapBleSlave_Test_2/src/nRF52840Twi/nRF52840Twi.h @@ -0,0 +1,250 @@ +//----------------------------------------------------------------------------- +// Thema: Social Manufacturing Network / Development Environment +// Datei: nRF52840Twi.h +// Editor: Robert Patzke +// URI/URL: www.mfp-portal.de +//----------------------------------------------------------------------------- +// Lizenz: CC-BY-SA (wikipedia: Creative Commons) +// + +#ifndef NRF52840TWI_H +#define NRF52840TWI_H + +#include "Arduino.h" +#include "arduinoDefs.h" +#include "IntrfTw.h" + +// ---------------------------------------------------------------------------- + +typedef struct _nrfTwi +{ + volatile dword TASKS_STARTRX; // 000 + volatile dword Reserve01; // 004 + volatile dword TASKS_STARTTX; // 008 + volatile dword Reserve02[2]; // 00C + volatile dword TASKS_STOP; // 014 + volatile dword Reserve03; // 018 + volatile dword TASKS_SUSPEND; // 01C + volatile dword TASKS_RESUME; // 020 + volatile dword Reserve04[56]; // 024 + volatile dword EVENTS_STOPPED; // 104 + volatile dword EVENTS_RXDREADY; // 108 + volatile dword Reserve05[4]; // 118 + volatile dword EVENTS_TXDSENT; // 11C + volatile dword Reserve06; // 120 + volatile dword EVENTS_ERROR; // 124 + volatile dword Reserve07[4]; // 128 + volatile dword EVENTS_BB; // 138 + volatile dword Reserve08[3]; // 13C + volatile dword EVENTS_SUSPENDED; // 148 + volatile dword Reserve09[45]; // 14C + volatile dword SHORTS; // 200 + volatile dword Reserve10[64]; // 204 + volatile dword INTENSET; // 304 + volatile dword INTENCLR; // 308 + volatile dword Reserve11[110]; // 30C + volatile dword ERRORSRC; // 4C4 + volatile dword Reserve12[14]; // 4C8 + volatile dword ENABLE; // 500 + volatile dword Reserve13; // 504 + volatile dword PSEL_SCL; // 508 + volatile dword PSEL_SDA; // 50C + volatile dword Reserve14[2]; // 510 + volatile dword RXD; // 518 + volatile dword TXD; // 51C + volatile dword Reserve15; // 520 + volatile dword FREQUENCY; // 524 + volatile dword Reserve16[24]; // 528 + volatile dword ADDRESS; // 588 +} nrfTwi, *nrfTwiPtr; + +#define NrfTwiBase0 0x40003000 +#define NrfTwiPtr0 ((nrfTwiPtr) NrfTwiBase0) +#define NrfTwiBase1 0x40004000 +#define NrfTwiPtr1 ((nrfTwiPtr) NrfTwiBase1) + +#define NrfTwi100k 0x01980000 +#define NrfTwi250k 0x04000000 +#define NrfTwi400k 0x06680000 + +typedef enum _TwiTrfMode +{ + ttmWriteByte = 1, + ttmWriteByteReg, + ttmReadByteReg, + ttmReadByteRegSeq +} TwiTrfMode; + +#ifndef nrfGpioDef + +typedef struct _nrfGpio +{ + volatile dword Reserve01; // 000 + volatile dword OUT; // 004 + volatile dword OUTSET; // 008 + volatile dword OUTCLR; // 00C + volatile dword IN; // 010 + volatile dword DIR; // 014 + volatile dword DIRSET; // 018 + volatile dword DIRCLR; // 01C + volatile dword LATCH; // 020 + volatile dword DETECTMODE; // 024 + volatile dword Reserve02[118]; // 026 + volatile dword PIN_CNF[32]; // 200 +} nrfGpio, *nrfGpioPtr; + +#define NrfGpioBase 0x50000000 +#define NrfGpioBase0 0x50000500 +#define NrfGpioPtr0 ((nrfGpioPtr) NrfGpioBase0) +#define NrfGpioBase1 0x50000800 +#define NrfGpioPtr1 ((nrfGpioPtr) NrfGpioBase1) + +#define GpioPinCnf_DIR ((dword) 0x00000001) + +#define GpioPinCnf_INPUT ((dword) 0x00000001 << 1) + +#define GpioPinCnf_PULL(x) ((dword) x << 2) +#define GpioPullDown 1 +#define GpioPullUp 3 + +#define GpioPinCnf_DRIVE(x) ((dword) x << 8) +#define GpioDriveS0S1 0 +#define GpioDriveH0S1 1 +#define GpioDriveS0H1 2 +#define GpioDriveH0H1 3 +#define GpioDriveD0S1 4 +#define GpioDriveD0H1 5 +#define GpioDriveS0D1 6 +#define GpioDriveH0D1 7 + +#define GpioPinCnf_SENSE(x) ((dword) x << 16) +#define GpioSenseHigh 2 +#define GpioSenseLow 3 + +#define nrfGpioDef +#endif + +// Festlegungen für die Paketkonfigurationsregister +// + +#define TwiInt_STOPPED ((dword) 0x00000001 << 1) +// Interrupt für Event STOPPED + +#define TwiInt_RXDREADY ((dword) 0x00000001 << 2) +// Interrupt für Event RXDREADY + +#define TwiInt_TXDSENT ((dword) 0x00000001 << 7) +// Interrupt für Event TXDSENT + +#define TwiInt_ERROR ((dword) 0x00000001 << 9) +// Interrupt für Event ERROR + +#define TwiInt_BB ((dword) 0x00000001 << 14) +// Interrupt für Event BB + +#define TwiInt_SUSPENDED ((dword) 0x00000001 << 18) +// Interrupt für Event SUSPENDED + +#define TwiEnable 5 +#define TwiDisable 0 + + + + +// ---------------------------------------------------------------------------- + +class nRF52840Twi : IntrfTw +{ +private: + // -------------------------------------------------------------------------- + // Lokale Daten und Funktionen + // -------------------------------------------------------------------------- + // + nrfTwiPtr twiPtr; + dword irqCounter; + + TwiBytePtr byteStruPtr; + TwiWordPtr wordStruPtr; + TwiByteSeqPtr byteSeqPtr; + + TwiTrfMode trfMode; + dword lastError; + byte lastIn; + int comIdx; + + int curIRQ; + dword curIntEn; + + TwiByte tmpByte; + + TwiParams params; + + void clrAllEvents(); + +public: + // -------------------------------------------------------------------------- + // Initialisierungen der Basis-Klasse + // -------------------------------------------------------------------------- + + nRF52840Twi(); + + // -------------------------------------------------------------------------- + // Konfigurationen + // -------------------------------------------------------------------------- + // + TwiError begin(TwiParamsPtr inParPtr); + void getParams(TwiParamsPtr parPtr); + + + // -------------------------------------------------------------------------- + // Steuerfunktionen + // -------------------------------------------------------------------------- + // + + // -------------------------------------------------------------------------- + // Datenaustausch + // -------------------------------------------------------------------------- + // + // asynchrone Kommunikation, Zustand in TwiByte.twiStatus + // + TwiError sendByte(int adr, TwiBytePtr refByte); + TwiError sendByteReg(int addr, int reg, TwiBytePtr refByte); + TwiError recByteReg(int addr, int reg, TwiBytePtr refByte); + TwiError recByteRegSeq(int adr, int reg, TwiByteSeqPtr refByteSeq); + + // synchrone Kommunikation + // + TwiStatus writeByteReg(int adr, int reg, byte value); + int readByteReg(int adr, int reg); + TwiStatus readByteRegSeq(int adr, int reg, TwiByteSeqPtr refByteSeq); + + // ---------------------------------------------------------------------------- + // Ereignisbearbeitung und Interrupts + // ---------------------------------------------------------------------------- + // + static nRF52840Twi *instPtr0; + static void irqHandler0(); + + static nRF52840Twi *instPtr1; + static void irqHandler1(); + + void irqHandler(); + + // ---------------------------------------------------------------------------- + // D e b u g - H i l f e n + // ---------------------------------------------------------------------------- + // + int irqIdx; + int irqList[8]; + + byte extraValue; + bool firstRead; + + dword getIrqCount(); + void resetIrqList(); + void getIrqList(char *dest); + +}; + +#endif // NRF52840RADIO_H + diff --git a/sketches/_PIO_Sketches/Karger/SoaapBleSlave_Test_2/template_platformio.txt b/sketches/_PIO_Sketches/Karger/SoaapBleSlave_Test_2/template_platformio.txt new file mode 100644 index 0000000000000000000000000000000000000000..bfec98771c70ca94f7c7c7198cb894d6330c8a09 --- /dev/null +++ b/sketches/_PIO_Sketches/Karger/SoaapBleSlave_Test_2/template_platformio.txt @@ -0,0 +1,32 @@ +; PlatformIO Project Configuration File +; +; Build options: build flags, source filter +; Upload options: custom upload port, speed and extra flags +; Library options: dependencies, extra library storages +; Advanced options: extra scripting +; +; Please visit documentation for the other options and examples +; https://docs.platformio.org/page/projectconf.html + +[env:nano33ble] +platform = nordicnrf52 +board = nano33ble +framework = arduino +upload_port = COM5 +build_flags = + -DsmnDEFBYBUILD -DsmnNANOBLE33 -DsmnDEBUG ;-DSlaveACM3 +lib_deps = + symlink://C:\Users\lenna\OneDrive\Dokumente\Git\SOAAP\libraries\BlePoll + symlink://C:\Users\lenna\OneDrive\Dokumente\Git\SOAAP\libraries\environment + symlink://C:\Users\lenna\OneDrive\Dokumente\Git\SOAAP\libraries\ComRingBuf + symlink://C:\Users\lenna\OneDrive\Dokumente\Git\SOAAP\libraries\LoopCheck + symlink://C:\Users\lenna\OneDrive\Dokumente\Git\SOAAP\libraries\MidiNotes + symlink://C:\Users\lenna\OneDrive\Dokumente\Git\SOAAP\libraries\Monitor + symlink://C:\Users\lenna\OneDrive\Dokumente\Git\SOAAP\libraries\nRF52840Gpio + symlink://C:\Users\lenna\OneDrive\Dokumente\Git\SOAAP\libraries\nRF52840Radio + symlink://C:\Users\lenna\OneDrive\Dokumente\Git\SOAAP\libraries\nRF52840Ser + symlink://C:\Users\lenna\OneDrive\Dokumente\Git\SOAAP\libraries\nRF52840Twi + symlink://C:\Users\lenna\OneDrive\Dokumente\Git\SOAAP\libraries\SensorLSM9DS1 + symlink://C:\Users\lenna\OneDrive\Dokumente\Git\SOAAP\libraries\SoaapMsg + symlink://C:\Users\lenna\OneDrive\Dokumente\Git\SOAAP\libraries\StateMachine + ;symlink://C:\Users\lenna\OneDrive\Dokumente\Git\SOAAP\libraries\SoaapComDue diff --git a/sketches/_PIO_Sketches/Karger/SoaapBleSlave_Test_2/test/README b/sketches/_PIO_Sketches/Karger/SoaapBleSlave_Test_2/test/README new file mode 100644 index 0000000000000000000000000000000000000000..9b1e87bc67c90e7f09a92a3e855444b085c655a6 --- /dev/null +++ b/sketches/_PIO_Sketches/Karger/SoaapBleSlave_Test_2/test/README @@ -0,0 +1,11 @@ + +This directory is intended for PlatformIO Test Runner and project tests. + +Unit Testing is a software testing method by which individual units of +source code, sets of one or more MCU program modules together with associated +control data, usage procedures, and operating procedures, are tested to +determine whether they are fit for use. Unit testing finds problems early +in the development cycle. + +More information about PlatformIO Unit Testing: +- https://docs.platformio.org/en/latest/advanced/unit-testing/index.html diff --git a/sketches/_PIO_Sketches/README.md b/sketches/_PIO_Sketches/README.md new file mode 100644 index 0000000000000000000000000000000000000000..a38fa89c3f61ca00246497ef2b7ba9e35902a5ed --- /dev/null +++ b/sketches/_PIO_Sketches/README.md @@ -0,0 +1,12 @@ +Speicherort für PlatformIO projekte. + +Workflow: + -PlatformIO öffnen + -Projekt öffnen -> Projektordner wählen, in dem die platformio.ini liegt. + -platformio.ini anpassen: + Inhalt für die platformio.ini aus der template_platformio.txt kopieren. + Dabei den Pfad für die libraries für den jeweiligen Rechner anpassen. + + +Trotz implementierung in der .gitignore will git nachwievor die platformio.ini synchronisieren, obwohl das eigentlich nicht der Fall sein soll. +Synchronisierung dieser ist aufgrund der unterschiedlichen Dateipfade nicht gewünscht. \ No newline at end of file