nrf_spim.h 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520
  1. /* Copyright (c) 2015 Nordic Semiconductor. All Rights Reserved.
  2. *
  3. * The information contained herein is property of Nordic Semiconductor ASA.
  4. * Terms and conditions of usage are described in detail in NORDIC
  5. * SEMICONDUCTOR STANDARD SOFTWARE LICENSE AGREEMENT.
  6. *
  7. * Licensees are granted free, non-transferable use of the information. NO
  8. * WARRANTY of ANY KIND is provided. This heading must NOT be removed from
  9. * the file.
  10. *
  11. */
  12. /**
  13. * @defgroup nrf_spim_hal SPIM HAL
  14. * @{
  15. * @ingroup nrf_spi_master
  16. *
  17. * @brief Hardware access layer for accessing the SPIM peripheral.
  18. */
  19. #ifndef NRF_SPIM_H__
  20. #define NRF_SPIM_H__
  21. #include <stddef.h>
  22. #include <stdbool.h>
  23. #include <stdint.h>
  24. #include "nrf.h"
  25. /**
  26. * @brief This value can be used as a parameter for the @ref nrf_spim_pins_set
  27. * function to specify that a given SPI signal (SCK, MOSI, or MISO)
  28. * shall not be connected to a physical pin.
  29. */
  30. #define NRF_SPIM_PIN_NOT_CONNECTED 0xFFFFFFFF
  31. /**
  32. * @brief SPIM tasks.
  33. */
  34. typedef enum
  35. {
  36. /*lint -save -e30*/
  37. NRF_SPIM_TASK_START = offsetof(NRF_SPIM_Type, TASKS_START), ///< Start SPI transaction.
  38. NRF_SPIM_TASK_STOP = offsetof(NRF_SPIM_Type, TASKS_STOP), ///< Stop SPI transaction.
  39. NRF_SPIM_TASK_SUSPEND = offsetof(NRF_SPIM_Type, TASKS_SUSPEND), ///< Suspend SPI transaction.
  40. NRF_SPIM_TASK_RESUME = offsetof(NRF_SPIM_Type, TASKS_RESUME) ///< Resume SPI transaction.
  41. /*lint -restore*/
  42. } nrf_spim_task_t;
  43. /**
  44. * @brief SPIM events.
  45. */
  46. typedef enum
  47. {
  48. /*lint -save -e30*/
  49. NRF_SPIM_EVENT_STOPPED = offsetof(NRF_SPIM_Type, EVENTS_STOPPED), ///< SPI transaction has stopped.
  50. NRF_SPIM_EVENT_ENDRX = offsetof(NRF_SPIM_Type, EVENTS_ENDRX), ///< End of RXD buffer reached.
  51. #ifdef NRF52
  52. NRF_SPIM_EVENT_END = offsetof(NRF_SPIM_Type, EVENTS_END), ///< End of RXD buffer and TXD buffer reached.
  53. #endif
  54. NRF_SPIM_EVENT_ENDTX = offsetof(NRF_SPIM_Type, EVENTS_ENDTX), ///< End of TXD buffer reached.
  55. NRF_SPIM_EVENT_STARTED = offsetof(NRF_SPIM_Type, EVENTS_STARTED) ///< Transaction started.
  56. /*lint -restore*/
  57. } nrf_spim_event_t;
  58. #ifdef NRF52
  59. /**
  60. * @brief SPIM shortcuts.
  61. */
  62. typedef enum
  63. {
  64. NRF_SPIM_SHORT_END_START_MASK = SPIM_SHORTS_END_START_Msk ///< Shortcut between END event and START task.
  65. } nrf_spim_short_mask_t;
  66. #endif
  67. /**
  68. * @brief SPIM interrupts.
  69. */
  70. typedef enum
  71. {
  72. NRF_SPIM_INT_STOPPED_MASK = SPIM_INTENSET_STOPPED_Msk, ///< Interrupt on STOPPED event.
  73. NRF_SPIM_INT_ENDRX_MASK = SPIM_INTENSET_ENDRX_Msk, ///< Interrupt on ENDRX event.
  74. #ifdef NRF52
  75. NRF_SPIM_INT_END_MASK = SPIM_INTENSET_END_Msk, ///< Interrupt on END event.
  76. #endif
  77. NRF_SPIM_INT_ENDTX_MASK = SPIM_INTENSET_ENDTX_Msk, ///< Interrupt on ENDTX event.
  78. NRF_SPIM_INT_STARTED_MASK = SPIM_INTENSET_STARTED_Msk ///< Interrupt on STARTED event.
  79. } nrf_spim_int_mask_t;
  80. /**
  81. * @brief SPI master data rates.
  82. */
  83. typedef enum
  84. {
  85. NRF_SPIM_FREQ_125K = SPIM_FREQUENCY_FREQUENCY_K125, ///< 125 kbps.
  86. NRF_SPIM_FREQ_250K = SPIM_FREQUENCY_FREQUENCY_K250, ///< 250 kbps.
  87. NRF_SPIM_FREQ_500K = SPIM_FREQUENCY_FREQUENCY_K500, ///< 500 kbps.
  88. NRF_SPIM_FREQ_1M = SPIM_FREQUENCY_FREQUENCY_M1, ///< 1 Mbps.
  89. NRF_SPIM_FREQ_2M = SPIM_FREQUENCY_FREQUENCY_M2, ///< 2 Mbps.
  90. NRF_SPIM_FREQ_4M = SPIM_FREQUENCY_FREQUENCY_M4, ///< 4 Mbps.
  91. // [conversion to 'int' needed to prevent compilers from complaining
  92. // that the provided value (0x80000000UL) is out of range of "int"]
  93. NRF_SPIM_FREQ_8M = (int)SPIM_FREQUENCY_FREQUENCY_M8 ///< 8 Mbps.
  94. } nrf_spim_frequency_t;
  95. /**
  96. * @brief SPI modes.
  97. */
  98. typedef enum
  99. {
  100. NRF_SPIM_MODE_0, ///< SCK active high, sample on leading edge of clock.
  101. NRF_SPIM_MODE_1, ///< SCK active high, sample on trailing edge of clock.
  102. NRF_SPIM_MODE_2, ///< SCK active low, sample on leading edge of clock.
  103. NRF_SPIM_MODE_3 ///< SCK active low, sample on trailing edge of clock.
  104. } nrf_spim_mode_t;
  105. /**
  106. * @brief SPI bit orders.
  107. */
  108. typedef enum
  109. {
  110. NRF_SPIM_BIT_ORDER_MSB_FIRST = SPIM_CONFIG_ORDER_MsbFirst, ///< Most significant bit shifted out first.
  111. NRF_SPIM_BIT_ORDER_LSB_FIRST = SPIM_CONFIG_ORDER_LsbFirst ///< Least significant bit shifted out first.
  112. } nrf_spim_bit_order_t;
  113. /**
  114. * @brief Function for activating a specific SPIM task.
  115. *
  116. * @param[in] p_spim SPIM instance.
  117. * @param[in] spim_task Task to activate.
  118. */
  119. __STATIC_INLINE void nrf_spim_task_trigger(NRF_SPIM_Type * p_spim,
  120. nrf_spim_task_t spim_task);
  121. /**
  122. * @brief Function for getting the address of a specific SPIM task register.
  123. *
  124. * @param[in] p_spim SPIM instance.
  125. * @param[in] spim_task Requested task.
  126. *
  127. * @return Address of the specified task register.
  128. */
  129. __STATIC_INLINE uint32_t nrf_spim_task_address_get(NRF_SPIM_Type * p_spim,
  130. nrf_spim_task_t spim_task);
  131. /**
  132. * @brief Function for clearing a specific SPIM event.
  133. *
  134. * @param[in] p_spim SPIM instance.
  135. * @param[in] spim_event Event to clear.
  136. */
  137. __STATIC_INLINE void nrf_spim_event_clear(NRF_SPIM_Type * p_spim,
  138. nrf_spim_event_t spim_event);
  139. /**
  140. * @brief Function for checking the state of a specific SPIM event.
  141. *
  142. * @param[in] p_spim SPIM instance.
  143. * @param[in] spim_event Event to check.
  144. *
  145. * @retval true If the event is set.
  146. * @retval false If the event is not set.
  147. */
  148. __STATIC_INLINE bool nrf_spim_event_check(NRF_SPIM_Type * p_spim,
  149. nrf_spim_event_t spim_event);
  150. /**
  151. * @brief Function for getting the address of a specific SPIM event register.
  152. *
  153. * @param[in] p_spim SPIM instance.
  154. * @param[in] spim_event Requested event.
  155. *
  156. * @return Address of the specified event register.
  157. */
  158. __STATIC_INLINE uint32_t nrf_spim_event_address_get(NRF_SPIM_Type * p_spim,
  159. nrf_spim_event_t spim_event);
  160. #ifdef NRF52
  161. /**
  162. * @brief Function for enabling specified shortcuts.
  163. *
  164. * @param[in] p_spim SPIM instance.
  165. * @param[in] spim_shorts_mask Shortcuts to enable.
  166. */
  167. __STATIC_INLINE void nrf_spim_shorts_enable(NRF_SPIM_Type * p_spim,
  168. uint32_t spim_shorts_mask);
  169. /**
  170. * @brief Function for disabling specified shortcuts.
  171. *
  172. * @param[in] p_spim SPIM instance.
  173. * @param[in] spim_shorts_mask Shortcuts to disable.
  174. */
  175. __STATIC_INLINE void nrf_spim_shorts_disable(NRF_SPIM_Type * p_spim,
  176. uint32_t spim_shorts_mask);
  177. /**
  178. * @brief Function for getting shorts setting.
  179. *
  180. * @param[in] p_spim SPIM instance.
  181. */
  182. __STATIC_INLINE uint32_t nrf_spim_shorts_get(NRF_SPIM_Type * p_spim);
  183. #endif
  184. /**
  185. * @brief Function for enabling specified interrupts.
  186. *
  187. * @param[in] p_spim SPIM instance.
  188. * @param[in] spim_int_mask Interrupts to enable.
  189. */
  190. __STATIC_INLINE void nrf_spim_int_enable(NRF_SPIM_Type * p_spim,
  191. uint32_t spim_int_mask);
  192. /**
  193. * @brief Function for disabling specified interrupts.
  194. *
  195. * @param[in] p_spim SPIM instance.
  196. * @param[in] spim_int_mask Interrupts to disable.
  197. */
  198. __STATIC_INLINE void nrf_spim_int_disable(NRF_SPIM_Type * p_spim,
  199. uint32_t spim_int_mask);
  200. /**
  201. * @brief Function for retrieving the state of a given interrupt.
  202. *
  203. * @param[in] p_spim SPIM instance.
  204. * @param[in] spim_int Interrupt to check.
  205. *
  206. * @retval true If the interrupt is enabled.
  207. * @retval false If the interrupt is not enabled.
  208. */
  209. __STATIC_INLINE bool nrf_spim_int_enable_check(NRF_SPIM_Type * p_spim,
  210. nrf_spim_int_mask_t spim_int);
  211. /**
  212. * @brief Function for enabling the SPIM peripheral.
  213. *
  214. * @param[in] p_spim SPIM instance.
  215. */
  216. __STATIC_INLINE void nrf_spim_enable(NRF_SPIM_Type * p_spim);
  217. /**
  218. * @brief Function for disabling the SPIM peripheral.
  219. *
  220. * @param[in] p_spim SPIM instance.
  221. */
  222. __STATIC_INLINE void nrf_spim_disable(NRF_SPIM_Type * p_spim);
  223. /**
  224. * @brief Function for configuring SPIM pins.
  225. *
  226. * If a given signal is not needed, pass the @ref NRF_SPIM_PIN_NOT_CONNECTED
  227. * value instead of its pin number.
  228. *
  229. * @param[in] p_spim SPIM instance.
  230. * @param[in] sck_pin SCK pin number.
  231. * @param[in] mosi_pin MOSI pin number.
  232. * @param[in] miso_pin MISO pin number.
  233. */
  234. __STATIC_INLINE void nrf_spim_pins_set(NRF_SPIM_Type * p_spim,
  235. uint32_t sck_pin,
  236. uint32_t mosi_pin,
  237. uint32_t miso_pin);
  238. /**
  239. * @brief Function for setting the SPI master data rate.
  240. *
  241. * @param[in] p_spim SPIM instance.
  242. * @param[in] frequency SPI frequency.
  243. */
  244. __STATIC_INLINE void nrf_spim_frequency_set(NRF_SPIM_Type * p_spim,
  245. nrf_spim_frequency_t frequency);
  246. /**
  247. * @brief Function for setting the transmit buffer.
  248. *
  249. * @param[in] p_spim SPIM instance.
  250. * @param[in] p_buffer Pointer to the buffer with data to send.
  251. * @param[in] length Maximum number of data bytes to transmit.
  252. */
  253. __STATIC_INLINE void nrf_spim_tx_buffer_set(NRF_SPIM_Type * p_spim,
  254. uint8_t const * p_buffer,
  255. uint8_t length);
  256. /**
  257. * @brief Function for setting the receive buffer.
  258. *
  259. * @param[in] p_spim SPIM instance.
  260. * @param[in] p_buffer Pointer to the buffer for received data.
  261. * @param[in] length Maximum number of data bytes to receive.
  262. */
  263. __STATIC_INLINE void nrf_spim_rx_buffer_set(NRF_SPIM_Type * p_spim,
  264. uint8_t * p_buffer,
  265. uint8_t length);
  266. /**
  267. * @brief Function for setting the SPI configuration.
  268. *
  269. * @param[in] p_spim SPIM instance.
  270. * @param[in] spi_mode SPI mode.
  271. * @param[in] spi_bit_order SPI bit order.
  272. */
  273. __STATIC_INLINE void nrf_spim_configure(NRF_SPIM_Type * p_spim,
  274. nrf_spim_mode_t spi_mode,
  275. nrf_spim_bit_order_t spi_bit_order);
  276. /**
  277. * @brief Function for setting the over-read character.
  278. *
  279. * @param[in] p_spim SPIM instance.
  280. * @param[in] orc Over-read character that is clocked out in case of
  281. * an over-read of the TXD buffer.
  282. */
  283. __STATIC_INLINE void nrf_spim_orc_set(NRF_SPIM_Type * p_spim,
  284. uint8_t orc);
  285. #ifdef NRF52
  286. /**
  287. * @brief Function for enabling the TX list feature.
  288. *
  289. * @param[in] p_spim SPIM instance.
  290. */
  291. __STATIC_INLINE void nrf_spim_tx_list_enable(NRF_SPIM_Type * p_spim);
  292. /**
  293. * @brief Function for disabling the TX list feature.
  294. *
  295. * @param[in] p_spim SPIM instance.
  296. */
  297. __STATIC_INLINE void nrf_spim_tx_list_disable(NRF_SPIM_Type * p_spim);
  298. /**
  299. * @brief Function for enabling the RX list feature.
  300. *
  301. * @param[in] p_spim SPIM instance.
  302. */
  303. __STATIC_INLINE void nrf_spim_rx_list_enable(NRF_SPIM_Type * p_spim);
  304. /**
  305. * @brief Function for disabling the RX list feature.
  306. *
  307. * @param[in] p_spim SPIM instance.
  308. */
  309. __STATIC_INLINE void nrf_spim_rx_list_disable(NRF_SPIM_Type * p_spim);
  310. #endif
  311. #ifndef SUPPRESS_INLINE_IMPLEMENTATION
  312. __STATIC_INLINE void nrf_spim_task_trigger(NRF_SPIM_Type * p_spim,
  313. nrf_spim_task_t spim_task)
  314. {
  315. *((volatile uint32_t *)((uint8_t *)p_spim + (uint32_t)spim_task)) = 0x1UL;
  316. }
  317. __STATIC_INLINE uint32_t nrf_spim_task_address_get(NRF_SPIM_Type * p_spim,
  318. nrf_spim_task_t spim_task)
  319. {
  320. return (uint32_t)((uint8_t *)p_spim + (uint32_t)spim_task);
  321. }
  322. __STATIC_INLINE void nrf_spim_event_clear(NRF_SPIM_Type * p_spim,
  323. nrf_spim_event_t spim_event)
  324. {
  325. *((volatile uint32_t *)((uint8_t *)p_spim + (uint32_t)spim_event)) = 0x0UL;
  326. }
  327. __STATIC_INLINE bool nrf_spim_event_check(NRF_SPIM_Type * p_spim,
  328. nrf_spim_event_t spim_event)
  329. {
  330. return (bool)*(volatile uint32_t *)((uint8_t *)p_spim + (uint32_t)spim_event);
  331. }
  332. __STATIC_INLINE uint32_t nrf_spim_event_address_get(NRF_SPIM_Type * p_spim,
  333. nrf_spim_event_t spim_event)
  334. {
  335. return (uint32_t)((uint8_t *)p_spim + (uint32_t)spim_event);
  336. }
  337. #ifdef NRF52
  338. __STATIC_INLINE void nrf_spim_shorts_enable(NRF_SPIM_Type * p_spim,
  339. uint32_t spim_shorts_mask)
  340. {
  341. p_spim->SHORTS |= spim_shorts_mask;
  342. }
  343. __STATIC_INLINE void nrf_spim_shorts_disable(NRF_SPIM_Type * p_spim,
  344. uint32_t spim_shorts_mask)
  345. {
  346. p_spim->SHORTS &= ~(spim_shorts_mask);
  347. }
  348. __STATIC_INLINE uint32_t nrf_spim_shorts_get(NRF_SPIM_Type * p_spim)
  349. {
  350. return p_spim->SHORTS;
  351. }
  352. #endif
  353. __STATIC_INLINE void nrf_spim_int_enable(NRF_SPIM_Type * p_spim,
  354. uint32_t spim_int_mask)
  355. {
  356. p_spim->INTENSET = spim_int_mask;
  357. }
  358. __STATIC_INLINE void nrf_spim_int_disable(NRF_SPIM_Type * p_spim,
  359. uint32_t spim_int_mask)
  360. {
  361. p_spim->INTENCLR = spim_int_mask;
  362. }
  363. __STATIC_INLINE bool nrf_spim_int_enable_check(NRF_SPIM_Type * p_spim,
  364. nrf_spim_int_mask_t spim_int)
  365. {
  366. return (bool)(p_spim->INTENSET & spim_int);
  367. }
  368. __STATIC_INLINE void nrf_spim_enable(NRF_SPIM_Type * p_spim)
  369. {
  370. p_spim->ENABLE = (SPIM_ENABLE_ENABLE_Enabled << SPIM_ENABLE_ENABLE_Pos);
  371. }
  372. __STATIC_INLINE void nrf_spim_disable(NRF_SPIM_Type * p_spim)
  373. {
  374. p_spim->ENABLE = (SPIM_ENABLE_ENABLE_Disabled << SPIM_ENABLE_ENABLE_Pos);
  375. }
  376. __STATIC_INLINE void nrf_spim_pins_set(NRF_SPIM_Type * p_spim,
  377. uint32_t sck_pin,
  378. uint32_t mosi_pin,
  379. uint32_t miso_pin)
  380. {
  381. p_spim->PSEL.SCK = sck_pin;
  382. p_spim->PSEL.MOSI = mosi_pin;
  383. p_spim->PSEL.MISO = miso_pin;
  384. }
  385. __STATIC_INLINE void nrf_spim_frequency_set(NRF_SPIM_Type * p_spim,
  386. nrf_spim_frequency_t frequency)
  387. {
  388. p_spim->FREQUENCY = frequency;
  389. }
  390. __STATIC_INLINE void nrf_spim_tx_buffer_set(NRF_SPIM_Type * p_spim,
  391. uint8_t const * p_buffer,
  392. uint8_t length)
  393. {
  394. p_spim->TXD.PTR = (uint32_t)p_buffer;
  395. p_spim->TXD.MAXCNT = length;
  396. }
  397. __STATIC_INLINE void nrf_spim_rx_buffer_set(NRF_SPIM_Type * p_spim,
  398. uint8_t * p_buffer,
  399. uint8_t length)
  400. {
  401. p_spim->RXD.PTR = (uint32_t)p_buffer;
  402. p_spim->RXD.MAXCNT = length;
  403. }
  404. __STATIC_INLINE void nrf_spim_configure(NRF_SPIM_Type * p_spim,
  405. nrf_spim_mode_t spi_mode,
  406. nrf_spim_bit_order_t spi_bit_order)
  407. {
  408. uint32_t config = (spi_bit_order == NRF_SPIM_BIT_ORDER_MSB_FIRST ?
  409. SPIM_CONFIG_ORDER_MsbFirst : SPIM_CONFIG_ORDER_LsbFirst);
  410. switch (spi_mode)
  411. {
  412. default:
  413. case NRF_SPIM_MODE_0:
  414. config |= (SPIM_CONFIG_CPOL_ActiveHigh << SPIM_CONFIG_CPOL_Pos) |
  415. (SPIM_CONFIG_CPHA_Leading << SPIM_CONFIG_CPHA_Pos);
  416. break;
  417. case NRF_SPIM_MODE_1:
  418. config |= (SPIM_CONFIG_CPOL_ActiveHigh << SPIM_CONFIG_CPOL_Pos) |
  419. (SPIM_CONFIG_CPHA_Trailing << SPIM_CONFIG_CPHA_Pos);
  420. break;
  421. case NRF_SPIM_MODE_2:
  422. config |= (SPIM_CONFIG_CPOL_ActiveLow << SPIM_CONFIG_CPOL_Pos) |
  423. (SPIM_CONFIG_CPHA_Leading << SPIM_CONFIG_CPHA_Pos);
  424. break;
  425. case NRF_SPIM_MODE_3:
  426. config |= (SPIM_CONFIG_CPOL_ActiveLow << SPIM_CONFIG_CPOL_Pos) |
  427. (SPIM_CONFIG_CPHA_Trailing << SPIM_CONFIG_CPHA_Pos);
  428. break;
  429. }
  430. p_spim->CONFIG = config;
  431. }
  432. __STATIC_INLINE void nrf_spim_orc_set(NRF_SPIM_Type * p_spim,
  433. uint8_t orc)
  434. {
  435. p_spim->ORC = orc;
  436. }
  437. #ifdef NRF52
  438. __STATIC_INLINE void nrf_spim_tx_list_enable(NRF_SPIM_Type * p_spim)
  439. {
  440. p_spim->TXD.LIST = 1;
  441. }
  442. __STATIC_INLINE void nrf_spim_tx_list_disable(NRF_SPIM_Type * p_spim)
  443. {
  444. p_spim->TXD.LIST = 0;
  445. }
  446. __STATIC_INLINE void nrf_spim_rx_list_enable(NRF_SPIM_Type * p_spim)
  447. {
  448. p_spim->RXD.LIST = 1;
  449. }
  450. __STATIC_INLINE void nrf_spim_rx_list_disable(NRF_SPIM_Type * p_spim)
  451. {
  452. p_spim->RXD.LIST = 0;
  453. }
  454. #endif
  455. #endif // SUPPRESS_INLINE_IMPLEMENTATION
  456. #endif // NRF_SPIM_H__
  457. /** @} */