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_I2S_H__ 33 #define NRFX_I2S_H__ 34 35 #include <nrfx.h> 36 #include <hal/nrf_i2s.h> 37 38 #ifdef __cplusplus 39 extern "C" { 40 #endif 41 42 /** 43 * @defgroup nrfx_i2s I2S driver 44 * @{ 45 * @ingroup nrf_i2s 46 * @brief Inter-IC Sound (I2S) peripheral driver. 47 */ 48 49 50 /** 51 * @brief This value can be provided instead of a pin number for the signals 52 * SDOUT, SDIN, and MCK to specify that a given signal is not used 53 * and therefore does not need to be connected to a pin. 54 */ 55 #define NRFX_I2S_PIN_NOT_USED 0xFF 56 57 /** @brief I2S driver configuration structure. */ 58 typedef struct 59 { 60 uint8_t sck_pin; ///< SCK pin number. 61 uint8_t lrck_pin; ///< LRCK pin number. 62 uint8_t mck_pin; ///< MCK pin number. 63 /**< Optional. Use @ref NRFX_I2S_PIN_NOT_USED 64 * if this signal is not needed. */ 65 uint8_t sdout_pin; ///< SDOUT pin number. 66 /**< Optional. Use @ref NRFX_I2S_PIN_NOT_USED 67 * if this signal is not needed. */ 68 uint8_t sdin_pin; ///< SDIN pin number. 69 /**< Optional. Use @ref NRFX_I2S_PIN_NOT_USED 70 * if this signal is not needed. */ 71 uint8_t irq_priority; ///< Interrupt priority. 72 73 nrf_i2s_mode_t mode; ///< Mode of operation. 74 nrf_i2s_format_t format; ///< Frame format. 75 nrf_i2s_align_t alignment; ///< Alignment of sample within a frame. 76 nrf_i2s_swidth_t sample_width; ///< Sample width. 77 nrf_i2s_channels_t channels; ///< Enabled channels. 78 nrf_i2s_mck_t mck_setup; ///< Master clock setup. 79 nrf_i2s_ratio_t ratio; ///< MCK/LRCK ratio. 80 } nrfx_i2s_config_t; 81 82 /** @brief I2S driver buffers structure. */ 83 typedef struct 84 { 85 uint32_t * p_rx_buffer; 86 uint32_t const * p_tx_buffer; 87 } nrfx_i2s_buffers_t; 88 89 /** 90 * @brief I2S driver default configuration. 91 */ 92 #define NRFX_I2S_DEFAULT_CONFIG \ 93 { \ 94 .sck_pin = NRFX_I2S_CONFIG_SCK_PIN, \ 95 .lrck_pin = NRFX_I2S_CONFIG_LRCK_PIN, \ 96 .mck_pin = NRFX_I2S_CONFIG_MCK_PIN, \ 97 .sdout_pin = NRFX_I2S_CONFIG_SDOUT_PIN, \ 98 .sdin_pin = NRFX_I2S_CONFIG_SDIN_PIN, \ 99 .irq_priority = NRFX_I2S_CONFIG_IRQ_PRIORITY, \ 100 .mode = (nrf_i2s_mode_t)NRFX_I2S_CONFIG_MASTER, \ 101 .format = (nrf_i2s_format_t)NRFX_I2S_CONFIG_FORMAT, \ 102 .alignment = (nrf_i2s_align_t)NRFX_I2S_CONFIG_ALIGN, \ 103 .sample_width = (nrf_i2s_swidth_t)NRFX_I2S_CONFIG_SWIDTH, \ 104 .channels = (nrf_i2s_channels_t)NRFX_I2S_CONFIG_CHANNELS, \ 105 .mck_setup = (nrf_i2s_mck_t)NRFX_I2S_CONFIG_MCK_SETUP, \ 106 .ratio = (nrf_i2s_ratio_t)NRFX_I2S_CONFIG_RATIO, \ 107 } 108 109 110 #define NRFX_I2S_STATUS_NEXT_BUFFERS_NEEDED (1UL << 0) 111 /**< The application should provide buffers that are to be used in the next 112 * part of the transfer. A call to @ref nrfx_i2s_next_buffers_set should 113 * be done before the currently used buffers are completely processed 114 * (i.e. the time remaining for supplying the next buffers depends on 115 * the used size of the buffers). */ 116 117 /** 118 * @brief I2S driver data handler type. 119 * 120 * A data handling function of this type must be specified during initialization 121 * of the driver. The driver will call this function when it finishes using 122 * buffers passed to it by the application, and when it needs to be provided 123 * with buffers for the next part of the transfer. 124 * 125 * @note The @c p_released pointer passed to this function is temporary and 126 * will be invalid after the function returns, hence it cannot be stored 127 * and used later. If needed, the pointed content (i.e. buffers pointers) 128 * should be copied instead. 129 * 130 * @param[in] p_released Pointer to a structure with pointers to buffers 131 * passed previously to the driver that will no longer 132 * be access by it (they can be now safely released or 133 * used for another purpose, in particular for a next 134 * part of the transfer). 135 * This pointer will be NULL if the application did not 136 * supply the buffers for the next part of the transfer 137 * (via a call to @ref nrfx_i2s_next_buffers_set) since 138 * the previous time the data handler signaled such need. 139 * This means that data corruption occurred (the previous 140 * buffers are used for the second time) and no buffers 141 * can be released at the moment. 142 * Both pointers in this structure are NULL when the 143 * handler is called for the first time after a transfer 144 * is started, because no data has been transferred yet 145 * at this point. In all successive calls the pointers 146 * specify what has been sent (TX) and what has been 147 * received (RX) in the part of transfer that has just 148 * been completed (provided that a given direction is 149 * enabled, see @ref nrfx_i2s_start). 150 * @param[in] status Bit field describing the current status of the transfer. 151 * It can be 0 or a combination of the following flags: 152 * - @ref NRFX_I2S_STATUS_NEXT_BUFFERS_NEEDED 153 */ 154 typedef void (* nrfx_i2s_data_handler_t)(nrfx_i2s_buffers_t const * p_released, 155 uint32_t status); 156 157 158 /** 159 * @brief Function for initializing the I2S driver. 160 * 161 * @param[in] p_config Pointer to the structure with initial configuration. 162 * @param[in] handler Data handler provided by the user. Must not be NULL. 163 * 164 * @retval NRFX_SUCCESS If initialization was successful. 165 * @retval NRFX_ERROR_INVALID_STATE If the driver was already initialized. 166 * @retval NRFX_ERROR_INVALID_PARAM If the requested combination of configuration 167 * options is not allowed by the I2S peripheral. 168 */ 169 nrfx_err_t nrfx_i2s_init(nrfx_i2s_config_t const * p_config, 170 nrfx_i2s_data_handler_t handler); 171 172 /** @brief Function for uninitializing the I2S driver. */ 173 void nrfx_i2s_uninit(void); 174 175 /** 176 * @brief Function for starting the continuous I2S transfer. 177 * 178 * The I2S data transfer can be performed in one of three modes: RX (reception) 179 * only, TX (transmission) only, or in both directions simultaneously. 180 * The mode is selected by specifying a proper buffer for a given direction 181 * in the call to this function or by passing NULL instead if this direction 182 * should be disabled. 183 * 184 * The length of the buffer (which is a common value for RX and TX if both 185 * directions are enabled) is specified in 32-bit words. One 32-bit memory 186 * word can either contain four 8-bit samples, two 16-bit samples, or one 187 * right-aligned 24-bit sample sign-extended to a 32-bit value. 188 * For a detailed memory mapping for different supported configurations, 189 * see the @linkProductSpecification52. 190 * 191 * @note Peripherals using EasyDMA (including I2S) require the transfer buffers 192 * to be placed in the Data RAM region. If this condition is not met, 193 * this function will fail with the error code NRFX_ERROR_INVALID_ADDR. 194 * 195 * @param[in] p_initial_buffers Pointer to a structure specifying the buffers 196 * to be used in the initial part of the transfer 197 * (buffers for all consecutive parts are provided 198 * through the data handler). 199 * @param[in] buffer_size Size of the buffers (in 32-bit words). 200 * Must not be 0. 201 * @param[in] flags Transfer options (0 for default settings). 202 * Currently, no additional flags are available. 203 * 204 * @retval NRFX_SUCCESS If the operation was successful. 205 * @retval NRFX_ERROR_INVALID_STATE If a transfer was already started or 206 * the driver has not been initialized. 207 * @retval NRFX_ERROR_INVALID_ADDR If the provided buffers are not placed 208 * in the Data RAM region. 209 */ 210 nrfx_err_t nrfx_i2s_start(nrfx_i2s_buffers_t const * p_initial_buffers, 211 uint16_t buffer_size, 212 uint8_t flags); 213 214 /** 215 * @brief Function for supplying the buffers to be used in the next part of 216 * the transfer. 217 * 218 * The application should call this function when the data handler receives 219 * @ref NRFX_I2S_STATUS_NEXT_BUFFERS_NEEDED in the @c status parameter. 220 * The call can be done immediately from the data handler function or later, 221 * but it has to be done before the I2S peripheral finishes processing the 222 * buffers supplied previously. Otherwise, data corruption will occur. 223 * 224 * @sa nrfx_i2s_data_handler_t 225 * 226 * @retval NRFX_SUCCESS If the operation was successful. 227 * @retval NRFX_ERROR_INVALID_STATE If the buffers were already supplied or 228 * the peripheral is currently being stopped. 229 */ 230 nrfx_err_t nrfx_i2s_next_buffers_set(nrfx_i2s_buffers_t const * p_buffers); 231 232 /** @brief Function for stopping the I2S transfer. */ 233 void nrfx_i2s_stop(void); 234 235 /** @} */ 236 237 238 void nrfx_i2s_irq_handler(void); 239 240 241 #ifdef __cplusplus 242 } 243 #endif 244 245 #endif // NRFX_I2S_H__ 246