Select Git revision
supported_sections.yaml
-
Tobias Jungel authoredTobias Jungel authored
TestSerial.ino 13.77 KiB
// =============================================================================
// 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"
"Sx String in Px eingeben\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 == 'S' || mon.lastKeyIn == 's')
{
sm.userVar = 0;
sm.enter(smWriteStrRB);
}
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++;
}
char smWrStNr;
void smWriteStrRB()
{
if(sm.firstEnter())
{
mon.print((char *) "String (Endezeichen TAB) eingeben für Puffer ");
}
if(mon.lastKeyIn == ':') return;
if(sm.userVar < 1)
{
if(mon.lastKeyIn < '1' || mon.lastKeyIn > '2') return;
smWrStNr = mon.lastKeyIn;
mon.cprint(smWrStNr);
mon.cprint(':');
mon.cprint(' ');
sm.userVar++;
mon.lastKeyIn = ':';
return;
}
if(mon.lastKeyIn != '\t')
{
tmpCharBuf[sm.userVar - 1] = mon.lastKeyIn;
mon.cprint(mon.lastKeyIn);
sm.userVar++;
mon.lastKeyIn = ':';
return;
}
tmpCharBuf[sm.userVar - 1] = '\0';
if(smWrStNr == '1')
crb1.putStr((char *) tmpCharBuf);
else if(smWrStNr == '2')
crb2.putStr((char *) tmpCharBuf);
mon.println();
mon.lastKeyIn = ':';
sm.enter(smCheckRB);
}
#endif // DebugTerminal