knx
ETS configurable knx-stack
tpuart_data_link_layer.h
Go to the documentation of this file.
1 #pragma once
2 
3 #include "config.h"
4 #ifdef USE_TP
5 
6 #include "data_link_layer.h"
7 #include "tp_frame.h"
8 #include <stdint.h>
9 
10 #define MAX_KNX_TELEGRAM_SIZE 263
11 
12 #ifndef MAX_RX_QUEUE_BYTES
13  #define MAX_RX_QUEUE_BYTES MAX_KNX_TELEGRAM_SIZE + 50
14 #endif
15 
16 #ifndef MAX_TX_QUEUE
17  #define MAX_TX_QUEUE 50
18 #endif
19 
20 // __time_critical_func fallback
21 #ifndef ARDUINO_ARCH_RP2040
22  #define __time_critical_func(X) X
23  #define __isr
24 #endif
25 
26 void printFrame(TpFrame* tpframe);
27 
29 {
30  public:
31  virtual ~ITpUartCallBacks() = default;
32  virtual TPAckType isAckRequired(uint16_t address, bool isGrpAddr) = 0;
33 };
34 
36 {
39 
40  public:
41  TpUartDataLinkLayer(DeviceObject& devObj, NetworkLayerEntity& netLayerEntity,
42  Platform& platform, ITpUartCallBacks& cb, DataLinkLayerCallbacks* dllcb = nullptr);
43 
44  void loop();
45  void enabled(bool value);
46  bool enabled() const;
47  DptMedium mediumType() const override;
48  bool reset();
49  void monitor();
50  void stop(bool state);
51  void requestBusy(bool state);
52  void forceAck(bool state);
53  void setRepetitions(uint8_t nack, uint8_t busy);
54  // Alias
55  void setFrameRepetition(uint8_t nack, uint8_t busy);
56  bool isConnected();
57  bool isMonitoring();
58  bool isStopped();
59  bool isBusy();
60  void resetStats();
61 
62 #ifdef USE_TP_RX_QUEUE
63  void processRxISR();
64 #endif
65 #ifdef NCN5120
66  void powerControl(bool state);
67 #endif
68 
69  uint32_t getRxInvalidFrameCounter();
70  uint32_t getRxProcessdFrameCounter();
71  uint32_t getRxIgnoredFrameCounter();
72  uint32_t getRxUnknownControlCounter();
73  uint32_t getTxFrameCounter();
74  uint32_t getTxProcessedFrameCounter();
75  uint8_t getMode();
76 
77  private:
78  // Frame
79  struct knx_tx_queue_entry_t
80  {
81  TpFrame* frame;
82  knx_tx_queue_entry_t* next = nullptr;
83 
84  knx_tx_queue_entry_t(TpFrame* tpFrame)
85  : frame(tpFrame)
86  {
87  }
88  };
89 
90  // TX Queue
91  struct knx_tx_queue_t
92  {
93  knx_tx_queue_entry_t* front = nullptr;
94  knx_tx_queue_entry_t* back = nullptr;
95  } _txFrameQueue;
96 
97  TpFrame* _txFrame = nullptr;
98  TpFrame* _rxFrame = nullptr;
99 
100  volatile bool _stopped = false;
101  volatile bool _connected = false;
102  volatile bool _monitoring = false;
103  volatile bool _busy = false;
104  volatile bool _initialized = false;
105 
106  volatile uint8_t _rxState = 0;
107  volatile uint8_t _txState = 0;
108  volatile uint32_t _rxProcessdFrameCounter = 0;
109  volatile uint32_t _rxInvalidFrameCounter = 0;
110  volatile uint32_t _rxIgnoredFrameCounter = 0;
111  volatile uint32_t _rxUnkownControlCounter = 0;
112  volatile uint32_t _txFrameCounter = 0;
113  volatile uint32_t _txProcessdFrameCounter = 0;
114  volatile bool _rxMarker = false;
115  volatile bool _rxOverflow = false;
116  volatile uint8_t _tpState = 0x0;
117  volatile uint32_t _txLastTime = 0;
118  volatile uint32_t _rxLastTime = 0;
119  volatile bool _forceAck = false;
120  uint8_t _txQueueCount = 0;
121 
122  inline bool markerMode();
123 
124  /*
125  * bits
126  *
127  * 5-7 Busy (Default 11 = 3)
128  * 0-3 Nack (Default 11 = 3)
129  */
130  volatile uint8_t _repetitions = 0b00110011;
131 
132  // to prevent parallel rx processing by isr (when using)
133  volatile bool _rxProcessing = false;
134 
135  volatile uint32_t _lastStateRequest = 0;
136 
137  // void loadNextTxFrame();
138  inline bool processTxFrameBytes();
139  bool sendFrame(CemiFrame& frame);
140  void rxFrameReceived(TpFrame* frame);
141  void dataConBytesReceived(uint8_t* buffer, uint16_t length, bool success);
142 
143  void processRx(bool isr = false);
144  void checkConnected();
145  void processRxByte();
146  void processTxQueue();
147  void clearTxFrameQueue();
148  void processRxFrameComplete();
149  inline void processRxFrame(TpFrame* tpFrame);
150  void pushTxFrameQueue(TpFrame* tpFrame);
151  void requestState(bool force = false);
152  void requestConfig();
153  inline void processRxFrameByte(uint8_t byte);
154 
155 #ifdef USE_TP_RX_QUEUE
156  // Es muss ein Extended Frame rein passen + 1Byte je erlaubter ms Verzögerung
157  volatile uint8_t _rxBuffer[MAX_RX_QUEUE_BYTES] = {};
158  volatile uint16_t _rxBufferFront = 0;
159  volatile uint16_t _rxBufferRear = 0;
160  volatile uint8_t _rxBufferCount = 0;
161 
162  void pushByteToRxQueue(uint8_t byte);
163  uint8_t pullByteFromRxQueue();
164  uint16_t availableInRxQueue();
165  void pushRxFrameQueue();
166  void processRxQueue();
167 #endif
168 
169  inline bool isrLock(bool blocking = false);
170  inline void isrUnlock();
171  inline void clearUartBuffer();
172  inline void connected(bool state = true);
173  void clearTxFrame();
174  void clearOutdatedTxFrame();
175  void processTxFrameComplete(bool success);
176 
177  ITpUartCallBacks& _cb;
178  DataLinkLayerCallbacks* _dllcb;
179 };
180 #endif
virtual ~ITpUartCallBacks()=default
virtual TPAckType isAckRequired(uint16_t address, bool isGrpAddr)=0
DptMedium
Definition: knx_types.h:254
TPAckType
Definition: knx_types.h:24