Browse Source

Functionality refactor of nBus Bridge plus documentation

xnecas 2 weeks ago
parent
commit
2e5c9dac6c

+ 117 - 92
Core/Inc/NbusBridge.h

@@ -1,8 +1,8 @@
 /**
  * @file NbusBridge.h
- * @brief Deklarácia modulu nBus Bridge
- * @date Mar 7, 2025
- * @author Juraj Dudak
+ * @brief Declaration of nBus Bridge
+ * @date Nov 27, 2025
+ * @author Juraj Dudak, Matus Necas
  */
 
 #ifndef SRC_NBUSBRIDGE_H_
@@ -10,106 +10,131 @@
 
 #include "NbusSlave.h"
 
-/* DEFINES BEGIN */
-
-/** Maximálny počet zariadení slave na internej zbernici.
- * Pozor, súvisí to s alokáciou prostriedkov na MCU.
- */
-#define MAX_SLAVES 16
-
-
-
-#define ECHO_SCAN_LENGTH	   4
-#define ECHO_SCAN_DATA	       {110, 66, 117, 115} // nBus
-#define ECHO_SCAN_CHAR0		   110
-#define ECHO_SCAN_CHAR1		   66
-#define ECHO_SCAN_CHAR2		   117
-#define ECHO_SCAN_CHAR3		   115
-
-/** Adresa broadcastu */
-#define BROADCAST_ADDRESS	0
-/** Virtuálna adresa modulu nBus Bridge */
-#define BRIDGE_ADDRESS		0xFF
-/** Macro for bridge terminator **/
-#define BRIDGE_TERMINATOR 	0xFF
-
-#define BRIDGE_INFO_VERSION		"1.0"
-#define BRIDGE_INFO_HW_FAMILY	"STM"
-#define BRIDGE_INFO_HW_VERSION	"0.5"
-
-
-
-
-#define DATAPACKET_SIZE  (NBUS_MAX_FRAME_SIZE*MAX_SLAVES)
-
-/* DEFINES END */
-
-
-typedef enum {
-	STATE_STOPPED,
-	STATE_TO_STOP,
-	STATE_RUNNING,
-}RunState_e;
-
 /**
- * @brief Trieda zabezpečujúca interpretáciu príkazov protokolu nBus.
+ * Class representing nBus Bridge.
  */
