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_TWI_H__ 33 #define NRFX_TWI_H__ 34 35 #include <nrfx.h> 36 #include <hal/nrf_twi.h> 37 38 #ifdef __cplusplus 39 extern "C" { 40 #endif 41 42 /** 43 * @defgroup nrfx_twi TWI driver 44 * @{ 45 * @ingroup nrf_twi 46 * @brief TWI peripheral driver. 47 */ 48 49 /** 50 * @brief Structure for the TWI master driver instance. 51 */ 52 typedef struct 53 { 54 NRF_TWI_Type * p_twi; ///< Pointer to a structure with TWI registers. 55 uint8_t drv_inst_idx; ///< Driver instance index. 56 } nrfx_twi_t; 57 58 /** 59 * @brief Macro for creating a TWI master driver instance. 60 */ 61 #define NRFX_TWI_INSTANCE(id) \ 62 { \ 63 .p_twi = NRFX_CONCAT_2(NRF_TWI, id), \ 64 .drv_inst_idx = NRFX_CONCAT_3(NRFX_TWI, id, _INST_IDX), \ 65 } 66 67 enum { 68 #if NRFX_CHECK(NRFX_TWI0_ENABLED) 69 NRFX_TWI0_INST_IDX, 70 #endif 71 #if NRFX_CHECK(NRFX_TWI1_ENABLED) 72 NRFX_TWI1_INST_IDX, 73 #endif 74 NRFX_TWI_ENABLED_COUNT 75 }; 76 77 /** 78 * @brief Structure for the TWI master driver instance configuration. 79 */ 80 typedef struct 81 { 82 uint32_t scl; ///< SCL pin number. 83 uint32_t sda; ///< SDA pin number. 84 nrf_twi_frequency_t frequency; ///< TWI frequency. 85 uint8_t interrupt_priority; ///< Interrupt priority. 86 bool hold_bus_uninit; ///< Hold pull up state on gpio pins after uninit. 87 } nrfx_twi_config_t; 88 89 /** 90 * @brief TWI master driver instance default configuration. 91 */ 92 #define NRFX_TWI_DEFAULT_CONFIG \ 93 { \ 94 .frequency = (nrf_twi_frequency_t)NRFX_TWI_DEFAULT_CONFIG_FREQUENCY, \ 95 .scl = 31, \ 96 .sda = 31, \ 97 .interrupt_priority = NRFX_TWI_DEFAULT_CONFIG_IRQ_PRIORITY, \ 98 .hold_bus_uninit = NRFX_TWI_DEFAULT_CONFIG_HOLD_BUS_UNINIT, \ 99 } 100 101 #define NRFX_TWI_FLAG_NO_XFER_EVT_HANDLER (1UL << 2) /**< Interrupt after each transfer is suppressed, and the event handler is not called. */ 102 #define NRFX_TWI_FLAG_TX_NO_STOP (1UL << 5) /**< Flag indicating that the TX transfer will not end with a stop condition. */ 103 104 /** 105 * @brief TWI master driver event types. 106 */ 107 typedef enum 108 { 109 NRFX_TWI_EVT_DONE, ///< Transfer completed event. 110 NRFX_TWI_EVT_ADDRESS_NACK, ///< Error event: NACK received after sending the address. 111 NRFX_TWI_EVT_DATA_NACK ///< Error event: NACK received after sending a data byte. 112 } nrfx_twi_evt_type_t; 113 114 /** 115 * @brief TWI master driver transfer types. 116 */ 117 typedef enum 118 { 119 NRFX_TWI_XFER_TX, ///< TX transfer. 120 NRFX_TWI_XFER_RX, ///< RX transfer. 121 NRFX_TWI_XFER_TXRX, ///< TX transfer followed by RX transfer with repeated start. 122 NRFX_TWI_XFER_TXTX ///< TX transfer followed by TX transfer with repeated start. 123 } nrfx_twi_xfer_type_t; 124 125 /** 126 * @brief Structure for a TWI transfer descriptor. 127 */ 128 typedef struct 129 { 130 nrfx_twi_xfer_type_t type; ///< Type of transfer. 131 uint8_t address; ///< Slave address. 132 size_t primary_length; ///< Number of bytes transferred. 133 size_t secondary_length; ///< Number of bytes transferred. 134 uint8_t * p_primary_buf; ///< Pointer to transferred data. 135 uint8_t * p_secondary_buf; ///< Pointer to transferred data. 136 } nrfx_twi_xfer_desc_t; 137 138 139 /**@brief Macro for setting the TX transfer descriptor. */ 140 #define NRFX_TWI_XFER_DESC_TX(addr, p_data, length) \ 141 { \ 142 .type = NRFX_TWI_XFER_TX, \ 143 .address = addr, \ 144 .primary_length = length, \ 145 .p_primary_buf = p_data, \ 146 } 147 148 /**@brief Macro for setting the RX transfer descriptor. */ 149 #define NRFX_TWI_XFER_DESC_RX(addr, p_data, length) \ 150 { \ 151 .type = NRFX_TWI_XFER_RX, \ 152 .address = addr, \ 153 .primary_length = length, \ 154 .p_primary_buf = p_data, \ 155 } 156 157 /**@brief Macro for setting the TXRX transfer descriptor. */ 158 #define NRFX_TWI_XFER_DESC_TXRX(addr, p_tx, tx_len, p_rx, rx_len) \ 159 { \ 160 .type = NRFX_TWI_XFER_TXRX, \ 161 .address = addr, \ 162 .primary_length = tx_len, \ 163 .secondary_length = rx_len, \ 164 .p_primary_buf = p_tx, \ 165 .p_secondary_buf = p_rx, \ 166 } 167 168 /**@brief Macro for setting the TXTX transfer descriptor. */ 169 #define NRFX_TWI_XFER_DESC_TXTX(addr, p_tx, tx_len, p_tx2, tx_len2) \ 170 { \ 171 .type = NRFX_TWI_XFER_TXTX, \ 172 .address = addr, \ 173 .primary_length = tx_len, \ 174 .secondary_length = tx_len2, \ 175 .p_primary_buf = p_tx, \ 176 .p_secondary_buf = p_tx2, \ 177 } 178 179 /** 180 * @brief Structure for a TWI event. 181 */ 182 typedef struct 183 { 184 nrfx_twi_evt_type_t type; ///< Event type. 185 nrfx_twi_xfer_desc_t xfer_desc; ///< Transfer details. 186 } nrfx_twi_evt_t; 187 188 /** 189 * @brief TWI event handler prototype. 190 */ 191 typedef void (* nrfx_twi_evt_handler_t)(nrfx_twi_evt_t const * p_event, 192 void * p_context); 193 194 /** 195 * @brief Function for initializing the TWI driver instance. 196 * 197 * @param[in] p_instance Pointer to the driver instance structure. 198 * @param[in] p_config Pointer to the structure with initial configuration. 199 * @param[in] event_handler Event handler provided by the user. If NULL, blocking mode is enabled. 200 * @param[in] p_context Context passed to event handler. 201 * 202 * @retval NRFX_SUCCESS If initialization was successful. 203 * @retval NRFX_ERROR_INVALID_STATE If the driver is in invalid state. 204 * @retval NRFX_ERROR_BUSY If some other peripheral with the same 205 * instance ID is already in use. This is 206 * possible only if @ref nrfx_prs module 207 * is enabled. 208 */ 209 nrfx_err_t nrfx_twi_init(nrfx_twi_t const * p_instance, 210 nrfx_twi_config_t const * p_config, 211 nrfx_twi_evt_handler_t event_handler, 212 void * p_context); 213 214 /** 215 * @brief Function for uninitializing the TWI instance. 216 * 217 * @param[in] p_instance Pointer to the driver instance structure. 218 */ 219 void nrfx_twi_uninit(nrfx_twi_t const * p_instance); 220 221 /** 222 * @brief Function for enabling the TWI instance. 223 * 224 * @param[in] p_instance Pointer to the driver instance structure. 225 */ 226 void nrfx_twi_enable(nrfx_twi_t const * p_instance); 227 228 /** 229 * @brief Function for disabling the TWI instance. 230 * 231 * @param[in] p_instance Pointer to the driver instance structure. 232 */ 233 void nrfx_twi_disable(nrfx_twi_t const * p_instance); 234 235 /** 236 * @brief Function for sending data to a TWI slave. 237 * 238 * The transmission will be stopped when an error occurs. If a transfer is ongoing, 239 * the function returns the error code @ref NRFX_ERROR_BUSY. 240 * 241 * @param[in] p_instance Pointer to the driver instance structure. 242 * @param[in] address Address of a specific slave device (only 7 LSB). 243 * @param[in] p_data Pointer to a transmit buffer. 244 * @param[in] length Number of bytes to send. 245 * @param[in] no_stop If set, the stop condition is not generated on the bus 246 * after the transfer has completed successfully (allowing 247 * for a repeated start in the next transfer). 248 * 249 * @retval NRFX_SUCCESS If the procedure was successful. 250 * @retval NRFX_ERROR_BUSY If the driver is not ready for a new transfer. 251 * @retval NRFX_ERROR_INTERNAL If an error was detected by hardware. 252 * @retval NRFX_ERROR_DRV_TWI_ERR_ANACK If NACK received after sending the address in polling mode. 253 * @retval NRFX_ERROR_DRV_TWI_ERR_DNACK If NACK received after sending a data byte in polling mode. 254 */ 255 nrfx_err_t nrfx_twi_tx(nrfx_twi_t const * p_instance, 256 uint8_t address, 257 uint8_t const * p_data, 258 size_t length, 259 bool no_stop); 260 261 /** 262 * @brief Function for reading data from a TWI slave. 263 * 264 * The transmission will be stopped when an error occurs. If a transfer is ongoing, 265 * the function returns the error code @ref NRFX_ERROR_BUSY. 266 * 267 * @param[in] p_instance Pointer to the driver instance structure. 268 * @param[in] address Address of a specific slave device (only 7 LSB). 269 * @param[in] p_data Pointer to a receive buffer. 270 * @param[in] length Number of bytes to be received. 271 * 272 * @retval NRFX_SUCCESS If the procedure was successful. 273 * @retval NRFX_ERROR_BUSY If the driver is not ready for a new transfer. 274 * @retval NRFX_ERROR_INTERNAL If an error was detected by hardware. 275 * @retval NRFX_ERROR_DRV_TWI_ERR_OVERRUN If the unread data was replaced by new data 276 * @retval NRFX_ERROR_DRV_TWI_ERR_ANACK If NACK received after sending the address in polling mode. 277 * @retval NRFX_ERROR_DRV_TWI_ERR_DNACK If NACK received after sending a data byte in polling mode. 278 */ 279 nrfx_err_t nrfx_twi_rx(nrfx_twi_t const * p_instance, 280 uint8_t address, 281 uint8_t * p_data, 282 size_t length); 283 284 /** 285 * @brief Function for preparing a TWI transfer. 286 * 287 * The following transfer types can be configured (@ref nrfx_twi_xfer_desc_t::type): 288 * - @ref NRFX_TWI_XFER_TXRX<span></span>: Write operation followed by a read operation (without STOP condition in between). 289 * - @ref NRFX_TWI_XFER_TXTX<span></span>: Write operation followed by a write operation (without STOP condition in between). 290 * - @ref NRFX_TWI_XFER_TX<span></span>: Write operation (with or without STOP condition). 291 * - @ref NRFX_TWI_XFER_RX<span></span>: Read operation (with STOP condition). 292 * 293 * @note TXRX and TXTX transfers are supported only in non-blocking mode. 294 * 295 * Additional options are provided using the flags parameter: 296 * - @ref NRFX_TWI_FLAG_NO_XFER_EVT_HANDLER<span></span>: No user event handler after transfer completion. In most cases, this also means no interrupt at the end of the transfer. 297 * - @ref NRFX_TWI_FLAG_TX_NO_STOP<span></span>: No stop condition after TX transfer. 298 * 299 * @note 300 * Some flag combinations are invalid: 301 * - @ref NRFX_TWI_FLAG_TX_NO_STOP with @ref nrfx_twi_xfer_desc_t::type different than @ref NRFX_TWI_XFER_TX 302 * 303 * @param[in] p_instance Pointer to the driver instance structure. 304 * @param[in] p_xfer_desc Pointer to the transfer descriptor. 305 * @param[in] flags Transfer options (0 for default settings). 306 * 307 * @retval NRFX_SUCCESS If the procedure was successful. 308 * @retval NRFX_ERROR_BUSY If the driver is not ready for a new transfer. 309 * @retval NRFX_ERROR_NOT_SUPPORTED If the provided parameters are not supported. 310 * @retval NRFX_ERROR_INTERNAL If an error was detected by hardware. 311 * @retval NRFX_ERROR_DRV_TWI_ERR_OVERRUN If the unread data was replaced by new data (TXRX and RX) 312 * @retval NRFX_ERROR_DRV_TWI_ERR_ANACK If NACK received after sending the address. 313 * @retval NRFX_ERROR_DRV_TWI_ERR_DNACK If NACK received after sending a data byte. 314 */ 315 nrfx_err_t nrfx_twi_xfer(nrfx_twi_t const * p_instance, 316 nrfx_twi_xfer_desc_t const * p_xfer_desc, 317 uint32_t flags); 318 319 /** 320 * @brief Function for checking the TWI driver state. 321 * 322 * @param[in] p_instance TWI instance. 323 * 324 * @retval true If the TWI driver is currently busy performing a transfer. 325 * @retval false If the TWI driver is ready for a new transfer. 326 */ 327 bool nrfx_twi_is_busy(nrfx_twi_t const * p_instance); 328 329 /** 330 * @brief Function for getting the transferred data count. 331 * 332 * @param[in] p_instance Pointer to the driver instance structure. 333 * 334 * @return Data count. 335 */ 336 size_t nrfx_twi_data_count_get(nrfx_twi_t const * const p_instance); 337 338 /** 339 * @brief Function for returning the address of a STOPPED TWI event. 340 * 341 * A STOPPED event can be used to detect the end of a transfer if the @ref NRFX_TWI_FLAG_NO_XFER_EVT_HANDLER 342 * option is used. 343 * 344 * @param[in] p_instance Pointer to the driver instance structure. 345 * 346 * @return STOPPED event address. 347 */ 348 uint32_t nrfx_twi_stopped_event_get(nrfx_twi_t const * p_instance); 349 350 void nrfx_twi_0_irq_handler(void); 351 void nrfx_twi_1_irq_handler(void); 352 353 /** @} */ 354 355 #ifdef __cplusplus 356 } 357 #endif 358 359 #endif // NRFX_TWI_H__ 360