mirror of
				https://github.com/thelsing/knx.git
				synced 2025-10-26 10:26:25 +01:00 
			
		
		
		
	"Restart device" implementation (#38)
* corrected float with DPT9 * Switch Programming-LED also via Bus/ETS * Again: Prog-LED switchable from bus/ETS * DPT16 (to bus) implemented * - Allows ProgButton interrupts on FALLING signal * restart device command * - removed magic numbers - added enum for restart states
This commit is contained in:
		
							parent
							
								
									4a0b46e062
								
							
						
					
					
						commit
						70f387a7b9
					
				@ -176,7 +176,10 @@ void ApplicationLayer::connectIndication(uint16_t tsap)
 | 
				
			|||||||
void ApplicationLayer::connectConfirm(uint16_t destination, uint16_t tsap, bool status)
 | 
					void ApplicationLayer::connectConfirm(uint16_t destination, uint16_t tsap, bool status)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    if (status)
 | 
					    if (status)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
        _connectedTsap = tsap;
 | 
					        _connectedTsap = tsap;
 | 
				
			||||||
 | 
					        _bau.connectConfirm(tsap);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
    else
 | 
					    else
 | 
				
			||||||
        _connectedTsap = -1;
 | 
					        _connectedTsap = -1;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -188,7 +191,7 @@ void ApplicationLayer::disconnectIndication(uint16_t tsap)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
void ApplicationLayer::disconnectConfirm(Priority priority, uint16_t tsap, bool status)
 | 
					void ApplicationLayer::disconnectConfirm(Priority priority, uint16_t tsap, bool status)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
					    _connectedTsap = -1;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void ApplicationLayer::dataConnectedIndication(Priority priority, uint16_t tsap, APDU& apdu)
 | 
					void ApplicationLayer::dataConnectedIndication(Priority priority, uint16_t tsap, APDU& apdu)
 | 
				
			||||||
@ -334,13 +337,23 @@ void ApplicationLayer::deviceDescriptorReadResponse(AckType ack, Priority priori
 | 
				
			|||||||
    individualSend(ack, hopType, priority, asap, apdu);
 | 
					    individualSend(ack, hopType, priority, asap, apdu);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void ApplicationLayer::restartRequest(AckType ack, Priority priority, HopCountType hopType, uint16_t asap)
 | 
					void ApplicationLayer::connectRequest(uint16_t destination, Priority priority)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    _transportLayer->connectRequest(destination, priority);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void ApplicationLayer::disconnectRequest(Priority priority)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    _transportLayer->disconnectRequest(_connectedTsap, priority);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void ApplicationLayer::restartRequest(AckType ack, Priority priority, HopCountType hopType)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    CemiFrame frame(1);
 | 
					    CemiFrame frame(1);
 | 
				
			||||||
    APDU& apdu = frame.apdu();
 | 
					    APDU& apdu = frame.apdu();
 | 
				
			||||||
    apdu.type(Restart);
 | 
					    apdu.type(Restart);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    individualSend(ack, hopType, priority, asap, apdu);
 | 
					    individualSend(ack, hopType, priority, _connectedTsap, apdu);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void ApplicationLayer::propertyValueReadRequest(AckType ack, Priority priority, HopCountType hopType, uint16_t asap, 
 | 
					void ApplicationLayer::propertyValueReadRequest(AckType ack, Priority priority, HopCountType hopType, uint16_t asap, 
 | 
				
			||||||
@ -788,3 +801,8 @@ void ApplicationLayer::individualSend(AckType ack, HopCountType hopType, Priorit
 | 
				
			|||||||
    else
 | 
					    else
 | 
				
			||||||
        _transportLayer->dataIndividualRequest(ack, hopType, priority, asap, apdu);
 | 
					        _transportLayer->dataIndividualRequest(ack, hopType, priority, asap, apdu);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool ApplicationLayer::isConnected()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    return (_connectedTsap >= 0);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -95,7 +95,10 @@ class ApplicationLayer
 | 
				
			|||||||
                                     uint8_t descriptorType);
 | 
					                                     uint8_t descriptorType);
 | 
				
			||||||
    void deviceDescriptorReadResponse(AckType ack, Priority priority, HopCountType hopType, uint16_t asap,
 | 
					    void deviceDescriptorReadResponse(AckType ack, Priority priority, HopCountType hopType, uint16_t asap,
 | 
				
			||||||
                                      uint8_t descriptorType, uint8_t* deviceDescriptor);
 | 
					                                      uint8_t descriptorType, uint8_t* deviceDescriptor);
 | 
				
			||||||
    void restartRequest(AckType ack, Priority priority, HopCountType hopType, uint16_t asap);
 | 
					    void connectRequest(uint16_t destination, Priority priority);
 | 
				
			||||||
 | 
					    void disconnectRequest(Priority priority);
 | 
				
			||||||
 | 
					    bool isConnected();
 | 
				
			||||||
 | 
					    void restartRequest(AckType ack, Priority priority, HopCountType hopType);
 | 
				
			||||||
    void propertyValueReadRequest(AckType ack, Priority priority, HopCountType hopType, uint16_t asap,
 | 
					    void propertyValueReadRequest(AckType ack, Priority priority, HopCountType hopType, uint16_t asap,
 | 
				
			||||||
                                  uint8_t objectIndex, uint8_t propertyId, uint8_t numberOfElements, uint16_t startIndex);
 | 
					                                  uint8_t objectIndex, uint8_t propertyId, uint8_t numberOfElements, uint16_t startIndex);
 | 
				
			||||||
    void propertyValueReadResponse(AckType ack, Priority priority, HopCountType hopType, uint16_t asap, uint8_t objectIndex,
 | 
					    void propertyValueReadResponse(AckType ack, Priority priority, HopCountType hopType, uint16_t asap, uint8_t objectIndex,
 | 
				
			||||||
@ -147,5 +150,5 @@ class ApplicationLayer
 | 
				
			|||||||
    AssociationTableObject& _assocTable;
 | 
					    AssociationTableObject& _assocTable;
 | 
				
			||||||
    BusAccessUnit& _bau;
 | 
					    BusAccessUnit& _bau;
 | 
				
			||||||
    TransportLayer* _transportLayer = 0;
 | 
					    TransportLayer* _transportLayer = 0;
 | 
				
			||||||
    int32_t _connectedTsap;
 | 
					    int32_t _connectedTsap = -1;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
				
			|||||||
@ -236,3 +236,7 @@ void BusAccessUnit::keyWriteResponseConfirm(AckType ack, Priority priority, HopC
 | 
				
			|||||||
void BusAccessUnit::keyWriteAppLayerConfirm(Priority priority, HopCountType hopType, uint16_t asap, uint8_t level)
 | 
					void BusAccessUnit::keyWriteAppLayerConfirm(Priority priority, HopCountType hopType, uint16_t asap, uint8_t level)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void BusAccessUnit::connectConfirm(uint16_t destination)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -108,4 +108,5 @@ class BusAccessUnit
 | 
				
			|||||||
    virtual void keyWriteResponseConfirm(AckType ack, Priority priority, HopCountType hopType, uint16_t asap, uint8_t level,
 | 
					    virtual void keyWriteResponseConfirm(AckType ack, Priority priority, HopCountType hopType, uint16_t asap, uint8_t level,
 | 
				
			||||||
                                         bool status);
 | 
					                                         bool status);
 | 
				
			||||||
    virtual void keyWriteAppLayerConfirm(Priority priority, HopCountType hopType, uint16_t asap, uint8_t level);
 | 
					    virtual void keyWriteAppLayerConfirm(Priority priority, HopCountType hopType, uint16_t asap, uint8_t level);
 | 
				
			||||||
 | 
					    virtual void connectConfirm(uint16_t destination);
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
				
			|||||||
@ -1,4 +1,5 @@
 | 
				
			|||||||
#include "bau_systemB.h"
 | 
					#include "bau_systemB.h"
 | 
				
			||||||
 | 
					#include "bits.h"
 | 
				
			||||||
#include <string.h>
 | 
					#include <string.h>
 | 
				
			||||||
#include <stdio.h>
 | 
					#include <stdio.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -21,6 +22,7 @@ void BauSystemB::loop()
 | 
				
			|||||||
    dataLinkLayer().loop();
 | 
					    dataLinkLayer().loop();
 | 
				
			||||||
    _transLayer.loop();
 | 
					    _transLayer.loop();
 | 
				
			||||||
    sendNextGroupTelegram();
 | 
					    sendNextGroupTelegram();
 | 
				
			||||||
 | 
					    nextRestartState();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
bool BauSystemB::enabled()
 | 
					bool BauSystemB::enabled()
 | 
				
			||||||
@ -293,8 +295,58 @@ void BauSystemB::addSaveRestore(SaveRestore* obj)
 | 
				
			|||||||
    _memory.addSaveRestore(obj);
 | 
					    _memory.addSaveRestore(obj);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bool BauSystemB::restartRequest(uint16_t asap)
 | 
				
			||||||
void BauSystemB::restartRequest(uint16_t asap)
 | 
					 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    _appLayer.restartRequest(AckRequested, LowPriority, NetworkLayerParameter, asap);
 | 
					    if (_appLayer.isConnected())
 | 
				
			||||||
 | 
					        return false;
 | 
				
			||||||
 | 
					    _restartState = Connecting; // order important, has to be set BEFORE connectRequest
 | 
				
			||||||
 | 
					    _appLayer.connectRequest(asap, SystemPriority);
 | 
				
			||||||
 | 
					    _appLayer.deviceDescriptorReadRequest(AckRequested, SystemPriority, NetworkLayerParameter, asap, 0);
 | 
				
			||||||
 | 
					    return true;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void BauSystemB::connectConfirm(uint16_t tsap)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    if (_restartState == Connecting && tsap >= 0)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        /* restart connection is confirmed, go to the next state */
 | 
				
			||||||
 | 
					        _restartState = Connected;
 | 
				
			||||||
 | 
					        _restartDelay = millis();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    else
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        _restartState = Idle;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void BauSystemB::nextRestartState()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    switch (_restartState)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        case Idle:
 | 
				
			||||||
 | 
					            /* inactive state, do nothing */
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					        case Connecting:
 | 
				
			||||||
 | 
					            /* wait for connection, we do nothing here */
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					        case Connected:
 | 
				
			||||||
 | 
					            /* connection confirmed, we send restartRequest, but we wait a moment (sending ACK etc)... */
 | 
				
			||||||
 | 
					            if (millis() - _restartDelay > 30)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                _appLayer.restartRequest(AckRequested, SystemPriority, NetworkLayerParameter);
 | 
				
			||||||
 | 
					                _restartState = Restarted;
 | 
				
			||||||
 | 
					                _restartDelay = millis();
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					        case Restarted:
 | 
				
			||||||
 | 
					            /* restart is finished, we send a discommect */
 | 
				
			||||||
 | 
					            if (millis() - _restartDelay > 30)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                _appLayer.disconnectRequest(SystemPriority);
 | 
				
			||||||
 | 
					                _restartState = Idle;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        default:
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -27,7 +27,7 @@ class BauSystemB : protected BusAccessUnit
 | 
				
			|||||||
    void readMemory();
 | 
					    void readMemory();
 | 
				
			||||||
    void writeMemory();
 | 
					    void writeMemory();
 | 
				
			||||||
    void addSaveRestore(SaveRestore* obj);
 | 
					    void addSaveRestore(SaveRestore* obj);
 | 
				
			||||||
    void restartRequest(uint16_t asap);
 | 
					    bool restartRequest(uint16_t asap);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  protected:
 | 
					  protected:
 | 
				
			||||||
    virtual DataLinkLayer& dataLinkLayer() = 0;
 | 
					    virtual DataLinkLayer& dataLinkLayer() = 0;
 | 
				
			||||||
@ -58,10 +58,20 @@ class BauSystemB : protected BusAccessUnit
 | 
				
			|||||||
                                       uint8_t* data, uint8_t dataLength) override;
 | 
					                                       uint8_t* data, uint8_t dataLength) override;
 | 
				
			||||||
    void groupValueWriteIndication(uint16_t asap, Priority priority, HopCountType hopType,
 | 
					    void groupValueWriteIndication(uint16_t asap, Priority priority, HopCountType hopType,
 | 
				
			||||||
                                   uint8_t* data, uint8_t dataLength) override;
 | 
					                                   uint8_t* data, uint8_t dataLength) override;
 | 
				
			||||||
 | 
					    void connectConfirm(uint16_t tsap) override;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    virtual InterfaceObject* getInterfaceObject(uint8_t idx) = 0;
 | 
					    virtual InterfaceObject* getInterfaceObject(uint8_t idx) = 0;
 | 
				
			||||||
    void sendNextGroupTelegram();
 | 
					    void sendNextGroupTelegram();
 | 
				
			||||||
    void updateGroupObject(GroupObject& go, uint8_t* data, uint8_t length);
 | 
					    void updateGroupObject(GroupObject& go, uint8_t* data, uint8_t length);
 | 
				
			||||||
 | 
					    void nextRestartState();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    enum RestartState
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        Idle,
 | 
				
			||||||
 | 
					        Connecting,
 | 
				
			||||||
 | 
					        Connected,
 | 
				
			||||||
 | 
					        Restarted
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    DeviceObject _deviceObj;
 | 
					    DeviceObject _deviceObj;
 | 
				
			||||||
    Memory _memory;
 | 
					    Memory _memory;
 | 
				
			||||||
@ -74,4 +84,6 @@ class BauSystemB : protected BusAccessUnit
 | 
				
			|||||||
    TransportLayer _transLayer;
 | 
					    TransportLayer _transLayer;
 | 
				
			||||||
    NetworkLayer _netLayer;
 | 
					    NetworkLayer _netLayer;
 | 
				
			||||||
    bool _configured = true;
 | 
					    bool _configured = true;
 | 
				
			||||||
 | 
					    RestartState _restartState = Idle;
 | 
				
			||||||
 | 
					    uint32_t _restartDelay = 0;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
		Loading…
	
		Reference in New Issue
	
	Block a user