1 /** 2 * Copyright (c) 2020 HiSilicon (Shanghai) Technologies CO., LIMITED. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 * 15 * Description: Provides I2S driver api \n 16 * 17 * History: \n 18 * 2023-03-10, Create file. \n 19 */ 20 21 #ifndef I2S_H 22 #define I2S_H 23 24 #include <stdint.h> 25 #include <stdbool.h> 26 #include "errcode.h" 27 #include "sio_porting.h" 28 29 #ifdef __cplusplus 30 #if __cplusplus 31 extern "C" { 32 #endif /* __cplusplus */ 33 #endif /* __cplusplus */ 34 35 /** 36 * @defgroup drivers_driver_i2s I2S 37 * @ingroup drivers_driver 38 * @{ 39 */ 40 41 /** 42 * @if Eng 43 * @brief Definition of I2S RX data structure. 44 * @else 45 * @brief I2S RX 传输结构体。 46 * @endif 47 */ 48 typedef struct i2s_rx_data { 49 uint32_t left_buff[CONFIG_DATA_LEN_MAX]; /*!< @if Eng Left data. 50 @else 左声道数据。 @endif */ 51 uint32_t right_buff[CONFIG_DATA_LEN_MAX]; /*!< @if Eng Right data. 52 @else 右声道数据。 @endif */ 53 uint32_t length; /*!< @if Eng Data length. 54 @else 数据长度。 @endif */ 55 } i2s_rx_data_t; 56 57 /** 58 * @if Eng 59 * @brief Definition of I2S TX data structure. 60 * @else 61 * @brief I2S TX 传输结构体。 62 * @endif 63 */ 64 typedef struct i2s_tx_data { 65 uint32_t *left_buff; /*!< @if Eng Data send through tx left FIFO. 66 @else 通过TX 左FIFO发送的数据。 @endif */ 67 uint32_t *right_buff; /*!< @if Eng Data send through tx right FIFO. 68 @else 通过TX 右FIFO发送的数据。 @endif */ 69 uint32_t length; /*!< @if Eng Bytes of data need to send. 70 @else 发送数据的个数。 @endif */ 71 } i2s_tx_data_t; 72 73 /** 74 * @if Eng 75 * @brief Definition of I2S configuration. 76 * @else 77 * @brief I2S 配置定义。 78 * @endif 79 */ 80 typedef struct i2s_config { 81 uint8_t drive_mode; /*!< @if Eng I2S divice modes: 82 * - 0: SLAVE 83 * - 1: MASTER 84 * @else I2S 设备模式: 85 * - 0: 从模式 86 * - 1: 主模式 87 * @endif */ 88 uint8_t transfer_mode; /*!< @if Eng I2S transmission path modes: 89 * - 0: Standard mode 90 * - 1: Multichannel mode 91 * @else I2S 传输路径模式: 92 * - 0: 标准模式 93 * - 1: 多路模式 94 * @endif */ 95 uint8_t data_width; /*!< @if Eng I2S data width: 96 * - 0: RESERVED 97 * - 1: 16 Bits 98 * - 2: 18 Bits 99 * - 3: 20 Bits 100 * - 4: 24 Bits 101 * - 5: 32 Bits 102 * @else I2S 数据宽度: 103 * - 0: 保留 104 * - 1: 16位 105 * - 2: 18位 106 * - 3: 20位 107 * - 4: 24位 108 * - 5: 32位 109 * @endif */ 110 uint8_t channels_num; /*!< @if Eng I2S transmission Channels Number: 111 * - 0: 2 Channels 112 * - 1: 4 Channels 113 * - 2: 8 Channels 114 * - 3: 16 Channels 115 * @else I2S 传输通道数: 116 * - 0: 2通道 117 * - 1: 4通道 118 * - 2: 8通道 119 * - 3: 16通道 120 * @endif */ 121 uint8_t timing; /*!< @if Eng I2S timing mode: 122 * - 0: Standard timing mode 123 * - 1: User-defined timing mode 124 * @else I2S 时序模式: 125 * - 0: 标准时序模式 126 * - 1: 自定义时序模式 127 * @endif */ 128 uint8_t clk_edge; /*!< @if Eng I2S clock edge mode: 129 * - 0: Falling edge 130 * - 1: Rising edge 131 * @else I2S 时钟边沿模式: 132 * - 0: 下降沿 133 * - 1: 上升沿 134 * @endif */ 135 uint8_t div_number; /*!< @if Eng Div number, see @ref i2s_config.data_width. 136 @else 分频系数,见 @ref i2s_config.data_width 成员。 @endif */ 137 uint8_t number_of_channels; /*!< @if Eng Number of channels, see @ref i2s_config.channels_num. 138 @else 通道数,见 @ref i2s_config.channels_num 成员。 @endif */ 139 } i2s_config_t; 140 141 /** 142 * @if Eng 143 * @brief The callback set to the I2S device. 144 * @param [in] left_buff Data received by the left channel. 145 * @param [in] right_buff Data received by the right channel. 146 * @param [in] length Data length. 147 * @else 148 * @brief I2S设备的回调函数。 149 * @param [in] left_buff 左声道接收的数据。 150 * @param [in] right_buff 右声道接收的数据。 151 * @param [in] length 数据的长度。 152 * @endif 153 */ 154 typedef void (*i2s_callback_t)(uint32_t *left_buff, uint32_t *right_buff, uint32_t length); 155 156 /** 157 * @if Eng 158 * @brief Initialize the I2S. 159 * @param [in] bus The SIO bus. For details, see @ref sio_bus_t. 160 * @param [in] callback The callback set to the I2S device. 161 * @retval ERRCODE_SUCC Success. 162 * @retval Other Failure. For details, see @ref errcode_t. 163 * @else 164 * @brief 初始化I2S。 165 * @param [in] bus 指定的SIO接口,参考 @ref sio_bus_t 。 166 * @param [in] callback I2S设备的回调函数。 167 * @retval ERRCODE_SUCC 成功。 168 * @retval Other 失败,参考 @ref errcode_t 。 169 * @endif 170 */ 171 errcode_t uapi_i2s_init(sio_bus_t bus, i2s_callback_t callback); 172 173 /** 174 * @if Eng 175 * @brief Deinitialize the I2S. 176 * @param [in] bus The SIO bus. For details, see @ref sio_bus_t. 177 * @retval ERRCODE_SUCC Success. 178 * @retval Other Failure. For details, see @ref errcode_t. 179 * @else 180 * @brief 去初始化I2S。 181 * @param [in] bus 指定的SIO接口,参考 @ref sio_bus_t 。 182 * @retval ERRCODE_SUCC 成功。 183 * @retval Other 失败,参考 @ref errcode_t 。 184 * @endif 185 */ 186 errcode_t uapi_i2s_deinit(sio_bus_t bus); 187 188 /** 189 * @if Eng 190 * @brief Set the configuration of the I2S device. 191 * @param [in] bus The SIO bus. For details, see @ref sio_bus_t. 192 * @param [in] config Config set to the I2S device. 193 * @retval ERRCODE_SUCC Success. 194 * @retval Other Failure. For details, see @ref errcode_t. 195 * @else 196 * @brief 设置I2S设备的配置信息。 197 * @param [in] bus 指定的SIO接口,参考 @ref sio_bus_t 。 198 * @param [in] config I2S设备的配置信息。 199 * @retval ERRCODE_SUCC 成功。 200 * @retval Other 失败,参考 @ref errcode_t 。 201 * @endif 202 */ 203 errcode_t uapi_i2s_set_config(sio_bus_t bus, const i2s_config_t *config); 204 205 /** 206 * @if Eng 207 * @brief Get the configuration of the I2S device. 208 * @param [in] bus The SIO bus. For details, see @ref sio_bus_t. 209 * @param [out] config Config set to the I2S device. 210 * @retval ERRCODE_SUCC Success. 211 * @retval Other Failure. For details, see @ref errcode_t. 212 * @else 213 * @brief 获取I2S设备配置信息。 214 * @param [in] bus 指定的SIO接口,参考 @ref sio_bus_t 。 215 * @param [out] config I2S设备的配置信息。 216 * @retval ERRCODE_SUCC 成功。 217 * @retval Other 失败,参考 @ref errcode_t 。 218 * @endif 219 */ 220 errcode_t uapi_i2s_get_config(sio_bus_t bus, i2s_config_t *config); 221 222 /** 223 * @if Eng 224 * @brief Write data to the I2S device in the polling mode. 225 * @param [in] bus The SIO bus. For details, see @ref sio_bus_t. 226 * @param [in] data Pointer to transfer data, @ref i2s_tx_data_t. 227 * @retval ERRCODE_SUCC Success. 228 * @retval Other Failure. For details, see @ref errcode_t. 229 * @else 230 * @brief 轮询模式下写入数据。 231 * @param [in] bus 指定的SIO接口,参考 @ref sio_bus_t 。 232 * @param [in] data 数据传输指针,参考 @ref i2s_tx_data_t 。 233 * @retval ERRCODE_SUCC 成功。 234 * @retval Other 失败,参考 @ref errcode_t 。 235 * @endif 236 */ 237 errcode_t uapi_i2s_write_data(sio_bus_t bus, i2s_tx_data_t *data); 238 239 /** 240 * @if Eng 241 * @brief Read data from I2S device in the interrupt mode. 242 * @param [in] bus The SIO bus. For details, see @ref sio_bus_t. 243 * @retval ERRCODE_SUCC Success. 244 * @retval Other Failure. For details, see @ref errcode_t. 245 * @else 246 * @brief 中断模式下读取数据。 247 * @param [in] bus 指定的SIO接口,参考 @ref sio_bus_t 。 248 * @retval ERRCODE_SUCC 成功。 249 * @retval Other 失败,参考 @ref errcode_t 。 250 * @endif 251 */ 252 errcode_t uapi_i2s_read_start(sio_bus_t bus); 253 254 /** 255 * @if Eng 256 * @brief I2S loop test. 257 * @param [in] bus The SIO bus. For details, see @ref sio_bus_t. 258 * @param [in] data Pointer to transfer data. @ref i2s_tx_data_t. 259 * @retval ERRCODE_SUCC Success. 260 * @retval Other Failure. For details, see @ref errcode_t. 261 * @else 262 * @brief I2S回路自测。 263 * @param [in] bus 指定的SIO接口,参考 @ref sio_bus_t 。 264 * @param [in] data 数据传输指针,参考 @ref i2s_tx_data_t 。 265 * @retval ERRCODE_SUCC 成功。 266 * @retval Other 失败,参考 @ref errcode_t 。 267 * @endif 268 */ 269 errcode_t uapi_i2s_loop_trans(sio_bus_t bus, i2s_tx_data_t *data); 270 271 /** 272 * @if Eng 273 * @brief Get the data received by the I2S device in the interrupt mode. 274 * @param [in] bus The SIO bus. For details, see @ref sio_bus_t. 275 * @param [out] data Pointer to receive data, @ref i2s_rx_data_t. 276 * @retval ERRCODE_SUCC Success. 277 * @retval Other Failure. For details, see @ref errcode_t. 278 * @else 279 * @brief 获取中断模式下I2S设备接收的数据。 280 * @param [in] bus 指定的SIO接口,参考 @ref sio_bus_t 。 281 * @param [out] data 数据接收指针,参考 @ref i2s_rx_data_t 。 282 * @retval ERRCODE_SUCC 成功。 283 * @retval Other 失败,参考 @ref errcode_t 。 284 * @endif 285 */ 286 errcode_t uapi_i2s_get_data(sio_bus_t bus, i2s_rx_data_t *data); 287 288 #if defined(CONFIG_I2S_SUPPORT_LOOPBACK) && (CONFIG_I2S_SUPPORT_LOOPBACK == 1) 289 /** 290 * @if Eng 291 * @brief Open loop mode. 292 * @param [in] bus The SIO bus. For details, see @ref sio_bus_t. 293 * @param [in] en Enable loop back mode or not. 294 * @retval ERRCODE_SUCC Success. 295 * @retval Other Failure. For details, see @ref errcode_t. 296 * @else 297 * @brief 打开自测模式。 298 * @param [in] bus 指定的SIO接口,参考 @ref sio_bus_t 。 299 * @param [in] en 是否开启回环模式。 300 * @retval ERRCODE_SUCC 成功。 301 * @retval Other 失败,参考 @ref errcode_t 。 302 * @endif 303 */ 304 errcode_t uapi_i2s_loopback(sio_bus_t bus, bool en); 305 #endif /* CONFIG_I2S_SUPPORT_LOOPBACK */ 306 307 #if defined(CONFIG_I2S_SUPPORT_DMA) 308 /** 309 * @if Eng 310 * @brief Definition of I2S DMA configuration. 311 * @else 312 * @brief I2S DMA配置数据结构定义 313 * @endif 314 */ 315 typedef struct i2s_dma_config { 316 uint8_t src_width; /*!< @if Eng Transfer data width of the source. 317 * - 0: 1byte 318 * - 1: 2byte 319 * - 2: 4byte 320 * @else 源端传输数据宽度 \n 321 * - 0: 1字节 322 * - 1: 2字节 323 * - 2: 4字节 324 * @endif */ 325 uint8_t dest_width; /*!< @if Eng Transfer data width of the destination. 326 * - 0: 1byte 327 * - 1: 2byte 328 * - 2: 4byte 329 * @else 目的端传输数据宽度 \n 330 * - 0: 1字节 331 * - 1: 2字节 332 * - 2: 4字节 333 * @endif */ 334 uint8_t burst_length; /*!< @if Eng Number of data items, to be written to the destination every time 335 * a destination burst transaction request is made from 336 * either the corresponding hardware or software handshaking interface. 337 * - 0: burst length is 1 338 * - 1: burst length is 4 339 * - 2: burst length is 8 340 * - 3: burst length is 16 341 * @else 每次从相应的硬件或软件握手接口发出目的burst请求时,要写入目的端数据量 342 * - 0: burst长度是1 343 * - 1: burst长度是4 344 * - 2: burst长度是8 345 * - 3: burst长度是16 346 * @endif */ 347 uint8_t priority; /*!< @if Eng Transfer channel priority(Minimum: 0 and Maximum: 3). 348 * @else 传输通道优先级(最小为0以及最大为3) @endif */ 349 } i2s_dma_config_t; 350 351 /** 352 * @if Eng 353 * @brief Definition of I2S DMA attributes. 354 * @else 355 * @brief I2S DMA配置参数定义 356 * @endif 357 */ 358 typedef struct i2s_dma_attr { 359 bool tx_dma_enable; /*!< @if Eng false: tx not use dma @ref uapi_i2s_write can be used. \n 360 true: tx use dma @ref uapi_i2s_write_by_dma can be used. 361 @else false: TX没有使用DMA,使用 @ref uapi_i2s_write 发送数据 \n 362 true: TX使用DMA,使用 @ref uapi_i2s_write_by_dma 发送数据 @endif */ 363 uint8_t tx_int_threshold; /*!< @if Eng i2s tx fifo level to trigger interrupt. 364 @else 触发中断的txfifo水线 @endif */ 365 bool rx_dma_enable; /*!< @if Eng false: rx not use dma @ref uapi_i2s_write can be used. \n 366 true: rx use dma @ref uapi_i2s_write_by_dma can be used. 367 @else false: RX没有使用DMA,使用 @ref uapi_i2s_write 发送数据 \n 368 true: RX使用DMA,使用 @ref uapi_i2s_write_by_dma 发送数据 @endif */ 369 uint8_t rx_int_threshold; /*!< @if Eng i2s rx fifo level to trigger interrupt. 370 @else 触发中断的rxfifo水线 @endif */ 371 } i2s_dma_attr_t; 372 373 /** 374 * @if Eng 375 * @brief configure i2s dma tranfering param. 376 * @param [in] bus The SIO bus. For details, see @ref sio_bus_t. 377 * @param [in] i2s_dma_cfg i2s configuration using dma, see @ref i2s_dma_attr_t. 378 * @retval ERRCODE_SUCC Success. 379 * @retval Other Failure. For details, see @ref errcode_t. 380 * @else 381 * @brief 配置i2s dma传输参数。 382 * @param [in] bus 指定的SIO接口,参考 @ref sio_bus_t 。 383 * @param [in] i2s_dma_cfg i2s dma传输时i2s的配置参数,参考 @ref i2s_dma_attr_t。 384 * @retval ERRCODE_SUCC 成功。 385 * @retval Other 失败,参考 @ref errcode_t 。 386 * @endif 387 */ 388 int32_t uapi_i2s_dma_config(sio_bus_t bus, i2s_dma_attr_t *i2s_dma_cfg); 389 390 /** 391 * @if Eng 392 * @brief i2s write data by data using merge model. 393 * @param [in] bus The SIO bus. For details, see @ref sio_bus_t. 394 * @param [in] buffer the data buffer needed to be writen. 395 * @param [in] length data length needed to be writen. 396 * @param [in] dma_cfg dma configuration for i2, see @ref i2s_dma_config_t. 397 * @param [in] arg priv data pointer which can be passed to interrupt callback. 398 * @param [in] block block tranfering or not. 399 * @retval ERRCODE_SUCC Success. 400 * @retval Other Failure. For details, see @ref errcode_t. 401 * @else 402 * @brief merge模式下i2s通过dma写数据。 403 * @param [in] bus 指定的SIO接口,参考 @ref sio_bus_t 。 404 * @param [in] buffer 写数据缓存区. 405 * @param [in] length 需要传输的数据长度. 406 * @param [in] dma_cfg i2s dma传输时dma的配置参数, 参考 @ref i2s_dma_config_t. 407 * @param [in] arg 自定义参数指针,可被传递到中断处理函数. 408 * @param [in] block 阻塞传输还是非阻塞. 409 * @retval ERRCODE_SUCC 成功。 410 * @retval Other 失败,参考 @ref errcode_t 。 411 * @endif 412 */ 413 int32_t uapi_i2s_merge_write_by_dma(sio_bus_t bus, const void *buffer, uint32_t length, 414 i2s_dma_config_t *dma_cfg, uintptr_t arg, bool block); 415 416 /** 417 * @if Eng 418 * @brief i2s read data by data using merge model. 419 * @param [in] bus The SIO bus. For details, see @ref sio_bus_t. 420 * @param [in] buffer the buffer to store the data reading form i2s. 421 * @param [in] length data length needed to be read. 422 * @param [in] dma_cfg dma configuration for i2s, see @ref i2s_dma_config_t.. 423 * @param [in] arg priv data pointer which can be passed to interrupt callback. 424 * @param [in] block block tranfering or not. 425 * @retval ERRCODE_SUCC Success. 426 * @retval Other Failure. For details, see @ref errcode_t. 427 * @else 428 * @brief merge模式下i2s通过dma读数据。 429 * @param [in] bus 指定的SIO接口,参考 @ref sio_bus_t 。 430 * @param [in] buffer 读数据缓存区. 431 * @param [in] length 需要读的数据长度. 432 * @param [in] dma_cfg i2s dma传输时dma的配置参数, 参考 @ref i2s_dma_config_t. 433 * @param [in] arg 自定义参数指针,可被传递到中断处理函数. 434 * @param [in] block 阻塞传输还是非阻塞. 435 * @retval ERRCODE_SUCC 成功。 436 * @retval Other 失败,参考 @ref errcode_t 。 437 * @endif 438 */ 439 int32_t uapi_i2s_merge_read_by_dma(sio_bus_t bus, const void *buffer, uint32_t length, 440 i2s_dma_config_t *dma_cfg, uintptr_t arg, bool block); 441 #endif 442 443 /** 444 * @} 445 */ 446 447 #ifdef __cplusplus 448 #if __cplusplus 449 } 450 #endif /* __cplusplus */ 451 #endif /* __cplusplus */ 452 453 #endif 454