mirror of
				https://github.com/thelsing/knx.git
				synced 2025-10-26 10:26:25 +01:00 
			
		
		
		
	implement remaining todos. Now testing can begin.
This commit is contained in:
		
							parent
							
								
									e1947045df
								
							
						
					
					
						commit
						aa05fa8418
					
				
							
								
								
									
										4
									
								
								bits.h
									
									
									
									
									
								
							
							
						
						
									
										4
									
								
								bits.h
									
									
									
									
									
								
							| @ -16,8 +16,8 @@ | |||||||
|                    ((x)>> 8 & 0x0000FF00UL) | \ |                    ((x)>> 8 & 0x0000FF00UL) | \ | ||||||
|                    ((x)>>24 & 0x000000FFUL) ) |                    ((x)>>24 & 0x000000FFUL) ) | ||||||
| #define ntohl(x) htonl(x) | #define ntohl(x) htonl(x) | ||||||
| #define println SerialUSB.println | #define _print SerialUSB.print | ||||||
| #define print SerialUSB.print | #define _println SerialUSB.println | ||||||
| #else | #else | ||||||
| #include <Arduino.h> | #include <Arduino.h> | ||||||
| #include <user_interface.h> | #include <user_interface.h> | ||||||
|  | |||||||
| @ -76,7 +76,7 @@ bool DataLinkLayer::sendTelegram(NPDU & npdu, AckType ack, uint16_t destinationA | |||||||
| 
 | 
 | ||||||
|     if (!frame.valid()) |     if (!frame.valid()) | ||||||
|     { |     { | ||||||
|         println("invalid frame\n"); |         _println("invalid frame\n"); | ||||||
|         return false; |         return false; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -10,6 +10,7 @@ | |||||||
| #include <string.h> | #include <string.h> | ||||||
| 
 | 
 | ||||||
| #define SerialKNX Serial1 | #define SerialKNX Serial1 | ||||||
|  | #define SerialDBG SerialUSB | ||||||
| 
 | 
 | ||||||
| // NCN5120
 | // NCN5120
 | ||||||
| 
 | 
 | ||||||
| @ -135,7 +136,7 @@ bool TpUartDataLinkLayer::sendFrame(CemiFrame& frame) | |||||||
| 
 | 
 | ||||||
|     _sendBuffer = buffer; |     _sendBuffer = buffer; | ||||||
|     _sendResult = false; |     _sendResult = false; | ||||||
| 
 |     _sendBufferLength = length; | ||||||
|     sendBytes(buffer, length); |     sendBytes(buffer, length); | ||||||
| 
 | 
 | ||||||
|     while (_sendBuffer != 0) |     while (_sendBuffer != 0) | ||||||
| @ -193,18 +194,100 @@ void TpUartDataLinkLayer::loop() | |||||||
| 
 | 
 | ||||||
| bool TpUartDataLinkLayer::checkDataInd(uint8_t firstByte) | bool TpUartDataLinkLayer::checkDataInd(uint8_t firstByte) | ||||||
| { | { | ||||||
|  |     const size_t bufferSize = 512; | ||||||
|  | 
 | ||||||
|     uint8_t tmp = firstByte & L_DATA_MASK; |     uint8_t tmp = firstByte & L_DATA_MASK; | ||||||
|     if (tmp != L_DATA_STANDARD_IND && tmp != L_DATA_EXTENDED_IND) |     if (tmp != L_DATA_STANDARD_IND && tmp != L_DATA_EXTENDED_IND) | ||||||
|         return false; |         return false; | ||||||
| 
 | 
 | ||||||
|     uint8_t buffer[512]; |  | ||||||
|     int len = 0; |     int len = 0; | ||||||
|     // TODO: get rest of data, compare to sendbuffer 
 |     uint8_t buffer[bufferSize]; | ||||||
|     CemiFrame frame(buffer, len); |     buffer[0] = firstByte; | ||||||
|     frameRecieved(frame); | 
 | ||||||
|  |     uint8_t payloadLength = 0; | ||||||
|  |     if (tmp == L_DATA_STANDARD_IND) | ||||||
|  |     { | ||||||
|  |         //convert to extended frame format
 | ||||||
|  |         SerialKNX.readBytes(buffer + 2, 5); | ||||||
|  |         payloadLength = buffer[6] & 0xF; | ||||||
|  |         SerialKNX.readBytes(buffer + 6, payloadLength + 2); //+1 for TCPI +1 for CRC
 | ||||||
|  |         len = payloadLength + 9; | ||||||
|  |         buffer[1] = buffer[6] & 0xF0; | ||||||
|  |         buffer[6] = payloadLength; | ||||||
|  |     } | ||||||
|  |     else | ||||||
|  |     { | ||||||
|  |         //extended frame
 | ||||||
|  |         SerialKNX.readBytes(buffer + 1, 6); | ||||||
|  |         payloadLength = buffer[6]; | ||||||
|  |         SerialKNX.readBytes(buffer + 7, payloadLength + 2); //+1 for TCPI +1 for CRC
 | ||||||
|  |         len = payloadLength + 9; | ||||||
|  |     } | ||||||
|  |     len = payloadLength + 9; | ||||||
|  | 
 | ||||||
|  |     const uint8_t queueLength = 5; | ||||||
|  |     static uint8_t buffers[queueLength][bufferSize]; | ||||||
|  |     static uint16_t bufferLengths[queueLength]; | ||||||
|  | 
 | ||||||
|  |     if (_sendBuffer > 0) | ||||||
|  |     { | ||||||
|  |         // we are trying to send a telegram queue received telegrams until we get our sent telegram
 | ||||||
|  | 
 | ||||||
|  |         if (len == _sendBufferLength && memcmp(_sendBuffer, buffer, len) == 0) | ||||||
|  |         { | ||||||
|  |             //we got the send telegramm back next byte is L_Data.con byte
 | ||||||
|  |             uint8_t confirm = SerialKNX.read(); | ||||||
|  |             confirm &= L_DATA_CON_MASK; | ||||||
|  |             _sendResult = (confirm > 0); | ||||||
|  |             _sendBuffer = 0; | ||||||
|  |             _sendBufferLength = 0; | ||||||
|  | 
 | ||||||
|  |             return true; | ||||||
|  |         } | ||||||
|  |          | ||||||
|  |         // queue telegram, if we get more the queueLength before send succeeds 
 | ||||||
|  |         // ignore the telegram
 | ||||||
|  |         for (int i = 0; i < queueLength; i++) | ||||||
|  |         { | ||||||
|  |             if (bufferLengths[i] != 0) | ||||||
|  |                 continue; | ||||||
|  | 
 | ||||||
|  |             bufferLengths[i] = len; | ||||||
|  |             memcpy(&buffers[i][0], buffer, len); | ||||||
|  |             break; | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  |     else | ||||||
|  |     { | ||||||
|  |         // process all previously queued telegramms first
 | ||||||
|  |         for (int i = 0; i < queueLength; i++) | ||||||
|  |         { | ||||||
|  |             if (bufferLengths[i] == 0) | ||||||
|  |                 break; | ||||||
|  | 
 | ||||||
|  |             frameBytesReceived(&buffers[i][0], bufferLengths[i]); | ||||||
|  |             bufferLengths[i] = 0; | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         frameBytesReceived(buffer, len); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     return true; |     return true; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | void TpUartDataLinkLayer::frameBytesReceived(uint8_t* buffer, uint16_t length) | ||||||
|  | { | ||||||
|  |     CemiFrame frame(buffer, length); | ||||||
|  | 
 | ||||||
|  |     if (_deviceObject.induvidualAddress() == 0 && frame.destinationAddress() == 0) | ||||||
|  |     { | ||||||
|  |         //send ack. Otherwise we have autoacknowledge
 | ||||||
|  |         SerialKNX.write(U_ACK_REQ + 1); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     frameRecieved(frame); | ||||||
|  | } | ||||||
|  | 
 | ||||||
| bool TpUartDataLinkLayer::checkDataCon(uint8_t firstByte) | bool TpUartDataLinkLayer::checkDataCon(uint8_t firstByte) | ||||||
| { | { | ||||||
|     uint8_t tmp = firstByte & L_DATA_CON_MASK; |     uint8_t tmp = firstByte & L_DATA_CON_MASK; | ||||||
| @ -219,6 +302,7 @@ bool TpUartDataLinkLayer::checkDataCon(uint8_t firstByte) | |||||||
| 
 | 
 | ||||||
|     _sendResult = (firstByte & SUCCESS) > 0; |     _sendResult = (firstByte & SUCCESS) > 0; | ||||||
|     _sendBuffer = 0; |     _sendBuffer = 0; | ||||||
|  |     _sendBufferLength = 0; | ||||||
| 
 | 
 | ||||||
|     return true; |     return true; | ||||||
| } | } | ||||||
| @ -368,6 +452,10 @@ void TpUartDataLinkLayer::sendBytes(uint8_t* bytes, uint16_t length) | |||||||
| 
 | 
 | ||||||
|     for (int i = 0; i < length; i++) |     for (int i = 0; i < length; i++) | ||||||
|     { |     { | ||||||
|  |         uint8_t idx = length / 64; | ||||||
|  |         cmd[0] = U_L_DATA_OFFSET_REQ | idx; | ||||||
|  |         SerialKNX.write(cmd, 1); | ||||||
|  | 
 | ||||||
|         if (i != length - 1) |         if (i != length - 1) | ||||||
|             cmd[0] = U_L_DATA_START_CONT_REQ | i; |             cmd[0] = U_L_DATA_START_CONT_REQ | i; | ||||||
|         else |         else | ||||||
|  | |||||||
| @ -17,6 +17,7 @@ private: | |||||||
|     bool _enabled = false; |     bool _enabled = false; | ||||||
|     uint8_t* _sendBuffer = 0; |     uint8_t* _sendBuffer = 0; | ||||||
|     bool _sendResult = false; |     bool _sendResult = false; | ||||||
|  |     uint16_t _sendBufferLength = 0; | ||||||
|     bool sendFrame(CemiFrame& frame); |     bool sendFrame(CemiFrame& frame); | ||||||
|     bool checkDataInd(uint8_t firstByte); |     bool checkDataInd(uint8_t firstByte); | ||||||
|     bool checkDataCon(uint8_t firstByte); |     bool checkDataCon(uint8_t firstByte); | ||||||
| @ -31,4 +32,5 @@ private: | |||||||
|     bool checkSystemStatInd(uint8_t firstByte); |     bool checkSystemStatInd(uint8_t firstByte); | ||||||
|     void handleUnexpected(uint8_t firstByte); |     void handleUnexpected(uint8_t firstByte); | ||||||
|     void sendBytes(uint8_t* buffer, uint16_t length); |     void sendBytes(uint8_t* buffer, uint16_t length); | ||||||
|  |     void frameBytesReceived(uint8_t* buffer, uint16_t length); | ||||||
| }; | }; | ||||||
		Loading…
	
		Reference in New Issue
	
	Block a user