1*150812a8SEvalZero /* 2*150812a8SEvalZero * Copyright (c) 2015 - 2018, Nordic Semiconductor ASA 3*150812a8SEvalZero * All rights reserved. 4*150812a8SEvalZero * 5*150812a8SEvalZero * Redistribution and use in source and binary forms, with or without 6*150812a8SEvalZero * modification, are permitted provided that the following conditions are met: 7*150812a8SEvalZero * 8*150812a8SEvalZero * 1. Redistributions of source code must retain the above copyright notice, this 9*150812a8SEvalZero * list of conditions and the following disclaimer. 10*150812a8SEvalZero * 11*150812a8SEvalZero * 2. Redistributions in binary form must reproduce the above copyright 12*150812a8SEvalZero * notice, this list of conditions and the following disclaimer in the 13*150812a8SEvalZero * documentation and/or other materials provided with the distribution. 14*150812a8SEvalZero * 15*150812a8SEvalZero * 3. Neither the name of the copyright holder nor the names of its 16*150812a8SEvalZero * contributors may be used to endorse or promote products derived from this 17*150812a8SEvalZero * software without specific prior written permission. 18*150812a8SEvalZero * 19*150812a8SEvalZero * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 20*150812a8SEvalZero * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21*150812a8SEvalZero * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22*150812a8SEvalZero * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 23*150812a8SEvalZero * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24*150812a8SEvalZero * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25*150812a8SEvalZero * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26*150812a8SEvalZero * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27*150812a8SEvalZero * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28*150812a8SEvalZero * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29*150812a8SEvalZero * POSSIBILITY OF SUCH DAMAGE. 30*150812a8SEvalZero */ 31*150812a8SEvalZero 32*150812a8SEvalZero #ifndef NRFX_I2S_H__ 33*150812a8SEvalZero #define NRFX_I2S_H__ 34*150812a8SEvalZero 35*150812a8SEvalZero #include <nrfx.h> 36*150812a8SEvalZero #include <hal/nrf_i2s.h> 37*150812a8SEvalZero 38*150812a8SEvalZero #ifdef __cplusplus 39*150812a8SEvalZero extern "C" { 40*150812a8SEvalZero #endif 41*150812a8SEvalZero 42*150812a8SEvalZero /** 43*150812a8SEvalZero * @defgroup nrfx_i2s I2S driver 44*150812a8SEvalZero * @{ 45*150812a8SEvalZero * @ingroup nrf_i2s 46*150812a8SEvalZero * @brief Inter-IC Sound (I2S) peripheral driver. 47*150812a8SEvalZero */ 48*150812a8SEvalZero 49*150812a8SEvalZero 50*150812a8SEvalZero /** 51*150812a8SEvalZero * @brief This value can be provided instead of a pin number for the signals 52*150812a8SEvalZero * SDOUT, SDIN, and MCK to specify that a given signal is not used 53*150812a8SEvalZero * and therefore does not need to be connected to a pin. 54*150812a8SEvalZero */ 55*150812a8SEvalZero #define NRFX_I2S_PIN_NOT_USED 0xFF 56*150812a8SEvalZero 57*150812a8SEvalZero /** @brief I2S driver configuration structure. */ 58*150812a8SEvalZero typedef struct 59*150812a8SEvalZero { 60*150812a8SEvalZero uint8_t sck_pin; ///< SCK pin number. 61*150812a8SEvalZero uint8_t lrck_pin; ///< LRCK pin number. 62*150812a8SEvalZero uint8_t mck_pin; ///< MCK pin number. 63*150812a8SEvalZero /**< Optional. Use @ref NRFX_I2S_PIN_NOT_USED 64*150812a8SEvalZero * if this signal is not needed. */ 65*150812a8SEvalZero uint8_t sdout_pin; ///< SDOUT pin number. 66*150812a8SEvalZero /**< Optional. Use @ref NRFX_I2S_PIN_NOT_USED 67*150812a8SEvalZero * if this signal is not needed. */ 68*150812a8SEvalZero uint8_t sdin_pin; ///< SDIN pin number. 69*150812a8SEvalZero /**< Optional. Use @ref NRFX_I2S_PIN_NOT_USED 70*150812a8SEvalZero * if this signal is not needed. */ 71*150812a8SEvalZero uint8_t irq_priority; ///< Interrupt priority. 72*150812a8SEvalZero 73*150812a8SEvalZero nrf_i2s_mode_t mode; ///< Mode of operation. 74*150812a8SEvalZero nrf_i2s_format_t format; ///< Frame format. 75*150812a8SEvalZero nrf_i2s_align_t alignment; ///< Alignment of sample within a frame. 76*150812a8SEvalZero nrf_i2s_swidth_t sample_width; ///< Sample width. 77*150812a8SEvalZero nrf_i2s_channels_t channels; ///< Enabled channels. 78*150812a8SEvalZero nrf_i2s_mck_t mck_setup; ///< Master clock setup. 79*150812a8SEvalZero nrf_i2s_ratio_t ratio; ///< MCK/LRCK ratio. 80*150812a8SEvalZero } nrfx_i2s_config_t; 81*150812a8SEvalZero 82*150812a8SEvalZero /** @brief I2S driver buffers structure. */ 83*150812a8SEvalZero typedef struct 84*150812a8SEvalZero { 85*150812a8SEvalZero uint32_t * p_rx_buffer; 86*150812a8SEvalZero uint32_t const * p_tx_buffer; 87*150812a8SEvalZero } nrfx_i2s_buffers_t; 88*150812a8SEvalZero 89*150812a8SEvalZero /** 90*150812a8SEvalZero * @brief I2S driver default configuration. 91*150812a8SEvalZero */ 92*150812a8SEvalZero #define NRFX_I2S_DEFAULT_CONFIG \ 93*150812a8SEvalZero { \ 94*150812a8SEvalZero .sck_pin = NRFX_I2S_CONFIG_SCK_PIN, \ 95*150812a8SEvalZero .lrck_pin = NRFX_I2S_CONFIG_LRCK_PIN, \ 96*150812a8SEvalZero .mck_pin = NRFX_I2S_CONFIG_MCK_PIN, \ 97*150812a8SEvalZero .sdout_pin = NRFX_I2S_CONFIG_SDOUT_PIN, \ 98*150812a8SEvalZero .sdin_pin = NRFX_I2S_CONFIG_SDIN_PIN, \ 99*150812a8SEvalZero .irq_priority = NRFX_I2S_CONFIG_IRQ_PRIORITY, \ 100*150812a8SEvalZero .mode = (nrf_i2s_mode_t)NRFX_I2S_CONFIG_MASTER, \ 101*150812a8SEvalZero .format = (nrf_i2s_format_t)NRFX_I2S_CONFIG_FORMAT, \ 102*150812a8SEvalZero .alignment = (nrf_i2s_align_t)NRFX_I2S_CONFIG_ALIGN, \ 103*150812a8SEvalZero .sample_width = (nrf_i2s_swidth_t)NRFX_I2S_CONFIG_SWIDTH, \ 104*150812a8SEvalZero .channels = (nrf_i2s_channels_t)NRFX_I2S_CONFIG_CHANNELS, \ 105*150812a8SEvalZero .mck_setup = (nrf_i2s_mck_t)NRFX_I2S_CONFIG_MCK_SETUP, \ 106*150812a8SEvalZero .ratio = (nrf_i2s_ratio_t)NRFX_I2S_CONFIG_RATIO, \ 107*150812a8SEvalZero } 108*150812a8SEvalZero 109*150812a8SEvalZero 110*150812a8SEvalZero #define NRFX_I2S_STATUS_NEXT_BUFFERS_NEEDED (1UL << 0) 111*150812a8SEvalZero /**< The application should provide buffers that are to be used in the next 112*150812a8SEvalZero * part of the transfer. A call to @ref nrfx_i2s_next_buffers_set should 113*150812a8SEvalZero * be done before the currently used buffers are completely processed 114*150812a8SEvalZero * (i.e. the time remaining for supplying the next buffers depends on 115*150812a8SEvalZero * the used size of the buffers). */ 116*150812a8SEvalZero 117*150812a8SEvalZero /** 118*150812a8SEvalZero * @brief I2S driver data handler type. 119*150812a8SEvalZero * 120*150812a8SEvalZero * A data handling function of this type must be specified during initialization 121*150812a8SEvalZero * of the driver. The driver will call this function when it finishes using 122*150812a8SEvalZero * buffers passed to it by the application, and when it needs to be provided 123*150812a8SEvalZero * with buffers for the next part of the transfer. 124*150812a8SEvalZero * 125*150812a8SEvalZero * @note The @c p_released pointer passed to this function is temporary and 126*150812a8SEvalZero * will be invalid after the function returns, hence it cannot be stored 127*150812a8SEvalZero * and used later. If needed, the pointed content (i.e. buffers pointers) 128*150812a8SEvalZero * should be copied instead. 129*150812a8SEvalZero * 130*150812a8SEvalZero * @param[in] p_released Pointer to a structure with pointers to buffers 131*150812a8SEvalZero * passed previously to the driver that will no longer 132*150812a8SEvalZero * be access by it (they can be now safely released or 133*150812a8SEvalZero * used for another purpose, in particular for a next 134*150812a8SEvalZero * part of the transfer). 135*150812a8SEvalZero * This pointer will be NULL if the application did not 136*150812a8SEvalZero * supply the buffers for the next part of the transfer 137*150812a8SEvalZero * (via a call to @ref nrfx_i2s_next_buffers_set) since 138*150812a8SEvalZero * the previous time the data handler signaled such need. 139*150812a8SEvalZero * This means that data corruption occurred (the previous 140*150812a8SEvalZero * buffers are used for the second time) and no buffers 141*150812a8SEvalZero * can be released at the moment. 142*150812a8SEvalZero * Both pointers in this structure are NULL when the 143*150812a8SEvalZero * handler is called for the first time after a transfer 144*150812a8SEvalZero * is started, because no data has been transferred yet 145*150812a8SEvalZero * at this point. In all successive calls the pointers 146*150812a8SEvalZero * specify what has been sent (TX) and what has been 147*150812a8SEvalZero * received (RX) in the part of transfer that has just 148*150812a8SEvalZero * been completed (provided that a given direction is 149*150812a8SEvalZero * enabled, see @ref nrfx_i2s_start). 150*150812a8SEvalZero * @param[in] status Bit field describing the current status of the transfer. 151*150812a8SEvalZero * It can be 0 or a combination of the following flags: 152*150812a8SEvalZero * - @ref NRFX_I2S_STATUS_NEXT_BUFFERS_NEEDED 153*150812a8SEvalZero */ 154*150812a8SEvalZero typedef void (* nrfx_i2s_data_handler_t)(nrfx_i2s_buffers_t const * p_released, 155*150812a8SEvalZero uint32_t status); 156*150812a8SEvalZero 157*150812a8SEvalZero 158*150812a8SEvalZero /** 159*150812a8SEvalZero * @brief Function for initializing the I2S driver. 160*150812a8SEvalZero * 161*150812a8SEvalZero * @param[in] p_config Pointer to the structure with initial configuration. 162*150812a8SEvalZero * @param[in] handler Data handler provided by the user. Must not be NULL. 163*150812a8SEvalZero * 164*150812a8SEvalZero * @retval NRFX_SUCCESS If initialization was successful. 165*150812a8SEvalZero * @retval NRFX_ERROR_INVALID_STATE If the driver was already initialized. 166*150812a8SEvalZero * @retval NRFX_ERROR_INVALID_PARAM If the requested combination of configuration 167*150812a8SEvalZero * options is not allowed by the I2S peripheral. 168*150812a8SEvalZero */ 169*150812a8SEvalZero nrfx_err_t nrfx_i2s_init(nrfx_i2s_config_t const * p_config, 170*150812a8SEvalZero nrfx_i2s_data_handler_t handler); 171*150812a8SEvalZero 172*150812a8SEvalZero /** @brief Function for uninitializing the I2S driver. */ 173*150812a8SEvalZero void nrfx_i2s_uninit(void); 174*150812a8SEvalZero 175*150812a8SEvalZero /** 176*150812a8SEvalZero * @brief Function for starting the continuous I2S transfer. 177*150812a8SEvalZero * 178*150812a8SEvalZero * The I2S data transfer can be performed in one of three modes: RX (reception) 179*150812a8SEvalZero * only, TX (transmission) only, or in both directions simultaneously. 180*150812a8SEvalZero * The mode is selected by specifying a proper buffer for a given direction 181*150812a8SEvalZero * in the call to this function or by passing NULL instead if this direction 182*150812a8SEvalZero * should be disabled. 183*150812a8SEvalZero * 184*150812a8SEvalZero * The length of the buffer (which is a common value for RX and TX if both 185*150812a8SEvalZero * directions are enabled) is specified in 32-bit words. One 32-bit memory 186*150812a8SEvalZero * word can either contain four 8-bit samples, two 16-bit samples, or one 187*150812a8SEvalZero * right-aligned 24-bit sample sign-extended to a 32-bit value. 188*150812a8SEvalZero * For a detailed memory mapping for different supported configurations, 189*150812a8SEvalZero * see the @linkProductSpecification52. 190*150812a8SEvalZero * 191*150812a8SEvalZero * @note Peripherals using EasyDMA (including I2S) require the transfer buffers 192*150812a8SEvalZero * to be placed in the Data RAM region. If this condition is not met, 193*150812a8SEvalZero * this function will fail with the error code NRFX_ERROR_INVALID_ADDR. 194*150812a8SEvalZero * 195*150812a8SEvalZero * @param[in] p_initial_buffers Pointer to a structure specifying the buffers 196*150812a8SEvalZero * to be used in the initial part of the transfer 197*150812a8SEvalZero * (buffers for all consecutive parts are provided 198*150812a8SEvalZero * through the data handler). 199*150812a8SEvalZero * @param[in] buffer_size Size of the buffers (in 32-bit words). 200*150812a8SEvalZero * Must not be 0. 201*150812a8SEvalZero * @param[in] flags Transfer options (0 for default settings). 202*150812a8SEvalZero * Currently, no additional flags are available. 203*150812a8SEvalZero * 204*150812a8SEvalZero * @retval NRFX_SUCCESS If the operation was successful. 205*150812a8SEvalZero * @retval NRFX_ERROR_INVALID_STATE If a transfer was already started or 206*150812a8SEvalZero * the driver has not been initialized. 207*150812a8SEvalZero * @retval NRFX_ERROR_INVALID_ADDR If the provided buffers are not placed 208*150812a8SEvalZero * in the Data RAM region. 209*150812a8SEvalZero */ 210*150812a8SEvalZero nrfx_err_t nrfx_i2s_start(nrfx_i2s_buffers_t const * p_initial_buffers, 211*150812a8SEvalZero uint16_t buffer_size, 212*150812a8SEvalZero uint8_t flags); 213*150812a8SEvalZero 214*150812a8SEvalZero /** 215*150812a8SEvalZero * @brief Function for supplying the buffers to be used in the next part of 216*150812a8SEvalZero * the transfer. 217*150812a8SEvalZero * 218*150812a8SEvalZero * The application should call this function when the data handler receives 219*150812a8SEvalZero * @ref NRFX_I2S_STATUS_NEXT_BUFFERS_NEEDED in the @c status parameter. 220*150812a8SEvalZero * The call can be done immediately from the data handler function or later, 221*150812a8SEvalZero * but it has to be done before the I2S peripheral finishes processing the 222*150812a8SEvalZero * buffers supplied previously. Otherwise, data corruption will occur. 223*150812a8SEvalZero * 224*150812a8SEvalZero * @sa nrfx_i2s_data_handler_t 225*150812a8SEvalZero * 226*150812a8SEvalZero * @retval NRFX_SUCCESS If the operation was successful. 227*150812a8SEvalZero * @retval NRFX_ERROR_INVALID_STATE If the buffers were already supplied or 228*150812a8SEvalZero * the peripheral is currently being stopped. 229*150812a8SEvalZero */ 230*150812a8SEvalZero nrfx_err_t nrfx_i2s_next_buffers_set(nrfx_i2s_buffers_t const * p_buffers); 231*150812a8SEvalZero 232*150812a8SEvalZero /** @brief Function for stopping the I2S transfer. */ 233*150812a8SEvalZero void nrfx_i2s_stop(void); 234*150812a8SEvalZero 235*150812a8SEvalZero /** @} */ 236*150812a8SEvalZero 237*150812a8SEvalZero 238*150812a8SEvalZero void nrfx_i2s_irq_handler(void); 239*150812a8SEvalZero 240*150812a8SEvalZero 241*150812a8SEvalZero #ifdef __cplusplus 242*150812a8SEvalZero } 243*150812a8SEvalZero #endif 244*150812a8SEvalZero 245*150812a8SEvalZero #endif // NRFX_I2S_H__ 246