/** * @file NbusCommunicator.cpp * @brief Implemetnácia komunikačnej vrstvy: 1) internej 2) externej * @date Mar 7, 2025 * @author Juraj Dudak */ #include "NbusCommunicator.h" NbusCommunicator::NbusCommunicator(UART_HandleTypeDef *uartUbus, UART_HandleTypeDef *uartMaster) { _packet_tx = new DataFrame(_data_packet_tx, sizeof(_data_packet_tx), TYPE_PLAIN, CRC_ON); if (_packet_tx == NULL) { while (1) { __NOP(); } } _packet_rx = new DataFrame(_data_packet_rx, sizeof(_data_packet_rx), TYPE_PLAIN, CRC_OFF); if (_packet_rx == NULL) { while (1) { __NOP(); } } if (uartUbus == NULL) { while (1) { __NOP(); } } _uart_nbus = uartUbus; if (uartMaster == NULL) { while (1) { __NOP(); } } _uart_master = uartMaster; } NbusCommunicator::~NbusCommunicator() { // empty } void NbusCommunicator::_receive() { 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 (status == HAL_OK) { if (received_size > 0) { _packet_rx->FromArray(_data_packet_comm, received_size); } } HAL_GPIO_WritePin(GPIOB, GPIO_PIN_3, GPIO_PIN_RESET); _packet_rx->Commit(); } DataFrame *NbusCommunicator::sendAndReceive(Nbus_pdu *pdu, uint8_t *data, uint8_t data_len) { this->send(pdu, data, data_len); this->_receive(); return _packet_rx; } void NbusCommunicator::send(Nbus_pdu *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); } void NbusCommunicator::sendToMaster(DataFrame *master_frame) { while (_uart_master->gState != HAL_UART_STATE_READY) { __NOP(); // cakanie na ukoncenie prebiehajuceho odosielania // tu to moze byt vcelku tesno odoslany dalsi paket. je tam pauza o dlzke 1.2bit } HAL_UART_Transmit_DMA(_uart_master, master_frame->GetFrame(), master_frame->GetLength()); } /** * Informácia o existujúcih moduloch nBus Slave. * Formát: [index1 adresa1 index2 adresa2 ... indexN andresaN] */ DataFrame *NbusCommunicator::formatSlaveInfo(uint8_t slave_address[], uint8_t num) { _packet_rx->Init(); for (uint8_t i = 0; i < num; i++) { _packet_rx->AddInt8(i + 1); _packet_rx->AddInt8(slave_address[i]); } _packet_rx->Commit(); return _packet_rx; }