mirror of
https://github.com/thelsing/knx.git
synced 2025-01-16 00:08:16 +01:00
some bugfixes
This commit is contained in:
parent
8388c79f9f
commit
cf1b6bc7ac
@ -169,11 +169,9 @@ void __isr __time_critical_func(TpUartDataLinkLayer::processRx)(bool isr)
|
|||||||
_rxOverflow = true;
|
_rxOverflow = true;
|
||||||
|
|
||||||
// verarbeiten daten
|
// verarbeiten daten
|
||||||
uint8_t counter = isr ? 10 : 255;
|
while (_platform.uartAvailable())
|
||||||
while (_platform.uartAvailable() && counter > 0)
|
|
||||||
{
|
{
|
||||||
processRxByte();
|
processRxByte();
|
||||||
counter--;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
isrUnlock();
|
isrUnlock();
|
||||||
@ -190,49 +188,28 @@ void TpUartDataLinkLayer::processRxByte()
|
|||||||
if (byte < 0)
|
if (byte < 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (_rxState == RX_FRAME)
|
/*
|
||||||
|
* Wenn ich im RX_INVALID state bin
|
||||||
|
* und das letzte Byte vor mehr als 2ms verarbeitet wurde (also pause >2ms)
|
||||||
|
* und keine weiteren Bytes vorliegen,
|
||||||
|
* dann kann ich den INVALID State verwerfen.
|
||||||
|
*/
|
||||||
|
if (_rxState == RX_INVALID && (millis() - _rxLastTime) > 2 && !_platform.uartAvailable())
|
||||||
{
|
{
|
||||||
processRxFrameByte(byte);
|
println("Reset RX_INVALID");
|
||||||
}
|
|
||||||
else if ((byte & L_DATA_MASK) == L_DATA_STANDARD_IND || (byte & L_DATA_MASK) == L_DATA_EXTENDED_IND)
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
* Verarbeite ein vorheriges Frame falls noch vorhanden. Das dürfte normal nur im Busmonitor auftreten, weil hier noch auch ein ACK gewartet wird
|
|
||||||
*/
|
|
||||||
processRxFrameComplete();
|
processRxFrameComplete();
|
||||||
|
_rxState = RX_IDLE;
|
||||||
_rxFrame->addByte(byte);
|
|
||||||
|
|
||||||
// Provoziere ungültige Frames für Tests
|
|
||||||
// if (millis() % 20 == 0)
|
|
||||||
// _rxFrame->addByte(0x1);
|
|
||||||
|
|
||||||
_rxMarker = false;
|
|
||||||
_rxState = RX_FRAME;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Hier wird inital ein Ack ohne Addressed gesetzt. Das dient dazu falls noch ein Ack vom vorherigen Frame gesetzt wurde,
|
|
||||||
* welches aber ggf nicht rechtzeitig verarbeitet (also nach der Übertragung gesendet wurde) sich nicht auf das neue Frame auswirkt.
|
|
||||||
* Der Zustand kann beliebig oft gesendet werden. Sobald der Moment gekommen ist, dass ein Ack gesendet wird, schaut TPUart im Buffer
|
|
||||||
* was der letzte Ackstatus war und sendet diesen.
|
|
||||||
*
|
|
||||||
* Das darf man natürlich nur wenn ich nicht gerade selber sende, da man eigene Frames nicht ACKt
|
|
||||||
*/
|
|
||||||
if (_txState == TX_IDLE)
|
|
||||||
{
|
|
||||||
_platform.writeUart(U_ACK_REQ);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else if (_rxState == RX_INVALID || _rxOverflow)
|
|
||||||
|
if (_rxState == RX_INVALID)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* Sobald ein Frame ungültig verarbeitet wurde oder ein unbekanntest Kommando eintrifft ist wechselt der Zustand in RX_INVALID.
|
* Sobald ein Frame ungültig verarbeitet wurde oder ein unbekanntes Kommando eintrifft, wechselt der Zustand in RX_INVALID.
|
||||||
* Ab jetzt muss ich davon ausgehen, dass einen Übertragungsfehler gegeben hat und die aktuellen Bytes ungültig sind.
|
* Ab jetzt muss ich davon ausgehen, dass einen Übertragungsfehler gegeben hat und die aktuellen Bytes ungültig sind.
|
||||||
* Gleiches gilt auch wenn ein HW Overflow erkannt wurde
|
* Gleiches gilt auch wenn ein HW Overflow erkannt wurde.
|
||||||
*
|
*
|
||||||
* - Dieser Zustand wird aufgehoben wenn ein Frame "vermutlich" erkannt wurde. (if Abfrage über dieser)
|
* - Die Zeit des letzten Frames 3ms vorbei ist (kann aber nicht garantiert werden, wegen möglichem ISR & DMA. Hier sollte es das Problem aber nicht geben)
|
||||||
* - Die Zeit des letzten Frames 3ms vorbei ist (erfolt im loop)
|
* - Wenn der Markermodus aktiv ist und ein U_FRAME_END_IND sauber erkannt wurde. (Wird hier geprüft)
|
||||||
* - Wenn der Markermodus aktiv ist und ein U_FRAME_END_IND sauber erkannt wurde. (passiert hiert)
|
|
||||||
*
|
*
|
||||||
* Ansonsten macht dieser Abschnitt nichts und verwirrft die ungültigen Bytes
|
* Ansonsten macht dieser Abschnitt nichts und verwirrft die ungültigen Bytes
|
||||||
*/
|
*/
|
||||||
@ -253,11 +230,38 @@ void TpUartDataLinkLayer::processRxByte()
|
|||||||
_rxMarker = false;
|
_rxMarker = false;
|
||||||
_rxState = RX_IDLE;
|
_rxState = RX_IDLE;
|
||||||
}
|
}
|
||||||
else
|
}
|
||||||
{
|
}
|
||||||
// print("RX_INVALID: ");
|
else if (_rxState == RX_FRAME)
|
||||||
// println(byte, HEX);
|
{
|
||||||
}
|
processRxFrameByte(byte);
|
||||||
|
}
|
||||||
|
else if ((byte & L_DATA_MASK) == L_DATA_STANDARD_IND || (byte & L_DATA_MASK) == L_DATA_EXTENDED_IND)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Verarbeite ein vorheriges Frame falls noch vorhanden. Das dürfte normal nur im Busmonitor auftreten, weil hier noch auch ein ACK gewartet wird
|
||||||
|
*/
|
||||||
|
processRxFrameComplete();
|
||||||
|
_rxFrame->addByte(byte);
|
||||||
|
|
||||||
|
// Provoziere ungültige Frames für Tests
|
||||||
|
// if (millis() % 20 == 0)
|
||||||
|
// _rxFrame->addByte(0x1);
|
||||||
|
|
||||||
|
_rxMarker = false;
|
||||||
|
_rxState = RX_FRAME;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Hier wird inital ein Ack ohne Addressed gesetzt. Das dient dazu falls noch ein Ack vom vorherigen Frame gesetzt wurde,
|
||||||
|
* welches aber ggf nicht rechtzeitig verarbeitet (also nach der Übertragung gesendet wurde) sich nicht auf das neue Frame auswirkt.
|
||||||
|
* Der Zustand kann beliebig oft gesendet werden. Sobald der Moment gekommen ist, dass ein Ack gesendet wird, schaut TPUart im Buffer
|
||||||
|
* was der letzte Ackstatus war und sendet diesen.
|
||||||
|
*
|
||||||
|
* Das darf man natürlich nur wenn ich nicht gerade selber sende, da man eigene Frames nicht ACKt
|
||||||
|
*/
|
||||||
|
if (_txState == TX_IDLE)
|
||||||
|
{
|
||||||
|
_platform.writeUart(U_ACK_REQ);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -576,17 +580,17 @@ bool TpUartDataLinkLayer::sendFrame(CemiFrame &cemiFrame)
|
|||||||
* Außerdem soll regelmäßig die aktuelle Config bzw der Modus übermittelt werden, so dass nach einem Disconnect,
|
* Außerdem soll regelmäßig die aktuelle Config bzw der Modus übermittelt werden, so dass nach einem Disconnect,
|
||||||
* der TPUart im richtigen Zustand ist.
|
* der TPUart im richtigen Zustand ist.
|
||||||
*/
|
*/
|
||||||
void TpUartDataLinkLayer::requestState()
|
void TpUartDataLinkLayer::requestState(bool force /* = false */)
|
||||||
{
|
{
|
||||||
if (_rxState != RX_IDLE)
|
if (!force)
|
||||||
return;
|
{
|
||||||
|
if (!(_rxState == RX_IDLE || _rxState == RX_INVALID))
|
||||||
|
return;
|
||||||
|
|
||||||
if (_txState != TX_IDLE)
|
// Nur 1x pro Sekunde
|
||||||
return;
|
if ((millis() - _lastStateRequest) < 1000)
|
||||||
|
return;
|
||||||
// Nur 1x pro Sekunde
|
}
|
||||||
if ((millis() - _lastStateRequest) < 1000)
|
|
||||||
return;
|
|
||||||
|
|
||||||
// println("requestState");
|
// println("requestState");
|
||||||
|
|
||||||
@ -720,7 +724,7 @@ bool TpUartDataLinkLayer::reset()
|
|||||||
if (success)
|
if (success)
|
||||||
{
|
{
|
||||||
_lastStateRequest = 0; // Force
|
_lastStateRequest = 0; // Force
|
||||||
requestState();
|
requestState(true);
|
||||||
_rxLastTime = millis();
|
_rxLastTime = millis();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -860,6 +864,7 @@ void TpUartDataLinkLayer::loop()
|
|||||||
{
|
{
|
||||||
println("TPUart overflow detected!");
|
println("TPUart overflow detected!");
|
||||||
_rxOverflow = false;
|
_rxOverflow = false;
|
||||||
|
_rxState = RX_INVALID;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_tpState)
|
if (_tpState)
|
||||||
@ -869,7 +874,7 @@ void TpUartDataLinkLayer::loop()
|
|||||||
_tpState = 0;
|
_tpState = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
processRx();
|
// processRx();
|
||||||
#ifdef USE_TP_RX_QUEUE
|
#ifdef USE_TP_RX_QUEUE
|
||||||
processRxQueue();
|
processRxQueue();
|
||||||
#endif
|
#endif
|
||||||
@ -877,16 +882,6 @@ void TpUartDataLinkLayer::loop()
|
|||||||
requestState();
|
requestState();
|
||||||
processTxQueue();
|
processTxQueue();
|
||||||
checkConnected();
|
checkConnected();
|
||||||
|
|
||||||
/*
|
|
||||||
* Normal ist alles so gebaut worde, dass anhand der Bytes entschieden wird wann ein Frame "fertig" ist oder nicht.
|
|
||||||
* Dennoch gibt es Situationen, wo ein Frame nicht geschlossen wurde, weil Bytes verloren geangen sind oder wie beim Busmonitor
|
|
||||||
* bewusst auf ein Ack gewartet werden muss.
|
|
||||||
*/
|
|
||||||
// if (!_platform.uartAvailable() && _rxFrame->size() > 0 && (millis() - _rxLastTime) > 2)
|
|
||||||
// {
|
|
||||||
// processRxFrameComplete();
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void TpUartDataLinkLayer::rxFrameReceived(TpFrame *tpFrame)
|
void TpUartDataLinkLayer::rxFrameReceived(TpFrame *tpFrame)
|
||||||
@ -1066,7 +1061,8 @@ void TpUartDataLinkLayer::processRxFrame(TpFrame *tpFrame)
|
|||||||
printFrame(tpFrame);
|
printFrame(tpFrame);
|
||||||
println();
|
println();
|
||||||
#endif
|
#endif
|
||||||
rxFrameReceived(tpFrame);
|
if (!(tpFrame->flags() & TP_FRAME_FLAG_ECHO))
|
||||||
|
rxFrameReceived(tpFrame);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -137,7 +137,7 @@ class TpUartDataLinkLayer : public DataLinkLayer
|
|||||||
void processRxFrameComplete();
|
void processRxFrameComplete();
|
||||||
inline void processRxFrame(TpFrame* tpFrame);
|
inline void processRxFrame(TpFrame* tpFrame);
|
||||||
void pushTxFrameQueue(TpFrame* tpFrame);
|
void pushTxFrameQueue(TpFrame* tpFrame);
|
||||||
void requestState();
|
void requestState(bool force = false);
|
||||||
void requestConfig();
|
void requestConfig();
|
||||||
inline void processRxFrameByte(uint8_t byte);
|
inline void processRxFrameByte(uint8_t byte);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user