3 #pragma GCC optimize("O3")
20 #define U_RESET_REQ 0x01
21 #define U_STATE_REQ 0x02
22 #define U_SET_BUSY_REQ 0x03
23 #define U_QUIT_BUSY_REQ 0x04
24 #define U_BUSMON_REQ 0x05
25 #define U_SET_ADDRESS_REQ 0xF1
26 #define U_L_DATA_OFFSET_REQ 0x08
27 #define U_SYSTEM_MODE 0x0D
28 #define U_STOP_MODE_REQ 0x0E
29 #define U_EXIT_STOP_MODE_REQ 0x0F
30 #define U_ACK_REQ 0x10
31 #define U_ACK_REQ_NACK 0x04
32 #define U_ACK_REQ_BUSY 0x02
33 #define U_ACK_REQ_ADRESSED 0x01
34 #define U_POLLING_STATE_REQ 0xE0
38 #define U_CONFIGURE_REQ 0x18
39 #define U_CONFIGURE_MARKER_REQ 0x1
40 #define U_CONFIGURE_CRC_CCITT_REQ 0x2
41 #define U_CONFIGURE_AUTO_POLLING_REQ 0x4
42 #define U_SET_REPETITION_REQ 0xF2
44 #define U_MXRSTCNT 0x24
48 #define U_L_DATA_START_REQ 0x80
49 #define U_L_DATA_CONT_REQ 0x80
50 #define U_L_DATA_END_REQ 0x40
55 #define L_DATA_STANDARD_IND 0x90
56 #define L_DATA_EXTENDED_IND 0x10
57 #define L_DATA_MASK 0xD3
58 #define L_POLL_DATA_IND 0xF0
61 #define L_ACKN_IND 0x00
62 #define L_ACKN_MASK 0x33
63 #define L_ACKN_BUSY_MASK 0x0C
64 #define L_ACKN_NACK_MASK 0xC0
65 #define L_DATA_CON 0x0B
66 #define L_DATA_CON_MASK 0x7F
70 #define U_RESET_IND 0x03
71 #define U_STATE_MASK 0x07
72 #define U_STATE_IND 0x07
73 #define SLAVE_COLLISION 0x80
74 #define RECEIVE_ERROR 0x40
75 #define TRANSMIT_ERROR 0x20
76 #define PROTOCOL_ERROR 0x10
77 #define TEMPERATURE_WARNING 0x08
78 #define U_FRAME_STATE_IND 0x13
79 #define U_FRAME_STATE_MASK 0x17
80 #define PARITY_BIT_ERROR 0x80
81 #define CHECKSUM_LENGTH_ERROR 0x40
82 #define TIMING_ERROR 0x20
83 #define U_CONFIGURE_IND 0x01
84 #define U_CONFIGURE_MASK 0x83
85 #define AUTO_ACKNOWLEDGE 0x20
86 #define AUTO_POLLING 0x10
87 #define CRC_CCITT 0x80
88 #define FRAME_END_WITH_MARKER 0x40
89 #define U_FRAME_END_IND 0xCB
90 #define U_STOP_MODE_IND 0x2B
91 #define U_SYSTEM_STAT_IND 0x4B
97 #define U_INT_REG_WR_REQ_WD 0x28
98 #define U_INT_REG_WR_REQ_ACR0 0x29
99 #define U_INT_REG_WR_REQ_ACR1 0x2A
100 #define U_INT_REG_WR_REQ_ASR0 0x2B
102 #define U_INT_REG_RD_REQ_WD 0x38
103 #define U_INT_REG_RD_REQ_ACR0 0x39
104 #define U_INT_REG_RD_REQ_ACR1 0x3A
105 #define U_INT_REG_RD_REQ_ASR0 0x3B
107 #define ACR0_FLAG_V20VEN 0x40
108 #define ACR0_FLAG_DC2EN 0x20
109 #define ACR0_FLAG_XCLKEN 0x10
110 #define ACR0_FLAG_TRIGEN 0x08
111 #define ACR0_FLAG_V20VCLIMIT 0x04
140 print((tpframe->
flags() & TP_FRAME_FLAG_INVALID) ?
'I' :
'_');
141 print((tpframe->
flags() & TP_FRAME_FLAG_EXTENDED) ?
'E' :
'_');
142 print((tpframe->
flags() & TP_FRAME_FLAG_REPEATED) ?
'R' :
'_');
143 print((tpframe->
flags() & TP_FRAME_FLAG_ECHO) ?
'T' :
'_');
144 print((tpframe->
flags() & TP_FRAME_FLAG_ADDRESSED) ?
'D' :
'_');
145 print((tpframe->
flags() & TP_FRAME_FLAG_ACK_NACK) ?
'N' :
'_');
146 print((tpframe->
flags() & TP_FRAME_FLAG_ACK_BUSY) ?
'B' :
'_');
147 print((tpframe->
flags() & TP_FRAME_FLAG_ACK) ?
'A' :
'_');
156 void __isr __time_critical_func(TpUartDataLinkLayer::processRx)(
bool isr)
166 if (_platform.overflowUart())
170 while (_platform.uartAvailable())
181 void TpUartDataLinkLayer::processRxByte()
197 processRxFrameComplete();
215 if (!_rxMarker &&
byte == U_FRAME_END_IND)
219 else if (_rxMarker &&
byte == U_FRAME_END_IND)
234 processRxFrameByte(
byte);
236 else if ((
byte & L_DATA_MASK) == L_DATA_STANDARD_IND || (
byte & L_DATA_MASK) == L_DATA_EXTENDED_IND)
241 processRxFrameComplete();
268 if (
byte == U_RESET_IND)
272 else if ((
byte & U_STATE_MASK) == U_STATE_IND)
274 _tpState |= (
byte ^ U_STATE_MASK);
280 _tpState &= 0b11101000;
283 else if ((
byte & U_CONFIGURE_MASK) == U_CONFIGURE_IND)
287 else if (
byte == U_STOP_MODE_IND)
291 else if ((
byte & L_ACKN_MASK) == L_ACKN_IND)
297 if (_rxFrame->
size() > 0)
299 if (!(
byte & L_ACKN_BUSY_MASK))
300 _rxFrame->
addFlags(TP_FRAME_FLAG_ACK_BUSY);
302 if (!(
byte & L_ACKN_NACK_MASK))
303 _rxFrame->
addFlags(TP_FRAME_FLAG_ACK_NACK);
305 _rxFrame->
addFlags(TP_FRAME_FLAG_ACK);
306 processRxFrameComplete();
311 else if ((
byte & L_DATA_CON_MASK) == L_DATA_CON)
315 const bool success = ((
byte ^ L_DATA_CON_MASK) >> 7);
316 processTxFrameComplete(success);
321 _rxUnkownControlCounter++;
326 else if (
byte == L_POLL_DATA_IND)
330 else if ((
byte & U_FRAME_STATE_MASK) == U_FRAME_STATE_IND)
336 _rxUnkownControlCounter++;
349 void TpUartDataLinkLayer::processRxFrameByte(uint8_t
byte)
355 if (markerMode() && (
byte == U_FRAME_END_IND && !_rxMarker))
364 else if (_rxMarker && (
byte & U_FRAME_STATE_MASK) == U_FRAME_STATE_IND)
367 processRxFrameComplete();
382 else if (markerMode() && _rxFrame->
isFull())
384 processRxFrameComplete();
397 else if (!markerMode() ||
byte != U_FRAME_END_IND || (
byte == U_FRAME_END_IND && _rxMarker))
408 if (_rxFrame->
size() == 7)
413 if (_forceAck || ack)
421 _rxFrame->
addFlags(TP_FRAME_FLAG_ADDRESSED);
427 _rxFrame->
addFlags(TP_FRAME_FLAG_ACK);
435 #ifdef USE_TP_RX_QUEUE
438 if (_rxFrame->
size() == 8 && (_rxFrame->
flags() & TP_FRAME_FLAG_ADDRESSED))
440 if (availableInRxQueue() < (_rxFrame->
size() + 3))
445 _platform.
writeUart(U_ACK_REQ | U_ACK_REQ_ADRESSED | U_ACK_REQ_BUSY);
459 if (!markerMode() && (_rxFrame->
isFull()))
461 processRxFrameComplete();
472 void TpUartDataLinkLayer::processRxFrameComplete()
475 if (!_rxFrame->
size())
489 _rxFrame->
addFlags(TP_FRAME_FLAG_ECHO);
496 if (_rxFrame->
flags() & TP_FRAME_FLAG_ADDRESSED || _monitoring)
509 _rxProcessdFrameCounter++;
514 _rxIgnoredFrameCounter++;
526 _rxInvalidFrameCounter++;
527 _rxFrame->
addFlags(TP_FRAME_FLAG_INVALID);
531 #ifdef USE_TP_RX_QUEUE
534 processRxFrame(_rxFrame);
541 void TpUartDataLinkLayer::clearTxFrame()
543 if (_txFrame !=
nullptr)
550 void TpUartDataLinkLayer::clearTxFrameQueue()
554 void TpUartDataLinkLayer::processTxFrameComplete(
bool success)
556 uint8_t* cemiData = _txFrame->
cemiData();
561 _txProcessdFrameCounter++;
568 void TpUartDataLinkLayer::pushTxFrameQueue(
TpFrame* tpFrame)
570 knx_tx_queue_entry_t* entry =
new knx_tx_queue_entry_t(tpFrame);
572 if (_txFrameQueue.back ==
nullptr)
574 _txFrameQueue.front = _txFrameQueue.back = entry;
578 _txFrameQueue.back->next = entry;
579 _txFrameQueue.back = entry;
587 _repetitions = (nack & 0b111) | ((busy & 0b111) << 4);
596 bool TpUartDataLinkLayer::sendFrame(
CemiFrame& cemiFrame)
600 if (!_connected || _monitoring || _txQueueCount > MAX_TX_QUEUE)
602 if (_txQueueCount > MAX_TX_QUEUE)
604 println(
"Ignore frame because transmit queue is full!");
613 pushTxFrameQueue(tpFrame);
622 void TpUartDataLinkLayer::requestState(
bool force )
630 if ((
millis() - _lastStateRequest) < 1000)
646 _lastStateRequest =
millis();
652 void TpUartDataLinkLayer::requestConfig()
657 _platform.
writeUart(U_CONFIGURE_REQ | U_CONFIGURE_MARKER_REQ);
664 _platform.
writeUart((address >> 8) & 0xFF);
671 if (_repetitions != 0b00110011)
674 _platform.
writeUart(U_SET_REPETITION_REQ);
680 _platform.
writeUart(((_repetitions & 0xF0) << 1) | (_repetitions & 0x0F));
689 bool TpUartDataLinkLayer::isrLock(
bool blocking )
692 while (_rxProcessing)
694 else if (_rxProcessing)
697 _rxProcessing =
true;
701 void TpUartDataLinkLayer::isrUnlock()
703 _rxProcessing =
false;
706 void TpUartDataLinkLayer::clearUartBuffer()
713 void TpUartDataLinkLayer::connected(
bool state )
725 _rxProcessdFrameCounter = 0;
726 _rxIgnoredFrameCounter = 0;
727 _rxInvalidFrameCounter = 0;
728 _rxInvalidFrameCounter = 0;
729 _rxUnkownControlCounter = 0;
731 _txProcessdFrameCounter = 0;
751 if (_rxFrame !=
nullptr)
765 bool success =
false;
767 const uint32_t start =
millis();
772 const int byte = _platform.
readUart();
777 if (
byte & U_RESET_IND)
782 }
while (!((
millis() - start) >= 10));
788 _lastStateRequest = 0;
807 if (state && !_stopped)
809 else if (!state && _stopped)
810 _platform.
writeUart(U_EXIT_STOP_MODE_REQ);
819 else if (!state && _busy)
827 if (!_initialized || _monitoring)
847 return _initialized && _connected;
855 void TpUartDataLinkLayer::clearOutdatedTxFrame()
858 processTxFrameComplete(
false);
866 void TpUartDataLinkLayer::processTxQueue()
871 if (_txFrameQueue.front !=
nullptr)
873 knx_tx_queue_entry_t* entry = _txFrameQueue.front;
874 _txFrameQueue.front = entry->next;
876 if (_txFrameQueue.front ==
nullptr)
878 _txFrameQueue.back =
nullptr;
886 _txFrame = entry->frame;
892 #ifdef DEBUG_TP_FRAMES
898 processTxFrameBytes();
908 void TpUartDataLinkLayer::checkConnected()
913 const uint32_t current =
millis();
918 const uint32_t timeout = _monitoring ? 10000 : 5000;
920 if ((current - _rxLastTime) > timeout)
927 if (_rxLastTime > 0 && (current - _rxLastTime) < 1000)
945 println(
"TPUart overflow detected!");
952 print(
"TPUart state error: ");
958 #ifdef USE_TP_RX_QUEUE
963 clearOutdatedTxFrame();
968 void TpUartDataLinkLayer::rxFrameReceived(
TpFrame* tpFrame)
970 uint8_t* cemiData = tpFrame->
cemiData();
975 #ifdef KNX_ACTIVITYCALLBACK
978 _dllcb->
activity((
_netIndex << KNX_ACTIVITYCALLBACK_NET) | (KNX_ACTIVITYCALLBACK_DIR_RECV << KNX_ACTIVITYCALLBACK_DIR));
997 _platform.
writeUart(U_INT_REG_WR_REQ_ACR0);
1000 _platform.
writeUart(ACR0_FLAG_DC2EN | ACR0_FLAG_V20VEN | ACR0_FLAG_XCLKEN | ACR0_FLAG_V20VCLIMIT);
1002 _platform.
writeUart(ACR0_FLAG_XCLKEN | ACR0_FLAG_V20VCLIMIT);
1006 bool TpUartDataLinkLayer::processTxFrameBytes()
1019 for (uint16_t i = 0; i < _txFrame->
size(); i++)
1021 uint8_t offset = (i >> 6);
1022 uint8_t position = (i & 0x3F);
1027 _platform.
writeUart(U_L_DATA_OFFSET_REQ | offset);
1030 if (i == (_txFrame->
size() - 1))
1031 _platform.
writeUart(U_L_DATA_END_REQ | position);
1033 _platform.
writeUart(U_L_DATA_START_REQ | position);
1038 #ifdef KNX_ACTIVITYCALLBACK
1041 _dllcb->
activity((
_netIndex << KNX_ACTIVITYCALLBACK_NET) | (KNX_ACTIVITYCALLBACK_DIR_SEND << KNX_ACTIVITYCALLBACK_DIR));
1057 _rxFrame =
new TpFrame(MAX_KNX_TELEGRAM_SIZE);
1065 return _rxInvalidFrameCounter;
1073 return _rxProcessdFrameCounter;
1081 return _rxIgnoredFrameCounter;
1089 return _rxUnkownControlCounter;
1097 return _txFrameCounter;
1104 return _txProcessdFrameCounter;
1127 bool TpUartDataLinkLayer::markerMode()
1139 void TpUartDataLinkLayer::processRxFrame(
TpFrame* tpFrame)
1147 else if (tpFrame->
flags() & TP_FRAME_FLAG_INVALID)
1158 else if (tpFrame->
flags() & TP_FRAME_FLAG_ADDRESSED)
1160 #ifdef DEBUG_TP_FRAMES
1166 if (!(tpFrame->
flags() & TP_FRAME_FLAG_ECHO))
1167 rxFrameReceived(tpFrame);
1171 #ifdef USE_TP_RX_QUEUE
1189 void TpUartDataLinkLayer::pushRxFrameQueue()
1191 if (availableInRxQueue() < (_rxFrame->
size() + 3))
1195 pushByteToRxQueue(_rxFrame->
size() & 0xFF);
1196 pushByteToRxQueue(_rxFrame->
size() >> 8);
1198 pushByteToRxQueue(_rxFrame->
flags());
1200 for (
size_t i = 0; i < _rxFrame->
size(); i++)
1202 pushByteToRxQueue(_rxFrame->
data(i));
1205 asm volatile(
"" :::
"memory");
1209 void TpUartDataLinkLayer::processRxQueue()
1214 while (_rxBufferCount)
1216 const uint16_t size = pullByteFromRxQueue() + (pullByteFromRxQueue() << 8);
1218 tpFrame.
addFlags(pullByteFromRxQueue());
1220 for (uint16_t i = 0; i < size; i++)
1221 tpFrame.
addByte(pullByteFromRxQueue());
1223 processRxFrame(&tpFrame);
1224 asm volatile(
"" :::
"memory");
1231 void TpUartDataLinkLayer::pushByteToRxQueue(uint8_t
byte)
1233 _rxBuffer[_rxBufferFront] = byte;
1234 _rxBufferFront = (_rxBufferFront + 1) % (MAX_RX_QUEUE_BYTES);
1237 uint8_t TpUartDataLinkLayer::pullByteFromRxQueue()
1239 uint8_t
byte = _rxBuffer[_rxBufferRear];
1240 _rxBufferRear = (_rxBufferRear + 1) % (MAX_RX_QUEUE_BYTES);
1244 uint16_t TpUartDataLinkLayer::availableInRxQueue()
1246 return ((_rxBufferFront == _rxBufferRear) ? (MAX_RX_QUEUE_BYTES) : ((((MAX_RX_QUEUE_BYTES) - _rxBufferFront) + _rxBufferRear) % (MAX_RX_QUEUE_BYTES))) - 1;
void printHex(const char *suffix, const uint8_t *data, size_t length, bool newline)
virtual void activity(uint8_t info)
void frameReceived(CemiFrame &frame)
void dataConReceived(CemiFrame &frame, bool success)
uint16_t individualAddress()
virtual TPAckType isAckRequired(uint16_t address, bool isGrpAddr)=0
std::string humanDestination()
uint8_t * cemiData()
Creates a buffer and converts the TpFrame into a CemiFrame.
void addByte(uint8_t byte)
std::string humanSource()
void addFlags(uint8_t flags)
void setRepetitions(uint8_t nack, uint8_t busy)
uint32_t getRxInvalidFrameCounter()
uint32_t getRxProcessdFrameCounter()
uint32_t getRxIgnoredFrameCounter()
DptMedium mediumType() const override
void powerControl(bool state)
uint32_t getTxProcessedFrameCounter()
void forceAck(bool state)
uint32_t getRxUnknownControlCounter()
uint32_t getTxFrameCounter()
void requestBusy(bool state)
void setFrameRepetition(uint8_t nack, uint8_t busy)
TpUartDataLinkLayer(DeviceObject &devObj, NetworkLayerEntity &netLayerEntity, Platform &platform, ITpUartCallBacks &cb, DataLinkLayerCallbacks *dllcb=nullptr)
void printFrame(TpFrame *tpframe)