NbusCommunicator.cpp 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  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 *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. void NbusCommunicator::send(Nbus_pdu *pdu, uint8_t *data, uint8_t data_len)
  60. {
  61. _packet_tx.Init();
  62. _packet_tx.AddInt8(pdu->ma); // Module address
  63. _packet_tx.AddInt8(pdu->sa); // Slave address
  64. _packet_tx.AddInt8(pdu->fc); // Function Code
  65. for (int i = 0; i < data_len; i++)
  66. {
  67. _packet_tx.AddInt8(data[i]);
  68. }
  69. int length = _packet_tx.Commit();
  70. HAL_GPIO_WritePin(GPIOB, GPIO_PIN_3, GPIO_PIN_SET);
  71. HAL_UART_Transmit(_uart_nbus, _packet_tx.GetFrame(), length, 10);
  72. HAL_GPIO_WritePin(GPIOB, GPIO_PIN_3, GPIO_PIN_RESET);
  73. }
  74. void NbusCommunicator::sendToMaster(DataFrame *master_frame)
  75. {
  76. if (master_frame == nullptr || master_frame->IsEmpty())
  77. return;
  78. while (_uart_master->gState != HAL_UART_STATE_READY)
  79. {
  80. __NOP(); // cakanie na ukoncenie prebiehajuceho odosielania
  81. // tu to moze byt vcelku tesno odoslany dalsi paket. je tam pauza o dlzke 1.2bit
  82. }
  83. HAL_UART_Transmit_DMA(_uart_master, master_frame->GetFrame(), master_frame->GetLength());
  84. }