NbusCommunicator.cpp 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  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. {
  10. _packet_tx = new DataFrame(_data_packet_tx, sizeof(_data_packet_tx), TYPE_PLAIN, CRC_ON);
  11. if (_packet_tx == NULL)
  12. {
  13. while (1)
  14. {
  15. __NOP();
  16. }
  17. }
  18. _packet_rx = new DataFrame(_data_packet_rx, sizeof(_data_packet_rx), TYPE_PLAIN, CRC_OFF);
  19. if (_packet_rx == NULL)
  20. {
  21. while (1)
  22. {
  23. __NOP();
  24. }
  25. }
  26. if (uartUbus == NULL)
  27. {
  28. while (1)
  29. {
  30. __NOP();
  31. }
  32. }
  33. _uart_nbus = uartUbus;
  34. if (uartMaster == NULL)
  35. {
  36. while (1)
  37. {
  38. __NOP();
  39. }
  40. }
  41. _uart_master = uartMaster;
  42. }
  43. NbusCommunicator::~NbusCommunicator()
  44. {
  45. // empty
  46. }
  47. void NbusCommunicator::_receive()
  48. {
  49. uint16_t received_size;
  50. HAL_GPIO_WritePin(GPIOB, GPIO_PIN_3, GPIO_PIN_SET);
  51. memset(_data_packet_comm, 0, NBUS_MAX_FRAME_SIZE);
  52. // komunikacia v DMA musi byt spracovana aj tak ako blokujuca
  53. // takto je tu menej rezie. Timeout je 5ms
  54. HAL_StatusTypeDef status = HAL_UARTEx_ReceiveToIdle(_uart_nbus, _data_packet_comm, NBUS_MAX_FRAME_SIZE,
  55. &received_size, UART_NBUS_RX_TIMEOUT);
  56. _packet_rx->Init();
  57. if (status == HAL_OK)
  58. {
  59. if (received_size > 0)
  60. {
  61. _packet_rx->FromArray(_data_packet_comm, received_size);
  62. }
  63. }
  64. HAL_GPIO_WritePin(GPIOB, GPIO_PIN_3, GPIO_PIN_RESET);
  65. _packet_rx->Commit();
  66. }
  67. DataFrame *NbusCommunicator::sendAndReceive(Nbus_pdu *pdu, uint8_t *data, uint8_t data_len)
  68. {
  69. this->send(pdu, data, data_len);
  70. this->_receive();
  71. return _packet_rx;
  72. }
  73. void NbusCommunicator::send(Nbus_pdu *pdu, uint8_t *data, uint8_t data_len)
  74. {
  75. _packet_tx->Init();
  76. _packet_tx->AddInt8(pdu->ma); // Module address
  77. _packet_tx->AddInt8(pdu->sa); // Slave address
  78. _packet_tx->AddInt8(pdu->fc); // Function Code
  79. for (int i = 0; i < data_len; i++)
  80. {
  81. _packet_tx->AddInt8(data[i]);
  82. }
  83. int length = _packet_tx->Commit();
  84. HAL_GPIO_WritePin(GPIOB, GPIO_PIN_3, GPIO_PIN_SET);
  85. HAL_UART_Transmit(_uart_nbus, _packet_tx->GetFrame(), length, 10);
  86. HAL_GPIO_WritePin(GPIOB, GPIO_PIN_3, GPIO_PIN_RESET);
  87. }
  88. void NbusCommunicator::sendToMaster(DataFrame *master_frame)
  89. {
  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. }
  97. /**
  98. * Informácia o existujúcih moduloch nBus Slave.
  99. * Formát: [index1 adresa1 index2 adresa2 ... indexN andresaN]
  100. */
  101. DataFrame *NbusCommunicator::formatSlaveInfo(uint8_t rx_frame[], uint8_t slave_address[], uint8_t num)
  102. {
  103. _packet_rx->Init();
  104. _packet_rx->AddArray(rx_frame, 3);
  105. for (uint8_t i = 0; i < num; i++)
  106. {
  107. _packet_rx->AddInt8(i + 1);
  108. _packet_rx->AddInt8(slave_address[i]);
  109. }
  110. _packet_rx->Commit();
  111. return _packet_rx;
  112. }
  113. /**
  114. * Informácia o existujúcih moduloch nBus Slave.
  115. * Formát: [index1 adresa1 index2 adresa2 ... indexN andresaN]
  116. */
  117. DataFrame *NbusCommunicator::formatPacket(uint8_t *rxFrame, uint8_t size)
  118. {
  119. _packet_rx->Init();
  120. for (uint8_t i = 0; i < size; i++)
  121. {
  122. _packet_rx->AddInt8(rxFrame[i]);
  123. }
  124. _packet_rx->Commit();
  125. return _packet_rx;
  126. }