ser_phy_nohci.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382
  1. /**
  2. * Copyright (c) 2014 - 2020, Nordic Semiconductor ASA
  3. *
  4. * All rights reserved.
  5. *
  6. * Redistribution and use in source and binary forms, with or without modification,
  7. * are permitted provided that the following conditions are met:
  8. *
  9. * 1. Redistributions of source code must retain the above copyright notice, this
  10. * list of conditions and the following disclaimer.
  11. *
  12. * 2. Redistributions in binary form, except as embedded into a Nordic
  13. * Semiconductor ASA integrated circuit in a product or a software update for
  14. * such product, must reproduce the above copyright notice, this list of
  15. * conditions and the following disclaimer in the documentation and/or other
  16. * materials provided with the distribution.
  17. *
  18. * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
  19. * contributors may be used to endorse or promote products derived from this
  20. * software without specific prior written permission.
  21. *
  22. * 4. This software, with or without modification, must only be used with a
  23. * Nordic Semiconductor ASA integrated circuit.
  24. *
  25. * 5. Any software provided in binary form under this license must not be reverse
  26. * engineered, decompiled, modified and/or disassembled.
  27. *
  28. * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
  29. * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  30. * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
  31. * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
  32. * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  33. * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
  34. * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  35. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  36. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
  37. * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  38. *
  39. */
  40. /**@file
  41. *
  42. * @defgroup ser_phy_spi_phy_driver_slave ser_phy_nrf51_spi_slave.c
  43. * @{
  44. * @ingroup ser_phy_spi_phy_driver_slave
  45. *
  46. * @brief SPI_RAW PHY slave driver.
  47. */
  48. #include <stddef.h>
  49. #include <string.h>
  50. #include "app_error.h"
  51. #include "app_util.h"
  52. #include "app_util_platform.h"
  53. #include "app_timer.h"
  54. #include "ser_phy.h"
  55. #include "ser_phy_hci.h"
  56. #include "crc16.h"
  57. #include "nrf_soc.h"
  58. #include "ser_phy_debug_comm.h"
  59. static bool m_flag_nohci_init = false;
  60. static bool m_flag_expect_ack;
  61. static bool m_flag_buffer_reqested = false;
  62. static uint16_t m_rx_packet_length;
  63. static uint8_t * m_p_rx_packet;
  64. static uint16_t m_rx_pending_packet_length;
  65. static uint8_t * m_p_rx_pending_packet;
  66. static uint16_t m_rx_allocated_packet_length;
  67. static uint8_t * m_p_rx_allocated_packet;
  68. static uint8_t * m_p_tx_packet = NULL;
  69. static uint16_t m_tx_packet_length;
  70. static ser_phy_events_handler_t m_ser_phy_callback = NULL;
  71. #define PKT_HDR_SIZE 4 /**< Packet header size in number of bytes. */
  72. #define PKT_CRC_SIZE 2 /**< Packet CRC size in number of bytes. */
  73. static void ser_phy_nohci_assert(bool cond)
  74. {
  75. APP_ERROR_CHECK_BOOL(cond);
  76. }
  77. static void ser_phy_event_callback(ser_phy_evt_t event)
  78. {
  79. if (m_ser_phy_callback)
  80. {
  81. m_ser_phy_callback(event);
  82. }
  83. }
  84. static void memory_request_callback(uint16_t size)
  85. {
  86. ser_phy_evt_t event;
  87. DEBUG_EVT_HCI_PHY_EVT_BUF_REQUEST(0);
  88. event.evt_type = SER_PHY_EVT_RX_BUF_REQUEST;
  89. event.evt_params.rx_buf_request.num_of_bytes = size;
  90. ser_phy_event_callback(event);
  91. }
  92. static void packet_received_callback(uint8_t * pBuffer, uint16_t size)
  93. {
  94. ser_phy_evt_t event;
  95. DEBUG_EVT_HCI_PHY_EVT_RX_PKT_RECEIVED(0);
  96. event.evt_type = SER_PHY_EVT_RX_PKT_RECEIVED;
  97. event.evt_params.rx_pkt_received.num_of_bytes = size;
  98. event.evt_params.rx_pkt_received.p_buffer = pBuffer;
  99. ser_phy_event_callback(event);
  100. }
  101. static void packet_dropped_callback(void)
  102. {
  103. ser_phy_evt_t event;
  104. DEBUG_EVT_HCI_PHY_EVT_RX_PKT_DROPPED(0);
  105. event.evt_type = SER_PHY_EVT_RX_PKT_DROPPED;
  106. ser_phy_event_callback(event);
  107. }
  108. static void packet_transmitted_callback(void)
  109. {
  110. ser_phy_evt_t event;
  111. DEBUG_EVT_HCI_PHY_EVT_TX_PKT_SENT(0);
  112. event.evt_type = SER_PHY_EVT_TX_PKT_SENT;
  113. ser_phy_event_callback(event);
  114. }
  115. static void hci_slip_event_handler(ser_phy_hci_slip_evt_t * p_event)
  116. {
  117. if ( p_event->evt_type == SER_PHY_HCI_SLIP_EVT_PKT_SENT )
  118. {
  119. DEBUG_EVT_SLIP_PACKET_TXED(0);
  120. if (!m_flag_expect_ack)
  121. {
  122. m_p_tx_packet = NULL;
  123. packet_transmitted_callback();
  124. }
  125. else
  126. {
  127. ser_phy_nohci_assert(false); // packet was send as a ACK packet, callback should be with ACK_SENT
  128. }
  129. }
  130. else if ( p_event->evt_type == SER_PHY_HCI_SLIP_EVT_ACK_SENT )
  131. {
  132. DEBUG_EVT_SLIP_ACK_TXED(0);
  133. if (m_flag_expect_ack)
  134. {
  135. m_p_tx_packet = NULL;
  136. packet_transmitted_callback();
  137. }
  138. else
  139. {
  140. ser_phy_nohci_assert(false); // packet was send as a normal packet, callback should be with PKT_SENT
  141. }
  142. }
  143. else if ( p_event->evt_type == SER_PHY_HCI_SLIP_EVT_PKT_RECEIVED )
  144. {
  145. CRITICAL_REGION_ENTER();
  146. if (m_p_rx_packet == NULL)
  147. {
  148. m_p_rx_packet = p_event->evt_params.received_pkt.p_buffer;
  149. m_rx_packet_length = p_event->evt_params.received_pkt.num_of_bytes;
  150. m_p_rx_allocated_packet = m_p_rx_packet;
  151. m_rx_allocated_packet_length = m_rx_packet_length;
  152. m_flag_buffer_reqested = true;
  153. memory_request_callback(m_rx_allocated_packet_length);
  154. }
  155. else if (m_p_rx_pending_packet == NULL)
  156. {
  157. m_p_rx_pending_packet = p_event->evt_params.received_pkt.p_buffer;
  158. m_rx_pending_packet_length = p_event->evt_params.received_pkt.num_of_bytes;
  159. }
  160. else
  161. {
  162. // both buffers are not released; this is fault
  163. ser_phy_nohci_assert(false);
  164. }
  165. CRITICAL_REGION_EXIT();
  166. }
  167. else
  168. {
  169. // no other callbacks are expected
  170. ser_phy_nohci_assert(false);
  171. }
  172. }
  173. /* ser_phy API function */
  174. void ser_phy_interrupts_enable(void)
  175. {
  176. NVIC_EnableIRQ(UART0_IRQn);
  177. return;
  178. }
  179. /* ser_phy API function */
  180. void ser_phy_interrupts_disable(void)
  181. {
  182. NVIC_DisableIRQ(UART0_IRQn);
  183. return;
  184. }
  185. /* ser_phy API function */
  186. uint32_t ser_phy_rx_buf_set(uint8_t * p_buffer)
  187. {
  188. uint32_t status = NRF_SUCCESS;
  189. if (m_flag_buffer_reqested)
  190. {
  191. m_flag_buffer_reqested = false;
  192. if (p_buffer)
  193. {
  194. memcpy(p_buffer, m_p_rx_allocated_packet, m_rx_allocated_packet_length);
  195. packet_received_callback(p_buffer, m_rx_allocated_packet_length);
  196. }
  197. else
  198. {
  199. packet_dropped_callback();
  200. }
  201. CRITICAL_REGION_ENTER();
  202. if (m_p_rx_allocated_packet == m_p_rx_packet && (m_p_rx_pending_packet == NULL))
  203. {
  204. // packet is copied and there is no pending packet
  205. (void) ser_phy_hci_slip_rx_buf_free(m_p_rx_packet);
  206. m_p_rx_packet = NULL;
  207. m_p_rx_allocated_packet = NULL;
  208. }
  209. else if (m_p_rx_allocated_packet == m_p_rx_packet && (m_p_rx_pending_packet != NULL))
  210. {
  211. // there is a pending packet - request memory for it
  212. m_p_rx_allocated_packet = m_p_rx_pending_packet;
  213. m_rx_allocated_packet_length = m_rx_pending_packet_length;
  214. m_flag_buffer_reqested = true;
  215. }
  216. else if (m_p_rx_allocated_packet == m_p_rx_pending_packet )
  217. {
  218. // the pending packet was serviced - release both
  219. m_p_rx_allocated_packet = NULL;
  220. (void) ser_phy_hci_slip_rx_buf_free(m_p_rx_packet);
  221. m_p_rx_packet = NULL;
  222. (void) ser_phy_hci_slip_rx_buf_free(m_p_rx_pending_packet);
  223. m_p_rx_pending_packet = NULL;
  224. }
  225. else
  226. {
  227. // no other calls are expected
  228. ser_phy_nohci_assert(false);
  229. }
  230. CRITICAL_REGION_EXIT();
  231. // request memory for a pending
  232. if (m_p_rx_allocated_packet)
  233. {
  234. memory_request_callback(m_rx_allocated_packet_length);
  235. }
  236. }
  237. else
  238. {
  239. status = NRF_ERROR_BUSY;
  240. }
  241. return status;
  242. }
  243. /* ser_phy API function */
  244. uint32_t ser_phy_tx_pkt_send(const uint8_t * p_buffer, uint16_t num_of_bytes)
  245. {
  246. uint32_t status = NRF_SUCCESS;
  247. uint32_t err_code;
  248. if ( p_buffer == NULL || num_of_bytes == 0)
  249. {
  250. return NRF_ERROR_NULL;
  251. }
  252. if ( m_p_tx_packet == NULL)
  253. {
  254. m_tx_packet_length = num_of_bytes;
  255. m_p_tx_packet = (uint8_t *)p_buffer;
  256. if (m_tx_packet_length <= PKT_HDR_SIZE + PKT_CRC_SIZE)
  257. {
  258. ser_phy_hci_pkt_params_t pkt; // all packets smaller than 6 goes as ACK
  259. m_flag_expect_ack = true;
  260. pkt.p_buffer = (uint8_t *)m_p_tx_packet;
  261. pkt.num_of_bytes = m_tx_packet_length;
  262. DEBUG_EVT_SLIP_ACK_TX(0);
  263. err_code = ser_phy_hci_slip_tx_pkt_send(&pkt, NULL, NULL); // this will look like ACK for slip
  264. ser_phy_nohci_assert(err_code == NRF_SUCCESS);
  265. }
  266. else
  267. {
  268. ser_phy_hci_pkt_params_t header; // this is fake header - just first 4 bytes
  269. ser_phy_hci_pkt_params_t crc; // this is fake header - just last 2 bytes
  270. ser_phy_hci_pkt_params_t payload; // this is fake payload - all except for header and crc
  271. m_flag_expect_ack = false;
  272. header.p_buffer = (uint8_t *)m_p_tx_packet;
  273. header.num_of_bytes = PKT_HDR_SIZE;
  274. crc.p_buffer = (uint8_t *)m_p_tx_packet + m_tx_packet_length - PKT_CRC_SIZE;
  275. crc.num_of_bytes = PKT_CRC_SIZE;
  276. payload.p_buffer = (uint8_t *)m_p_tx_packet + PKT_HDR_SIZE;
  277. payload.num_of_bytes = m_tx_packet_length - PKT_HDR_SIZE - PKT_CRC_SIZE;
  278. DEBUG_EVT_SLIP_PACKET_TX(0);
  279. err_code = ser_phy_hci_slip_tx_pkt_send(&header, &payload, &crc); // this will look like normal packet for slip
  280. ser_phy_nohci_assert(err_code == NRF_SUCCESS);
  281. }
  282. }
  283. else
  284. {
  285. status = NRF_ERROR_BUSY;
  286. }
  287. return status;
  288. }
  289. /* ser_phy API function */
  290. uint32_t ser_phy_open(ser_phy_events_handler_t events_handler)
  291. {
  292. uint32_t err_code;
  293. if (m_flag_nohci_init)
  294. {
  295. return NRF_ERROR_INVALID_STATE;
  296. }
  297. if (events_handler == NULL)
  298. {
  299. return NRF_ERROR_NULL;
  300. }
  301. err_code = ser_phy_hci_slip_open(hci_slip_event_handler);
  302. if (err_code != NRF_SUCCESS)
  303. {
  304. return err_code;
  305. }
  306. m_ser_phy_callback = events_handler;
  307. m_flag_nohci_init = true;
  308. return NRF_SUCCESS;
  309. }
  310. /* ser_phy API function */
  311. void ser_phy_close(void)
  312. {
  313. m_ser_phy_callback = NULL;
  314. ser_phy_hci_slip_close();
  315. m_flag_nohci_init = false;
  316. }