mirror of
				https://github.com/thelsing/knx.git
				synced 2025-10-26 10:26:25 +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)
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
        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
 | 
					     * 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())
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        println("Reset RX_INVALID");
 | 
				
			||||||
        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,12 +230,39 @@ void TpUartDataLinkLayer::processRxByte()
 | 
				
			|||||||
                _rxMarker = false;
 | 
					                _rxMarker = false;
 | 
				
			||||||
                _rxState = RX_IDLE;
 | 
					                _rxState = RX_IDLE;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            else
 | 
					 | 
				
			||||||
            {
 | 
					 | 
				
			||||||
                // print("RX_INVALID: ");
 | 
					 | 
				
			||||||
                // println(byte, HEX);
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					    else if (_rxState == RX_FRAME)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        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))
 | 
				
			||||||
    if (_txState != TX_IDLE)
 | 
					 | 
				
			||||||
            return;
 | 
					            return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // Nur 1x pro Sekunde
 | 
					        // Nur 1x pro Sekunde
 | 
				
			||||||
        if ((millis() - _lastStateRequest) < 1000)
 | 
					        if ((millis() - _lastStateRequest) < 1000)
 | 
				
			||||||
            return;
 | 
					            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,6 +1061,7 @@ void TpUartDataLinkLayer::processRxFrame(TpFrame *tpFrame)
 | 
				
			|||||||
        printFrame(tpFrame);
 | 
					        printFrame(tpFrame);
 | 
				
			||||||
        println();
 | 
					        println();
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					        if (!(tpFrame->flags() & TP_FRAME_FLAG_ECHO))
 | 
				
			||||||
            rxFrameReceived(tpFrame);
 | 
					            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