2021-08-18 07:45:51 -04:00
/*
2024-01-08 21:50:08 -05:00
* SPDX - FileCopyrightText : 2015 - 2024 Espressif Systems ( Shanghai ) CO LTD
2021-08-18 07:45:51 -04:00
*
* SPDX - License - Identifier : Apache - 2.0
*/
# pragma once
2022-04-07 03:32:46 -04:00
# include "driver/i2s_types.h"
2021-08-18 07:45:51 -04:00
# include "hal/i2s_types.h"
# include "esp_types.h"
# include "esp_err.h"
# ifdef __cplusplus
extern " C " {
# endif
/**
* @ brief get default I2S property
*/
2022-04-02 09:31:35 -04:00
# define I2S_CHANNEL_DEFAULT_CONFIG(i2s_num, i2s_role) { \
. id = i2s_num , \
2021-08-18 07:45:51 -04:00
. role = i2s_role , \
2022-06-20 08:30:31 -04:00
. dma_desc_num = 6 , \
2022-07-04 23:22:27 -04:00
. dma_frame_num = 240 , \
2024-03-26 23:37:51 -04:00
. auto_clear_after_cb = false , \
. auto_clear_before_cb = false , \
2023-09-07 04:47:26 -04:00
. intr_priority = 0 , \
2021-08-18 07:45:51 -04:00
}
# define I2S_GPIO_UNUSED GPIO_NUM_NC /*!< Used in i2s_gpio_config_t for signals which are not used */
2022-04-07 03:32:46 -04:00
/**
* @ brief Group of I2S callbacks
* @ note The callbacks are all running under ISR environment
* @ note When CONFIG_I2S_ISR_IRAM_SAFE is enabled , the callback itself and functions called by it should be placed in IRAM .
* The variables used in the function should be in the SRAM as well .
*/
typedef struct {
2023-10-10 21:38:28 -04:00
i2s_isr_callback_t on_recv ; /**< Callback of data received event, only for RX channel
2022-07-01 02:53:35 -04:00
* The event data includes DMA buffer address and size that just finished receiving data
*/
2023-10-10 21:38:28 -04:00
i2s_isr_callback_t on_recv_q_ovf ; /**< Callback of receiving queue overflowed event, only for RX channel
2022-07-01 02:53:35 -04:00
* The event data includes buffer size that has been overwritten
*/
2023-10-10 21:38:28 -04:00
i2s_isr_callback_t on_sent ; /**< Callback of data sent event, only for TX channel
2022-07-01 02:53:35 -04:00
* The event data includes DMA buffer address and size that just finished sending data
*/
2023-10-10 21:38:28 -04:00
i2s_isr_callback_t on_send_q_ovf ; /**< Callback of sending queue overflowed event, only for TX channel
2022-07-01 02:53:35 -04:00
* The event data includes buffer size that has been overwritten
*/
2022-04-07 03:32:46 -04:00
} i2s_event_callbacks_t ;
2021-08-18 07:45:51 -04:00
/**
* @ brief I2S controller channel configuration
*/
typedef struct {
2022-07-01 02:53:35 -04:00
i2s_port_t id ; /*!< I2S port id */
i2s_role_t role ; /*!< I2S role, I2S_ROLE_MASTER or I2S_ROLE_SLAVE */
2021-08-18 07:45:51 -04:00
/* DMA configurations */
2022-07-01 02:53:35 -04:00
uint32_t dma_desc_num ; /*!< I2S DMA buffer number, it is also the number of DMA descriptor */
2022-07-04 23:22:27 -04:00
uint32_t dma_frame_num ; /*!< I2S frame number in one DMA buffer. One frame means one-time sample data in all slots,
2023-10-10 21:38:28 -04:00
* it should be the multiple of ` 3 ` when the data bit width is 24.
2022-07-01 02:53:35 -04:00
*/
2024-03-26 23:37:51 -04:00
union {
bool auto_clear ; /*!< Alias of `auto_clear_after_cb` to be compatible with previous version */
bool auto_clear_after_cb ; /*!< Set to auto clear DMA TX buffer after `on_sent` callback, I2S will always send zero automatically if no data to send.
* So that user can assign the data to the DMA buffers directly in the callback , and the data won ' t be cleared after quitted the callback .
*/
} ;
bool auto_clear_before_cb ; /*!< Set to auto clear DMA TX buffer before `on_sent` callback, I2S will always send zero automatically if no data to send
* So that user can access data in the callback that just finished to send .
*/
2023-09-07 04:47:26 -04:00
int intr_priority ; /*!< I2S interrupt priority, range [0, 7], if set to 0, the driver will try to allocate an interrupt with a relative low priority (1,2,3) */
2021-08-18 07:45:51 -04:00
} i2s_chan_config_t ;
/**
2022-04-07 03:32:46 -04:00
* @ brief I2S channel information
*/
typedef struct {
2022-07-01 02:53:35 -04:00
i2s_port_t id ; /*!< I2S port id */
i2s_role_t role ; /*!< I2S role, I2S_ROLE_MASTER or I2S_ROLE_SLAVE */
i2s_dir_t dir ; /*!< I2S channel direction */
i2s_comm_mode_t mode ; /*!< I2S channel communication mode */
i2s_chan_handle_t pair_chan ; /*!< I2S pair channel handle in duplex mode, always NULL in simplex mode */
2024-01-08 21:50:08 -05:00
uint32_t total_dma_buf_size ; /*!< Total size of all the allocated DMA buffers
* - 0 if the channel has not been initialized
* - non - zero if the channel has been initialized
*/
2022-04-07 03:32:46 -04:00
} i2s_chan_info_t ;
/**
* @ brief Allocate new I2S channel ( s )
* @ note The new created I2S channel handle will be REGISTERED state after it is allocated successfully .
* @ note When the port id in channel configuration is I2S_NUM_AUTO , driver will allocate I2S port automatically
2023-10-10 21:38:28 -04:00
* on one of the I2S controller , otherwise driver will try to allocate the new channel on the selected port .
2022-04-07 03:32:46 -04:00
* @ note If both tx_handle and rx_handle are not NULL , it means this I2S controller will work at full - duplex mode ,
2023-10-10 21:38:28 -04:00
* the RX and TX channels will be allocated on a same I2S port in this case .
* Note that some configurations of TX / RX channel are shared on ESP32 and ESP32S2 ,
2022-04-07 03:32:46 -04:00
* so please make sure they are working at same condition and under same status ( start / stop ) .
2023-10-10 21:38:28 -04:00
* Currently , full - duplex mode can ' t guarantee TX / RX channels write / read synchronously ,
2022-04-07 03:32:46 -04:00
* they can only share the clock signals for now .
* @ note If tx_handle OR rx_handle is NULL , it means this I2S controller will work at simplex mode .
2023-10-10 21:38:28 -04:00
* For ESP32 and ESP32S2 , the whole I2S controller ( i . e . both RX and TX channel ) will be occupied ,
* even if only one of RX or TX channel is registered .
2022-04-07 03:32:46 -04:00
* For the other targets , another channel on this controller will still available .
2021-08-18 07:45:51 -04:00
*
* @ param [ in ] chan_cfg I2S controller channel configurations
2022-04-07 03:32:46 -04:00
* @ param [ out ] ret_tx_handle I2S channel handler used for managing the sending channel ( optional )
* @ param [ out ] ret_rx_handle I2S channel handler used for managing the receiving channel ( optional )
2021-08-18 07:45:51 -04:00
* @ return
2022-04-07 03:32:46 -04:00
* - ESP_OK Allocate new channel ( s ) success
2021-08-18 07:45:51 -04:00
* - ESP_ERR_NOT_SUPPORTED The communication mode is not supported on the current chip
* - ESP_ERR_INVALID_ARG NULL pointer or illegal parameter in i2s_chan_config_t
* - ESP_ERR_NOT_FOUND No available I2S channel found
*/
2022-04-07 03:32:46 -04:00
esp_err_t i2s_new_channel ( const i2s_chan_config_t * chan_cfg , i2s_chan_handle_t * ret_tx_handle , i2s_chan_handle_t * ret_rx_handle ) ;
2021-08-18 07:45:51 -04:00
/**
2023-10-10 21:38:28 -04:00
* @ brief Delete the I2S channel
* @ note Only allowed to be called when the I2S channel is at REGISTERED or READY state ( i . e . , it should stop before deleting it ) .
2021-08-18 07:45:51 -04:00
* @ note Resource will be free automatically if all channels in one port are deleted
*
* @ param [ in ] handle I2S channel handler
* - ESP_OK Delete successfully
* - ESP_ERR_INVALID_ARG NULL pointer
*/
esp_err_t i2s_del_channel ( i2s_chan_handle_t handle ) ;
/**
2022-04-07 03:32:46 -04:00
* @ brief Get I2S channel information
2021-08-18 07:45:51 -04:00
*
* @ param [ in ] handle I2S channel handler
2022-04-07 03:32:46 -04:00
* @ param [ out ] chan_info I2S channel basic information
2021-08-18 07:45:51 -04:00
* @ return
2023-10-10 21:38:28 -04:00
* - ESP_OK Get I2S channel information success
* - ESP_ERR_NOT_FOUND The input handle doesn ' t match any registered I2S channels , it may not an I2S channel handle or not available any more
2022-04-07 03:32:46 -04:00
* - ESP_ERR_INVALID_ARG The input handle or chan_info pointer is NULL
2021-08-18 07:45:51 -04:00
*/
2022-04-07 03:32:46 -04:00
esp_err_t i2s_channel_get_info ( i2s_chan_handle_t handle , i2s_chan_info_t * chan_info ) ;
2021-08-18 07:45:51 -04:00
/**
2023-10-10 21:38:28 -04:00
* @ brief Enable the I2S channel
2021-08-18 07:45:51 -04:00
* @ note Only allowed to be called when the channel state is READY , ( i . e . , channel has been initialized , but not started )
2022-04-07 03:32:46 -04:00
* the channel will enter RUNNING state once it is enabled successfully .
2023-10-10 21:38:28 -04:00
* @ note Enable the channel can start the I2S communication on hardware . It will start outputting BCLK and WS signal .
* For MCLK signal , it will start to output when initialization is finished
2021-08-18 07:45:51 -04:00
*
* @ param [ in ] handle I2S channel handler
* - ESP_OK Start successfully
* - ESP_ERR_INVALID_ARG NULL pointer
* - ESP_ERR_INVALID_STATE This channel has not initialized or already started
*/
2022-04-07 03:32:46 -04:00
esp_err_t i2s_channel_enable ( i2s_chan_handle_t handle ) ;
2021-08-18 07:45:51 -04:00
/**
2023-10-10 21:38:28 -04:00
* @ brief Disable the I2S channel
2023-01-05 07:14:43 -05:00
* @ note Only allowed to be called when the channel state is RUNNING , ( i . e . , channel has been started )
2022-04-07 03:32:46 -04:00
* the channel will enter READY state once it is disabled successfully .
2023-10-10 21:38:28 -04:00
* @ note Disable the channel can stop the I2S communication on hardware . It will stop BCLK and WS signal but not MCLK signal
2021-08-18 07:45:51 -04:00
*
* @ param [ in ] handle I2S channel handler
* @ return
* - ESP_OK Stop successfully
* - ESP_ERR_INVALID_ARG NULL pointer
* - ESP_ERR_INVALID_STATE This channel has not stated
*/
2022-04-07 03:32:46 -04:00
esp_err_t i2s_channel_disable ( i2s_chan_handle_t handle ) ;
2021-08-18 07:45:51 -04:00
2023-01-05 07:14:43 -05:00
/**
* @ brief Preload the data into TX DMA buffer
* @ note Only allowed to be called when the channel state is READY , ( i . e . , channel has been initialized , but not started )
* @ note As the initial DMA buffer has no data inside , it will transmit the empty buffer after enabled the channel ,
2023-01-05 23:13:21 -05:00
* this function is used to preload the data into the DMA buffer , so that the valid data can be transmitted immediately
* after the channel is enabled .
2023-01-05 07:14:43 -05:00
* @ note This function can be called multiple times before enabling the channel , the buffer that loaded later will be concatenated
* behind the former loaded buffer . But when all the DMA buffers have been loaded , no more data can be preload then , please
* check the ` bytes_loaded ` parameter to see how many bytes are loaded successfully , when the ` bytes_loaded ` is smaller than
* the ` size ` , it means the DMA buffers are full .
*
2023-01-05 23:13:21 -05:00
* @ param [ in ] tx_handle I2S TX channel handler
2023-01-05 07:14:43 -05:00
* @ param [ in ] src The pointer of the source buffer to be loaded
* @ param [ in ] size The source buffer size
* @ param [ out ] bytes_loaded The bytes that successfully been loaded into the TX DMA buffer
* @ return
* - ESP_OK Load data successful
* - ESP_ERR_INVALID_ARG NULL pointer or not TX direction
* - ESP_ERR_INVALID_STATE This channel has not stated
*/
2023-01-05 23:13:21 -05:00
esp_err_t i2s_channel_preload_data ( i2s_chan_handle_t tx_handle , const void * src , size_t size , size_t * bytes_loaded ) ;
2023-01-05 07:14:43 -05:00
2021-08-18 07:45:51 -04:00
/**
* @ brief I2S write data
2023-10-10 21:38:28 -04:00
* @ note Only allowed to be called when the channel state is RUNNING , ( i . e . , TX channel has been started and is not writing now )
2022-04-07 03:32:46 -04:00
* but the RUNNING only stands for the software state , it doesn ' t mean there is no the signal transporting on line .
2021-08-18 07:45:51 -04:00
*
* @ param [ in ] handle I2S channel handler
* @ param [ in ] src The pointer of sent data buffer
* @ param [ in ] size Max data buffer length
2023-01-05 23:13:21 -05:00
* @ param [ out ] bytes_written Byte number that actually be sent , can be NULL if not needed
2022-04-07 03:32:46 -04:00
* @ param [ in ] timeout_ms Max block time
2021-08-18 07:45:51 -04:00
* @ return
* - ESP_OK Write successfully
2023-10-10 21:38:28 -04:00
* - ESP_ERR_INVALID_ARG NULL pointer or this handle is not TX handle
2021-08-18 07:45:51 -04:00
* - ESP_ERR_TIMEOUT Writing timeout , no writing event received from ISR within ticks_to_wait
* - ESP_ERR_INVALID_STATE I2S is not ready to write
*/
2022-04-07 03:32:46 -04:00
esp_err_t i2s_channel_write ( i2s_chan_handle_t handle , const void * src , size_t size , size_t * bytes_written , uint32_t timeout_ms ) ;
2021-08-18 07:45:51 -04:00
/**
* @ brief I2S read data
2022-04-07 03:32:46 -04:00
* @ note Only allowed to be called when the channel state is RUNNING
* but the RUNNING only stands for the software state , it doesn ' t mean there is no the signal transporting on line .
2021-08-18 07:45:51 -04:00
*
* @ param [ in ] handle I2S channel handler
* @ param [ in ] dest The pointer of receiving data buffer
* @ param [ in ] size Max data buffer length
2023-01-05 23:13:21 -05:00
* @ param [ out ] bytes_read Byte number that actually be read , can be NULL if not needed
2022-04-07 03:32:46 -04:00
* @ param [ in ] timeout_ms Max block time
2021-08-18 07:45:51 -04:00
* @ return
* - ESP_OK Read successfully
2023-10-10 21:38:28 -04:00
* - ESP_ERR_INVALID_ARG NULL pointer or this handle is not RX handle
2021-08-18 07:45:51 -04:00
* - ESP_ERR_TIMEOUT Reading timeout , no reading event received from ISR within ticks_to_wait
* - ESP_ERR_INVALID_STATE I2S is not ready to read
*/
2022-04-07 03:32:46 -04:00
esp_err_t i2s_channel_read ( i2s_chan_handle_t handle , void * dest , size_t size , size_t * bytes_read , uint32_t timeout_ms ) ;
2021-08-18 07:45:51 -04:00
/**
2022-04-07 03:32:46 -04:00
* @ brief Set event callbacks for I2S channel
2021-08-18 07:45:51 -04:00
*
2023-01-05 23:13:21 -05:00
* @ note Only allowed to be called when the channel state is REGISTERED / READY , ( i . e . , before channel starts )
2022-04-07 03:32:46 -04:00
* @ note User can deregister a previously registered callback by calling this function and setting the callback member in the ` callbacks ` structure to NULL .
* @ note When CONFIG_I2S_ISR_IRAM_SAFE is enabled , the callback itself and functions called by it should be placed in IRAM .
* The variables used in the function should be in the SRAM as well . The ` user_data ` should also reside in SRAM or internal RAM as well .
2021-08-18 07:45:51 -04:00
*
2022-04-07 03:32:46 -04:00
* @ param [ in ] handle I2S channel handler
* @ param [ in ] callbacks Group of callback functions
* @ param [ in ] user_data User data , which will be passed to callback functions directly
2021-08-18 07:45:51 -04:00
* @ return
2022-04-07 03:32:46 -04:00
* - ESP_OK Set event callbacks successfully
* - ESP_ERR_INVALID_ARG Set event callbacks failed because of invalid argument
2023-01-05 23:13:21 -05:00
* - ESP_ERR_INVALID_STATE Set event callbacks failed because the current channel state is not REGISTERED or READY
2021-08-18 07:45:51 -04:00
*/
2022-04-07 03:32:46 -04:00
esp_err_t i2s_channel_register_event_callback ( i2s_chan_handle_t handle , const i2s_event_callbacks_t * callbacks , void * user_data ) ;
2021-08-18 07:45:51 -04:00
# ifdef __cplusplus
}
# endif