NbusCommunicator.cpp 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. /**
  2. * @file NbusCommunicator.cpp
  3. * @brief Implemetnácia komunikačnej vrstvy: 1) internej 2) externej
  4. * @date Mar 7, 2025
  5. * @author Juraj Dudak
  6. */
  7. #include "NbusCommunicator.h"
  8. NbusCommunicator::NbusCommunicator(UART_HandleTypeDef *uartUbus, UART_HandleTypeDef *uartMaster)
  9. : _packet_tx(_data_packet_tx, NBUS_MAX_FRAME_SIZE, TYPE_PLAIN, CRC_ON),
  10. _packet_rx(_data_packet_rx, NBUS_MAX_FRAME_SIZE, TYPE_PLAIN, CRC_OFF)
  11. {
  12. if (uartUbus == NULL)
  13. {
  14. while (1)
  15. {
  16. __NOP();
  17. }
  18. }
  19. _uart_nbus = uartUbus;
  20. if (uartMaster == NULL)
  21. {
  22. while (1)
  23. {
  24. __NOP();
  25. }
  26. }
  27. _uart_master = uartMaster;
  28. }
  29. NbusCommunicator::~NbusCommunicator()
  30. {
  31. // empty
  32. }
  33. void NbusCommunicator::_receive()
  34. {
  35. uint16_t received_size;
  36. HAL_GPIO_WritePin(GPIOB, GPIO_PIN_3, GPIO_PIN_SET);
  37. memset(_data_packet_comm, 0, NBUS_MAX_FRAME_SIZE);
  38. // komunikacia v DMA musi byt spracovana aj tak ako blokujuca
  39. // takto je tu menej rezie. Timeout je 5ms
  40. HAL_StatusTypeDef status = HAL_UARTEx_ReceiveToIdle(_uart_nbus, _data_packet_comm, NBUS_MAX_FRAME_SIZE,
  41. &received_size, UART_NBUS_RX_TIMEOUT);
  42. _packet_rx.Init();
  43. if (status == HAL_OK)
  44. {
  45. if (received_size > 0)
  46. {
  47. _packet_rx.FromArray(_data_packet_comm, received_size);
  48. }
  49. }
  50. HAL_GPIO_WritePin(GPIOB, GPIO_PIN_3, GPIO_PIN_RESET);
  51. _packet_rx.Commit();
  52. }
  53. DataFrame *NbusCommunicator::sendAndReceive(Nbus_PDU_t *pdu, uint8_t *data, uint8_t data_len)
  54. {
  55. this->send(pdu, data, data_len);
  56. this->_receive();
  57. return &_packet_rx;
  58. }
  59. DataFrame *NbusCommunicator::sendAndReceiveSlave(DataFrame *slave_frame)
  60. {
  61. this->sendToSlave(slave_frame);
  62. this->_receive();
  63. return &_packet_rx;
  64. }
  65. void NbusCommunicator::sendToSlave(DataFrame *slave_frame)
  66. {
  67. HAL_GPIO_WritePin(GPIOB, GPIO_PIN_3, GPIO_PIN_SET);
  68. HAL_UART_Transmit(_uart_nbus, slave_frame->GetFrame(), slave_frame->GetLength(), 10);
  69. HAL_GPIO_WritePin(GPIOB, GPIO_PIN_3, GPIO_PIN_RESET);
  70. }
  71. void NbusCommunicator::send(Nbus_PDU_t *pdu, uint8_t *data, uint8_t data_len)
  72. {
  73. _packet_tx.Init();
  74. _packet_tx.AddInt8(pdu->ma); // Module address
  75. _packet_tx.AddInt8(pdu->sa); // Slave address
  76. _packet_tx.AddInt8(pdu->fc); // Function Code
  77. for (int i = 0; i < data_len; i++)
  78. {
  79. _packet_tx.AddInt8(data[i]);
  80. }
  81. int length = _packet_tx.Commit();
  82. HAL_GPIO_WritePin(GPIOB, GPIO_PIN_3, GPIO_PIN_SET);
  83. HAL_UART_Transmit(_uart_nbus, _packet_tx.GetFrame(), length, 10);
  84. HAL_GPIO_WritePin(GPIOB, GPIO_PIN_3, GPIO_PIN_RESET);
  85. }
  86. void NbusCommunicator::sendToMaster(DataFrame *master_frame)
  87. {
  88. if (master_frame == nullptr || master_frame->IsEmpty())
  89. return;
  90. while (_uart_master->gState != HAL_UART_STATE_READY)
  91. {
  92. __NOP(); // cakanie na ukoncenie prebiehajuceho odosielania
  93. // tu to moze byt vcelku tesno odoslany dalsi paket. je tam pauza o dlzke 1.2bit
  94. }
  95. HAL_UART_Transmit_DMA(_uart_master, master_frame->GetFrame(), master_frame->GetLength());
  96. }