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 NRF_I2S_H__ 33 #define NRF_I2S_H__ 34 35 #include <nrfx.h> 36 37 #ifdef __cplusplus 38 extern "C" { 39 #endif 40 41 /** 42 * @defgroup nrf_i2s_hal I2S HAL 43 * @{ 44 * @ingroup nrf_i2s 45 * @brief Hardware access layer for managing the Inter-IC Sound (I2S) peripheral. 46 */ 47 48 /** 49 * @brief This value can be provided as a parameter for the @ref nrf_i2s_pins_set 50 * function call to specify that a given I2S signal (SDOUT, SDIN, or MCK) 51 * shall not be connected to a physical pin. 52 */ 53 #define NRF_I2S_PIN_NOT_CONNECTED 0xFFFFFFFF 54 55 56 /** 57 * @brief I2S tasks. 58 */ 59 typedef enum 60 { 61 /*lint -save -e30*/ 62 NRF_I2S_TASK_START = offsetof(NRF_I2S_Type, TASKS_START), ///< Starts continuous I2S transfer. Also starts the MCK generator if this is enabled. 63 NRF_I2S_TASK_STOP = offsetof(NRF_I2S_Type, TASKS_STOP) ///< Stops I2S transfer. Also stops the MCK generator. 64 /*lint -restore*/ 65 } nrf_i2s_task_t; 66 67 /** 68 * @brief I2S events. 69 */ 70 typedef enum 71 { 72 /*lint -save -e30*/ 73 NRF_I2S_EVENT_RXPTRUPD = offsetof(NRF_I2S_Type, EVENTS_RXPTRUPD), ///< The RXD.PTR register has been copied to internal double-buffers. 74 NRF_I2S_EVENT_TXPTRUPD = offsetof(NRF_I2S_Type, EVENTS_TXPTRUPD), ///< The TXD.PTR register has been copied to internal double-buffers. 75 NRF_I2S_EVENT_STOPPED = offsetof(NRF_I2S_Type, EVENTS_STOPPED) ///< I2S transfer stopped. 76 /*lint -restore*/ 77 } nrf_i2s_event_t; 78 79 /** 80 * @brief I2S interrupts. 81 */ 82 typedef enum 83 { 84 NRF_I2S_INT_RXPTRUPD_MASK = I2S_INTENSET_RXPTRUPD_Msk, ///< Interrupt on RXPTRUPD event. 85 NRF_I2S_INT_TXPTRUPD_MASK = I2S_INTENSET_TXPTRUPD_Msk, ///< Interrupt on TXPTRUPD event. 86 NRF_I2S_INT_STOPPED_MASK = I2S_INTENSET_STOPPED_Msk ///< Interrupt on STOPPED event. 87 } nrf_i2s_int_mask_t; 88 89 /** 90 * @brief I2S modes of operation. 91 */ 92 typedef enum 93 { 94 NRF_I2S_MODE_MASTER = I2S_CONFIG_MODE_MODE_Master, ///< Master mode. 95 NRF_I2S_MODE_SLAVE = I2S_CONFIG_MODE_MODE_Slave ///< Slave mode. 96 } nrf_i2s_mode_t; 97 98 /** 99 * @brief I2S master clock generator settings. 100 */ 101 typedef enum 102 { 103 NRF_I2S_MCK_DISABLED = 0, ///< MCK disabled. 104 #if defined(I2S_CONFIG_MCKFREQ_MCKFREQ_32MDIV2) || defined(__NRFX_DOXYGEN__) 105 // [conversion to 'int' needed to prevent compilers from complaining 106 // that the provided value (0x80000000UL) is out of range of "int"] 107 NRF_I2S_MCK_32MDIV2 = (int)I2S_CONFIG_MCKFREQ_MCKFREQ_32MDIV2, ///< 32 MHz / 2 = 16.0 MHz. 108 #endif 109 #if defined(I2S_CONFIG_MCKFREQ_MCKFREQ_32MDIV3) || defined(__NRFX_DOXYGEN__) 110 NRF_I2S_MCK_32MDIV3 = I2S_CONFIG_MCKFREQ_MCKFREQ_32MDIV3, ///< 32 MHz / 3 = 10.6666667 MHz. 111 #endif 112 #if defined(I2S_CONFIG_MCKFREQ_MCKFREQ_32MDIV4) || defined(__NRFX_DOXYGEN__) 113 NRF_I2S_MCK_32MDIV4 = I2S_CONFIG_MCKFREQ_MCKFREQ_32MDIV4, ///< 32 MHz / 4 = 8.0 MHz. 114 #endif 115 #if defined(I2S_CONFIG_MCKFREQ_MCKFREQ_32MDIV5) || defined(__NRFX_DOXYGEN__) 116 NRF_I2S_MCK_32MDIV5 = I2S_CONFIG_MCKFREQ_MCKFREQ_32MDIV5, ///< 32 MHz / 5 = 6.4 MHz. 117 #endif 118 #if defined(I2S_CONFIG_MCKFREQ_MCKFREQ_32MDIV6) || defined(__NRFX_DOXYGEN__) 119 NRF_I2S_MCK_32MDIV6 = I2S_CONFIG_MCKFREQ_MCKFREQ_32MDIV6, ///< 32 MHz / 6 = 5.3333333 MHz. 120 #endif 121 NRF_I2S_MCK_32MDIV8 = I2S_CONFIG_MCKFREQ_MCKFREQ_32MDIV8, ///< 32 MHz / 8 = 4.0 MHz. 122 NRF_I2S_MCK_32MDIV10 = I2S_CONFIG_MCKFREQ_MCKFREQ_32MDIV10, ///< 32 MHz / 10 = 3.2 MHz. 123 NRF_I2S_MCK_32MDIV11 = I2S_CONFIG_MCKFREQ_MCKFREQ_32MDIV11, ///< 32 MHz / 11 = 2.9090909 MHz. 124 NRF_I2S_MCK_32MDIV15 = I2S_CONFIG_MCKFREQ_MCKFREQ_32MDIV15, ///< 32 MHz / 15 = 2.1333333 MHz. 125 NRF_I2S_MCK_32MDIV16 = I2S_CONFIG_MCKFREQ_MCKFREQ_32MDIV16, ///< 32 MHz / 16 = 2.0 MHz. 126 NRF_I2S_MCK_32MDIV21 = I2S_CONFIG_MCKFREQ_MCKFREQ_32MDIV21, ///< 32 MHz / 21 = 1.5238095 MHz. 127 NRF_I2S_MCK_32MDIV23 = I2S_CONFIG_MCKFREQ_MCKFREQ_32MDIV23, ///< 32 MHz / 23 = 1.3913043 MHz. 128 NRF_I2S_MCK_32MDIV31 = I2S_CONFIG_MCKFREQ_MCKFREQ_32MDIV31, ///< 32 MHz / 31 = 1.0322581 MHz. 129 NRF_I2S_MCK_32MDIV42 = I2S_CONFIG_MCKFREQ_MCKFREQ_32MDIV42, ///< 32 MHz / 42 = 0.7619048 MHz. 130 NRF_I2S_MCK_32MDIV63 = I2S_CONFIG_MCKFREQ_MCKFREQ_32MDIV63, ///< 32 MHz / 63 = 0.5079365 MHz. 131 NRF_I2S_MCK_32MDIV125 = I2S_CONFIG_MCKFREQ_MCKFREQ_32MDIV125 ///< 32 MHz / 125 = 0.256 MHz. 132 } nrf_i2s_mck_t; 133 134 /** 135 * @brief I2S MCK/LRCK ratios. 136 */ 137 typedef enum 138 { 139 NRF_I2S_RATIO_32X = I2S_CONFIG_RATIO_RATIO_32X, ///< LRCK = MCK / 32. 140 NRF_I2S_RATIO_48X = I2S_CONFIG_RATIO_RATIO_48X, ///< LRCK = MCK / 48. 141 NRF_I2S_RATIO_64X = I2S_CONFIG_RATIO_RATIO_64X, ///< LRCK = MCK / 64. 142 NRF_I2S_RATIO_96X = I2S_CONFIG_RATIO_RATIO_96X, ///< LRCK = MCK / 96. 143 NRF_I2S_RATIO_128X = I2S_CONFIG_RATIO_RATIO_128X, ///< LRCK = MCK / 128. 144 NRF_I2S_RATIO_192X = I2S_CONFIG_RATIO_RATIO_192X, ///< LRCK = MCK / 192. 145 NRF_I2S_RATIO_256X = I2S_CONFIG_RATIO_RATIO_256X, ///< LRCK = MCK / 256. 146 NRF_I2S_RATIO_384X = I2S_CONFIG_RATIO_RATIO_384X, ///< LRCK = MCK / 384. 147 NRF_I2S_RATIO_512X = I2S_CONFIG_RATIO_RATIO_512X ///< LRCK = MCK / 512. 148 } nrf_i2s_ratio_t; 149 150 /** 151 * @brief I2S sample widths. 152 */ 153 typedef enum 154 { 155 NRF_I2S_SWIDTH_8BIT = I2S_CONFIG_SWIDTH_SWIDTH_8Bit, ///< 8 bit. 156 NRF_I2S_SWIDTH_16BIT = I2S_CONFIG_SWIDTH_SWIDTH_16Bit, ///< 16 bit. 157 NRF_I2S_SWIDTH_24BIT = I2S_CONFIG_SWIDTH_SWIDTH_24Bit ///< 24 bit. 158 } nrf_i2s_swidth_t; 159 160 /** 161 * @brief I2S alignments of sample within a frame. 162 */ 163 typedef enum 164 { 165 NRF_I2S_ALIGN_LEFT = I2S_CONFIG_ALIGN_ALIGN_Left, ///< Left-aligned. 166 NRF_I2S_ALIGN_RIGHT = I2S_CONFIG_ALIGN_ALIGN_Right ///< Right-aligned. 167 } nrf_i2s_align_t; 168 169 /** 170 * @brief I2S frame formats. 171 */ 172 typedef enum 173 { 174 NRF_I2S_FORMAT_I2S = I2S_CONFIG_FORMAT_FORMAT_I2S, ///< Original I2S format. 175 NRF_I2S_FORMAT_ALIGNED = I2S_CONFIG_FORMAT_FORMAT_Aligned ///< Alternate (left- or right-aligned) format. 176 } nrf_i2s_format_t; 177 178 /** 179 * @brief I2S enabled channels. 180 */ 181 typedef enum 182 { 183 NRF_I2S_CHANNELS_STEREO = I2S_CONFIG_CHANNELS_CHANNELS_Stereo, ///< Stereo. 184 NRF_I2S_CHANNELS_LEFT = I2S_CONFIG_CHANNELS_CHANNELS_Left, ///< Left only. 185 NRF_I2S_CHANNELS_RIGHT = I2S_CONFIG_CHANNELS_CHANNELS_Right ///< Right only. 186 } nrf_i2s_channels_t; 187 188 189 /** 190 * @brief Function for activating a specific I2S task. 191 * 192 * @param[in] p_reg Pointer to the structure of registers of the peripheral. 193 * @param[in] task Task to activate. 194 */ 195 __STATIC_INLINE void nrf_i2s_task_trigger(NRF_I2S_Type * p_reg, 196 nrf_i2s_task_t task); 197 198 /** 199 * @brief Function for getting the address of a specific I2S task register. 200 * 201 * @param[in] p_reg Pointer to the structure of registers of the peripheral. 202 * @param[in] task Requested task. 203 * 204 * @return Address of the specified task register. 205 */ 206 __STATIC_INLINE uint32_t nrf_i2s_task_address_get(NRF_I2S_Type const * p_reg, 207 nrf_i2s_task_t task); 208 209 /** 210 * @brief Function for clearing a specific I2S event. 211 * 212 * @param[in] p_reg Pointer to the structure of registers of the peripheral. 213 * @param[in] event Event to clear. 214 */ 215 __STATIC_INLINE void nrf_i2s_event_clear(NRF_I2S_Type * p_reg, 216 nrf_i2s_event_t event); 217 218 /** 219 * @brief Function for checking the state of a specific I2S event. 220 * 221 * @param[in] p_reg Pointer to the structure of registers of the peripheral. 222 * @param[in] event Event to check. 223 * 224 * @retval true If the event is set. 225 * @retval false If the event is not set. 226 */ 227 __STATIC_INLINE bool nrf_i2s_event_check(NRF_I2S_Type const * p_reg, 228 nrf_i2s_event_t event); 229 230 /** 231 * @brief Function for getting the address of a specific I2S event register. 232 * 233 * @param[in] p_reg Pointer to the structure of registers of the peripheral. 234 * @param[in] event Requested event. 235 * 236 * @return Address of the specified event register. 237 */ 238 __STATIC_INLINE uint32_t nrf_i2s_event_address_get(NRF_I2S_Type const * p_reg, 239 nrf_i2s_event_t event); 240 241 /** 242 * @brief Function for enabling specified interrupts. 243 * 244 * @param[in] p_reg Pointer to the structure of registers of the peripheral. 245 * @param[in] mask Interrupts to enable. 246 */ 247 __STATIC_INLINE void nrf_i2s_int_enable(NRF_I2S_Type * p_reg, uint32_t mask); 248 249 /** 250 * @brief Function for disabling specified interrupts. 251 * 252 * @param[in] p_reg Pointer to the structure of registers of the peripheral. 253 * @param[in] mask Interrupts to disable. 254 */ 255 __STATIC_INLINE void nrf_i2s_int_disable(NRF_I2S_Type * p_reg, uint32_t mask); 256 257 /** 258 * @brief Function for retrieving the state of a given interrupt. 259 * 260 * @param[in] p_reg Pointer to the structure of registers of the peripheral. 261 * @param[in] i2s_int Interrupt to check. 262 * 263 * @retval true If the interrupt is enabled. 264 * @retval false If the interrupt is not enabled. 265 */ 266 __STATIC_INLINE bool nrf_i2s_int_enable_check(NRF_I2S_Type const * p_reg, 267 nrf_i2s_int_mask_t i2s_int); 268 269 /** 270 * @brief Function for enabling the I2S peripheral. 271 * 272 * @param[in] p_reg Pointer to the structure of registers of the peripheral. 273 */ 274 __STATIC_INLINE void nrf_i2s_enable(NRF_I2S_Type * p_reg); 275 276 /** 277 * @brief Function for disabling the I2S peripheral. 278 * 279 * @param[in] p_reg Pointer to the structure of registers of the peripheral. 280 */ 281 __STATIC_INLINE void nrf_i2s_disable(NRF_I2S_Type * p_reg); 282 283 #if defined(DPPI_PRESENT) || defined(__NRFX_DOXYGEN__) 284 /** 285 * @brief Function for setting the subscribe configuration for a given 286 * I2S task. 287 * 288 * @param[in] p_reg Pointer to the structure of registers of the peripheral. 289 * @param[in] task Task for which to set the configuration. 290 * @param[in] channel Channel through which to subscribe events. 291 */ 292 __STATIC_INLINE void nrf_i2s_subscribe_set(NRF_I2S_Type * p_reg, 293 nrf_i2s_task_t task, 294 uint8_t channel); 295 296 /** 297 * @brief Function for clearing the subscribe configuration for a given 298 * I2S task. 299 * 300 * @param[in] p_reg Pointer to the structure of registers of the peripheral. 301 * @param[in] task Task for which to clear the configuration. 302 */ 303 __STATIC_INLINE void nrf_i2s_subscribe_clear(NRF_I2S_Type * p_reg, 304 nrf_i2s_task_t task); 305 306 /** 307 * @brief Function for setting the publish configuration for a given 308 * I2S event. 309 * 310 * @param[in] p_reg Pointer to the structure of registers of the peripheral. 311 * @param[in] event Event for which to set the configuration. 312 * @param[in] channel Channel through which to publish the event. 313 */ 314 __STATIC_INLINE void nrf_i2s_publish_set(NRF_I2S_Type * p_reg, 315 nrf_i2s_event_t event, 316 uint8_t channel); 317 318 /** 319 * @brief Function for clearing the publish configuration for a given 320 * I2S event. 321 * 322 * @param[in] p_reg Pointer to the structure of registers of the peripheral. 323 * @param[in] event Event for which to clear the configuration. 324 */ 325 __STATIC_INLINE void nrf_i2s_publish_clear(NRF_I2S_Type * p_reg, 326 nrf_i2s_event_t event); 327 #endif // defined(DPPI_PRESENT) || defined(__NRFX_DOXYGEN__) 328 329 /** 330 * @brief Function for configuring I2S pins. 331 * 332 * Usage of the SDOUT, SDIN, and MCK signals is optional. 333 * If a given signal is not needed, pass the @ref NRF_I2S_PIN_NOT_CONNECTED 334 * value instead of its pin number. 335 * 336 * @param[in] p_reg Pointer to the structure of registers of the peripheral. 337 * @param[in] sck_pin SCK pin number. 338 * @param[in] lrck_pin LRCK pin number. 339 * @param[in] mck_pin MCK pin number. 340 * @param[in] sdout_pin SDOUT pin number. 341 * @param[in] sdin_pin SDIN pin number. 342 */ 343 __STATIC_INLINE void nrf_i2s_pins_set(NRF_I2S_Type * p_reg, 344 uint32_t sck_pin, 345 uint32_t lrck_pin, 346 uint32_t mck_pin, 347 uint32_t sdout_pin, 348 uint32_t sdin_pin); 349 350 /** 351 * @brief Function for setting the I2S peripheral configuration. 352 * 353 * @param[in] p_reg Pointer to the structure of registers of the peripheral. 354 * @param[in] mode Mode of operation (master or slave). 355 * @param[in] format I2S frame format. 356 * @param[in] alignment Alignment of sample within a frame. 357 * @param[in] sample_width Sample width. 358 * @param[in] channels Enabled channels. 359 * @param[in] mck_setup Master clock generator setup. 360 * @param[in] ratio MCK/LRCK ratio. 361 * 362 * @retval true If the configuration has been set successfully. 363 * @retval false If the requested configuration is not allowed. 364 */ 365 __STATIC_INLINE bool nrf_i2s_configure(NRF_I2S_Type * p_reg, 366 nrf_i2s_mode_t mode, 367 nrf_i2s_format_t format, 368 nrf_i2s_align_t alignment, 369 nrf_i2s_swidth_t sample_width, 370 nrf_i2s_channels_t channels, 371 nrf_i2s_mck_t mck_setup, 372 nrf_i2s_ratio_t ratio); 373 374 /** 375 * @brief Function for setting up the I2S transfer. 376 * 377 * This function sets up the RX and TX buffers and enables reception and/or 378 * transmission accordingly. If the transfer in a given direction is not 379 * required, pass NULL instead of the pointer to the corresponding buffer. 380 * 381 * @param[in] p_reg Pointer to the structure of registers of the peripheral. 382 * @param[in] size Size of the buffers (in 32-bit words). 383 * @param[in] p_rx_buffer Pointer to the receive buffer. 384 * Pass NULL to disable reception. 385 * @param[in] p_tx_buffer Pointer to the transmit buffer. 386 * Pass NULL to disable transmission. 387 */ 388 __STATIC_INLINE void nrf_i2s_transfer_set(NRF_I2S_Type * p_reg, 389 uint16_t size, 390 uint32_t * p_rx_buffer, 391 uint32_t const * p_tx_buffer); 392 393 /** 394 * @brief Function for setting the pointer to the receive buffer. 395 * 396 * @note The size of the buffer can be set only by calling 397 * @ref nrf_i2s_transfer_set. 398 * 399 * @param[in] p_reg Pointer to the structure of registers of the peripheral. 400 * @param[in] p_buffer Pointer to the receive buffer. 401 */ 402 __STATIC_INLINE void nrf_i2s_rx_buffer_set(NRF_I2S_Type * p_reg, 403 uint32_t * p_buffer); 404 405 /** 406 * @brief Function for getting the pointer to the receive buffer. 407 * 408 * @param[in] p_reg Pointer to the structure of registers of the peripheral. 409 * 410 * @return Pointer to the receive buffer. 411 */ 412 __STATIC_INLINE uint32_t * nrf_i2s_rx_buffer_get(NRF_I2S_Type const * p_reg); 413 414 /** 415 * @brief Function for setting the pointer to the transmit buffer. 416 * 417 * @note The size of the buffer can be set only by calling 418 * @ref nrf_i2s_transfer_set. 419 * 420 * @param[in] p_reg Pointer to the structure of registers of the peripheral. 421 * @param[in] p_buffer Pointer to the transmit buffer. 422 */ 423 __STATIC_INLINE void nrf_i2s_tx_buffer_set(NRF_I2S_Type * p_reg, 424 uint32_t const * p_buffer); 425 426 /** 427 * @brief Function for getting the pointer to the transmit buffer. 428 * 429 * @param[in] p_reg Pointer to the structure of registers of the peripheral. 430 * 431 * @return Pointer to the transmit buffer. 432 */ 433 __STATIC_INLINE uint32_t * nrf_i2s_tx_buffer_get(NRF_I2S_Type const * p_reg); 434 435 436 #ifndef SUPPRESS_INLINE_IMPLEMENTATION 437 438 __STATIC_INLINE void nrf_i2s_task_trigger(NRF_I2S_Type * p_reg, 439 nrf_i2s_task_t task) 440 { 441 *((volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)task)) = 0x1UL; 442 } 443 444 __STATIC_INLINE uint32_t nrf_i2s_task_address_get(NRF_I2S_Type const * p_reg, 445 nrf_i2s_task_t task) 446 { 447 return ((uint32_t)p_reg + (uint32_t)task); 448 } 449 450 __STATIC_INLINE void nrf_i2s_event_clear(NRF_I2S_Type * p_reg, 451 nrf_i2s_event_t event) 452 { 453 *((volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)event)) = 0x0UL; 454 #if __CORTEX_M == 0x04 455 volatile uint32_t dummy = *((volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)event)); 456 (void)dummy; 457 #endif 458 } 459 460 __STATIC_INLINE bool nrf_i2s_event_check(NRF_I2S_Type const * p_reg, 461 nrf_i2s_event_t event) 462 { 463 return (bool)*(volatile uint32_t *)((uint8_t *)p_reg + (uint32_t)event); 464 } 465 466 __STATIC_INLINE uint32_t nrf_i2s_event_address_get(NRF_I2S_Type const * p_reg, 467 nrf_i2s_event_t event) 468 { 469 return ((uint32_t)p_reg + (uint32_t)event); 470 } 471 472 __STATIC_INLINE void nrf_i2s_int_enable(NRF_I2S_Type * p_reg, uint32_t mask) 473 { 474 p_reg->INTENSET = mask; 475 } 476 477 __STATIC_INLINE void nrf_i2s_int_disable(NRF_I2S_Type * p_reg, uint32_t mask) 478 { 479 p_reg->INTENCLR = mask; 480 } 481 482 __STATIC_INLINE bool nrf_i2s_int_enable_check(NRF_I2S_Type const * p_reg, 483 nrf_i2s_int_mask_t i2s_int) 484 { 485 return (bool)(p_reg->INTENSET & i2s_int); 486 } 487 488 __STATIC_INLINE void nrf_i2s_enable(NRF_I2S_Type * p_reg) 489 { 490 p_reg->ENABLE = (I2S_ENABLE_ENABLE_Enabled << I2S_ENABLE_ENABLE_Pos); 491 } 492 493 __STATIC_INLINE void nrf_i2s_disable(NRF_I2S_Type * p_reg) 494 { 495 p_reg->ENABLE = (I2S_ENABLE_ENABLE_Disabled << I2S_ENABLE_ENABLE_Pos); 496 } 497 498 #if defined(DPPI_PRESENT) 499 __STATIC_INLINE void nrf_i2s_subscribe_set(NRF_I2S_Type * p_reg, 500 nrf_i2s_task_t task, 501 uint8_t channel) 502 { 503 *((volatile uint32_t *) ((uint8_t *) p_reg + (uint32_t) task + 0x80uL)) = 504 ((uint32_t)channel | I2S_SUBSCRIBE_START_EN_Msk); 505 } 506 507 __STATIC_INLINE void nrf_i2s_subscribe_clear(NRF_I2S_Type * p_reg, 508 nrf_i2s_task_t task) 509 { 510 *((volatile uint32_t *) ((uint8_t *) p_reg + (uint32_t) task + 0x80uL)) = 0; 511 } 512 513 __STATIC_INLINE void nrf_i2s_publish_set(NRF_I2S_Type * p_reg, 514 nrf_i2s_event_t event, 515 uint8_t channel) 516 { 517 *((volatile uint32_t *) ((uint8_t *) p_reg + (uint32_t) event + 0x80uL)) = 518 ((uint32_t)channel | I2S_PUBLISH_STOPPED_EN_Msk); 519 } 520 521 __STATIC_INLINE void nrf_i2s_publish_clear(NRF_I2S_Type * p_reg, 522 nrf_i2s_event_t event) 523 { 524 *((volatile uint32_t *) ((uint8_t *) p_reg + (uint32_t) event + 0x80uL)) = 0; 525 } 526 #endif // defined(DPPI_PRESENT) 527 528 __STATIC_INLINE void nrf_i2s_pins_set(NRF_I2S_Type * p_reg, 529 uint32_t sck_pin, 530 uint32_t lrck_pin, 531 uint32_t mck_pin, 532 uint32_t sdout_pin, 533 uint32_t sdin_pin) 534 { 535 p_reg->PSEL.SCK = sck_pin; 536 p_reg->PSEL.LRCK = lrck_pin; 537 p_reg->PSEL.MCK = mck_pin; 538 p_reg->PSEL.SDOUT = sdout_pin; 539 p_reg->PSEL.SDIN = sdin_pin; 540 } 541 542 __STATIC_INLINE bool nrf_i2s_configure(NRF_I2S_Type * p_reg, 543 nrf_i2s_mode_t mode, 544 nrf_i2s_format_t format, 545 nrf_i2s_align_t alignment, 546 nrf_i2s_swidth_t sample_width, 547 nrf_i2s_channels_t channels, 548 nrf_i2s_mck_t mck_setup, 549 nrf_i2s_ratio_t ratio) 550 { 551 if (mode == NRF_I2S_MODE_MASTER) 552 { 553 // The MCK/LRCK ratio shall be a multiple of 2 * sample width. 554 if (((sample_width == NRF_I2S_SWIDTH_16BIT) && 555 (ratio == NRF_I2S_RATIO_48X)) 556 || 557 ((sample_width == NRF_I2S_SWIDTH_24BIT) && 558 ((ratio == NRF_I2S_RATIO_32X) || 559 (ratio == NRF_I2S_RATIO_64X) || 560 (ratio == NRF_I2S_RATIO_128X) || 561 (ratio == NRF_I2S_RATIO_256X) || 562 (ratio == NRF_I2S_RATIO_512X)))) 563 { 564 return false; 565 } 566 } 567 568 p_reg->CONFIG.MODE = mode; 569 p_reg->CONFIG.FORMAT = format; 570 p_reg->CONFIG.ALIGN = alignment; 571 p_reg->CONFIG.SWIDTH = sample_width; 572 p_reg->CONFIG.CHANNELS = channels; 573 p_reg->CONFIG.RATIO = ratio; 574 575 if (mck_setup == NRF_I2S_MCK_DISABLED) 576 { 577 p_reg->CONFIG.MCKEN = 578 (I2S_CONFIG_MCKEN_MCKEN_Disabled << I2S_CONFIG_MCKEN_MCKEN_Pos); 579 } 580 else 581 { 582 p_reg->CONFIG.MCKFREQ = mck_setup; 583 p_reg->CONFIG.MCKEN = 584 (I2S_CONFIG_MCKEN_MCKEN_Enabled << I2S_CONFIG_MCKEN_MCKEN_Pos); 585 } 586 587 return true; 588 } 589 590 __STATIC_INLINE void nrf_i2s_transfer_set(NRF_I2S_Type * p_reg, 591 uint16_t size, 592 uint32_t * p_buffer_rx, 593 uint32_t const * p_buffer_tx) 594 { 595 p_reg->RXTXD.MAXCNT = size; 596 597 nrf_i2s_rx_buffer_set(p_reg, p_buffer_rx); 598 p_reg->CONFIG.RXEN = (p_buffer_rx != NULL) ? 1 : 0; 599 600 nrf_i2s_tx_buffer_set(p_reg, p_buffer_tx); 601 p_reg->CONFIG.TXEN = (p_buffer_tx != NULL) ? 1 : 0; 602 } 603 604 __STATIC_INLINE void nrf_i2s_rx_buffer_set(NRF_I2S_Type * p_reg, 605 uint32_t * p_buffer) 606 { 607 p_reg->RXD.PTR = (uint32_t)p_buffer; 608 } 609 610 __STATIC_INLINE uint32_t * nrf_i2s_rx_buffer_get(NRF_I2S_Type const * p_reg) 611 { 612 return (uint32_t *)(p_reg->RXD.PTR); 613 } 614 615 __STATIC_INLINE void nrf_i2s_tx_buffer_set(NRF_I2S_Type * p_reg, 616 uint32_t const * p_buffer) 617 { 618 p_reg->TXD.PTR = (uint32_t)p_buffer; 619 } 620 621 __STATIC_INLINE uint32_t * nrf_i2s_tx_buffer_get(NRF_I2S_Type const * p_reg) 622 { 623 return (uint32_t *)(p_reg->TXD.PTR); 624 } 625 626 #endif // SUPPRESS_INLINE_IMPLEMENTATION 627 628 /** @} */ 629 630 #ifdef __cplusplus 631 } 632 #endif 633 634 #endif // NRF_I2S_H__ 635