-class NbusBridge {
-
-private:
-
-	uint8_t _crc8x_fast(void const *mem, uint16_t len);
-
-	/** Objekt zabezpečujúci komunikáciu na internej aj externej zbernici nBus */
-	NbusCommunicator *_communicator{nullptr};
-	/** Statické pole objektov nBus slave */
-	NbusSlave _slaves[MAX_SLAVES];
-	/** Pole detegovaných adries modulov slave. Pole sa naplní pri automatickom skene internej zbernice */
-	uint8_t _slave_adress[MAX_SLAVES]{0};
-	/** Počet detegovaných slave zariadení. */
-	uint8_t _num_slaves{0};
-	/** Príznak indikuje, či je modul Bridge v stave RUN */
-	RunState_e _run_state{STATE_STOPPED};
-    /** Interný buffer */
-	DataFrame *_worker_frame_ptr{nullptr};
-	/** Pole bajtov použité pre generovanie odpovede pomocou triedy DataFrame */
-	uint8_t _data_packet[DATAPACKET_SIZE]{0};
-	/** Dataframe (wrapper nad _dataPacket), do ktorého za vygeneruje odsielaný packet.*/
-	DataFrame _raw_data_frame{_data_packet, DATAPACKET_SIZE, TYPE_RAW, CRC_OFF};
-	DataFrame _master_frame{_data_packet, DATAPACKET_SIZE, TYPE_PLAIN, CRC_ON};
-
-	uint8_t _scan_request{0};
-	Nbus_PDU_t _pdu{BROADCAST_ADDRESS, BROADCAST_ADDRESS, FC_ECHO};
-
+class NbusBridge
+{
 public:
 
-	/** Nastaví komunikačný modul */
-	void setCommunicator(NbusCommunicator *nc);
-
-	void scan();
-	uint8_t getNumSlaves();
-	NbusSlave * getSlave(uint8_t index);
-
-
-	DataFrame * bridge_getSlaves();
-	DataFrame * bridge_getInfo();
-	DataFrame * bridge_getData();
-	DataFrame * bridge_setErrResponse(Nbus_EC_e ec);
+	/** Constructor
+	 * @param nbus_communicator: hardware communicator.
+	 */
+	NbusBridge(NbusCommunicator *nbus_communicator);
 
+	/** Provide scan of internal nBus net and initialize local slave devices data.
+	 */
+	void scanNetwork();
 
+	/** Process incoming requests.
+	 * @param rx_frame: RX data packet
+	 * @param size: size of rx_frame
+	 */
 	void processRequest(uint8_t *rxFrame, uint8_t size);
 
-	void process_broadcast(uint8_t *rxFrame);
-	void process_bridge_request(uint8_t *rxFrame, uint8_t size);
-	void process_slave_request(uint8_t *rxFrame, uint8_t size);
-
-	void broadcastStart();
-	void broadcastStop();
+	/**
+	 * Implementation of the STATE_RUNNING state.
+	 * In this state, automatic reading of data from all slaves/all sensors is running.
+	 * The data is sent to the Master in a batch (for all slaves).
+	 */
 	void processRunningState();
 
+private:
+	/** Get slave pointer.
+	 * @param index: slave id
+	 * @return pointer to slave
+	 * @note: can be nullptr
+	 */
+	NbusSlave* _getSlave(uint8_t index);
+
+	/** Calculate 8-bit CRC.
+	 *  @param mem: data buffer
+	 *  @param len: buffer length
+	 *  @return> crc
+	 */
+	uint8_t _crc8x_fast(void const *mem, uint16_t len);
 
-
-
+	/** Process broadcast request.
+	 * @param rx_frame: RX data packet
+	 * @param size: size of rx_frame
+	 */
+	void _processBroadcast(uint8_t *rx_frame, uint8_t size);
+
+	/** Process bridge request (e.g. bridge-cast).
+	 * @param rx_frame: RX data packet
+	 * @param size: size of rx_frame
+	 */
+	void _processBridgeRequest(uint8_t *rxFrame, uint8_t size);
+
+	/** Process slave request (e.g. uni-cast).
+	 * @param rx_frame: RX data packet
+	 * @param size: size of rx_frame
+	 */
+	void _processSlaveRequest(uint8_t *rxFrame, uint8_t size);
+
+	/** Implementation of CMD_GET_DATA for bridge.
+	 * @return: response to master
+	 */
+	DataFrame * _cmdGetData();
+
+	/** Implementation of CMD_GET_INFO for bridge.
+	 * @return: response to master
+	 */
+	DataFrame * _cmdGetInfo();
+
+	/** Implementation of CMD_GET_SLAVES for bridge.
+	 * @return: response to master
+	 */
+	DataFrame * _cmdGetSlaves();
+
+	/** Implementation of CMD_SET_STOPfor bridge.
+	 */
+	void _cmdSetStop();
+
+	/** Implementation of CMD_SET_START for bridge.
+	 */
+	void _cmdSetStart();
+
+	/** Set error response to master.
+	 * @param error_code: error code
+	 * @return: response to master
+	 */
+	DataFrame * _rspSetError(Nbus_EC_e error_code);
+
+	/** Set status response to master.
+	 * @param error_code: error code
+	 * @return: response to master
+	 */
+	DataFrame * _rspSetStatus(Nbus_SC_e status_code);
+
+	/** Make default packet from pdu and data.
+	 * @param pdu: current pdu
+	 * @param data: application data
+	 * @param size: application data size
+	 * @return: response to master
+	 */
+	DataFrame * _makePacket(Nbus_PDU_t pdu, uint8_t *data, uint8_t size);
+
+	/** Make raw packet (just copy whole input frame).
+	 * @param daa: application data
+	 * @param size: application data size
+	 * @return: response to master
+	 */
+	DataFrame * _forwardPacket(uint8_t *data, uint8_t size);
+
+
+	NbusCommunicator *_communicator{nullptr};													///< nBus HW communicator
+	NbusSlave _slaves[MAX_SLAVES];                                                              ///< array of nBus slaves
+	uint8_t _slave_adress[MAX_SLAVES]{0};                                                       ///< array of slave addresses
+	uint8_t _num_slaves{0};                                                                     ///< number of slaves
+	Nbus_RunState_e _run_state{STATE_STOPPED};                                                  ///< running state flag
+	DataFrame *_worker_frame_ptr{nullptr};														///< pointer to actual data frame
+	uint8_t _data_packet[DATAPACKET_SIZE]{0};                                                   ///< data packet buffer
+	DataFrame _bridge_cast_frame{_data_packet, DATAPACKET_SIZE, TYPE_HEADER_2B, CRC_OFF};		///< data frame for bridge cast
+	DataFrame _default_frame{_data_packet, DATAPACKET_SIZE, TYPE_PLAIN, CRC_ON};                ///< data frame for default operation
+	DataFrame _raw_data_frame{_data_packet, DATAPACKET_SIZE, TYPE_RAW, CRC_OFF};                ///< raw data frame for copying
+	uint8_t _scan_request{0};																	///< flag if scan request is necessary
+	Nbus_PDU_t _pdu{BROADCAST_ADDRESS, BROADCAST_ADDRESS, FC_ECHO};                             ///< nBus actual PDU
 };
 
 #endif /* SRC_NBUSBRIDGE_H_ */

+ 44 - 23
Core/Inc/NbusCommunicator.h

@@ -1,8 +1,8 @@
 /**
  * @file NbusCommunicator.h
- * @brief Deklarácia komunikačnej vrstvy: 1) internej 2) externej
- * @date Mar 7, 2025
- * @author Juraj Dudak
+ * @brief Declaration of hardware communication interface.
+ * @date Nov 27, 2025
+ * @author Juraj Dudak, Matus Necas
  */
 
 #ifndef SRC_NBUSCOMMUNICATOR_H_
@@ -17,35 +17,56 @@
 
 /* DEFINES BEGIN */
 
-#define NBUS_MAX_FRAME_SIZE 64
-
-#define UART_NBUS_RX_TIMEOUT	5
+/** Macro for frame size of nBus Communicator. */
+#define NBUS_COMM_MAX_FRAME_SIZE  64
+/** Macro for receive timeout in ms. */
+#define NBUS_COMM_UART_RX_TIMEOUT  5
+/** Macro for transfer timeout in ms. */
+#define NBUS_COMM_UART_TX_TIMEOUT 10
 
 /* DEFINES END */
 
-class NbusCommunicator {
-
-private:
-	uint8_t _data_packet_tx[NBUS_MAX_FRAME_SIZE];
-	uint8_t _data_packet_comm[NBUS_MAX_FRAME_SIZE];
-	uint8_t _data_packet_rx[NBUS_MAX_FRAME_SIZE];
-	DataFrame _packet_tx;
-	DataFrame _packet_rx;
-	UART_HandleTypeDef *_uart_nbus;
-	UART_HandleTypeDef *_uart_master;
-	void _receive();
+/** @brief Class for NBus Communicator handle.
+ */
+class NbusCommunicator
+{
 public:
-	NbusCommunicator(UART_HandleTypeDef*, UART_HandleTypeDef*);
-	void sendToMaster(DataFrame *master_frame);
 
-	virtual ~NbusCommunicator();
+	/** Constructor.
+	 * @param uart_nbus: pointer to UART nBus instance
+	 * @param uart_master: pointer to UART master instance
+	 */
+	NbusCommunicator(UART_HandleTypeDef *uart_nbus, UART_HandleTypeDef *uart_master);
 
-	DataFrame* sendAndReceive(Nbus_PDU_t *pdu, uint8_t *data, uint8_t data_len);
+	/** Send data to master.
+	 *  @param master_frame: data frame to send
+	 */
+	void sendToMaster(DataFrame *master_frame);
 
+	/** Send data to slave.
+	 *  @param slave_frame: data frame to send
+	 */
 	void sendToSlave(DataFrame *slave_frame);
 
-	DataFrame * sendAndReceiveSlave(DataFrame *slave_frame);
-	void send(Nbus_PDU_t *pdu, uint8_t *data, uint8_t data_len);
+	/** Send data to slave and receive response.
+	 *  @param slave_frame: data frame to send
+	 *  @return: response data frame
+	 */
+	DataFrame* sendAndReceiveSlave(DataFrame *slave_frame);
+
+private:
+
+	/** Receive data from slave.
+	 */
+	void _receiveFromSlave();
+
+	uint8_t _data_packet_tx[NBUS_COMM_MAX_FRAME_SIZE]{0};									///< raw TX data packet
+	uint8_t _data_packet_comm[NBUS_COMM_MAX_FRAME_SIZE]{0};									///< raw common data packet
+	uint8_t _data_packet_rx[NBUS_COMM_MAX_FRAME_SIZE]{0};									///< raw RX data packet
+	DataFrame _packet_tx{_data_packet_tx, NBUS_COMM_MAX_FRAME_SIZE, TYPE_PLAIN, CRC_ON};	///< TX data frame
+	DataFrame _packet_rx{_data_packet_rx, NBUS_COMM_MAX_FRAME_SIZE, TYPE_PLAIN, CRC_OFF};   ///< RX data frame
+	UART_HandleTypeDef *_uart_nbus{nullptr};												///< pointer to UART nBus
+	UART_HandleTypeDef *_uart_master{nullptr};												///< pointer to UART master
 };
 
 

+ 28 - 36
Core/Inc/NbusSlave.h

@@ -7,73 +7,65 @@
 #ifndef SRC_APPSLAVE_H_
 #define SRC_APPSLAVE_H_
 
-
 #include "inttypes.h"
 #include "dataframe.h"
 #include "NbusCommunicator.h"
 
-
-/** Macro for module-only address. */
-#define SLAVE_ADDRESS_MODULE   0
-
-
-/** Class for nBus slave communication */
-class NbusSlave {
-
-private:
-	NbusCommunicator* _communicator{nullptr};	///< hardware bus communicator
-	Nbus_PDU_t _pdu{0, 0, FC_ECHO}; 			///< slave PDU
-	uint8_t _sensor_cache[16]{0};				///< sensor temporary data
-	uint8_t _sensor_count{0};					///< number of sensors
-
+/** @brief Class for nBus slave communication
+ */
+class NbusSlave
+{
 public:
-	/** Set nBus communicator
+	/** Set nBus communicator.
 	 * @param nbus_comm: communicator to set
 	 */
 	void setCommunicator(NbusCommunicator* nbus_comm);
 
-	/** Set nBus address
+	/** Set nBus address.
 	 * @param addr: address to set
 	 */
 	void setAddress(uint8_t addr);
 
-	/** Get slave active status
+	/** Get slave active status.
 	 * @return: active status (1 = active, 0 = inactive)
 	 */
 	bool isActive();
 
-	/** Get nBus module address
+	/** Get nBus module address.
      * @return: actual address (0 if not set)
 	 */
 	uint8_t getModuleAddress();
 
-	/** Send nBus request and get sensor count
-	 * @param check_hw: 1 = load from bus, 0 = use local cache
+	/** Send any nBus request and get response.
+	 * @param slave_frame: data to send
 	 * @return: response data frame
 	 */
-	uint8_t nbusSlaveCmd_getSensorCnt(bool check_hw);
+	DataFrame * cmdProcessAnyRequest(DataFrame *slave_frame);
 
-	/** Send any nBus request and get response
-	 * @param slave_frame: data to send
+	/** Send nBus request and get sensor data.
 	 * @return: response data frame
 	 */
-	DataFrame * nbusSlaveCmd_processRequest(DataFrame *slave_frame);
+	DataFrame * cmdGetData();
 
-	/** Send nBus request and get sensor data
+	/** Send nBus request and get sensor count.
+	 * @param check_hw: 1 = load from bus, 0 = use local cache
 	 * @return: response data frame
 	 */
-	DataFrame * nbusSlaveCmd_getData();
-};
-
+	uint8_t nbusSlaveCmd_getSensorCnt(bool check_hw);
 
-#ifdef __cplusplus
-extern "C"
-{
-#endif
+private:
+	/** Make nBus packet for selected function code.
+	 * @param fc: function code
+	 * @return: _slave_cache
+	 */
+	DataFrame* _makePacket(Nbus_FC_e fc);
 
+	NbusCommunicator* _communicator{nullptr};											///< hardware bus communicator
+	uint8_t _sensor_count{0};															///< number of sensors
+	Nbus_PDU_t _pdu{0, 0, FC_ECHO}; 													///< slave PDU
+	uint8_t _slave_cache[NBUS_SLAVE_CACHE_SIZE]{0};									    ///< slave temporary data
+	DataFrame _cache_frame{_slave_cache, NBUS_SLAVE_CACHE_SIZE, TYPE_PLAIN, CRC_ON};    ///< data frame of _slave_cache
+};
 
-#ifdef __cplusplus
-}
-#endif
 
 #endif /* SRC_APPSLAVE_H_ */

+ 68 - 6
Core/Inc/nbus_structs.h

@@ -21,20 +21,70 @@
 #include "stm32l0xx_hal.h"
 #endif
 
+
+
 /** Macro for module address in RX packet */
-#define MODULE_RX_ADDRESS(packet)	(packet)[0]
+#define MODULE_RX_ADDRESS(packet)		(packet)[0]
 /** Macro for sensor address in RX packet */
-#define SENSOR_RX_ADDRESS(packet)	(packet)[1]
+#define SENSOR_RX_ADDRESS(packet)		(packet)[1]
 /** Macro for function code in RX packet */
-#define FUNCTION_RX_CODE(packet)	(packet)[2]
+#define FUNCTION_RX_CODE(packet)		(packet)[2]
 /** Macro for #0 data byte in RX packet */
-#define DATA0_RX_ADDRESS(packet)	(packet)[3]
+#define DATA0_RX_ADDRESS(packet)		(packet)[3]
+/** Macro for CRC8 byte in RX packet */
+#define CRC8_RX_ADDRESS(packet, size)	(packet)[(size) - 1]
+
+
 /** Macro for #0 data byte in TX packet */
 #define DATA0_TX_ADDRESS(packet) (packet)[4]
+
 /** Macro to set error response */
 #define SET_ERR_RESPONSE(fc)	((fc) | 0x80)
 /** Macro for RX meta size in bytes */
 #define RX_META_SIZE	4
+/** Macro for TX meta size in bytes */
+#define TX_META_SIZE	5
+
+/** Macro for set command flag */
+#define SET_CMD(cmd)	((cmd) | 0x20)
+
+/** Macro for module-only address. */
+#define NBUS_SLAVE_ADDRESS_MODULE  0
+/** Macro for slave cache size. */
+#define NBUS_SLAVE_CACHE_SIZE	   TX_META_SIZE
+
+/* DEFINES BEGIN */
+
+/** Maximálny počet zariadení slave na internej zbernici.
+ * Pozor, súvisí to s alokáciou prostriedkov na MCU.
+ */
+#define MAX_SLAVES 16
+
+#define ECHO_SCAN_LENGTH	   4
+#define ECHO_SCAN_DATA	       {110, 66, 117, 115} // nBus
+#define ECHO_SCAN_CHAR0		   110
+#define ECHO_SCAN_CHAR1		   66
+#define ECHO_SCAN_CHAR2		   117
+#define ECHO_SCAN_CHAR3		   115
+
+/** Adresa broadcastu */
+#define BROADCAST_ADDRESS	0
+/** Virtuálna adresa modulu nBus Bridge */
+#define BRIDGE_ADDRESS		0xFF
+/** Macro for bridge terminator **/
+#define BRIDGE_TERMINATOR 	0xFF
+#define BRIDGE_RUNNING_STATE_DELAY  50
+
+#define BRIDGE_INFO_VERSION		"1.0"
+#define BRIDGE_INFO_HW_FAMILY	"STM"
+#define BRIDGE_INFO_HW_VERSION	"0.5"
+
+
+
+
+#define DATAPACKET_SIZE  (NBUS_COMM_MAX_FRAME_SIZE*MAX_SLAVES)
+
+/* DEFINES END */
 
 
 /** Enumerate for function codes  */
@@ -58,15 +108,20 @@ typedef enum {
 	FC_SLAVES,		 	/* 0x10 => 16 */
 } Nbus_FC_e;
 
+/** Enumerate for Bridge run state. */
+typedef enum {
+	STATE_STOPPED,
+	STATE_TO_STOP,
+	STATE_RUNNING,
+}Nbus_RunState_e;
 
-/** Structure for PDU data */
+/** Structure for PDU data. */
 typedef struct {
 	uint8_t ma;
 	uint8_t sa;
 	Nbus_FC_e fc;
 } Nbus_PDU_t;
 
-
 /** Enumerate for error codes  */
 typedef enum {
 	OK_CODE = 0x00,
@@ -92,6 +147,13 @@ typedef enum {
 	ERR_INPUT_ONLY = 0x22
 } Nbus_EC_e;
 
+/** Enumerate for status codes  */
+typedef enum {
+    STATUS_NOT_SUPPORTED = 0xFF,
+    STATUS_SUCCESS = 0,
+    STATUS_FAIL = 1
+} Nbus_SC_e;
+
 
 
 #endif /* INC_NBUS_STRUCTS_H_ */

+ 5 - 9
Core/Src/AppBridge.cpp

@@ -25,7 +25,7 @@ volatile uint8_t vMasterUartIndex;
 volatile uint8_t vMasterUartSize;
 
 /** @brief Objekt reprezentujúci funkcionality nBusBridge.  */
-NbusBridge bridge;
+
 
 static void init_app()
 {
@@ -55,8 +55,10 @@ void app(UART_HandleTypeDef *uartNbus, UART_HandleTypeDef *uartMaster)
     init_app();
 
     NbusCommunicator nc(uartNbus, uartMaster);
-    bridge.setCommunicator(&nc);
-    bridge.scan();
+    NbusBridge bridge(&nc);
+
+
+    bridge.scanNetwork();
 
     while (1)
     {
@@ -100,12 +102,6 @@ void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size)
             vMasterUartSize = 0;
             vMasterUartIndex = 0;
             pMasterUartRx[0] = 0;
-            if (MODULE_RX_ADDRESS(pMasterUartFrame) == 0)
-            {
-                bridge.process_broadcast(pMasterUartFrame);
-                // TODO tu este mozno deaktivovat spracovanie broadcast paketu
-                // flagUartMasterDataReady = 0;
-            }
         }
     }
 }

+ 199 - 239
Core/Src/NbusBridge.cpp

@@ -1,8 +1,8 @@
 /**
  * @file NbusBridge.cpp
- * @brief Implemetnácia modulu nBus Brige
- * @date Mar 7, 2025
- * @author Juraj Dudak
+ * @brief Implementation of  nBus Brige
+ * @date Nov 27, 2025
+ * @author Juraj Dudak, Matus Necas
  */
 
 #include "NbusBridge.h"
@@ -24,49 +24,22 @@ static const uint8_t __crc8x_table[] = {
     0xB2, 0xB5, 0xBC, 0xBB, 0x96, 0x91, 0x98, 0x9F, 0x8A, 0x8D, 0x84, 0x83, 0xDE, 0xD9, 0xD0, 0xD7, 0xC2, 0xC5, 0xCC,
     0xCB, 0xE6, 0xE1, 0xE8, 0xEF, 0xFA, 0xFD, 0xF4, 0xF3};
 
-uint8_t NbusBridge::_crc8x_fast(void const *mem, uint16_t len)
-{
-    uint8_t crc = 0;
-    uint8_t const *data = (uint8_t *)mem;
-    if (data == nullptr)
-        return 0xff;
-    crc &= 0xff;
-    while (len--)
-        crc = __crc8x_table[crc ^ *data++];
-    return crc;
-}
 
-void NbusBridge::setCommunicator(NbusCommunicator *nc)
+
+NbusBridge::NbusBridge(NbusCommunicator *nbus_communicator)
+: _communicator(nbus_communicator)
 {
-    if (nc == nullptr)
-    {
-        while (1)
-        {
-            __NOP();
-        }
-    }
 
-    _communicator = nc;
-    _num_slaves = 0;
-    _run_state = STATE_STOPPED;
-    _pdu.sa = BROADCAST_ADDRESS;
 }
 
-
-/**
- * Spustí scan internej nbus siete.
- * Posiela requesty pre celý adresný priestor ako ECHO paket.
- * Výsledok je uložený interne. K jednotlivým slave-om sa dá dostať cez metódu getSlave(index), kde 0<=index<num_slaves
- */
-void NbusBridge::scan()
+void NbusBridge::scanNetwork()
 {
     HAL_GPIO_WritePin(GPIOB, GPIO_PIN_3, GPIO_PIN_SET);
 
     _num_slaves = 0;
 
-    DataFrame *response_frame;
     uint8_t   *response_raw;
-    Nbus_PDU_t   pdu = {SLAVE_ADDRESS_MODULE, SLAVE_ADDRESS_MODULE, FC_ECHO};
+    Nbus_PDU_t  pdu = {NBUS_SLAVE_ADDRESS_MODULE, NBUS_SLAVE_ADDRESS_MODULE, FC_ECHO};
     uint8_t    data[] = ECHO_SCAN_DATA;
     uint8_t    slave_index = 0;
 
@@ -79,11 +52,12 @@ void NbusBridge::scan()
     {
         HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_3);
         pdu.ma = i;
-        response_frame = _communicator->sendAndReceive(&pdu, data, ECHO_SCAN_LENGTH);
 
-        if (!response_frame->IsEmpty())
+        _worker_frame_ptr = _communicator->sendAndReceiveSlave(_makePacket(pdu, data, ECHO_SCAN_LENGTH));
+
+        if (!_worker_frame_ptr->IsEmpty())
         {
-            response_raw = response_frame->GetFrame();
+            response_raw = _worker_frame_ptr->GetFrame();
 
             if (DATA0_TX_ADDRESS(response_raw + 0) == ECHO_SCAN_CHAR0 && DATA0_TX_ADDRESS(response_raw + 1) == ECHO_SCAN_CHAR1 &&
             	DATA0_TX_ADDRESS(response_raw + 2) == ECHO_SCAN_CHAR2 && DATA0_TX_ADDRESS(response_raw + 3) == ECHO_SCAN_CHAR3)
@@ -100,284 +74,270 @@ void NbusBridge::scan()
     HAL_GPIO_WritePin(GPIOB, GPIO_PIN_3, GPIO_PIN_RESET);
 }
 
-/**
- * @brief Vráti inštanciu index-teho zdetegovaného nBus slave.
- * @return Smerník na existujúc NbusBridge alebo NULL
- */
-NbusSlave *NbusBridge::getSlave(uint8_t index)
+void NbusBridge::processRequest(uint8_t *rxFrame, uint8_t size)
 {
-    if (index >= 0 && index < MAX_SLAVES)
+    uint8_t crcC = _crc8x_fast(rxFrame, size - 1);
+
+    if (crcC != CRC8_RX_ADDRESS(rxFrame, size))
     {
-        if (_slaves[index].isActive())
+        return;
+    }
+
+    _pdu.ma = rxFrame[0];
+    _pdu.sa = rxFrame[1];
+    _pdu.fc = (Nbus_FC_e)rxFrame[2];
+
+    if (_pdu.ma == BROADCAST_ADDRESS)
+    {
+        if (_pdu.sa == BRIDGE_ADDRESS)
         {
-            return &_slaves[index];
+            _processBridgeRequest(rxFrame, size);
+        }
+        else
+        {
+            _processBroadcast(rxFrame, size);
         }
     }
-
-    return nullptr;
+    else
+    {
+        _processSlaveRequest(rxFrame, size);
+    }
 }
 
-/**
- * Vráti počet detegovaných nBus slave modulov na internej zbernici.
- * @return počet nBus slave zariadení.
- */
-uint8_t NbusBridge::getNumSlaves()
+void NbusBridge::processRunningState()
 {
-    return _num_slaves;
-}
 
-/**
- * Na internú zbernicu odošle Broadcast request "START"
- */
-void NbusBridge::broadcastStart()
-{
-    _pdu.fc = FC_START;
-    _pdu.ma = BROADCAST_ADDRESS;
-    _communicator->send(&_pdu, nullptr, 0);
-    _run_state = STATE_RUNNING;
+    if (_scan_request == 1)
+    {
+        _scan_request = 0;
+        this->scanNetwork();
+    }
+
+    if (_run_state == STATE_STOPPED)
+    {
+        return;
+    }
+
+    if (_run_state == STATE_TO_STOP)
+    {
+        HAL_GPIO_WritePin(GPIOB, GPIO_PIN_3, GPIO_PIN_RESET);
+        _run_state = STATE_STOPPED;
+        return;
+    }
+
+    HAL_GPIO_WritePin(GPIOB, GPIO_PIN_3, GPIO_PIN_SET);
+
+    _worker_frame_ptr = _cmdGetData();
+
+    // TODO problem: v stavi RUNNING pride STOP prikaz, ale ten sa nespracuje, pretoze bezi obsluha tejto funkcie.
+    if (_run_state == STATE_RUNNING)
+    {
+        _communicator->sendToMaster(_worker_frame_ptr);
+    }
+
+    /// TODO toto sa MI NEPACI, TREBA VYRIESIT INAK!!!!!!
+    HAL_Delay(BRIDGE_RUNNING_STATE_DELAY); // TREBA VYSKUSAT
 }
 
-/**
- * Na internú zbernicu odošle Broadcast request "STOP"
- */
-void NbusBridge::broadcastStop()
+uint8_t NbusBridge::_crc8x_fast(void const *mem, uint16_t len)
 {
-    _pdu.fc = FC_STOP;
-    _pdu.ma = BROADCAST_ADDRESS;
-    _communicator->send(&_pdu, nullptr, 0);
-    _run_state = STATE_TO_STOP;
+    uint8_t crc = 0;
+    uint8_t const *data = (uint8_t *)mem;
+    if (data == nullptr)
+        return 0xff;
+    crc &= 0xff;
+    while (len--)
+        crc = __crc8x_table[crc ^ *data++];
+    return crc;
 }
 
-/**
- * Spracovanie broadcast requestu.
- * Inplementované funkcie:
- * - FC_STOP
- * - FC_START
- */
-void NbusBridge::process_broadcast(uint8_t *rxFrame)
+NbusSlave *NbusBridge::_getSlave(uint8_t index)
 {
-    switch (FUNCTION_RX_CODE(rxFrame))
+    if (index >= 0 && index < MAX_SLAVES)
     {
+        if (_slaves[index].isActive())
+        {
+            return &_slaves[index];
+        }
+    }
 
-    case FC_STOP: /* 2 */
-        this->broadcastStop();
-        break;
-
-    case FC_START: /* 3 */
-        this->broadcastStart();
-        break;
+    return nullptr;
+}
 
-    default:; // nothing
-    }
+void NbusBridge::_processBroadcast(uint8_t *rx_frame, uint8_t size)
+{
+    _communicator->sendToSlave(_forwardPacket(rx_frame, size));
 }
 
-/**
- * Spracovanie requestu pre bridge.
- * Implementované funkcie:
- * - FC_SLAVES
- *   Formát odpovede: [senzor_idenx:sensor_address,]
- * - FC_RESET
- * 	 Odpoveď: kópia požiadavky
- * - FC_INFO
- * 	 Odpoved: XXXYYYZZZ, kde X-verzia FW, Y-použitá platfoma MCU, Z-verzia HW (formát: ASCII)
- * - FC_ECHO
- * 	 Odpoveď: kópia požiadavky
- */
-void NbusBridge::process_bridge_request(uint8_t *rxFrame, uint8_t size)
+void NbusBridge::_processBridgeRequest(uint8_t *rx_frame, uint8_t size)
 {
-	switch (FUNCTION_RX_CODE(rxFrame))
+	switch (FUNCTION_RX_CODE(rx_frame))
     {
-    case FC_ECHO: /* 1 */
-    	_master_frame.AddArray(&DATA0_RX_ADDRESS(rxFrame), size  - RX_META_SIZE);
-        break;
+    case FC_ECHO:			/* GET 1 */
+    	_worker_frame_ptr = _forwardPacket(rx_frame, size);
+    	break;
 
-    case FC_RESET: /* 9 */
-	{
+    case SET_CMD(FC_STOP):  /* SET 2 */
+    	_cmdSetStop();
+    	break;
+
+    case SET_CMD(FC_START): /* SET 3 */
+    	_cmdSetStart();
+    	break;
+
+    case SET_CMD(FC_RESET): /* SET 9 */
         _scan_request = 1;
-        // send same frame back
-    	_master_frame.AddArray(&DATA0_RX_ADDRESS(rxFrame), size  - RX_META_SIZE);
-    }
-    break;
+        _worker_frame_ptr = _rspSetStatus(STATUS_SUCCESS);
+        break;
 
-    case FC_DATA: /* 11 */
-    	_worker_frame_ptr = bridge_getData();
+    case FC_DATA:           /* GET 11 */
+    	_worker_frame_ptr = _cmdGetData();
     	break;
 
-    case FC_INFO: /* 0xE => 15 */
-    	_worker_frame_ptr = bridge_getInfo();
+    case FC_INFO:           /* GET 0xE => 15 */
+    	_worker_frame_ptr = _cmdGetInfo();
         break;
 
-    case FC_SLAVES: /* 0x10 => 16 */
-       	_worker_frame_ptr = bridge_getSlaves();
+    case FC_SLAVES:         /* GET 0x10 => 16 */
+       	_worker_frame_ptr = _cmdGetSlaves();
         break;
 
     default:
-      	_worker_frame_ptr = bridge_setErrResponse(ILLEGAL_FUNCTION);
+      	_worker_frame_ptr = _rspSetError(ILLEGAL_FUNCTION);
     }
 
 	_communicator->sendToMaster(_worker_frame_ptr);
 }
 
-void NbusBridge::process_slave_request(uint8_t *rxFrame, uint8_t size)
+void NbusBridge::_processSlaveRequest(uint8_t *rx_frame, uint8_t size)
 {
-    NbusSlave *selected_slave = getSlave(MODULE_RX_ADDRESS(rxFrame));
+    NbusSlave *selected_slave = _getSlave(MODULE_RX_ADDRESS(rx_frame));
 
     if (selected_slave == nullptr)
     {
-    	_worker_frame_ptr = bridge_setErrResponse(ILLEGAL_DEVICE_ADDRESS);
+    	_worker_frame_ptr = _rspSetError(ILLEGAL_DEVICE_ADDRESS);
     }
-
-    _raw_data_frame.Init();
-    _raw_data_frame.AddUint8(size);
-    _raw_data_frame.AddArray(rxFrame, size);
-    _raw_data_frame.Commit();
-
-    _worker_frame_ptr = selected_slave->nbusSlaveCmd_processRequest(&_raw_data_frame);
-    _communicator->sendToMaster(_worker_frame_ptr);
-}
-
-/**
- * Pripraví informáciu o všetkcýh nBus slave moduloch
- */
-DataFrame* NbusBridge::bridge_getSlaves()
-{
-	_master_frame.Init();
-	_master_frame.AddUint8(BROADCAST_ADDRESS);
-	_master_frame.AddUint8(BRIDGE_ADDRESS);
-	_master_frame.AddUint8(FC_SLAVES);
-
-	for (uint8_t i = 0; i < _num_slaves; i++)
+    else
     {
-		_master_frame.AddInt8(i + 1);
-		_master_frame.AddInt8(_slave_adress[i]);
+    	_worker_frame_ptr = _forwardPacket(rx_frame, size);
     }
 
-	_master_frame.Commit();
-
-	return &_master_frame;
-}
-
-DataFrame * NbusBridge::bridge_getInfo()
-{
-	_master_frame.Init();
-	_master_frame.AddUint8(BROADCAST_ADDRESS);
-	_master_frame.AddUint8(BRIDGE_ADDRESS);
-	_master_frame.AddUint8(FC_INFO);
-	_master_frame.AddArray((uint8_t *)BRIDGE_INFO_VERSION, 3);
-	_master_frame.AddArray((uint8_t *)BRIDGE_INFO_HW_FAMILY, 3);
-	_master_frame.AddArray((uint8_t *)BRIDGE_INFO_HW_VERSION, 3);
-	_master_frame.Commit();
-
-	return &_master_frame;
+    _communicator->sendToMaster(_worker_frame_ptr);
 }
 
-DataFrame * NbusBridge::bridge_getData()
+DataFrame* NbusBridge::_cmdGetData()
 {
 	NbusSlave * slave_ptr = nullptr;
 
-	_raw_data_frame.Init();
-	_raw_data_frame.AddHeader(TYPE_HEADER_2B);
-	_raw_data_frame.AddInt32(HAL_GetTick());
+	_bridge_cast_frame.Init();
+	_bridge_cast_frame.AddInt32(HAL_GetTick());
 
 	for (uint32_t i = 0; i < _num_slaves; i++)
 	{
-		slave_ptr = getSlave(_slave_adress[i]);
+		slave_ptr = _getSlave(_slave_adress[i]);
 		if (slave_ptr != nullptr)
 		{
-			_raw_data_frame.AddInt8(slave_ptr->getModuleAddress());
-			_worker_frame_ptr = slave_ptr->nbusSlaveCmd_getData();
-			_raw_data_frame.AddArray(&DATA0_RX_ADDRESS(_worker_frame_ptr->GetFrame() + 1), _worker_frame_ptr->GetLength() - (RX_META_SIZE + 1));
+			_bridge_cast_frame.AddInt8(slave_ptr->getModuleAddress());
+			_worker_frame_ptr = slave_ptr->cmdGetData();
+			_bridge_cast_frame.AddArray(&DATA0_RX_ADDRESS(_worker_frame_ptr->GetFrame() + 1), _worker_frame_ptr->GetLength() - (RX_META_SIZE + 1)); // add without length byte
 		}
 	}
 
-	_raw_data_frame.AddInt8(BRIDGE_TERMINATOR);
-	_raw_data_frame.AddInt8(BRIDGE_TERMINATOR);
-	_raw_data_frame.Commit();
+	_bridge_cast_frame.AddInt8(BRIDGE_TERMINATOR);
+	_bridge_cast_frame.AddInt8(BRIDGE_TERMINATOR);
+	_bridge_cast_frame.Commit();
 
-	return &_raw_data_frame;
+	return &_bridge_cast_frame;
 }
 
-DataFrame * NbusBridge::bridge_setErrResponse(Nbus_EC_e ec)
+DataFrame * NbusBridge::_cmdGetInfo()
 {
-	_master_frame.Init();
-	_master_frame.AddUint8(_pdu.ma);
-	_master_frame.AddUint8(_pdu.sa);
-	_master_frame.AddUint8(SET_ERR_RESPONSE(_pdu.fc));
-	_master_frame.AddUint8(ec);
-	_master_frame.Commit();
-
-	return &_master_frame;
+	_default_frame.Init();
+	_default_frame.AddUint8(BROADCAST_ADDRESS);
+	_default_frame.AddUint8(BRIDGE_ADDRESS);
+	_default_frame.AddUint8(FC_INFO);
+	_default_frame.AddArray((uint8_t*)BRIDGE_INFO_VERSION, 3);
+	_default_frame.AddArray((uint8_t*)BRIDGE_INFO_HW_FAMILY, 3);
+	_default_frame.AddArray((uint8_t*)BRIDGE_INFO_HW_VERSION, 3);
+	_default_frame.Commit();
+
+	return &_default_frame;
 }
 
-/**
- * Implementácia rozhrania nBus.
- */
-void NbusBridge::processRequest(uint8_t *rxFrame, uint8_t size)
+DataFrame* NbusBridge::_cmdGetSlaves()
 {
-    uint8_t crcC = _crc8x_fast(rxFrame, size - 1);
+	_default_frame.Init();
+	_default_frame.AddUint8(BROADCAST_ADDRESS);
+	_default_frame.AddUint8(BRIDGE_ADDRESS);
+	_default_frame.AddUint8(FC_SLAVES);
 
-    if (crcC != rxFrame[size - 1])
+	for (uint8_t i = 0; i < _num_slaves; i++)
     {
-        return;
+		_default_frame.AddUint8(i + 1);
+		_default_frame.AddUint8(_slave_adress[i]);
     }
 
-    _pdu.ma = rxFrame[0];
-    _pdu.sa = rxFrame[1];
-    _pdu.fc = (Nbus_FC_e)rxFrame[2];
+	_default_frame.Commit();
 
-    if (_pdu.ma == BROADCAST_ADDRESS)
-    {
-        if (_pdu.sa == BRIDGE_ADDRESS)
-        {
-            process_bridge_request(rxFrame, size);
-        }
-        else
-        {
-            process_broadcast(rxFrame);
-        }
-    }
-    else
-    {
-        process_slave_request(rxFrame, size);
-    }
+	return &_default_frame;
 }
 
-/**
- * Implementácia stavu STATE_RUNNING.
- * V tomto stave je spustené automatické odčítanie údajov zo všetkých slave/všetkých senzorov.
- * Dáta sa v dávke (za všetky slavy) odosielajú na Master.
- */
-void NbusBridge::processRunningState()
+void NbusBridge::_cmdSetStop()
 {
+	_pdu.sa = BROADCAST_ADDRESS;
+    _communicator->sendToSlave(_makePacket(_pdu, nullptr, 0));
+    _run_state = STATE_TO_STOP;
+}
 
-    if (_scan_request == 1)
-    {
-        _scan_request = 0;
-        this->scan();
-    }
-
-    if (_run_state == STATE_STOPPED)
-    {
-        return;
-    }
+void NbusBridge::_cmdSetStart()
+{
+	_pdu.sa = BROADCAST_ADDRESS;
+    _communicator->sendToSlave(_makePacket(_pdu, nullptr, 0));
+    _run_state = STATE_RUNNING;
+}
 
-    if (_run_state == STATE_TO_STOP)
-    {
-        HAL_GPIO_WritePin(GPIOB, GPIO_PIN_3, GPIO_PIN_RESET);
-        _run_state = STATE_STOPPED;
-        return;
-    }
+DataFrame* NbusBridge::_rspSetError(Nbus_EC_e error_code)
+{
+	_default_frame.Init();
+	_default_frame.AddUint8(_pdu.ma);
+	_default_frame.AddUint8(_pdu.sa);
+	_default_frame.AddUint8(SET_ERR_RESPONSE(_pdu.fc));
+	_default_frame.AddUint8(error_code);
+	_default_frame.Commit();
+
+	return &_default_frame;
+}
 
-    HAL_GPIO_WritePin(GPIOB, GPIO_PIN_3, GPIO_PIN_SET);
+DataFrame* NbusBridge::_rspSetStatus(Nbus_SC_e status_code)
+{
+	_default_frame.Init();
+	_default_frame.AddUint8(_pdu.ma);
+	_default_frame.AddUint8(_pdu.sa);
+	_default_frame.AddUint8(_pdu.fc);
+	_default_frame.AddUint8(status_code);
+	_default_frame.Commit();
+
+	return &_default_frame;
+}
 
-    _worker_frame_ptr = bridge_getData();
+DataFrame* NbusBridge::_makePacket(Nbus_PDU_t pdu, uint8_t *data, uint8_t size)
+{
+	_default_frame.Init();
+	_default_frame.AddUint8(pdu.ma);
+	_default_frame.AddUint8(pdu.sa);
+	_default_frame.AddUint8((Nbus_FC_e)pdu.fc);
+	_default_frame.AddArray(data, size);
+	_default_frame.Commit();
+
+	return &_default_frame;
+}
 
-    // TODO problem: v stavi RUNNING pride STOP prikaz, ale ten sa nespracuje, pretoze bezi obsluha tejto funkcie.
-    if (_run_state == STATE_RUNNING)
-    {
-        _communicator->sendToMaster(_worker_frame_ptr);
-    }
+DataFrame* NbusBridge::_forwardPacket(uint8_t *data, uint8_t size)
+{
+	_raw_data_frame.Init();
+	_raw_data_frame.AddUint8(size);
+	_raw_data_frame.AddArray(data, size);
+	_raw_data_frame.Commit();
 
-    /// TODO toto sa MI NEPACI, TREBA VYRIESIT INAK!!!!!!
-    HAL_Delay(50); // TREBA VYSKUSAT
+	return &_raw_data_frame;
 }

+ 33 - 81
Core/Src/NbusCommunicator.cpp

@@ -1,115 +1,67 @@
 /**
  * @file NbusCommunicator.cpp
- * @brief Implemetnácia komunikačnej vrstvy: 1) internej 2) externej
- * @date Mar 7, 2025
- * @author Juraj Dudak
+ * @brief Implementation of hardware communication interface.
+ * @date Nov 27, 2025
+ * @author Juraj Dudak, Matus Necas
  */
 
 #include "NbusCommunicator.h"
 
-NbusCommunicator::NbusCommunicator(UART_HandleTypeDef *uartUbus, UART_HandleTypeDef *uartMaster)
-: _packet_tx(_data_packet_tx, NBUS_MAX_FRAME_SIZE, TYPE_PLAIN, CRC_ON),
-  _packet_rx(_data_packet_rx, NBUS_MAX_FRAME_SIZE, TYPE_PLAIN, CRC_OFF)
+NbusCommunicator::NbusCommunicator(UART_HandleTypeDef *uartNbus, UART_HandleTypeDef *uartMaster)
+: _uart_nbus{uartNbus}, _uart_master{uartMaster}
 {
-    if (uartUbus == NULL)
-    {
-        while (1)
-        {
-            __NOP();
-        }
-    }
-    _uart_nbus = uartUbus;
-
-    if (uartMaster == NULL)
-    {
-        while (1)
-        {
-            __NOP();
-        }
-    }
-    _uart_master = uartMaster;
-}
 
-NbusCommunicator::~NbusCommunicator()
-{
-    // empty
 }
 
-void NbusCommunicator::_receive()
+void NbusCommunicator::sendToMaster(DataFrame *master_frame)
 {
-    uint16_t received_size;
-    HAL_GPIO_WritePin(GPIOB, GPIO_PIN_3, GPIO_PIN_SET);
-
-    memset(_data_packet_comm, 0, NBUS_MAX_FRAME_SIZE);
-    // komunikacia v DMA musi byt spracovana aj tak ako blokujuca
-    // takto je tu menej rezie. Timeout je 5ms
-    HAL_StatusTypeDef status = HAL_UARTEx_ReceiveToIdle(_uart_nbus, _data_packet_comm, NBUS_MAX_FRAME_SIZE,
-                                                        &received_size, UART_NBUS_RX_TIMEOUT);
-
-    _packet_rx.Init();
+	if (master_frame == nullptr || master_frame->IsEmpty())
+		return;
 
-    if (status == HAL_OK)
+	while (_uart_master->gState != HAL_UART_STATE_READY)
     {
-        if (received_size > 0)
-        {
-            _packet_rx.FromArray(_data_packet_comm, received_size);
-        }
+        __NOP(); // cakanie na ukoncenie prebiehajuceho odosielania
+                 // tu to moze byt vcelku tesno odoslany dalsi paket. je tam pauza o dlzke 1.2bit
     }
 
-    HAL_GPIO_WritePin(GPIOB, GPIO_PIN_3, GPIO_PIN_RESET);
-
-    _packet_rx.Commit();
+    HAL_UART_Transmit_DMA(_uart_master, master_frame->GetFrame(), master_frame->GetLength());
 }
 
-DataFrame *NbusCommunicator::sendAndReceive(Nbus_PDU_t *pdu, uint8_t *data, uint8_t data_len)
+void NbusCommunicator::sendToSlave(DataFrame *slaveFrame)
 {
-    this->send(pdu, data, data_len);
-    this->_receive();
-    return &_packet_rx;
+    HAL_GPIO_WritePin(GPIOB, GPIO_PIN_3, GPIO_PIN_SET);
+    HAL_UART_Transmit(_uart_nbus, slaveFrame->GetFrame(), slaveFrame->GetLength(), NBUS_COMM_UART_TX_TIMEOUT);
+    HAL_GPIO_WritePin(GPIOB, GPIO_PIN_3, GPIO_PIN_RESET);
 }
 
-DataFrame *NbusCommunicator::sendAndReceiveSlave(DataFrame *slave_frame)
+DataFrame* NbusCommunicator::sendAndReceiveSlave(DataFrame *slave_frame)
 {
     this->sendToSlave(slave_frame);
-    this->_receive();
+    this->_receiveFromSlave();
     return &_packet_rx;
 }
 
-void NbusCommunicator::sendToSlave(DataFrame *slave_frame)
+void NbusCommunicator::_receiveFromSlave()
 {
+    uint16_t received_size;
     HAL_GPIO_WritePin(GPIOB, GPIO_PIN_3, GPIO_PIN_SET);
-    HAL_UART_Transmit(_uart_nbus, slave_frame->GetFrame(), slave_frame->GetLength(), 10);
-    HAL_GPIO_WritePin(GPIOB, GPIO_PIN_3, GPIO_PIN_RESET);
-}
-
-void NbusCommunicator::send(Nbus_PDU_t *pdu, uint8_t *data, uint8_t data_len)
-{
-    _packet_tx.Init();
-    _packet_tx.AddInt8(pdu->ma); // Module address
-    _packet_tx.AddInt8(pdu->sa); // Slave address
-    _packet_tx.AddInt8(pdu->fc); // Function Code
-    for (int i = 0; i < data_len; i++)
-    {
-        _packet_tx.AddInt8(data[i]);
-    }
 
-    int length = _packet_tx.Commit();
-
-    HAL_GPIO_WritePin(GPIOB, GPIO_PIN_3, GPIO_PIN_SET);
-    HAL_UART_Transmit(_uart_nbus, _packet_tx.GetFrame(), length, 10);
-    HAL_GPIO_WritePin(GPIOB, GPIO_PIN_3, GPIO_PIN_RESET);
-}
+    memset(_data_packet_comm, 0, NBUS_COMM_MAX_FRAME_SIZE);
+    // DMA communication must be in blocking mode for less overhead
+    HAL_StatusTypeDef status = HAL_UARTEx_ReceiveToIdle(_uart_nbus, _data_packet_comm, NBUS_COMM_MAX_FRAME_SIZE,
+                                                        &received_size, NBUS_COMM_UART_RX_TIMEOUT);
 
-void NbusCommunicator::sendToMaster(DataFrame *master_frame)
-{
-	if (master_frame == nullptr || master_frame->IsEmpty())
-		return;
+    _packet_rx.Init();
 
-	while (_uart_master->gState != HAL_UART_STATE_READY)
+    if (status == HAL_OK)
     {
-        __NOP(); // cakanie na ukoncenie prebiehajuceho odosielania
-                 // tu to moze byt vcelku tesno odoslany dalsi paket. je tam pauza o dlzke 1.2bit
+        if (received_size > 0)
+        {
+            _packet_rx.FromArray(_data_packet_comm, received_size);
+        }
     }
 
-    HAL_UART_Transmit_DMA(_uart_master, master_frame->GetFrame(), master_frame->GetLength());
+    HAL_GPIO_WritePin(GPIOB, GPIO_PIN_3, GPIO_PIN_RESET);
+
+    _packet_rx.Commit();
 }

+ 16 - 10
Core/Src/NbusSlave.cpp

@@ -1,13 +1,12 @@
 /*
  * @file AppBridge.cpp
  * @brief Implementation of nBus Slave.
- * @date Nov 26, 2025
+ * @date Nov 27, 2025
  * @author Juraj Dudak, Matus Necas
  */
 
 #include <NbusSlave.h>
 
-
 void NbusSlave::setCommunicator(NbusCommunicator *nbus_comm)
 {
     _communicator = nbus_comm;
@@ -28,27 +27,34 @@ bool NbusSlave::isActive()
     return _communicator != nullptr && _pdu.ma != 0;
 }
 
-DataFrame *NbusSlave::nbusSlaveCmd_processRequest(DataFrame *slave_frame)
+DataFrame *NbusSlave::cmdProcessAnyRequest(DataFrame *slave_frame)
 {
 	return _communicator->sendAndReceiveSlave(slave_frame);
 }
 
-DataFrame *NbusSlave::nbusSlaveCmd_getData()
+DataFrame *NbusSlave::cmdGetData()
 {
-	_pdu.sa = SLAVE_ADDRESS_MODULE;
-	_pdu.fc = FC_DATA;
-	return _communicator->sendAndReceive(&_pdu, _sensor_cache, 0);
+	return _communicator->sendAndReceiveSlave(_makePacket(FC_DATA));
 }
 
 uint8_t NbusSlave::nbusSlaveCmd_getSensorCnt(bool check_hw)
 {
     if (_sensor_count == 0 || check_hw == true)
     {
-    	_pdu.sa = SLAVE_ADDRESS_MODULE;
-		_pdu.fc = FC_SENSOR_CNT;
-		DataFrame *df = _communicator->sendAndReceive(&_pdu, _sensor_cache, 0);
+		DataFrame *df = _communicator->sendAndReceiveSlave(_makePacket(FC_SENSOR_CNT));
 		_sensor_count = df->GetFrame()[3];
     }
 
     return _sensor_count;
 }
+
+DataFrame* NbusSlave::_makePacket(Nbus_FC_e fc)
+{
+	_cache_frame.Init();
+	_cache_frame.AddUint8(_pdu.ma);
+	_cache_frame.AddUint8(NBUS_SLAVE_ADDRESS_MODULE);
+	_cache_frame.AddUint8(fc);
+	_cache_frame.Commit();
+
+	return &_cache_frame;
+}