diff --git a/sketches/TestSerial/TestSerial.h b/sketches/TestSerial/TestSerial.h new file mode 100644 index 0000000000000000000000000000000000000000..32a8a2c221d37e0b5c3730c94f524c636d03acbe --- /dev/null +++ b/sketches/TestSerial/TestSerial.h @@ -0,0 +1,42 @@ +//----------------------------------------------------------------------------- +// Thema: Social Manufacturing Network / Development Environment +// Datei: TestSerial.h +// Editor: Robert Patzke +// URI/URL: www.mfp-portal.de +//----------------------------------------------------------------------------- +// Lizenz: CC-BY-SA (wikipedia: Creative Commons) +// + +#ifndef TestSerial_h +#define TestSerial_h + +#include "Arduino.h" + +#include "environment.h" +#include "LoopCheck.h" +#include "StateMachine.h" +#include "Monitor.h" +#include "nRF52840SerE.h" +#include "ComRingBuf.h" + +#define TmpVerMsg "Version 20230923-10 " + +#ifdef DebugTerminal +// **************************************************************************** +// Z u s t a n d s m a s c h i n e +// **************************************************************************** +// + +void smInit(); +void smCheckJobs(); +void smCheckMemory(); +void smTestSerMem(); +void smCheckRB(); +void smPutCharRB(); +void smReadPtrRB(); +void smGetCntIntSer(); +void smReadAllRB(); +#endif + + +#endif // TestSerial_h diff --git a/sketches/TestSerial/TestSerial.ino b/sketches/TestSerial/TestSerial.ino new file mode 100644 index 0000000000000000000000000000000000000000..57eb0a0bac893542efcf3b734c62768fba3350c4 --- /dev/null +++ b/sketches/TestSerial/TestSerial.ino @@ -0,0 +1,458 @@ +// ============================================================================= +// Testprogramm für serielle Schnittstellen (eigene Treiber) +// ============================================================================= +// + +#include "TestSerial.h" + +char *StartMsg = +{ + "%@TestSerial " + TmpVerMsg +}; + +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 statistische Daten +// greift die Monitor-Instanz auf die LoopCheck-Instanz zu + +char *infoThis = +{ + "DHE TestSerial Version 1.0.0\r\n" + "c0 Abschalten der periodischen Meldung\r\n" + "c1 Prüfen der Speicheradressen\r\n" + "c2 Testen der Ringpuffer und seriellen Schnittstellen\r\n" + //"c3 Steuern/Analysieren der Messwerterfassung\r\n" + //"c4 Testen von Peripheriezugriffen\r\n" + //"c5 Temporäre lokale Tests\r\n" +}; + +#endif + +#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 + + +SerParams tty1Params, tty2Params; +// ---------------------------------------------------------------------------- +nRF52840SerE tty1,tty2; +// ---------------------------------------------------------------------------- +// Eine statische Instanz der Klasse nRF52840SerE (UARTE) +// 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 sndBuffer1[sndBufSize]; +byte sndBuffer2[sndBufSize]; +#define recBufSize 256 +byte recBuffer1[recBufSize]; +byte recBuffer2[recBufSize]; + +// ---------------------------------------------------------------------------- +ComRingBuf crb1,crb2; +// ---------------------------------------------------------------------------- +// 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. + + +void setup() +{ +#if defined(DebugTerminal) + #if defined(ArduinoMonTerm) + 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 + mon.setInfo(infoThis); +#endif + + // Initialisierung von serieller Schnittstelle 1 und Ringpuffer 1 + // -------------------------------------------------------------------------- + tty1Params.inst = SerCom1; // Instanzindex der Schnittstelle (0,1) + tty1Params.rxdPort = 1; // Nummer des IO-Port mit RxD-Pin + tty1Params.rxdPin = 10; // Nummer des RxD-Pin am Port + tty1Params.txdPort = 1; // Nummer des IO-Port mit TxD-Pin + tty1Params.txdPin = 3; // Nummer des TxD-Pin am Port + tty1Params.speed = Baud115200; // Enumerator für Bitrate + tty1Params.type = stStd; // Standard-RS232 + + tty1.begin(&tty1Params, (IntrfBuf *) &crb1); + // Übergeben von Parametern und Referenz auf Ringpufferverwaltung + // für die Übergabe empfangener Zeichen + + crb1.setWriteBuffer(sndBufSize, sndBuffer1); + crb1.setReadBuffer(recBufSize, recBuffer1); + // Speicher an Ringpufferverwaltung übergeben + + crb1.begin((IntrfSerial *) &tty1); + // Referenz auf Schnittstelle an Ringpufferverwaltung + // für die Übergabe zu sendender Zeichen + + tty1.startSend(); // Sendebetrieb aktivieren + tty1.startRec(); // Empfangsbetrieb aktivieren + + // Initialisierung von serieller Schnittstelle 2 und Ringpuffer 2 + // -------------------------------------------------------------------------- + tty2Params.inst = SerCom2; // Instanzindex der Schnittstelle (0,1) + tty2Params.rxdPort = 1; // Nummer des IO-Port mit RxD-Pin + tty2Params.rxdPin = 11; // Nummer des RxD-Pin am Port + tty2Params.txdPort = 1; // Nummer des IO-Port mit TxD-Pin + tty2Params.txdPin = 12; // Nummer des TxD-Pin am Port + tty2Params.speed = Baud115200; // Enumerator für Bitrate + tty2Params.type = stStd; // Standard-RS232 + + tty2.begin(&tty2Params, (IntrfBuf *) &crb2); + // Übergeben von Parametern und Referenz auf Ringpufferverwaltung + // für die Übergabe empfangener Zeichen + + crb2.setWriteBuffer(sndBufSize, sndBuffer2); + crb2.setReadBuffer(recBufSize, recBuffer2); + // Speicher an Ringpufferverwaltung übergeben + + crb2.begin((IntrfSerial *) &tty2); + // Referenz auf Schnittstelle an Ringpufferverwaltung + // für die Übergabe zu sendender Zeichen + + tty2.startSend(); // Sendebetrieb aktivieren + tty2.startRec(); // Empfangsbetrieb aktivieren +} + +#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 + +#ifdef DebugTerminal + // Alle 5 Millisekunden wird die Zustandsmaschine für + // betriebliche Abläufe aufgerufen + // + if(lc.timerMilli(lcTimer4, smCycleTime, 0)) + { + sm.run(); + } + + // Jede halbe Sekunde erfolgt die Ausgabe der Version + // + if(lc.timerMilli(lcTimer5, 500, 0)) + { + if(!mon.cFlag[0]) + { + mon.print(StartMsg); + mon.cprintcr(runView[runViewIdx]); + runViewIdx++; + if(runViewIdx > 3) runViewIdx = 0; + } + } +#endif + // -------------------------------------------------------------------------- + lc.end(); +} + +#ifdef DebugTerminal +// **************************************************************************** +// Z u s t a n d s m a s c h i n e (für Monitor-Ergänzung) +// **************************************************************************** +// + +dword debDword; +byte tmpByteArray[256]; +int tmpInt; + + +void smInit() +{ + sm.enter(smCheckJobs); +} + +// ---------------------------------------------------------------------------- +// Abfrage der Monitorschalter +// ---------------------------------------------------------------------------- +// +char tmpOut[256]; +char charOut[2]; + + +void smCheckJobs() +{ + if(mon.cFlag[1] && !mon.busy) + sm.enter(smCheckMemory); + else if(mon.cFlag[2] && !mon.busy) + sm.enter(smCheckRB); +/* else if(mon.cFlag[3] && !mon.busy) + sm.enter(sm); + else if(mon.cFlag[4] && !mon.busy) + sm.enter(sm); + else if(mon.cFlag[5] && !mon.busy) + sm.enter(sm); + */ +} + +// ---------------------------------------------------------------------------- +// Testen der Speicherzugriffe (Datenstruktur) +// ---------------------------------------------------------------------------- +// + +void smCheckMemory() +{ + if(sm.firstEnter()) + { + mon.print((char *) "Speichertest "); + mon.lastKeyIn = ':'; + } + + if(mon.lastKeyIn == ':') return; + + charOut[0] = mon.lastKeyIn; + charOut[1] = '\0'; + mon.println(charOut); + + if(mon.lastKeyIn == '0' || mon.lastKeyIn == ' ') + { + mon.cFlag[1] = false; + mon.print((char *) "-- Schleifenabbruch - drücke Enter"); + sm.enter(smCheckJobs); + } + else if(mon.lastKeyIn == 'S' || mon.lastKeyIn == 's') + { + mon.println(); + sm.enter(smTestSerMem); + } + mon.lastKeyIn = ':'; + sm.resetEnter(); +} + + +void smTestSerMem() +{ + nrfSerPtr perMem = NULL; + + dword res1 = (dword) &perMem->EVENTS_ENDRX; + dword res2 = (dword) &perMem->INTEN; + dword res3 = (dword) &perMem->EVENTS_ERROR; + dword res4 = (dword) &perMem->ENABLE; + dword res5 = (dword) &perMem->BAUDRATE; + dword res6 = (dword) &perMem->RXD_AMOUNT; + dword res7 = (dword) &perMem->CONFIG; + + sprintf(tmpOut,"%X %X %X %X %X %X %X",res1,res2,res3,res4,res5,res6,res7); + mon.println(tmpOut); + sm.enter(smCheckMemory); +} + + +// ---------------------------------------------------------------------------- +// Testen der Ringpuffer +// ---------------------------------------------------------------------------- +// + +char *smCheckRBHelp = +{ + "A Zeichen in P1 eingeben\r\n" + "B Zeichen in P2 eingeben\r\n" + "I Anzahl der Interrupts anzeigen\r\n" + "R Inhalte der Empfangspuffer auslesen\r\n" + "Z Zeiger/Index der Ringpuffer anzeigen\r\n" +}; + +void smCheckRB() +{ + if(sm.firstEnter()) + { + mon.print((char *) "Testen der Ringpuffer und seriellen Schnittstellen "); + mon.lastKeyIn = ':'; + } + + if(mon.lastKeyIn == ':') return; + + charOut[0] = mon.lastKeyIn; + charOut[1] = '\0'; + mon.println(charOut); + + if(mon.lastKeyIn == 'A' || mon.lastKeyIn == 'a') + { + sm.userVar = 1; + sm.enter(smPutCharRB); + } + else if(mon.lastKeyIn == 'B' || mon.lastKeyIn == 'b') + { + sm.userVar = 2; + sm.enter(smPutCharRB); + } + else if(mon.lastKeyIn == 'I' || mon.lastKeyIn == 'i') + { + sm.userVar = 1; + sm.enter(smGetCntIntSer); + } + else if(mon.lastKeyIn == 'R' || mon.lastKeyIn == 'r') + { + sm.userVar = 1; + sm.enter(smReadAllRB); + } + else if(mon.lastKeyIn == 'Z' || mon.lastKeyIn == 'z') + { + sm.userVar = 1; + sm.enter(smReadPtrRB); + } + else if(mon.lastKeyIn == '0' || mon.lastKeyIn == ' ') + { + mon.cFlag[2] = false; + mon.print((char *) "-- Schleifenabbruch - drücke Enter"); + sm.enter(smCheckJobs); + } + else if(mon.lastKeyIn == 'H' || mon.lastKeyIn == 'h' || mon.lastKeyIn == '?') + { + mon.print(smCheckRBHelp); + } + mon.lastKeyIn = ':'; + sm.resetEnter(); +} + +void smPutCharRB() +{ + int retv; + + if(sm.firstEnter()) + { + mon.print((char *) "Zeichen eingeben für Puffer "); + mon.print(sm.userVar); + mon.print((char *) " "); + mon.lastKeyIn = ':'; + } + if(mon.lastKeyIn == ':') return; + + mon.cprint(mon.lastKeyIn); + if(sm.userVar == 1) + retv = crb1.putChr(mon.lastKeyIn); + else + retv = crb2.putChr(mon.lastKeyIn); + mon.println(retv); + mon.lastKeyIn = ':'; + sm.enter(smCheckRB); +} + +void smReadPtrRB() +{ + ComRingBuf::DbBufValues bv; + + mon.print((char *) "Instanz ["); + mon.print(sm.userVar); + mon.print((char *) "]: Indizes RbIn="); + if(sm.userVar == 1) + crb1.dbGetBufValues(&bv); + else + crb2.dbGetBufValues(&bv); + mon.print(bv.rbRdIdx); + mon.print((char *) " RbOut="); + mon.print(bv.rbWrIdx); + + mon.print((char *) " TbIn="); + mon.print(bv.tbRdIdx); + + mon.print((char *) " TbOut="); + mon.println(bv.tbWrIdx); + + if(sm.userVar == 2) + { + mon.lastKeyIn = ':'; + sm.enter(smCheckRB); + } + else + sm.userVar++; +} + +void smGetCntIntSer() +{ + int cnt1, cnt2; + + cnt1 = tty1.getIrqCount(); + cnt2 = tty2.getIrqCount(); + mon.print((char *) "Interrupts Ser1="); + mon.print(cnt1); + mon.print((char *) " Ser2="); + mon.println(cnt2); + mon.lastKeyIn = ':'; + sm.enter(smCheckRB); +} + +unsigned char tmpCharBuf[32]; + +void smReadAllRB() +{ + int nrIn; + + if(sm.userVar == 1) + { + nrIn = crb1.getAll(tmpCharBuf); + mon.print((char *) "In(1)={"); + } + else + { + nrIn = crb2.getAll(tmpCharBuf); + mon.print((char *) "In(2)={"); + } + if(nrIn > 32) nrIn = 32; + mon.print(tmpCharBuf,nrIn,','); + mon.cprintln('}'); + if(sm.userVar == 2) + { + mon.lastKeyIn = ':'; + sm.enter(smCheckRB); + } + else + sm.userVar++; +} + +#endif // DebugTerminal +