nrfx_twis.h 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403
  1. /**
  2. * Copyright (c) 2015 - 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. #ifndef NRFX_TWIS_H__
  41. #define NRFX_TWIS_H__
  42. #include <nrfx.h>
  43. #include <hal/nrf_twis.h>
  44. #include <hal/nrf_gpio.h>
  45. #ifdef __cplusplus
  46. extern "C" {
  47. #endif
  48. /**
  49. * @defgroup nrfx_twis TWIS driver
  50. * @{
  51. * @ingroup nrf_twis
  52. * @brief Two Wire Interface Slave with EasyDMA (TWIS) peripheral driver.
  53. */
  54. /** @brief TWIS driver instance data structure. */
  55. typedef struct
  56. {
  57. NRF_TWIS_Type * p_reg; ///< Pointer to a structure with TWIS registers.
  58. uint8_t drv_inst_idx; ///< Index of the driver instance. For internal use only.
  59. } nrfx_twis_t;
  60. #ifndef __NRFX_DOXYGEN__
  61. enum {
  62. #if NRFX_CHECK(NRFX_TWIS0_ENABLED)
  63. NRFX_TWIS0_INST_IDX,
  64. #endif
  65. #if NRFX_CHECK(NRFX_TWIS1_ENABLED)
  66. NRFX_TWIS1_INST_IDX,
  67. #endif
  68. #if NRFX_CHECK(NRFX_TWIS2_ENABLED)
  69. NRFX_TWIS2_INST_IDX,
  70. #endif
  71. #if NRFX_CHECK(NRFX_TWIS3_ENABLED)
  72. NRFX_TWIS3_INST_IDX,
  73. #endif
  74. NRFX_TWIS_ENABLED_COUNT
  75. };
  76. #endif
  77. /** @brief Macro for creating a TWIS driver instance. */
  78. #define NRFX_TWIS_INSTANCE(id) \
  79. { \
  80. .p_reg = NRFX_CONCAT_2(NRF_TWIS, id), \
  81. .drv_inst_idx = NRFX_CONCAT_3(NRFX_TWIS, id, _INST_IDX), \
  82. }
  83. /** @brief Event callback function event definitions. */
  84. typedef enum
  85. {
  86. NRFX_TWIS_EVT_READ_REQ, ///< Read request detected.
  87. /**< If there is no buffer prepared, buf_req flag in the even will be set.
  88. Call then @ref nrfx_twis_tx_prepare to give parameters for buffer.
  89. */
  90. NRFX_TWIS_EVT_READ_DONE, ///< Read request finished - free any data.
  91. NRFX_TWIS_EVT_READ_ERROR, ///< Read request finished with error.
  92. NRFX_TWIS_EVT_WRITE_REQ, ///< Write request detected.
  93. /**< If there is no buffer prepared, buf_req flag in the even will be set.
  94. Call then @ref nrfx_twis_rx_prepare to give parameters for buffer.
  95. */
  96. NRFX_TWIS_EVT_WRITE_DONE, ///< Write request finished - process data.
  97. NRFX_TWIS_EVT_WRITE_ERROR, ///< Write request finished with error.
  98. NRFX_TWIS_EVT_GENERAL_ERROR ///< Error that happens not inside WRITE or READ transaction.
  99. } nrfx_twis_evt_type_t;
  100. /**
  101. * @brief Possible error sources.
  102. *
  103. * This is flag enum - values from this enum can be connected using logical or operator.
  104. * @note
  105. * You can use directly @ref nrf_twis_error_t. Error type enum is redefined here because
  106. * of possible future extension (eg. supporting timeouts and synchronous mode).
  107. */
  108. typedef enum
  109. {
  110. NRFX_TWIS_ERROR_OVERFLOW = NRF_TWIS_ERROR_OVERFLOW, /**< RX buffer overflow detected, and prevented. */
  111. NRFX_TWIS_ERROR_DATA_NACK = NRF_TWIS_ERROR_DATA_NACK, /**< NACK sent after receiving a data byte. */
  112. NRFX_TWIS_ERROR_OVERREAD = NRF_TWIS_ERROR_OVERREAD, /**< TX buffer over-read detected, and prevented. */
  113. NRFX_TWIS_ERROR_UNEXPECTED_EVENT = 1 << 8 /**< Unexpected event detected by state machine. */
  114. } nrfx_twis_error_t;
  115. /** @brief TWIS driver event structure. */
  116. typedef struct
  117. {
  118. nrfx_twis_evt_type_t type; ///< Event type.
  119. union
  120. {
  121. bool buf_req; ///< Flag for @ref NRFX_TWIS_EVT_READ_REQ and @ref NRFX_TWIS_EVT_WRITE_REQ.
  122. /**< Information if transmission buffer requires to be prepared. */
  123. uint32_t tx_amount; ///< Data for @ref NRFX_TWIS_EVT_READ_DONE.
  124. uint32_t rx_amount; ///< Data for @ref NRFX_TWIS_EVT_WRITE_DONE.
  125. uint32_t error; ///< Data for @ref NRFX_TWIS_EVT_GENERAL_ERROR.
  126. } data; ///< Union to store event data.
  127. } nrfx_twis_evt_t;
  128. /**
  129. * @brief TWI slave event callback function type.
  130. *
  131. * @param[in] p_event Event information structure.
  132. */
  133. typedef void (*nrfx_twis_event_handler_t)(nrfx_twis_evt_t const * p_event);
  134. /** @brief Structure for TWIS configuration. */
  135. typedef struct
  136. {
  137. uint32_t addr[2]; //!< Set addresses that this slave should respond. Set 0 to disable.
  138. uint32_t scl; //!< SCL pin number.
  139. uint32_t sda; //!< SDA pin number.
  140. nrf_gpio_pin_pull_t scl_pull; //!< SCL pin pull.
  141. nrf_gpio_pin_pull_t sda_pull; //!< SDA pin pull.
  142. uint8_t interrupt_priority; //!< The priority of interrupt for the module to be set.
  143. } nrfx_twis_config_t;
  144. /** @brief Generate the default configuration for the TWIS driver instance. */
  145. #define NRFX_TWIS_DEFAULT_CONFIG \
  146. { \
  147. .addr = { NRFX_TWIS_DEFAULT_CONFIG_ADDR0, \
  148. NRFX_TWIS_DEFAULT_CONFIG_ADDR1 }, \
  149. .scl = 31, \
  150. .sda = 31, \
  151. .scl_pull = (nrf_gpio_pin_pull_t)NRFX_TWIS_DEFAULT_CONFIG_SCL_PULL, \
  152. .sda_pull = (nrf_gpio_pin_pull_t)NRFX_TWIS_DEFAULT_CONFIG_SDA_PULL, \
  153. .interrupt_priority = NRFX_TWIS_DEFAULT_CONFIG_IRQ_PRIORITY \
  154. }
  155. /**
  156. * @brief Function for initializing the TWIS driver instance.
  157. *
  158. * Function initializes and enables the TWIS driver.
  159. * @attention After driver initialization enable it with @ref nrfx_twis_enable.
  160. *
  161. * @param[in] p_instance Pointer to the driver instance structure.
  162. * @attention @em p_instance has to be global object.
  163. * It will be used by interrupts so make it sure that object
  164. * is not destroyed when function is leaving.
  165. * @param[in] p_config Pointer to the structure with the initial configuration.
  166. * @param[in] event_handler Event handler provided by the user.
  167. *
  168. * @retval NRFX_SUCCESS Initialization is successful.
  169. * @retval NRFX_ERROR_INVALID_STATE The driver is already initialized.
  170. * @retval NRFX_ERROR_BUSY Some other peripheral with the same
  171. * instance ID is already in use. This is
  172. * possible only if NRFX_PRS_ENABLED
  173. * is set to a value other than zero.
  174. */
  175. nrfx_err_t nrfx_twis_init(nrfx_twis_t const * p_instance,
  176. nrfx_twis_config_t const * p_config,
  177. nrfx_twis_event_handler_t event_handler);
  178. /**
  179. * @brief Function for uninitializing the TWIS driver instance.
  180. *
  181. * Function uninitializes the peripheral and resets all registers to default values.
  182. *
  183. * @note
  184. * It is safe to call nrfx_twis_uninit even before initialization.
  185. * Actually, @ref nrfx_twis_init function calls this function to
  186. * make sure that TWIS state is known.
  187. * @note
  188. * If TWIS driver was in uninitialized state before calling this function,
  189. * the selected pins would not be reset to default configuration.
  190. *
  191. * @param[in] p_instance Pointer to the driver instance structure.
  192. */
  193. void nrfx_twis_uninit(nrfx_twis_t const * p_instance);
  194. /**
  195. * @brief Function for enabling the TWIS instance.
  196. *
  197. * This function enables the TWIS instance.
  198. * Function defined if there is need for dynamically enabling and disabling the peripheral.
  199. * Use @ref nrfx_twis_enable and @ref nrfx_twis_disable functions.
  200. * They do not change any configuration registers.
  201. *
  202. * @param p_instance Pointer to the driver instance structure.
  203. */
  204. void nrfx_twis_enable(nrfx_twis_t const * p_instance);
  205. /**
  206. * @brief Function for disabling the TWIS instance.
  207. *
  208. * This function disables the TWIS instance, which gives possibility to turn off the TWIS while
  209. * holding configuration done by @ref nrfx_twis_init.
  210. *
  211. * @param p_instance Pointer to the driver instance structure.
  212. */
  213. void nrfx_twis_disable(nrfx_twis_t const * p_instance);
  214. /**
  215. * @brief Function for getting and clearing the last error flags.
  216. *
  217. * This function gets the information about errors.
  218. * This is also the only possibility to exit from the error substate of the internal state machine.
  219. * @attention
  220. * This function clears error state and flags.
  221. *
  222. * @param[in] p_instance Pointer to the driver instance structure.
  223. *
  224. * @return Error flags defined in @ref nrfx_twis_error_t.
  225. */
  226. uint32_t nrfx_twis_error_get_and_clear(nrfx_twis_t const * p_instance);
  227. /**
  228. * @brief Function for preparing the data for sending.
  229. *
  230. * This function is to be used in response to the @ref NRFX_TWIS_EVT_READ_REQ event.
  231. *
  232. * @note Peripherals using EasyDMA (including TWIS) require the transfer buffers
  233. * to be placed in the Data RAM region. If this condition is not met,
  234. * this function will fail with the error code NRFX_ERROR_INVALID_ADDR.
  235. * @attention Transmission buffer must be placed in RAM.
  236. *
  237. * @param[in] p_instance Pointer to the driver instance structure.
  238. * @param[in] p_buf Transmission buffer.
  239. * @param[in] size Maximum number of bytes that master may read from buffer given.
  240. *
  241. * @retval NRFX_SUCCESS The preparation finished properly.
  242. * @retval NRFX_ERROR_INVALID_ADDR The given @em p_buf is not placed inside the RAM.
  243. * @retval NRFX_ERROR_INVALID_LENGTH There is a wrong value in the @em size parameter.
  244. * @retval NRFX_ERROR_INVALID_STATE The module is not initialized or not enabled.
  245. */
  246. nrfx_err_t nrfx_twis_tx_prepare(nrfx_twis_t const * p_instance,
  247. void const * p_buf,
  248. size_t size);
  249. /**
  250. * @brief Function for getting the number of transmitted bytes.
  251. *
  252. * This function returns the number of bytes sent.
  253. * This function can be called after @ref NRFX_TWIS_EVT_READ_DONE or @ref NRFX_TWIS_EVT_READ_ERROR events.
  254. *
  255. * @param[in] p_instance Pointer to the driver instance structure.
  256. *
  257. * @return Number of bytes sent.
  258. */
  259. __STATIC_INLINE size_t nrfx_twis_tx_amount(nrfx_twis_t const * p_instance);
  260. /**
  261. * @brief Function for preparing the data for receiving.
  262. *
  263. * This function must be used in response to the @ref NRFX_TWIS_EVT_WRITE_REQ event.
  264. *
  265. * @note Peripherals using EasyDMA (including TWIS) require the transfer buffers
  266. * to be placed in the Data RAM region. If this condition is not met,
  267. * this function fails with the error code NRFX_ERROR_INVALID_ADDR.
  268. *
  269. * @param[in] p_instance Pointer to the driver instance structure.
  270. * @param[in] p_buf Buffer that is to be filled with received data.
  271. * @param[in] size Size of the buffer (maximum amount of data to receive).
  272. *
  273. * @retval NRFX_SUCCESS The preparation finished properly.
  274. * @retval NRFX_ERROR_INVALID_ADDR The given @em p_buf is not placed inside the RAM.
  275. * @retval NRFX_ERROR_INVALID_LENGTH There is a wrong value in the @em size parameter.
  276. * @retval NRFX_ERROR_INVALID_STATE The module is not initialized or not enabled.
  277. */
  278. nrfx_err_t nrfx_twis_rx_prepare(nrfx_twis_t const * p_instance,
  279. void * p_buf,
  280. size_t size);
  281. /**
  282. * @brief Function for getting the number of received bytes.
  283. *
  284. * This function returns number of bytes received.
  285. * It can be called after @ref NRFX_TWIS_EVT_WRITE_DONE or @ref NRFX_TWIS_EVT_WRITE_ERROR events.
  286. *
  287. * @param[in] p_instance Pointer to the driver instance structure.
  288. *
  289. * @return Number of bytes received.
  290. */
  291. __STATIC_INLINE size_t nrfx_twis_rx_amount(nrfx_twis_t const * p_instance);
  292. /**
  293. * @brief Function for checking if the driver is busy right now.
  294. *
  295. * This function tests the actual driver substate.
  296. * If the driver is in any other state than IDLE or ERROR, this function returns true.
  297. *
  298. * @param[in] p_instance Pointer to the driver instance structure.
  299. *
  300. * @retval true The driver is in state other than ERROR or IDLE.
  301. * @retval false There is no transmission pending.
  302. */
  303. bool nrfx_twis_is_busy(nrfx_twis_t const * p_instance);
  304. /**
  305. * @brief Function for checking if the driver is waiting for a TX buffer.
  306. *
  307. * If this function returns true, the driver is stalled expecting
  308. * of the @ref nrfx_twis_tx_prepare function call.
  309. *
  310. * @param[in] p_instance Pointer to the driver instance structure.
  311. *
  312. * @retval true The driver is waiting for @ref nrfx_twis_tx_prepare.
  313. * @retval false The driver is not in the state where it is waiting for preparing a TX buffer.
  314. */
  315. bool nrfx_twis_is_waiting_tx_buff(nrfx_twis_t const * p_instance);
  316. /**
  317. * @brief Function for checking if the driver is waiting for an RX buffer.
  318. *
  319. * If this function returns true, the driver is stalled expecting
  320. * of the @ref nrfx_twis_rx_prepare function call.
  321. *
  322. * @param[in] p_instance Pointer to the driver instance structure.
  323. *
  324. * @retval true The driver is waiting for @ref nrfx_twis_rx_prepare.
  325. * @retval false The driver is not in the state where it is waiting for preparing an RX buffer.
  326. */
  327. bool nrfx_twis_is_waiting_rx_buff(nrfx_twis_t const * p_instance);
  328. /**
  329. * @brief Function for checking if the driver is sending data.
  330. *
  331. * If this function returns true, there is an ongoing output transmission.
  332. *
  333. * @param[in] p_instance Pointer to the driver instance structure.
  334. *
  335. * @retval true There is an ongoing output transmission.
  336. * @retval false The driver is in other state.
  337. */
  338. bool nrfx_twis_is_pending_tx(nrfx_twis_t const * p_instance);
  339. /**
  340. * @brief Function for checking if the driver is receiving data.
  341. *
  342. * If this function returns true, there is an ongoing input transmission.
  343. *
  344. * @param[in] p_instance Pointer to the driver instance structure.
  345. *
  346. * @retval true There is an ongoing input transmission.
  347. * @retval false The driver is in other state.
  348. */
  349. bool nrfx_twis_is_pending_rx(nrfx_twis_t const * p_instance);
  350. #ifndef SUPPRESS_INLINE_IMPLEMENTATION
  351. __STATIC_INLINE size_t nrfx_twis_tx_amount(nrfx_twis_t const * p_instance)
  352. {
  353. return nrf_twis_tx_amount_get(p_instance->p_reg);
  354. }
  355. __STATIC_INLINE size_t nrfx_twis_rx_amount(nrfx_twis_t const * p_instance)
  356. {
  357. return nrf_twis_rx_amount_get(p_instance->p_reg);
  358. }
  359. #endif // SUPPRESS_INLINE_IMPLEMENTATION
  360. /** @} */
  361. void nrfx_twis_0_irq_handler(void);
  362. void nrfx_twis_1_irq_handler(void);
  363. void nrfx_twis_2_irq_handler(void);
  364. void nrfx_twis_3_irq_handler(void);
  365. #ifdef __cplusplus
  366. }
  367. #endif
  368. #endif // NRFX_TWIS_H__