spi_5W_master.c 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629
  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_5W_hw_driver_master spi_5W_master.c
  43. * @{
  44. * @ingroup ser_phy_spi_5W_hw_driver_master
  45. *
  46. * @brief SPI_5W_RAW hardware driver.
  47. */
  48. #include "app_error.h"
  49. #include "app_util_platform.h"
  50. #include "nrf_gpio.h"
  51. #include "nrf.h"
  52. #include "spi_5W_master.h"
  53. #include "ser_config_5W_app.h"
  54. #include "ser_phy_debug_app.h"
  55. #include "sdk_common.h"
  56. #define _static
  57. #define DOUBLE_BUFFERED /**< A flag for enabling double buffering. */
  58. #define SPI_PIN_DISCONNECTED 0xFFFFFFFF /**< A value used to the PIN deinitialization. */
  59. #define SPI_DEFAULT_TX_BYTE 0x00 /**< Default byte (used to clock transmission
  60. from slave to the master) */
  61. typedef struct
  62. {
  63. NRF_SPI_Type * p_nrf_spi; /**< A pointer to the NRF SPI master */
  64. IRQn_Type irq_type; /**< A type of NVIC IRQn */
  65. uint8_t * p_tx_buffer; /**< A pointer to TX buffer. */
  66. uint16_t tx_length; /**< A length of TX buffer. */
  67. uint16_t tx_index; /**< A index of the current element in the TX buffer. */
  68. uint8_t * p_rx_buffer; /**< A pointer to RX buffer. */
  69. uint16_t rx_length; /**< A length RX buffer. */
  70. uint16_t rx_index; /**< A index of the current element in the RX buffer. */
  71. uint16_t max_length; /**< Max length (Max of the TX and RX length). */
  72. uint16_t bytes_count;
  73. uint8_t pin_slave_select; /**< A pin for Slave Select. */
  74. spi_master_event_handler_t callback_event_handler; /**< A handler for event callback function. */
  75. spi_master_state_t state; /**< A state of an instance of SPI master. */
  76. bool start_flag;
  77. bool abort_flag;
  78. } spi_master_instance_t;
  79. #ifdef _SPI_5W_
  80. typedef enum
  81. {
  82. HOOK_STATE_DISABLED,
  83. HOOK_STATE_IDLE,
  84. HOOK_STATE_GUARDED,
  85. HOOK_STATE_ABORTED,
  86. HOOK_STATE_RESTARTED,
  87. HOOK_STATE_PASSING
  88. } spi_hook_state_t;
  89. _static spi_master_event_handler_t m_ser_phy_event_handler;
  90. _static spi_master_hw_instance_t m_spi_master_hw_instance;
  91. _static spi_hook_state_t m_hook_state = HOOK_STATE_DISABLED;
  92. #endif
  93. #ifdef SER_PHY_DEBUG_APP_ENABLE
  94. _static spi_master_raw_callback_t m_debug_callback;
  95. #endif
  96. _static spi_master_instance_t m_spi_master_instances[SPI_MASTER_HW_ENABLED_COUNT];
  97. static __INLINE spi_master_instance_t * spi_master_get_instance(
  98. const spi_master_hw_instance_t spi_master_hw_instance);
  99. static __INLINE void spi_master_send_recv_irq(spi_master_instance_t * const p_spi_instance);
  100. static __INLINE void spi_master_signal_evt(spi_master_instance_t * const p_spi_instance,
  101. spi_master_evt_type_t event_type,
  102. const uint16_t data);
  103. #ifdef SPI_MASTER_0_ENABLE
  104. /**
  105. * @brief SPI0 interrupt handler.
  106. */
  107. void SPI0_TWI0_IRQHandler(void)
  108. {
  109. if (NRF_SPI0->EVENTS_READY != 0)
  110. {
  111. NRF_SPI0->EVENTS_READY = 0;
  112. spi_master_instance_t * p_spi_instance = spi_master_get_instance(SPI_MASTER_0);
  113. spi_master_send_recv_irq(p_spi_instance);
  114. }
  115. }
  116. #endif //SPI_MASTER_0_ENABLE
  117. #ifdef SPI_MASTER_1_ENABLE
  118. /**
  119. * @brief SPI0 interrupt handler.
  120. */
  121. void SPI1_TWI1_IRQHandler(void)
  122. {
  123. if (NRF_SPI1->EVENTS_READY != 0)
  124. {
  125. NRF_SPI1->EVENTS_READY = 0;
  126. spi_master_instance_t * p_spi_instance = spi_master_get_instance(SPI_MASTER_1);
  127. spi_master_send_recv_irq(p_spi_instance);
  128. }
  129. }
  130. #endif //SPI_MASTER_1_ENABLE
  131. #if defined(SPI_MASTER_0_ENABLE) || defined(SPI_MASTER_1_ENABLE)
  132. /**@brief Function for getting an instance of SPI master. */
  133. static __INLINE spi_master_instance_t * spi_master_get_instance(
  134. const spi_master_hw_instance_t spi_master_hw_instance)
  135. {
  136. return &(m_spi_master_instances[(uint8_t)spi_master_hw_instance]);
  137. }
  138. /** @brief Function for initializing instance of SPI master by default values. */
  139. static __INLINE void spi_master_init_hw_instance(NRF_SPI_Type * p_nrf_spi,
  140. IRQn_Type irq_type,
  141. spi_master_instance_t * p_spi_instance)
  142. {
  143. APP_ERROR_CHECK_BOOL(p_spi_instance != NULL);
  144. p_spi_instance->p_nrf_spi = p_nrf_spi;
  145. p_spi_instance->irq_type = irq_type;
  146. p_spi_instance->p_tx_buffer = NULL;
  147. p_spi_instance->tx_length = 0;
  148. p_spi_instance->tx_index = 0;
  149. p_spi_instance->p_rx_buffer = NULL;
  150. p_spi_instance->rx_length = 0;
  151. p_spi_instance->rx_index = 0;
  152. p_spi_instance->bytes_count = 0;
  153. p_spi_instance->max_length = 0;
  154. p_spi_instance->pin_slave_select = 0;
  155. p_spi_instance->callback_event_handler = NULL;
  156. p_spi_instance->state = SPI_MASTER_STATE_DISABLED;
  157. p_spi_instance->abort_flag = false;
  158. p_spi_instance->start_flag = false;
  159. }
  160. /**@brief Function for initializing TX or RX buffer. */
  161. static __INLINE void spi_master_buffer_init(uint8_t * const p_buf,
  162. const uint16_t buf_len,
  163. uint8_t * * pp_buf,
  164. uint16_t * const p_buf_len,
  165. uint16_t * const p_index)
  166. {
  167. APP_ERROR_CHECK_BOOL(pp_buf != NULL);
  168. APP_ERROR_CHECK_BOOL(p_buf_len != NULL);
  169. APP_ERROR_CHECK_BOOL(p_index != NULL);
  170. *pp_buf = p_buf;
  171. *p_buf_len = (p_buf != NULL) ? buf_len : 0;
  172. *p_index = 0;
  173. }
  174. /**@brief Function for releasing TX or RX buffer. */
  175. static __INLINE void spi_master_buffer_release(uint8_t * * const pp_buf, uint16_t * const p_buf_len)
  176. {
  177. APP_ERROR_CHECK_BOOL(pp_buf != NULL);
  178. APP_ERROR_CHECK_BOOL(p_buf_len != NULL);
  179. *pp_buf = NULL;
  180. *p_buf_len = 0;
  181. }
  182. /**@brief Function for sending events by callback. */
  183. static __INLINE void spi_master_signal_evt(spi_master_instance_t * const p_spi_instance,
  184. spi_master_evt_type_t event_type,
  185. const uint16_t data)
  186. {
  187. APP_ERROR_CHECK_BOOL(p_spi_instance != NULL);
  188. if (p_spi_instance->callback_event_handler != NULL)
  189. {
  190. spi_master_evt_t event = {SPI_MASTER_EVT_TYPE_MAX, 0};
  191. event.type = event_type;
  192. event.data = data;
  193. p_spi_instance->callback_event_handler(event);
  194. }
  195. }
  196. /**@brief Function insert to a TX buffer another byte or two bytes (depends on flag @ref DOUBLE_BUFFERED). */
  197. static __INLINE void spi_master_send_initial_bytes(spi_master_instance_t * const p_spi_instance)
  198. {
  199. APP_ERROR_CHECK_BOOL(p_spi_instance != NULL);
  200. p_spi_instance->p_nrf_spi->TXD = ((p_spi_instance->p_tx_buffer != NULL) &&
  201. (p_spi_instance->tx_index < p_spi_instance->tx_length)) ?
  202. p_spi_instance->p_tx_buffer[p_spi_instance->tx_index] :
  203. SPI_DEFAULT_TX_BYTE;
  204. (p_spi_instance->tx_index)++;
  205. #ifdef DOUBLE_BUFFERED
  206. if (p_spi_instance->tx_index < p_spi_instance->max_length)
  207. {
  208. p_spi_instance->p_nrf_spi->TXD = ((p_spi_instance->p_tx_buffer != NULL) &&
  209. (p_spi_instance->tx_index < p_spi_instance->tx_length)) ?
  210. p_spi_instance->p_tx_buffer[p_spi_instance->tx_index] :
  211. SPI_DEFAULT_TX_BYTE;
  212. (p_spi_instance->tx_index)++;
  213. }
  214. #endif
  215. }
  216. /**@brief Function for receiving and sending data from IRQ. (The same for both IRQs). */
  217. static __INLINE void spi_master_send_recv_irq(spi_master_instance_t * const p_spi_instance)
  218. {
  219. uint8_t rx_byte;
  220. APP_ERROR_CHECK_BOOL(p_spi_instance != NULL);
  221. APP_ERROR_CHECK_BOOL(p_spi_instance->state == SPI_MASTER_STATE_BUSY);
  222. p_spi_instance->bytes_count++;
  223. rx_byte = p_spi_instance->p_nrf_spi->RXD;
  224. if (p_spi_instance->start_flag)
  225. {
  226. p_spi_instance->start_flag = false;
  227. spi_master_signal_evt(p_spi_instance, SPI_MASTER_EVT_FIRST_BYTE_RECEIVED, (uint16_t)rx_byte);
  228. }
  229. else if (p_spi_instance->abort_flag ) //this is tricky, but callback for SPI_MASTER_EVT_FIRST_BYTE_RECEIVED will set this flag for a first byte, which is bad because there is still byte in a buffer
  230. { //and for a single byte transaction you will get XFERDONE event to restart
  231. p_spi_instance->abort_flag = false;
  232. p_spi_instance->state = SPI_MASTER_STATE_ABORTED;
  233. nrf_gpio_pin_set(p_spi_instance->pin_slave_select);
  234. spi_master_signal_evt(p_spi_instance, SPI_MASTER_EVT_TRANSFER_ABORTED, 0);
  235. return;
  236. }
  237. if ((p_spi_instance->p_rx_buffer != NULL) &&
  238. (p_spi_instance->rx_index < p_spi_instance->rx_length))
  239. {
  240. p_spi_instance->p_rx_buffer[p_spi_instance->rx_index++] = rx_byte;
  241. }
  242. if ((p_spi_instance->tx_index < p_spi_instance->max_length) && (!(p_spi_instance->abort_flag))) //do not TX if you know that there is an abort to be done - this should work for a DOUBLE BUFFERING ???
  243. {
  244. p_spi_instance->p_nrf_spi->TXD = ((p_spi_instance->p_tx_buffer != NULL) &&
  245. (p_spi_instance->tx_index < p_spi_instance->tx_length)) ?
  246. p_spi_instance->p_tx_buffer[p_spi_instance->tx_index] :
  247. SPI_DEFAULT_TX_BYTE;
  248. (p_spi_instance->tx_index)++;
  249. }
  250. if (p_spi_instance->bytes_count >= p_spi_instance->max_length)
  251. {
  252. APP_ERROR_CHECK_BOOL(p_spi_instance->bytes_count == p_spi_instance->max_length);
  253. nrf_gpio_pin_set(p_spi_instance->pin_slave_select);
  254. p_spi_instance->state = SPI_MASTER_STATE_IDLE;
  255. spi_master_signal_evt(p_spi_instance,
  256. SPI_MASTER_EVT_TRANSFER_COMPLETED,
  257. p_spi_instance->tx_index);
  258. }
  259. return;
  260. }
  261. #endif //defined(SPI_MASTER_0_ENABLE) || defined(SPI_MASTER_1_ENABLE)
  262. /**
  263. * @brief Function for opening and initializing a SPI master driver. */
  264. uint32_t spi_master_open(const spi_master_hw_instance_t spi_master_hw_instance,
  265. spi_master_config_t const * const p_spi_master_config)
  266. {
  267. #if defined(SPI_MASTER_0_ENABLE) || defined(SPI_MASTER_1_ENABLE)
  268. VERIFY_PARAM_NOT_NULL(p_spi_master_config);
  269. spi_master_instance_t * p_spi_instance = spi_master_get_instance(spi_master_hw_instance);
  270. switch (spi_master_hw_instance)
  271. {
  272. #ifdef SPI_MASTER_0_ENABLE
  273. case SPI_MASTER_0:
  274. spi_master_init_hw_instance(NRF_SPI0, SPI0_TWI0_IRQn, p_spi_instance);
  275. break;
  276. #endif //SPI_MASTER_0_ENABLE
  277. #ifdef SPI_MASTER_1_ENABLE
  278. case SPI_MASTER_1:
  279. spi_master_init_hw_instance(NRF_SPI1, SPI1_TWI1_IRQn, p_spi_instance);
  280. break;
  281. #endif //SPI_MASTER_1_ENABLE
  282. default:
  283. break;
  284. }
  285. //A Slave select must be set as high before setting it as output,
  286. //because during connect it to the pin it causes glitches.
  287. nrf_gpio_pin_set(p_spi_master_config->SPI_Pin_SS);
  288. nrf_gpio_cfg_output(p_spi_master_config->SPI_Pin_SS);
  289. nrf_gpio_pin_set(p_spi_master_config->SPI_Pin_SS);
  290. //Configure GPIO
  291. nrf_gpio_cfg_output(p_spi_master_config->SPI_Pin_SCK);
  292. nrf_gpio_cfg_output(p_spi_master_config->SPI_Pin_MOSI);
  293. nrf_gpio_cfg_input(p_spi_master_config->SPI_Pin_MISO, NRF_GPIO_PIN_NOPULL);
  294. p_spi_instance->pin_slave_select = p_spi_master_config->SPI_Pin_SS;
  295. /* Configure SPI hardware */
  296. p_spi_instance->p_nrf_spi->PSELSCK = p_spi_master_config->SPI_Pin_SCK;
  297. p_spi_instance->p_nrf_spi->PSELMOSI = p_spi_master_config->SPI_Pin_MOSI;
  298. p_spi_instance->p_nrf_spi->PSELMISO = p_spi_master_config->SPI_Pin_MISO;
  299. p_spi_instance->p_nrf_spi->FREQUENCY = p_spi_master_config->SPI_Freq;
  300. p_spi_instance->p_nrf_spi->CONFIG =
  301. (uint32_t)(p_spi_master_config->SPI_CPHA << SPI_CONFIG_CPHA_Pos) |
  302. (p_spi_master_config->SPI_CPOL << SPI_CONFIG_CPOL_Pos) |
  303. (p_spi_master_config->SPI_ORDER << SPI_CONFIG_ORDER_Pos);
  304. /* Clear waiting interrupts and events */
  305. p_spi_instance->p_nrf_spi->EVENTS_READY = 0;
  306. NVIC_ClearPendingIRQ(p_spi_instance->irq_type);
  307. NVIC_SetPriority(p_spi_instance->irq_type, APP_IRQ_PRIORITY_MID);
  308. /* Clear event handler */
  309. p_spi_instance->callback_event_handler = NULL;
  310. /* Enable interrupt */
  311. p_spi_instance->p_nrf_spi->INTENSET = (SPI_INTENSET_READY_Set << SPI_INTENCLR_READY_Pos);
  312. NVIC_EnableIRQ(p_spi_instance->irq_type);
  313. /* Enable SPI hardware */
  314. p_spi_instance->p_nrf_spi->ENABLE = (SPI_ENABLE_ENABLE_Enabled << SPI_ENABLE_ENABLE_Pos);
  315. /* Change state to IDLE */
  316. p_spi_instance->state = SPI_MASTER_STATE_IDLE;
  317. return NRF_SUCCESS;
  318. #else
  319. return NRF_ERROR_NOT_SUPPORTED;
  320. #endif
  321. }
  322. /**
  323. * @brief Function for closing a SPI master driver.
  324. */
  325. void spi_master_close(const spi_master_hw_instance_t spi_master_hw_instance)
  326. {
  327. #if defined(SPI_MASTER_0_ENABLE) || defined(SPI_MASTER_1_ENABLE)
  328. spi_master_instance_t * p_spi_instance = spi_master_get_instance(spi_master_hw_instance);
  329. /* Disable interrupt */
  330. NVIC_ClearPendingIRQ(p_spi_instance->irq_type);
  331. NVIC_DisableIRQ(p_spi_instance->irq_type);
  332. p_spi_instance->p_nrf_spi->ENABLE = (SPI_ENABLE_ENABLE_Disabled << SPI_ENABLE_ENABLE_Pos);
  333. /* Set Slave Select pin as input with pull-up. */
  334. nrf_gpio_pin_set(p_spi_instance->pin_slave_select);
  335. nrf_gpio_cfg_input(p_spi_instance->pin_slave_select, NRF_GPIO_PIN_PULLUP);
  336. p_spi_instance->pin_slave_select = (uint8_t)0xFF;
  337. /* Disconnect pins from SPI hardware */
  338. p_spi_instance->p_nrf_spi->PSELSCK = (uint32_t)SPI_PIN_DISCONNECTED;
  339. p_spi_instance->p_nrf_spi->PSELMOSI = (uint32_t)SPI_PIN_DISCONNECTED;
  340. p_spi_instance->p_nrf_spi->PSELMISO = (uint32_t)SPI_PIN_DISCONNECTED;
  341. /* Reset to default values */
  342. spi_master_init_hw_instance(NULL, (IRQn_Type)0, p_spi_instance);
  343. #else
  344. return;
  345. #endif
  346. }
  347. /**
  348. * @brief Function for getting current state of the SPI master driver.
  349. */
  350. __INLINE spi_master_state_t spi_master_get_state(
  351. const spi_master_hw_instance_t spi_master_hw_instance)
  352. {
  353. #if defined(SPI_MASTER_0_ENABLE) || defined(SPI_MASTER_1_ENABLE)
  354. spi_master_instance_t * spi_instance = spi_master_get_instance(spi_master_hw_instance);
  355. return spi_instance->state;
  356. #else
  357. return SPI_MASTER_STATE_DISABLED;
  358. #endif
  359. }
  360. /**
  361. * @brief Function for event handler registration.
  362. */
  363. __INLINE void spi_master_evt_handler_reg(const spi_master_hw_instance_t spi_master_hw_instance,
  364. spi_master_event_handler_t event_handler)
  365. {
  366. #if defined(SPI_MASTER_0_ENABLE) || defined(SPI_MASTER_1_ENABLE)
  367. spi_master_instance_t * spi_instance = spi_master_get_instance(spi_master_hw_instance);
  368. spi_instance->callback_event_handler = event_handler;
  369. #else
  370. return;
  371. #endif
  372. }
  373. /**
  374. * @brief Function for transmitting data between SPI master and SPI slave.
  375. */
  376. uint32_t spi_master_send_recv(const spi_master_hw_instance_t spi_master_hw_instance,
  377. uint8_t * const p_tx_buf, const uint16_t tx_buf_len,
  378. uint8_t * const p_rx_buf, const uint16_t rx_buf_len)
  379. {
  380. #if defined(SPI_MASTER_0_ENABLE) || defined(SPI_MASTER_1_ENABLE)
  381. spi_master_instance_t * p_spi_instance = spi_master_get_instance(spi_master_hw_instance);
  382. uint32_t err_code = NRF_SUCCESS;
  383. uint16_t max_length = 0;
  384. if (p_spi_instance->state == SPI_MASTER_STATE_IDLE)
  385. {
  386. NVIC_DisableIRQ(p_spi_instance->irq_type);
  387. max_length = (rx_buf_len > tx_buf_len) ? rx_buf_len : tx_buf_len;
  388. if (max_length > 0)
  389. {
  390. p_spi_instance->state = SPI_MASTER_STATE_BUSY;
  391. p_spi_instance->start_flag = true; //abort_flag should set by abort and cleared only by restart
  392. p_spi_instance->bytes_count = 0;
  393. p_spi_instance->max_length = max_length;
  394. spi_master_buffer_release(&(p_spi_instance->p_tx_buffer), &(p_spi_instance->tx_length));
  395. spi_master_buffer_release(&(p_spi_instance->p_rx_buffer), &(p_spi_instance->rx_length));
  396. /* Initialize buffers */
  397. spi_master_buffer_init(p_tx_buf, tx_buf_len, &(p_spi_instance->p_tx_buffer),
  398. &(p_spi_instance->tx_length), &(p_spi_instance->tx_index));
  399. spi_master_buffer_init(p_rx_buf, rx_buf_len, &(p_spi_instance->p_rx_buffer),
  400. &(p_spi_instance->rx_length), &(p_spi_instance->rx_index));
  401. nrf_gpio_pin_clear(p_spi_instance->pin_slave_select);
  402. spi_master_send_initial_bytes(p_spi_instance);
  403. spi_master_signal_evt(p_spi_instance, SPI_MASTER_EVT_TRANSFER_STARTED, max_length);
  404. }
  405. else
  406. {
  407. err_code = NRF_ERROR_INVALID_PARAM;
  408. }
  409. NVIC_EnableIRQ(p_spi_instance->irq_type);
  410. }
  411. else
  412. {
  413. err_code = NRF_ERROR_BUSY;
  414. }
  415. return err_code;
  416. #else
  417. return NRF_ERROR_NOT_SUPPORTED;
  418. #endif
  419. }
  420. #ifdef _SPI_5W_
  421. /**
  422. * @brief Function for aborting transfer
  423. */
  424. uint32_t spi_master_abort(const spi_master_hw_instance_t spi_master_hw_instance)
  425. {
  426. spi_master_instance_t * p_spi_instance = spi_master_get_instance(spi_master_hw_instance);
  427. NVIC_DisableIRQ(p_spi_instance->irq_type);
  428. if (p_spi_instance->state == SPI_MASTER_STATE_BUSY)
  429. {
  430. //set_flag - but only when there are events pending
  431. //ignore when in IDLE - must be able to restart a completed transfer
  432. p_spi_instance->abort_flag = true;
  433. }
  434. NVIC_EnableIRQ(p_spi_instance->irq_type);
  435. return NRF_SUCCESS;
  436. }
  437. /**
  438. * @brief Function for restarting transfer
  439. */
  440. uint32_t spi_master_restart(const spi_master_hw_instance_t spi_master_hw_instance)
  441. {
  442. spi_master_instance_t * p_spi_instance = spi_master_get_instance(spi_master_hw_instance);
  443. NVIC_DisableIRQ(p_spi_instance->irq_type);
  444. spi_master_signal_evt(p_spi_instance, SPI_MASTER_EVT_TRANSFER_RESTARTED, 0);
  445. p_spi_instance->state = SPI_MASTER_STATE_BUSY;
  446. p_spi_instance->bytes_count = 0;
  447. p_spi_instance->tx_index = 0;
  448. p_spi_instance->rx_index = 0;
  449. p_spi_instance->start_flag = true;
  450. p_spi_instance->abort_flag = false; //you should force clearing abort flag - no other way for 1 byte transfer
  451. nrf_gpio_pin_clear(p_spi_instance->pin_slave_select);
  452. spi_master_send_initial_bytes(p_spi_instance);
  453. NVIC_EnableIRQ(p_spi_instance->irq_type);
  454. return NRF_SUCCESS;
  455. }
  456. static void spi_5W_master_event_handler(spi_master_evt_t evt)
  457. {
  458. switch (m_hook_state)
  459. {
  460. case HOOK_STATE_IDLE:
  461. if (evt.type == SPI_MASTER_EVT_TRANSFER_STARTED)
  462. {
  463. DEBUG_EVT_SPI_MASTER_RAW_XFER_GUARDED(0);
  464. m_hook_state = HOOK_STATE_GUARDED;
  465. m_ser_phy_event_handler(evt);
  466. }
  467. break;
  468. case HOOK_STATE_GUARDED:
  469. if (evt.type == SPI_MASTER_EVT_FIRST_BYTE_RECEIVED)
  470. {
  471. if (evt.data == 0)
  472. {
  473. DEBUG_EVT_SPI_MASTER_RAW_XFER_PASSED(0);
  474. m_hook_state = HOOK_STATE_PASSING;
  475. }
  476. else
  477. {
  478. DEBUG_EVT_SPI_MASTER_RAW_XFER_ABORTED(0);
  479. m_hook_state = HOOK_STATE_ABORTED;
  480. (void)spi_master_abort(m_spi_master_hw_instance);
  481. }
  482. }
  483. break;
  484. case HOOK_STATE_ABORTED:
  485. if ((evt.type == SPI_MASTER_EVT_TRANSFER_ABORTED) ||
  486. (evt.type == SPI_MASTER_EVT_TRANSFER_COMPLETED))
  487. {
  488. DEBUG_EVT_SPI_MASTER_RAW_XFER_RESTARTED(0);
  489. m_hook_state = HOOK_STATE_RESTARTED;
  490. (void)spi_master_restart(m_spi_master_hw_instance);
  491. }
  492. break;
  493. case HOOK_STATE_RESTARTED:
  494. if (evt.type == SPI_MASTER_EVT_TRANSFER_RESTARTED)
  495. {
  496. DEBUG_EVT_SPI_MASTER_RAW_XFER_GUARDED(0);
  497. m_hook_state = HOOK_STATE_GUARDED;
  498. }
  499. break;
  500. case HOOK_STATE_PASSING:
  501. if (evt.type == SPI_MASTER_EVT_TRANSFER_COMPLETED)
  502. {
  503. m_hook_state = HOOK_STATE_IDLE;
  504. m_ser_phy_event_handler(evt); //this is the only way to get a signal from complete transaction
  505. }
  506. break;
  507. default:
  508. break;
  509. }
  510. }
  511. void spi_5W_master_evt_handler_reg(const spi_master_hw_instance_t spi_master_hw_instance,
  512. spi_master_event_handler_t event_handler)
  513. {
  514. m_ser_phy_event_handler = event_handler;
  515. m_spi_master_hw_instance = spi_master_hw_instance;
  516. m_hook_state = HOOK_STATE_IDLE;
  517. spi_master_evt_handler_reg(spi_master_hw_instance, spi_5W_master_event_handler);
  518. return;
  519. }
  520. #endif
  521. /** @} */