esp_spi_spinel_interface.hpp 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144
  1. /*
  2. * SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. */
  6. #pragma once
  7. #include "esp_err.h"
  8. #include "esp_openthread_types.h"
  9. #include "driver/spi_master.h"
  10. #include "lib/spinel/spinel_interface.hpp"
  11. namespace esp {
  12. namespace openthread {
  13. class SpiSpinelInterface {
  14. public:
  15. /**
  16. * @brief This constructor of object.
  17. *
  18. * @param[in] callback Callback on frame received
  19. * @param[in] callback_context Callback context
  20. * @param[in] frame_buffer A reference to a `RxFrameBuffer` object.
  21. *
  22. */
  23. SpiSpinelInterface(ot::Spinel::SpinelInterface::ReceiveFrameCallback callback, void *callback_context,
  24. ot::Spinel::SpinelInterface::RxFrameBuffer &frame_buffer);
  25. /**
  26. * @brief This destructor of the object.
  27. *
  28. */
  29. ~SpiSpinelInterface(void);
  30. /**
  31. * @brief This method initializes the spinel interface.
  32. *
  33. * @return
  34. * - ESP_OK on success
  35. * - ESP_ERR_INVALID_STATE if already initialized
  36. * - ESP_ERR_NO_MEM if allocation has failed
  37. * - ESP_FAIL on failure
  38. */
  39. esp_err_t Init(const esp_openthread_spi_host_config_t &spi_config);
  40. /**
  41. * @brief This method deinitializes the HDLC interface.
  42. *
  43. * @return
  44. * - ESP_OK on success
  45. * - ESP_FAIL on failure
  46. */
  47. esp_err_t Deinit(void);
  48. /**
  49. * @brief This method encodes and sends a spinel frame to Radio Co-processor (RCP) over the socket.
  50. *
  51. * @param[in] frame A pointer to buffer containing the spinel frame to send.
  52. * @param[in] length The length (number of bytes) in the frame.
  53. *
  54. * @return
  55. * -OT_ERROR_NONE Successfully encoded and sent the spinel frame.
  56. * -OT_ERROR_NO_BUFS Insufficient buffer space available to encode the frame.
  57. * -OT_ERROR_FAILED Failed to send due to socket not becoming writable within `kMaxWaitTime`.
  58. *
  59. */
  60. otError SendFrame(const uint8_t *frame, uint16_t length);
  61. /**
  62. * This method waits for receiving part or all of spinel frame within specified timeout.
  63. *
  64. * @param[in] timeout_us The timeout value in microseconds.
  65. *
  66. * @return
  67. * -OT_ERROR_NONE Part or all of spinel frame is received.
  68. * -OT_ERROR_RESPONSE_TIMEOUT No spinel frame is received within @p timeout_us.
  69. *
  70. */
  71. otError WaitForFrame(uint64_t timeout_us);
  72. /**
  73. * This method performs spi processing to the RCP.
  74. *
  75. * @param[in] mainloop The mainloop context
  76. *
  77. */
  78. void Process(const void *mainloop);
  79. /**
  80. * This methods updates the mainloop context.
  81. *
  82. * @param[inout] mainloop The mainloop context.
  83. *
  84. */
  85. void Update(void *mainloop);
  86. /**
  87. * This methods registers the callback for RCP failure.
  88. *
  89. * @param[in] handler The RCP failure handler.
  90. *
  91. */
  92. void RegisterRcpFailureHandler(esp_openthread_rcp_failure_handler handler) { mRcpFailureHandler = handler; }
  93. /**
  94. * This method is called when RCP is reset to recreate the connection with it.
  95. * Intentionally empty.
  96. *
  97. */
  98. otError ResetConnection(void) { return OT_ERROR_NONE; }
  99. /**
  100. * This method is called when RCP failure detected and resets internal states of the interface.
  101. *
  102. */
  103. otError HardwareReset(void);
  104. private:
  105. static constexpr uint8_t kSPIFrameHeaderSize = 5;
  106. static constexpr uint16_t kSPIFrameSize = ot::Spinel::SpinelInterface::kMaxFrameSize + kSPIFrameHeaderSize;
  107. static constexpr uint8_t kSmallPacketSize = 32;
  108. static constexpr uint16_t kSPIDataEvent = 1;
  109. static void GpioIntrHandler(void *arg);
  110. esp_err_t ConductSPITransaction(bool reset, uint16_t tx_data_size, uint16_t rx_data_size);
  111. esp_openthread_spi_host_config_t m_spi_config;
  112. uint8_t m_tx_buffer[kSPIFrameSize];
  113. int m_event_fd;
  114. volatile uint16_t m_pending_data_len;
  115. ot::Spinel::SpinelInterface::ReceiveFrameCallback m_receiver_frame_callback;
  116. void *m_receiver_frame_context;
  117. ot::Spinel::SpinelInterface::RxFrameBuffer &m_receive_frame_buffer;
  118. bool m_has_pending_device_frame;
  119. spi_device_handle_t m_device;
  120. esp_openthread_rcp_failure_handler mRcpFailureHandler;
  121. };
  122. } // namespace openthread
  123. } // namespace esp