High level interface for interacting with the Inter-IC Sound (I2S).
The I2S protocol is a asynchronous serial interface protocol. This driver supports both transmit and receive modes of operation. The communication frequency, sample rate, word size, and channel size can all be configured.
Initialize an I2S instance using the cyhal_i2s_init and provide the transmit (tx) and/or receive (rx) pins. Call cyhal_i2s_start_tx and/or cyhal_i2s_start_rx to enable transmit and/or receive functionality as desired.
See Snippet 1: I2S Initialization and Configuration for example initialization as transmit or receive.
The sclk frequency is determined as sclk = sample_rate_hz * channel_length * 2
(multiplying by 2 for 2 channels - left and right). The input clock must be a multiple of this sclk frequency; see the implementation specific documentation for the supported multipliers.
It is possible to use either only TX functionality, only RX functionality, or both RX and TX functionality at the same time. If RX and TX are both in use, the same sample rate, channel length, word length, sclk frequency will be used for both.
This snippet initializes an I2S resource for transmit or receive and assigns the pins.
Initializing as I2S transmitter
Initializing as I2S receiver
This snippet shows how to transmit data using cyhal_i2s_write_async when the entire sample is available at once.
This snippet shows how to transmit data using cyhal_i2s_write_async when sample data is being continuously loaded and transmitted (e.g. streaming over the network).
This snippet shows how to receive data using cyhal_i2s_read_async.
Code examples (Github)
API Reference | |
I2S HAL Results | |
I2S specific return codes. | |
Data Structures | |
struct | cyhal_i2s_pins_t |
Pins to use for one I2S direction. More... | |
struct | cyhal_i2s_config_t |
I2S Configuration. More... | |
Typedefs | |
typedef void(* | cyhal_i2s_event_callback_t) (void *callback_arg, cyhal_i2s_event_t event) |
Handler for I2S event callbacks. | |
Enumerations | |
enum | cyhal_i2s_event_t { CYHAL_I2S_TX_NOT_FULL = 1 << 0, CYHAL_I2S_TX_HALF_EMPTY = 1 << 1, CYHAL_I2S_TX_EMPTY = 1 << 2, CYHAL_I2S_TX_OVERFLOW = 1 << 3, CYHAL_I2S_TX_UNDERFLOW = 1 << 4, CYHAL_I2S_ASYNC_TX_COMPLETE = 1 << 5, CYHAL_I2S_RX_NOT_EMPTY = 1 << 6, CYHAL_I2S_RX_HALF_FULL = 1 << 7, CYHAL_I2S_RX_FULL = 1 << 8, CYHAL_I2S_RX_OVERFLOW = 1 << 9, CYHAL_I2S_RX_UNDERFLOW = 1 << 10, CYHAL_I2S_ASYNC_RX_COMPLETE = 1 << 11 } |
I2S events. More... | |
enum | cyhal_i2s_output_t { CYHAL_I2S_TRIGGER_RX_HALF_FULL, CYHAL_I2S_TRIGGER_TX_HALF_EMPTY } |
Selections for I2S output signals. More... | |
Functions | |
cy_rslt_t | cyhal_i2s_init (cyhal_i2s_t *obj, const cyhal_i2s_pins_t *tx_pins, const cyhal_i2s_pins_t *rx_pins, const cyhal_i2s_config_t *config, cyhal_clock_t *clk) |
Initialize the I2S peripheral. More... | |
cy_rslt_t | cyhal_i2s_init_cfg (cyhal_i2s_t *obj, const cyhal_i2s_configurator_t *cfg) |
Initialize the I2S peripheral using a configurator generated configuration struct. More... | |
void | cyhal_i2s_free (cyhal_i2s_t *obj) |
Deinitialize the i2s object. More... | |
cy_rslt_t | cyhal_i2s_set_sample_rate (cyhal_i2s_t *obj, uint32_t sample_rate_hz) |
Set the I2S sample rate. More... | |
cy_rslt_t | cyhal_i2s_start_tx (cyhal_i2s_t *obj) |
Starts transmitting data. More... | |
cy_rslt_t | cyhal_i2s_stop_tx (cyhal_i2s_t *obj) |
Stops transmitting data. More... | |
cy_rslt_t | cyhal_i2s_clear_tx (cyhal_i2s_t *obj) |
Clears the tx hardware buffer. More... | |
cy_rslt_t | cyhal_i2s_start_rx (cyhal_i2s_t *obj) |
Starts receiving data. More... | |
cy_rslt_t | cyhal_i2s_stop_rx (cyhal_i2s_t *obj) |
Stops receiving data. More... | |
cy_rslt_t | cyhal_i2s_clear_rx (cyhal_i2s_t *obj) |
Clears the rx hardware buffer. More... | |
cy_rslt_t | cyhal_i2s_read (cyhal_i2s_t *obj, void *data, size_t *length) |
Read data synchronously. More... | |
cy_rslt_t | cyhal_i2s_write (cyhal_i2s_t *obj, const void *data, size_t *length) |
Send data synchronously. More... | |
bool | cyhal_i2s_is_tx_enabled (cyhal_i2s_t *obj) |
Checks if the transmit functionality is enabled for the specified I2S peripheral (regardless of whether data is currently queued for transmission). More... | |
bool | cyhal_i2s_is_tx_busy (cyhal_i2s_t *obj) |
Checks if the specified I2S peripheral is transmitting data, including if a pending async transfer is waiting to write more data to the transmit buffer. More... | |
bool | cyhal_i2s_is_rx_enabled (cyhal_i2s_t *obj) |
Checks if the receive functionality is enabled for the specified I2S peripheral (regardless of whether any unread data has been received). More... | |
bool | cyhal_i2s_is_rx_busy (cyhal_i2s_t *obj) |
Checks if the specified I2S peripheral has received data that has not yet been read out of the hardware buffer. More... | |
cy_rslt_t | cyhal_i2s_read_async (cyhal_i2s_t *obj, void *rx, size_t rx_length) |
Start I2S asynchronous read. More... | |
cy_rslt_t | cyhal_i2s_write_async (cyhal_i2s_t *obj, const void *tx, size_t tx_length) |
Start I2S asynchronous write. More... | |
cy_rslt_t | cyhal_i2s_set_async_mode (cyhal_i2s_t *obj, cyhal_async_mode_t mode, uint8_t dma_priority) |
Set the mechanism that is used to perform I2S asynchronous transfers. More... | |
bool | cyhal_i2s_is_read_pending (cyhal_i2s_t *obj) |
Checks if the specified I2S peripheral is in the process of reading data from the hardware buffer into RAM. More... | |
bool | cyhal_i2s_is_write_pending (cyhal_i2s_t *obj) |
Checks if the specified I2S peripheral is in the process of writing data into the hardware buffer. More... | |
cy_rslt_t | cyhal_i2s_abort_read_async (cyhal_i2s_t *obj) |
Abort I2S asynchronous read. More... | |
cy_rslt_t | cyhal_i2s_abort_write_async (cyhal_i2s_t *obj) |
Abort I2S asynchronous write. More... | |
void | cyhal_i2s_register_callback (cyhal_i2s_t *obj, cyhal_i2s_event_callback_t callback, void *callback_arg) |
Register an I2S callback handler. More... | |
void | cyhal_i2s_enable_event (cyhal_i2s_t *obj, cyhal_i2s_event_t event, uint8_t intr_priority, bool enable) |
Configure I2S events. More... | |
cy_rslt_t | cyhal_i2s_enable_output (cyhal_i2s_t *obj, cyhal_i2s_output_t output, cyhal_source_t *source) |
Enables the specified output signal. More... | |
cy_rslt_t | cyhal_i2s_disable_output (cyhal_i2s_t *obj, cyhal_i2s_output_t output) |
Disables the specified output signal. More... | |
struct cyhal_i2s_pins_t |
Data Fields | ||
---|---|---|
cyhal_gpio_t | sck | Clock pin. |
cyhal_gpio_t | ws | Word select. |
cyhal_gpio_t | data | Data pin (sdo or sdi) |
cyhal_gpio_t | mclk | Mclk input pin. Set to NC if an internal clock source should be used. |
struct cyhal_i2s_config_t |
enum cyhal_i2s_event_t |
I2S events.
enum cyhal_i2s_output_t |
cy_rslt_t cyhal_i2s_init | ( | cyhal_i2s_t * | obj, |
const cyhal_i2s_pins_t * | tx_pins, | ||
const cyhal_i2s_pins_t * | rx_pins, | ||
const cyhal_i2s_config_t * | config, | ||
cyhal_clock_t * | clk | ||
) |
Initialize the I2S peripheral.
It sets the default parameters for I2S peripheral, and configures its specifieds pins. If only one direction is to be used, then the pins for the other direction need not be specified (i.e. they may be set to NC). For example, if only RX is needed, tx_sck, tx_ws, and tx_sdo may all be set to NC. If one pin is specified for a direction, all pins for that direction must be specified.
[out] | obj | Pointer to an I2S object. The caller must allocate the memory for this object but the init function will initialize its contents. |
[in] | tx_pins | Pins for I2S transmit. If NULL, transmit functionality will be disabled. |
[in] | rx_pins | Pins for I2S receive. If NULL, receive functionality will be disabled. |
[in] | config | Initial block configuration |
[in] | clk | Clock source to use for this instance. If NULL, a dedicated clock divider will be allocated for this instance. |
cy_rslt_t cyhal_i2s_init_cfg | ( | cyhal_i2s_t * | obj, |
const cyhal_i2s_configurator_t * | cfg | ||
) |
Initialize the I2S peripheral using a configurator generated configuration struct.
[out] | obj | Pointer to a I2S object. The caller must allocate the memory for this object but the init function will initialize its contents. |
[in] | cfg | Configuration structure generated by a configurator. |
void cyhal_i2s_free | ( | cyhal_i2s_t * | obj | ) |
Deinitialize the i2s object.
[in,out] | obj | The i2s object |
cy_rslt_t cyhal_i2s_set_sample_rate | ( | cyhal_i2s_t * | obj, |
uint32_t | sample_rate_hz | ||
) |
Set the I2S sample rate.
[in] | obj | The I2S object |
[in] | sample_rate_hz | Sample rate in Hz |
cy_rslt_t cyhal_i2s_start_tx | ( | cyhal_i2s_t * | obj | ) |
Starts transmitting data.
Transmission will continue until it is stopped by calling cyhal_i2s_stop_tx.
[in] | obj | The I2S object |
cy_rslt_t cyhal_i2s_stop_tx | ( | cyhal_i2s_t * | obj | ) |
Stops transmitting data.
This immediately terminates transmission.
[in] | obj | The I2S object |
cy_rslt_t cyhal_i2s_clear_tx | ( | cyhal_i2s_t * | obj | ) |
Clears the tx hardware buffer.
[in] | obj | The i2s peripheral |
cy_rslt_t cyhal_i2s_start_rx | ( | cyhal_i2s_t * | obj | ) |
Starts receiving data.
Data will continue to be received until it is stopped by calling cyhal_i2s_stop_rx.
[in] | obj | The I2S object |
cy_rslt_t cyhal_i2s_stop_rx | ( | cyhal_i2s_t * | obj | ) |
Stops receiving data.
This immediately terminates data receipt.
[in] | obj | The I2S object |
cy_rslt_t cyhal_i2s_clear_rx | ( | cyhal_i2s_t * | obj | ) |
Clears the rx hardware buffer.
[in] | obj | The i2s peripheral |
cy_rslt_t cyhal_i2s_read | ( | cyhal_i2s_t * | obj, |
void * | data, | ||
size_t * | length | ||
) |
Read data synchronously.
This will read the number of words specified by the length
parameter, or the number of words that are currently available in the receive buffer, whichever is less, then return. The value pointed to by length
will be updated to reflect the number of words that were actually read.
[in] | obj | The I2S object |
[out] | data | The buffer for receiving |
[in,out] | length | Number of words to (as configured in cyhal_i2s_config_t.word_length) read, updated with the number actually read |
cy_rslt_t cyhal_i2s_write | ( | cyhal_i2s_t * | obj, |
const void * | data, | ||
size_t * | length | ||
) |
Send data synchronously.
This will write either length
words or until the write buffer is full, whichever is less, then return. The value pointed to by length
will be updated to reflect the number of words that were actually written.
[in] | obj | The I2S object |
[in] | data | The buffer for sending |
[in,out] | length | Number of words to write (as configured in cyhal_i2s_config_t.word_length, updated with the number actually written |
bool cyhal_i2s_is_tx_enabled | ( | cyhal_i2s_t * | obj | ) |
Checks if the transmit functionality is enabled for the specified I2S peripheral (regardless of whether data is currently queued for transmission).
The transmit functionality can be enabled by calling cyhal_i2s_start_tx and disabled by calling cyhal_i2s_stop_tx
[in] | obj | The I2S peripheral to check |
bool cyhal_i2s_is_tx_busy | ( | cyhal_i2s_t * | obj | ) |
Checks if the specified I2S peripheral is transmitting data, including if a pending async transfer is waiting to write more data to the transmit buffer.
[in] | obj | The I2S peripheral to check |
bool cyhal_i2s_is_rx_enabled | ( | cyhal_i2s_t * | obj | ) |
Checks if the receive functionality is enabled for the specified I2S peripheral (regardless of whether any unread data has been received).
The receive functionality can be enabled by calling cyhal_i2s_start_rx and disabled by calling cyhal_i2s_stop_rx
[in] | obj | The I2S peripheral to check |
bool cyhal_i2s_is_rx_busy | ( | cyhal_i2s_t * | obj | ) |
Checks if the specified I2S peripheral has received data that has not yet been read out of the hardware buffer.
This includes if an async read transfer is pending.
[in] | obj | The I2S peripheral to check |
cy_rslt_t cyhal_i2s_read_async | ( | cyhal_i2s_t * | obj, |
void * | rx, | ||
size_t | rx_length | ||
) |
Start I2S asynchronous read.
This will transfer rx_length
words into the buffer pointed to by rx
in the background. When the requested quantity of data has been read, the CYHAL_I2S_ASYNC_RX_COMPLETE event will be raised. See cyhal_i2s_register_callback and cyhal_i2s_enable_event.
cyhal_i2s_set_async_mode can be used to control whether this uses DMA or a CPU-driven transfer.
[in] | obj | The I2S object |
[out] | rx | The receive buffer. |
[in] | rx_length | Number of words (as configured in cyhal_i2s_config_t.word_length) to read. |
cy_rslt_t cyhal_i2s_write_async | ( | cyhal_i2s_t * | obj, |
const void * | tx, | ||
size_t | tx_length | ||
) |
Start I2S asynchronous write.
This will transfer tx_length
words into the tx buffer in the background. When the requested quantity of data has been queued in the transmit buffer, the CYHAL_I2S_ASYNC_TX_COMPLETE event will be raised. See cyhal_i2s_register_callback and cyhal_i2s_enable_event.
cyhal_i2s_set_async_mode can be used to control whether this uses DMA or a SW (CPU-driven) transfer.
[in] | obj | The I2S object |
[in] | tx | The transmit buffer. |
[in] | tx_length | The number of words to transmit. |
cy_rslt_t cyhal_i2s_set_async_mode | ( | cyhal_i2s_t * | obj, |
cyhal_async_mode_t | mode, | ||
uint8_t | dma_priority | ||
) |
Set the mechanism that is used to perform I2S asynchronous transfers.
The default is SW.
[in] | obj | The I2S object |
[in] | mode | The transfer mode |
[in] | dma_priority | The priority, if DMA is used. Valid values are the same as for cyhal_dma_init. If DMA is not selected, the only valid value is CYHAL_DMA_PRIORITY_DEFAULT, and no guarantees are made about prioritization. |
bool cyhal_i2s_is_read_pending | ( | cyhal_i2s_t * | obj | ) |
Checks if the specified I2S peripheral is in the process of reading data from the hardware buffer into RAM.
[in] | obj | The I2S peripheral to check |
bool cyhal_i2s_is_write_pending | ( | cyhal_i2s_t * | obj | ) |
Checks if the specified I2S peripheral is in the process of writing data into the hardware buffer.
[in] | obj | The I2S peripheral to check |
cy_rslt_t cyhal_i2s_abort_read_async | ( | cyhal_i2s_t * | obj | ) |
Abort I2S asynchronous read.
This function does not perform any validation before aborting the transfer. Any validation which is required is the responsibility of the application.
[in] | obj | The I2S object |
cy_rslt_t cyhal_i2s_abort_write_async | ( | cyhal_i2s_t * | obj | ) |
Abort I2S asynchronous write.
This function does not perform any validation before aborting the transfer. Any validation which is required is the responsibility of the application.
[in] | obj | The I2S object |
void cyhal_i2s_register_callback | ( | cyhal_i2s_t * | obj, |
cyhal_i2s_event_callback_t | callback, | ||
void * | callback_arg | ||
) |
Register an I2S callback handler.
This function will be called when one of the events enabled by cyhal_i2s_enable_event occurs.
[in] | obj | The I2S object |
[in] | callback | The callback handler which will be invoked when the interrupt fires |
[in] | callback_arg | Generic argument that will be provided to the callback when called |
void cyhal_i2s_enable_event | ( | cyhal_i2s_t * | obj, |
cyhal_i2s_event_t | event, | ||
uint8_t | intr_priority, | ||
bool | enable | ||
) |
Configure I2S events.
When an enabled event occurs, the function specified by cyhal_i2s_register_callback will be called.
[in] | obj | The I2S object |
[in] | event | The I2S event type |
[in] | intr_priority | The priority for NVIC interrupt events |
[in] | enable | True to turn on specified events, False to turn off |
cy_rslt_t cyhal_i2s_enable_output | ( | cyhal_i2s_t * | obj, |
cyhal_i2s_output_t | output, | ||
cyhal_source_t * | source | ||
) |
Enables the specified output signal.
[in] | obj | The I2S object |
[in] | output | Which output signal to enable |
[out] | source | Pointer to user-allocated source signal object which will be initialized by enable_output. source should be passed to (dis)connect_digital functions to (dis)connect the associated endpoints. |
cy_rslt_t cyhal_i2s_disable_output | ( | cyhal_i2s_t * | obj, |
cyhal_i2s_output_t | output | ||
) |
Disables the specified output signal.
[in] | obj | The I2S object |
[in] | output | Which output signal to disable |