1 /* 2 * Copyright (c) 2015 - 2018, Nordic Semiconductor ASA 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions are met: 7 * 8 * 1. Redistributions of source code must retain the above copyright notice, this 9 * list of conditions and the following disclaimer. 10 * 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * 3. Neither the name of the copyright holder nor the names of its 16 * contributors may be used to endorse or promote products derived from this 17 * software without specific prior written permission. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 20 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 23 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 * POSSIBILITY OF SUCH DAMAGE. 30 */ 31 32 #ifndef NRFX_TWIS_H__ 33 #define NRFX_TWIS_H__ 34 35 #include <nrfx.h> 36 #include <hal/nrf_twis.h> 37 #include <hal/nrf_gpio.h> 38 39 #ifdef __cplusplus 40 extern "C" { 41 #endif 42 43 /** 44 * @defgroup nrfx_twis TWIS driver 45 * @{ 46 * @ingroup nrf_twis 47 * @brief Two Wire Slave interface (TWIS) peripheral driver. 48 */ 49 50 /** 51 * @brief TWIS driver instance data structure. 52 */ 53 typedef struct 54 { 55 NRF_TWIS_Type * p_reg; ///< Pointer to a structure with TWIS registers. 56 uint8_t drv_inst_idx; ///< Driver instance index. 57 } nrfx_twis_t; 58 59 enum { 60 #if NRFX_CHECK(NRFX_TWIS0_ENABLED) 61 NRFX_TWIS0_INST_IDX, 62 #endif 63 #if NRFX_CHECK(NRFX_TWIS1_ENABLED) 64 NRFX_TWIS1_INST_IDX, 65 #endif 66 #if NRFX_CHECK(NRFX_TWIS2_ENABLED) 67 NRFX_TWIS2_INST_IDX, 68 #endif 69 #if NRFX_CHECK(NRFX_TWIS3_ENABLED) 70 NRFX_TWIS3_INST_IDX, 71 #endif 72 NRFX_TWIS_ENABLED_COUNT 73 }; 74 75 /** 76 * @brief Macro for creating a TWIS driver instance. 77 */ 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 84 /** 85 * @brief Event callback function event definitions. 86 */ 87 typedef enum 88 { 89 NRFX_TWIS_EVT_READ_REQ, ///< Read request detected. 90 /**< If there is no buffer prepared, buf_req flag in the even will be set. 91 Call then @ref nrfx_twis_tx_prepare to give parameters for buffer. 92 */ 93 NRFX_TWIS_EVT_READ_DONE, ///< Read request has finished - free any data. 94 NRFX_TWIS_EVT_READ_ERROR, ///< Read request finished with error. 95 NRFX_TWIS_EVT_WRITE_REQ, ///< Write request detected. 96 /**< If there is no buffer prepared, buf_req flag in the even will be set. 97 Call then @ref nrfx_twis_rx_prepare to give parameters for buffer. 98 */ 99 NRFX_TWIS_EVT_WRITE_DONE, ///< Write request has finished - process data. 100 NRFX_TWIS_EVT_WRITE_ERROR, ///< Write request finished with error. 101 NRFX_TWIS_EVT_GENERAL_ERROR ///< Error that happens not inside WRITE or READ transaction. 102 } nrfx_twis_evt_type_t; 103 104 /** 105 * @brief Possible error sources. 106 * 107 * This is flag enum - values from this enum can be connected using logical or operator. 108 * @note 109 * We could use directly @ref nrf_twis_error_t. Error type enum is redefined here because 110 * of possible future extension (eg. supporting timeouts and synchronous mode). 111 */ 112 typedef enum 113 { 114 NRFX_TWIS_ERROR_OVERFLOW = NRF_TWIS_ERROR_OVERFLOW, /**< RX buffer overflow detected, and prevented. */ 115 NRFX_TWIS_ERROR_DATA_NACK = NRF_TWIS_ERROR_DATA_NACK, /**< NACK sent after receiving a data byte. */ 116 NRFX_TWIS_ERROR_OVERREAD = NRF_TWIS_ERROR_OVERREAD, /**< TX buffer over-read detected, and prevented. */ 117 NRFX_TWIS_ERROR_UNEXPECTED_EVENT = 1 << 8 /**< Unexpected event detected by state machine. */ 118 } nrfx_twis_error_t; 119 120 /** 121 * @brief TWIS driver event structure. 122 */ 123 typedef struct 124 { 125 nrfx_twis_evt_type_t type; ///< Event type. 126 union 127 { 128 bool buf_req; ///< Flag for @ref NRFX_TWIS_EVT_READ_REQ and @ref NRFX_TWIS_EVT_WRITE_REQ. 129 /**< Information if transmission buffer requires to be prepared. */ 130 uint32_t tx_amount; ///< Data for @ref NRFX_TWIS_EVT_READ_DONE. 131 uint32_t rx_amount; ///< Data for @ref NRFX_TWIS_EVT_WRITE_DONE. 132 uint32_t error; ///< Data for @ref NRFX_TWIS_EVT_GENERAL_ERROR. 133 } data; 134 } nrfx_twis_evt_t; 135 136 /** 137 * @brief TWI slave event callback function type. 138 * 139 * @param[in] p_event Event information structure. 140 */ 141 typedef void (*nrfx_twis_event_handler_t)(nrfx_twis_evt_t const * p_event); 142 143 /** 144 * @brief Structure for TWIS configuration. 145 */ 146 typedef struct 147 { 148 uint32_t addr[2]; //!< Set addresses that this slave should respond. Set 0 to disable. 149 uint32_t scl; //!< SCL pin number. 150 uint32_t sda; //!< SDA pin number. 151 nrf_gpio_pin_pull_t scl_pull; //!< SCL pin pull. 152 nrf_gpio_pin_pull_t sda_pull; //!< SDA pin pull. 153 uint8_t interrupt_priority; //!< The priority of interrupt for the module to set. 154 } nrfx_twis_config_t; 155 156 /** 157 * @brief Generate default configuration for TWIS driver instance. 158 */ 159 #define NRFX_TWIS_DEFAULT_CONFIG \ 160 { \ 161 .addr = { NRFX_TWIS_DEFAULT_CONFIG_ADDR0, \ 162 NRFX_TWIS_DEFAULT_CONFIG_ADDR1 }, \ 163 .scl = 31, \ 164 .scl_pull = (nrf_gpio_pin_pull_t)NRFX_TWIS_DEFAULT_CONFIG_SCL_PULL, \ 165 .sda = 31, \ 166 .sda_pull = (nrf_gpio_pin_pull_t)NRFX_TWIS_DEFAULT_CONFIG_SDA_PULL, \ 167 .interrupt_priority = NRFX_TWIS_DEFAULT_CONFIG_IRQ_PRIORITY \ 168 } 169 170 /** 171 * @brief Function for initializing the TWIS driver instance. 172 * 173 * Function initializes and enables TWIS driver. 174 * @attention After driver initialization enable it by @ref nrfx_twis_enable. 175 * 176 * @param[in] p_instance Pointer to the driver instance structure. 177 * @attention @em p_instance has to be global object. 178 * It would be used by interrupts so make it sure that object 179 * would not be destroyed when function is leaving. 180 * @param[in] p_config Pointer to the structure with initial configuration. 181 * @param[in] event_handler Event handler provided by the user. 182 * 183 * @retval NRFX_SUCCESS If initialization was successful. 184 * @retval NRFX_ERROR_INVALID_STATE If the driver is already initialized. 185 * @retval NRFX_ERROR_BUSY If some other peripheral with the same 186 * instance ID is already in use. This is 187 * possible only if NRFX_PRS_ENABLED 188 * is set to a value other than zero. 189 */ 190 nrfx_err_t nrfx_twis_init(nrfx_twis_t const * p_instance, 191 nrfx_twis_config_t const * p_config, 192 nrfx_twis_event_handler_t event_handler); 193 194 /** 195 * @brief Function for uninitializing the TWIS driver instance. 196 * 197 * Function initializes the peripheral and resets all registers to default values. 198 * 199 * @param[in] p_instance Pointer to the driver instance structure. 200 * @note 201 * It is safe to call nrfx_twis_uninit even before initialization. 202 * Actually @ref nrfx_twis_init function calls this function to 203 * make sure that TWIS state is known. 204 * @note 205 * If TWIS driver was in uninitialized state before calling this function, 206 * selected pins would not be reset to default configuration. 207 */ 208 void nrfx_twis_uninit(nrfx_twis_t const * p_instance); 209 210 /** 211 * @brief Enable TWIS instance. 212 * 213 * This function enables TWIS instance. 214 * Function defined if there is needs for dynamically enabling and disabling the peripheral. 215 * Use @ref nrfx_twis_enable and @ref nrfx_twis_disable functions. 216 * They do not change any configuration registers. 217 * 218 * @param p_instance Pointer to the driver instance structure. 219 */ 220 void nrfx_twis_enable(nrfx_twis_t const * p_instance); 221 222 /** 223 * @brief Disable TWIS instance. 224 * 225 * Disabling TWIS instance gives possibility to turn off the TWIS while 226 * holding configuration done by @ref nrfx_twis_init. 227 * 228 * @param p_instance Pointer to the driver instance structure. 229 */ 230 void nrfx_twis_disable(nrfx_twis_t const * p_instance); 231 232 /** 233 * @brief Get and clear last error flags. 234 * 235 * Function gets information about errors. 236 * This is also the only possibility to exit from error substate of the internal state machine. 237 * 238 * @param[in] p_instance Pointer to the driver instance structure. 239 * @return Error flags defined in @ref nrfx_twis_error_t. 240 * @attention 241 * This function clears error state and flags. 242 */ 243 uint32_t nrfx_twis_error_get_and_clear(nrfx_twis_t const * p_instance); 244 245 246 /** 247 * @brief Prepare data for sending. 248 * 249 * This function should be used in response for @ref NRFX_TWIS_EVT_READ_REQ event. 250 * 251 * @note Peripherals using EasyDMA (including TWIS) require the transfer buffers 252 * to be placed in the Data RAM region. If this condition is not met, 253 * this function will fail with the error code NRFX_ERROR_INVALID_ADDR. 254 * 255 * @param[in] p_instance Pointer to the driver instance structure. 256 * @param[in] p_buf Transmission buffer. 257 * @attention Transmission buffer has to be placed in RAM. 258 * @param size Maximum number of bytes that master may read from buffer given. 259 * 260 * @retval NRFX_SUCCESS Preparation finished properly. 261 * @retval NRFX_ERROR_INVALID_ADDR Given @em p_buf is not placed inside the RAM. 262 * @retval NRFX_ERROR_INVALID_LENGTH Wrong value in @em size parameter. 263 * @retval NRFX_ERROR_INVALID_STATE Module not initialized or not enabled. 264 */ 265 nrfx_err_t nrfx_twis_tx_prepare(nrfx_twis_t const * p_instance, 266 void const * p_buf, 267 size_t size); 268 269 /** 270 * @brief Get number of transmitted bytes. 271 * 272 * Function returns number of bytes sent. 273 * This function may be called after @ref NRFX_TWIS_EVT_READ_DONE or @ref NRFX_TWIS_EVT_READ_ERROR events. 274 * 275 * @param[in] p_instance Pointer to the driver instance structure. 276 * 277 * @return Number of bytes sent. 278 */ 279 __STATIC_INLINE size_t nrfx_twis_tx_amount(nrfx_twis_t const * p_instance); 280 281 /** 282 * @brief Prepare data for receiving 283 * 284 * This function should be used in response for @ref NRFX_TWIS_EVT_WRITE_REQ event. 285 * 286 * @note Peripherals using EasyDMA (including TWIS) require the transfer buffers 287 * to be placed in the Data RAM region. If this condition is not met, 288 * this function will fail with the error code NRFX_ERROR_INVALID_ADDR. 289 * 290 * @param[in] p_instance Pointer to the driver instance structure. 291 * @param[in] p_buf Buffer that would be filled with received data. 292 * @attention Receiving buffer has to be placed in RAM. 293 * @param size Size of the buffer (maximum amount of data to receive). 294 * 295 * @retval NRFX_SUCCESS Preparation finished properly. 296 * @retval NRFX_ERROR_INVALID_ADDR Given @em p_buf is not placed inside the RAM. 297 * @retval NRFX_ERROR_INVALID_LENGTH Wrong value in @em size parameter. 298 * @retval NRFX_ERROR_INVALID_STATE Module not initialized or not enabled. 299 */ 300 nrfx_err_t nrfx_twis_rx_prepare(nrfx_twis_t const * p_instance, 301 void * p_buf, 302 size_t size); 303 304 /** 305 * @brief Get number of received bytes. 306 * 307 * Function returns number of bytes received. 308 * This function may be called after @ref NRFX_TWIS_EVT_WRITE_DONE or @ref NRFX_TWIS_EVT_WRITE_ERROR events. 309 * 310 * @param[in] p_instance Pointer to the driver instance structure. 311 * 312 * @return Number of bytes received. 313 */ 314 __STATIC_INLINE size_t nrfx_twis_rx_amount(nrfx_twis_t const * p_instance); 315 316 /** 317 * @brief Function checks if driver is busy right now. 318 * 319 * Actual driver substate is tested. 320 * If driver is in any other state than IDLE or ERROR this function returns true. 321 * 322 * @param[in] p_instance Pointer to the driver instance structure. 323 * 324 * @retval true Driver is in state other than ERROR or IDLE. 325 * @retval false There is no transmission pending. 326 */ 327 bool nrfx_twis_is_busy(nrfx_twis_t const * p_instance); 328 329 /** 330 * @brief Function checks if driver is waiting for tx buffer. 331 * 332 * If this function returns true, it means that driver is stalled expecting 333 * of the @ref nrfx_twis_tx_prepare function call. 334 * 335 * @param[in] p_instance Pointer to the driver instance structure. 336 * 337 * @retval true Driver waits for @ref nrfx_twis_tx_prepare. 338 * @retval false Driver is not in the state where it waits for preparing tx buffer. 339 */ 340 bool nrfx_twis_is_waiting_tx_buff(nrfx_twis_t const * p_instance); 341 342 /** 343 * @brief Function checks if driver is waiting for rx buffer. 344 * 345 * If this function returns true, it means that driver is staled expecting 346 * of the @ref nrfx_twis_rx_prepare function call. 347 * 348 * @param[in] p_instance Pointer to the driver instance structure. 349 * 350 * @retval true Driver waits for @ref nrfx_twis_rx_prepare. 351 * @retval false Driver is not in the state where it waits for preparing rx buffer. 352 */ 353 bool nrfx_twis_is_waiting_rx_buff(nrfx_twis_t const * p_instance); 354 355 /** 356 * @brief Check if driver is sending data. 357 * 358 * If this function returns true, it means that there is ongoing output transmission. 359 * 360 * @param[in] p_instance Pointer to the driver instance structure. 361 * 362 * @retval true There is ongoing output transmission. 363 * @retval false Driver is in other state. 364 */ 365 bool nrfx_twis_is_pending_tx(nrfx_twis_t const * p_instance); 366 367 /** 368 * @brief Check if driver is receiving data. 369 * 370 * If this function returns true, it means that there is ongoing input transmission. 371 * 372 * @param[in] p_instance Pointer to the driver instance structure. 373 * 374 * @retval true There is ongoing input transmission. 375 * @retval false Driver is in other state. 376 */ 377 bool nrfx_twis_is_pending_rx(nrfx_twis_t const * p_instance); 378 379 #ifndef SUPPRESS_INLINE_IMPLEMENTATION 380 __STATIC_INLINE size_t nrfx_twis_tx_amount(nrfx_twis_t const * p_instance) 381 { 382 return nrf_twis_tx_amount_get(p_instance->p_reg); 383 } 384 385 __STATIC_INLINE size_t nrfx_twis_rx_amount(nrfx_twis_t const * p_instance) 386 { 387 return nrf_twis_rx_amount_get(p_instance->p_reg); 388 } 389 #endif // SUPPRESS_INLINE_IMPLEMENTATION 390 391 392 void nrfx_twis_0_irq_handler(void); 393 void nrfx_twis_1_irq_handler(void); 394 void nrfx_twis_2_irq_handler(void); 395 void nrfx_twis_3_irq_handler(void); 396 397 398 /** @} */ 399 400 #ifdef __cplusplus 401 } 402 #endif 403 404 #endif // NRFX_TWIS_H__ 405