/** * @file AppBridge.cpp * @brief High-level logic of nBusBridge. This is the application entry point. * * @date Nov 28, 2025 * @author Juraj Dudak, Matus Necas */ #include "AppBridge.h" #include "NbusBridge.h" #define NBUS_UART_FRAME_TIMEOUT 5 #define MAX_SYSTICK 0xFFFFFFFF /** @brief UARTinterface between Master-Bridge. */ UART_HandleTypeDef *pUartMasterGlobal; /** @brief flag for data-ready from pUartMasterGlobal. */ volatile uint32_t flagUartMasterDataReady; /** @brief reading buffer from pUartMasterGlobal. */ uint8_t pMasterUartRx[NBUS_APP_UART_FRAME_SIZE]; /** @brief master buffer for pUartMasterGlobal. */ uint8_t pMasterUartFrame[NBUS_APP_UART_FRAME_SIZE]; /** @brief internal index for data acquisition from pUartMasterGlobal. */ //volatile uint8_t vMasterUartIndex; /** @brief size of received request from pUartMasterGlobal. */ //volatile uint8_t vMasterUartSize; ProtocolState state = STATE_WAIT_LEN; volatile uint32_t uart_timeout = MAX_SYSTICK; volatile uint16_t rx_read_pos = 0; // DAM UART CIRCULAR - tail volatile uint8_t msg_len = 0; volatile uint8_t msg_idx = 0; uint8_t rx_ring_buffer[BUFF_SIZE]; void HAL_UART_ErrorCallback(UART_HandleTypeDef *huart){ HAL_UART_Receive_DMA(pUartMasterGlobal, rx_ring_buffer, BUFF_SIZE); } /** Initialize resources and provide boot sequence. */ static void init_app() { uart_timeout = HAL_GetTick(); rx_ring_buffer[0] = 0; //HAL_UARTEx_ReceiveToIdle_DMA(pUartMasterGlobal, pMasterUartRx, NBUS_APP_UART_FRAME_SIZE); HAL_UART_Receive_DMA(pUartMasterGlobal, rx_ring_buffer, BUFF_SIZE); flagUartMasterDataReady = 0; // vMasterUartIndex = 0; // vMasterUartSize = 0; // boot long blink for (uint32_t i = 0; i < NBUS_APP_BLINK_COUNT; i++) { HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_3); HAL_Delay(NBUS_APP_BLINK_DELAY); } } static uint8_t Parse_Protocol_Byte(uint8_t b) { uint8_t packet_finished = 0; // Timeout reset logic if (state != STATE_WAIT_LEN) { if ((HAL_GetTick() - uart_timeout) > NBUS_UART_FRAME_TIMEOUT){ state = STATE_WAIT_LEN; msg_len = 0; msg_idx = 0; } } switch (state) { case STATE_WAIT_LEN: // Validácia dĺžky (max 128 bajtov, min 4 bajty) if (b > 3 && b < PAYLOAD_SIZE) { msg_len = b; msg_idx = 0; state = STATE_PAYLOAD; uart_timeout = HAL_GetTick(); // Reset timeoutu } break; case STATE_PAYLOAD: pMasterUartRx[msg_idx++] = b; uart_timeout = HAL_GetTick(); // Aktualizácia timeoutu pri každom bajte if (msg_idx >= msg_len) { // Koniec paketu (podľa definície dĺžky) //nbus_cb_UART_RX(msg_idx); // callback to nBus, notify message length state = STATE_WAIT_LEN; packet_finished = 1; flagUartMasterDataReady = 1; } break; } return packet_finished; } static uint8_t process_UART_RingBuffer(void) { // Zistíme, kde sa aktuálne nachádza DMA (Head) // CNDTR register obsahuje počet ZOSTÁVAJÚCICH bajtov do konca buffra uint16_t rx_dma_pos = BUFF_SIZE - __HAL_DMA_GET_COUNTER(pUartMasterGlobal->hdmarx); while (rx_read_pos != rx_dma_pos) { uint8_t byte = rx_ring_buffer[rx_read_pos]; rx_read_pos++; if (rx_read_pos >= BUFF_SIZE) { rx_read_pos = 0; } if( Parse_Protocol_Byte(byte) != 0){ return 1; } } return 0; } /** * Entrypoint of nBusBridge applicattion. * @param uart_nbus: interface for internal bridge-slave * @param uart_master: nterface for external bridge-master */ void app(UART_HandleTypeDef *uart_nbus, UART_HandleTypeDef *uart_master) { pUartMasterGlobal = uart_master; init_app(); NbusCommunicator nc(uart_nbus, uart_master); NbusBridge bridge(&nc); bridge.scanNetwork(); while (1) { if (process_UART_RingBuffer() != 0){ bridge.processRequest(pMasterUartRx, msg_len); flagUartMasterDataReady = 0; } bridge.processRunningState(); } } /** * @brief Application callback of STM32 HAL. */ /* void HAL_UARTEx_RxEventCallback(UART_HandleTypeDef *huart, uint16_t Size) { if (huart == pUartMasterGlobal) { HAL_UARTEx_ReceiveToIdle_DMA(pUartMasterGlobal, pMasterUartRx, NBUS_APP_UART_FRAME_SIZE); uint8_t copy_offset = 0; if (vMasterUartIndex == 0) { vMasterUartSize = pMasterUartRx[0]; vMasterUartIndex = 1; Size--; copy_offset = 1; } if (Size > 0) { memcpy(&pMasterUartFrame[vMasterUartIndex - 1], &pMasterUartRx[copy_offset], Size); vMasterUartIndex += Size; } if (vMasterUartIndex > vMasterUartSize) { flagUartMasterDataReady = vMasterUartSize; vMasterUartSize = 0; vMasterUartIndex = 0; pMasterUartRx[0] = 0; } } } */