I2S
- group I2S
I2S (Inter-IC Sound) Interface.
The I2S API provides support for the I2S interface.
Defines
-
PI_I2S_CH_FMT_DATA_ORDER_MSB
Data order MSB.
Data bits are transferred MSB first.
-
PI_I2S_CH_FMT_DATA_ORDER_LSB
Data order LSB.
Data bits are transferred LSB first.
-
PI_I2S_CH_FMT_DATA_ALIGN_LEFT
Data alignment left.
Left Justified.
-
PI_I2S_CH_FMT_DATA_ALIGN_RIGHT
Data alignment right.
Right Justified.
-
PI_I2S_CH_FMT_DATA_SIGN_NO_EXTEND
Data sign extension disabled.
Data are not sign extended when I2S data size is inferior to memory data size.
-
PI_I2S_CH_FMT_DATA_SIGN_EXTEND
Data sign extension enabled.
Data are sign extended when I2S data size is inferior to memory data size. For example when I2S data are on 16 bits but are stored in a 32 bits word, MSB sign is extended.
-
PI_I2S_OPT_PINGPONG
-
PI_I2S_OPT_MEM_SLAB
Mem slab mode.
In mem slab mode TX output or RX sampling will keep alternating between a a set of buffers given by the user. Memory slab pointed to by the mem_slab field has to be defined and initialized by the user. For I2S driver to function correctly number of memory blocks in a slab has to be at least 2 per queue. Size of the memory block should be multiple of frame_size where frame_size = (channels * word_size_bytes). As an example 16 bit word will occupy 2 bytes, 24 or 32 bit word will occupy 4 bytes.
-
PI_I2S_OPT_FULL_DUPLEX
Full duplex mode.
The normal and default mode is to use a single pin for both TX and RX. In full duplex mode, RX and TX will use 2 different pins(called sdi and sdo so that samples can be received and sent at the same time).
-
PI_I2S_OPT_DISABLED
Disable the channel.
If set, this desactivates the channel being configured (either RX or TX). Once the sampling is running, this will make sure this channel is not receiving or sending samples.
-
PI_I2S_OPT_ENABLED
Enable the channel.
If set, this activates the channel being configured (either RX or TX). Once the sampling is running, this will make sure this channel is receiving or sending samples.
-
PI_I2S_OPT_IS_TX
Configure TX channel.
If set, the configuration will apply to the TX channel and won’t change anything for what concerns the RX channel. Note that this does not prevent from using the RX channel, they must just be configured separately.
Setting this configuration allows to send data from memory to speakers.
-
PI_I2S_OPT_IS_RX
Configure RX channel.
If set, the configuration will apply to the RX channel and won’t change anything for what concerns the TX channel. Note that this does not prevent from using the TX channel, they must just be configured separately.
Setting this configuration allows to receive data from microphones to memory.
-
PI_I2S_OPT_LOOPBACK
TX loopback.
If set, this activates an internal loopback between the RX pin and TX pin. All data received on the RX will be sent to the TX pin. Note that this does not prevent from receiving data. Data received on the RX can be sent both to a memory buffer (if RX channel is enabled) and to the TX (if the loopback is enabled). The loopback must be applied on the TX channel.
-
PI_I2S_OPT_INT_CLK
Use internal clock.
Clock is generated internally from SOC’s clock.
This is default clock source.
-
PI_I2S_OPT_EXT_CLK
Use external clock.
If this option is specified, no clock is generated and an external clock is used.
-
PI_I2S_OPT_INT_WS
Use internal word strobe.
WS signal is generated internally from SCK signal.
This is default WS source.
-
PI_I2S_OPT_EXT_WS
Use external word strobe.
If this option is specified, no word strobe is generated and an external one is used.
-
PI_I2S_OPT_EXT_CLK_INT_ROUTED
Use internally routed ext clk.
If this option is specified, the clk of SAI1 or SAI2 is routed internnally from SAI0
-
PI_I2S_OPT_EXT_WS_INT_ROUTED
Use internally routed ext ws.
If this option is specified, the ws of SAI1 or SAI2 is routed internnally from SAI0
-
PI_I2S_OPT_CLK_POLARITY_RISING_EDGE
Data sampling on rising edge of the clock.
If this option is specified, the data are sampled and generated on the rising edge of the clock
-
PI_I2S_OPT_CLK_POLARITY_FALLING_EDGE
Data sampling on falling edge of the clock.
If this option is specified, the data are sampled and generated on the falling edge of the clock
-
PI_I2S_OPT_WS_POLARITY_RISING_EDGE
WS sampling on rising edge of the clock.
If this option is specified, the WS is sampled and generated on the rising edge of the clock.
-
PI_I2S_OPT_WS_POLARITY_FALLING_EDGE
Data sampling on falling edge of the clock.
If this option is specified, the WS is sampled and generated on the falling edge of the clock
-
PI_I2S_OPT_REF_CLK_FAST
Enable the ref clk fast.
If this option is specified, the clk will be based on the ref clk fast, but not the FLL.
Typedefs
-
typedef uint8_t pi_i2s_fmt_t
-
typedef uint16_t pi_i2s_opt_t
-
typedef struct pi_i2s_conf pi_i2s_conf_t
-
typedef struct pi_i2s_channel_conf pi_i2s_channel_conf_t
Enums
-
enum pi_i2s_mode_t
Values:
-
enumerator PI_I2S_MODE_I2S = 0
I2S mode.
This mode encapsulates standard 2-channel I2S mode and TDM mode. I2S vs TDM mode is selected by ‘ws_type’ field. Clocking and WS are controlled by related bits in ‘options’ field. PCM sample is packed into the slot according to its format settings: MSB vs LSB first, left or right alignment etc.
Example: Serial data is transmitted in two’s complement with the MSB first. Both Word Select (WS) and Serial Data (SD) signals are sampled on the rising edge of the clock signal (SCK). The MSB is always sent one clock period after the WS changes. Left channel data are sent first indicated by WS = 0, followed by right channel data indicated by WS = 1.
-. .-. .-. .-. .-. .-. .-. .-. .-. .-. .-. .-. .-. .-. .-. .-. .-. .-. SCK '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' '-' ' -. .-------------------------------. WS '-------------------------------' '---- -.---.---.---.---.---.---.---.---.---.---.---.---.---.---.---.---.---. SD | |MSB| |...| |LSB| x |...| x |MSB| |...| |LSB| x |...| x | -'---'---'---'---'---'---'---'---'---'---'---'---'---'---'---'---'---' | Left channel | Right channel |
-
enumerator PI_I2S_MODE_PDM = 1
Pulse-density modulation mode.
Serial data is transmitted/received using pulse-density modulation. SAI has various options to control number of PDM streams, signle vs differential mode and single-edge vs double-edge reception. The driver does not have direct access to PDM bit-stream, since it is routed to SFU PDM_OUT/PDM_IN blocks for modulation/demodulation, respectively. PCM samples therefore must pass via SFU, either simply from/to L2 via its MEM_IN/MEM_OUT blocks or form/to an internal SFU node.
-
enumerator PI_I2S_MODE_I2S = 0
-
enum pi_i2s_ioctl_cmd_e
IOCTL command.
Values:
-
enumerator PI_I2S_IOCTL_START
Start the transmission / reception of data.
This command can be used when the interface has been opened or stopped to start sampling.
-
enumerator PI_I2S_IOCTL_STOP
Stop the transmission / reception of data.
Stop the transmission / reception of data at the end of the current memory block. This command can be used when the interface is sampling and is stopping the interface. When the current TX / RX block is transmitted / received the interface is stopped. Subsequent START command will resume transmission / reception where it stopped.
-
enumerator PI_I2S_IOCTL_SYNC
Synchronize transmission / reception of data between different interfaces.
This command can be used when the sampling over different I2S interfaces has to be synchronized. The argument is an integer which specifies the list of interfaces which must be synchronized (one bit per interface). Once called, all further PI_I2S_IOCTL_START and PI_I2S_IOCTL_STOP as well as calls to pi_i2s_channel_enable on other interfaces are put on hold until a PI_I2S_IOCTL_START or PI_I2S_IOCTL_STOP command is issued on the interface where PI_I2S_IOCTL_SYNC was called, which commits the commands on all involved interfaces at the same time.
-
enumerator PI_I2S_IOCTL_CONF_SET
Configure a channel in TDM mode.
In TDM mode, the same interface is time-multiplexed to transmit data for multiple channels, and each channel can have a specific configuration. This command can be used to give the configuration of one channel. The argument must be a pointer to a structure of type struct pi_i2s_conf containing the channel configuration.
-
enumerator PI_I2S_IOCTL_CONF_GET
Get the current configuration of a channel in TDM mode.
In TDM mode, the same interface is time-multiplexed to transmit data for multiple channels, and each channel can have a specific configuration. This command can be used to get the current configuration of one channel. The argument must be a pointer to a structure of type struct pi_i2s_conf where the current channel configuration will be stored.
-
enumerator PI_I2S_IOCTL_CLOCK_ENABLE
Enable clock.
Enable clock for the i2s interface. This command does not sample data, and does not save data. It allows the interface to receive clock signals from SoC and propgate it to slave devices on end line.
-
enumerator PI_I2S_IOCTL_CLOCK_DISABLE
Disable clock.
Disable clock for the i2s interface.
-
enumerator PI_I2S_IOCTL_EN_TIMESTAMP
Enable the timestamp.
Enable the timestamp feature for the i2s interface.
-
enumerator PI_I2S_IOCTL_START
Functions
-
void pi_i2s_setup(uint32_t flags)
Setup specific I2S aspects.
This function can be called to set specific I2S properties such as the number of clock generator. This is typically used by the BSP to give board specific information.
- Parameters:
flags – A bitfield of chip-dependant properties.
-
void pi_i2s_conf_init(struct pi_i2s_conf *conf)
Initialize an I2S configuration with default values.
This function can be called to get default values for all parameters before setting some of them. The structure containing the configuration must be kept alive until the I2S device is opened.
- Parameters:
conf – A pointer to the I2S configuration.
-
int32_t pi_i2s_open(struct pi_device *device)
Open an I2S device.
This function must be called before the I2S device can be used. It will do all the needed configuration to make it usable and initialize the handle used to refer to this opened device when calling other functions. The caller is blocked until the operation is finished.
- Parameters:
device – A pointer to the device structure of the device to open. This structure is allocated by the caller and must be kept alive until the device is closed.
- Return values:
0 – Success
-1 – Failure
- Returns:
Operation status
-
int32_t pi_i2s_close(struct pi_device *device)
Close an opened I2S device.
This function can be called to close an opened I2S device once it is not needed anymore, in order to free all allocated resources. Once this function is called, the device is not accessible anymore and must be opened again before being used. The caller is blocked until the operation is finished.
- Parameters:
device – A pointer to the structure describing the device.
-
int pi_i2s_ioctl(struct pi_device *device, uint32_t cmd, void *arg)
Dynamically change the device configuration.
This function can be called to change part of the device configuration after it has been opened or to control it.
- Parameters:
device – A pointer to the structure describing the device.
cmd – The command which specifies which parameters of the driver to modify and for some of them also their values. The command must be one of those defined in pi_i2s_ioctl_cmd_e enum.
arg – An additional value which is required for some parameters when they are set.
-
int pi_i2s_read(struct pi_device *dev, void **mem_block, size_t *size)
Read data from the RX queue.
Data received by the I2S interface is stored in the RX queue consisting of two memory blocks preallocated by the user and given to the driver in the configuration. Calling this function will return the next available buffer to the caller, which has to use it before the sampling for this buffer starts again.
The data is read in chunks equal to the size of the memory block.
When using several channels, the organization of the samples for each channel in the buffer, is chip-dependent, check the chip-specific documentation to get more information.
If there is no data in the RX queue the function will block waiting for the next RX memory block to fill in.
Due to hardware constraints, the address of the buffer must be aligned on 4 bytes.
- Parameters:
dev – Pointer to the device structure for the driver instance.
mem_block – Pointer to the variable storing the address of the RX memory block containing received data.
size – Pointer to the variable storing the number of bytes read.
- Return values:
0 – Success
-1 – Failure
- Returns:
Status operation
-
int pi_i2s_read_async(struct pi_device *dev, pi_evt_t *event)
Read data asynchronously from the RX queue.
Data received by the I2S interface is stored in the RX queue consisting of two memory blocks preallocated by the user and given to the driver in the configuration. Calling this function will return the next available buffer to the caller, which has to use it before the sampling for this buffer starts again.
The data is read in chunks equal to the size of the memory block.
When using several channels, the organization of the samples for each channel in the buffer, is chip-dependent, check the chip-specific documentation to get more information.
The specified task will be pushed as soon as data is ready in the RX queue, and the information about the memory block and the size will be available in the task.
Due to hardware constraints, the address of the buffer must be aligned on 4 bytes.
- Parameters:
dev – Pointer to the device structure for the driver instance.
event – The event used to notify the end of transfer.
- Return values:
0 – Success
-1 – Failure
- Returns:
Status operation
-
int pi_i2s_write(struct pi_device *dev, void *mem_block, size_t size)
Write data to the TX queue of a channel.
Data to be sent by the I2S interface is stored first in the TX queue consisting of memory blocks preallocated by the user with either pingpong buffers or a memory slab allocator.
In pingpong mode, the driver will automatically alternate between 2 buffers and the user code is supposed to call this function to notify the driver that the specified buffer is ready to be sent. This is used by the driver to report when an underrun or an overrun occurs.
In memory slab allocator mode, the user has to allocate buffers from the memory slab allocator and pass them to the driver by calling this function when they are ready to be sent.
This fonction will block until the specified buffer has been transfered.
- Parameters:
dev – Pointer to the device structure for the driver instance.
mem_block – Pointer to the TX memory block containing data to be sent.
size – Number of bytes to write. This value has to be equal or smaller than the size of the memory block.
- Return values:
0 – Success
-1 – Failure
- Returns:
Status operation
-
int pi_i2s_write_async(struct pi_device *dev, void *mem_block, size_t size, pi_evt_t *event)
Write data asynchronously to the TX queue of a channel.
Data to be sent by the I2S interface is stored first in the TX queue consisting of memory blocks preallocated by the user with either pingpong buffers or a memory slab allocator.
In pingpong mode, the driver will automatically alternate between 2 buffers and the user code is supposed to call this function to notify the driver that the specified buffer is ready to be sent. This is used by the driver to report when an underrun or an overrun occurs.
In memory slab allocator mode, the user has to allocate buffers from the memory slab allocator and pass them to the driver by calling this function when they are ready to be sent.
The specified event will be pushed as soon as data is has been transfered.
- Parameters:
dev – Pointer to the device structure for the driver instance.
mem_block – Pointer to the TX memory block containing data to be sent.
size – Number of bytes to write. This value has to be equal or smaller than the size of the memory block.
event – The event used to notify the end of transfer.
- Return values:
0 – Success
-1 – Failure
- Returns:
Status operation
-
void pi_i2s_channel_conf_init(struct pi_i2s_channel_conf *conf)
Initialize an I2S channel configuration with default values.
This function can be called to get default values for all parameters before setting some of them. The structure containing the configuration must be kept alive until the I2S channel is configured.
- Parameters:
conf – A pointer to the I2S channel configuration.
-
PI_INLINE_I2S_LVL_0 int pi_i2s_channel_conf_set(struct pi_device *dev, int channel, struct pi_i2s_channel_conf *conf)
Configure a channel in TDM mode.
In TDM mode, the same interface is time-multiplexed to transmit data for multiple channels, and each channel can have a specific configuration. This function can be used to give the configuration of one channel.
Warning
: On GAP9, i2s module must be reset between reconfigurations of i2s/tdm channels, otherwise the new configuration will be ignored. Asserting reset is included in pi_i2s_close() function. Deasserting reset (and configuring i2s afterwards) is done in pi_i2s_open() function.
Warning
: On GAP9, if in SAI Tx direction there are both slots sourced from L2 (stream_id == -1) and slots sourced from streams (stream_id != -1), then all stream slots must be placed before all L2 slots. Otherwise, the correct order of slots in the frame on SDO pad is not guaranteed.
- Parameters:
dev – Pointer to the device structure for the driver instance.
channel – ID of the slot, from 0 to the number of channels minus 1.
conf – A pointer to the I2S channel configuration.
- Return values:
0 – Success
-1 – Failure
- Returns:
Status operation
-
PI_INLINE_I2S_LVL_0 int pi_i2s_frame_channel_conf_set(struct pi_device *dev, uint32_t frame, int channel, struct pi_i2s_channel_conf *conf)
Configure a channel of a frame in TDM mode.
A frame is a set of channels gathered together so that they can be controlled all together in terms of data transfer. This function can be used to configure a channel which is part of a frame. In TDM mode, the same interface is time-multiplexed to transmit data for multiple channels, and each channel can have a specific configuration. This function can be used to give the configuration of one channel.
- Parameters:
dev – Pointer to the device structure for the driver instance.
frame – A bitfield containing the channels of the part (one bit per channel).
channel – ID of the slot, from 0 to the number of channels minus 1.
conf – A pointer to the I2S channel configuration.
- Return values:
0 – Success
-1 – Failure
- Returns:
Status operation
-
int pi_i2s_channel_conf_get(struct pi_device *dev, int channel, struct pi_i2s_channel_conf *conf)
Get the current configuration of a channel in TDM mode.
In TDM mode, the same interface is time-multiplexed to transmit data for multiple channels, and each channel can have a specific configuration. This function can be used to get the current configuration of one channel
- Parameters:
dev – Pointer to the device structure for the driver instance.
channel – ID of the slot, from 0 to the number of channels minus 1.
conf – A pointer to the I2S channel configuration.
- Return values:
0 – Success
-1 – Failure
- Returns:
Status operation
-
int pi_i2s_channel_timestamp_set(struct pi_device *dev, int channel, struct pi_i2s_channel_conf *conf)
Enable the timestamp.
Enable the timestamp feature for the i2s interface.
- Parameters:
dev – Pointer to the device structure for the driver instance.
channel – ID of the channel, from 0 to the number of channels minus 1.
conf – A pointer to the I2S channel configuration.
-
int pi_i2s_slots_enable(struct pi_device *dev, uint32_t slots, int enabled)
Enable or disable slots in TDM mode.
In TDM mode, the same interface is time-multiplexed to transmit data for multiple slots of time. Each slot can send and receive data at the same time in full-duplex mode, and is thus made of one 1 RX channels and 1 TX channel. This function can be called to enable or disable the 2 channels of a slot, for example for muting the channels to reconfigure them. The slot is by default enabled when the channel configuration is initialized. Enabling slots will allow them to received or send data, while disabling them will allow it. These operations are not immediate and can take up to 2 frame periods to be effective. When disabling a slot, the buffers are kept, and data continues from the same buffer position after the slot is reenabled.
- Parameters:
dev – Pointer to the device structure for the driver instance.
slots – Bitfield of the slots to enable or disable, with one bit per slot. Each slot whose bit is set to 1 will be configured.
enabled – 1 if the specified slots should be enabled, 0 if they should be disabled.
- Return values:
0 – Success
-1 – Failure
- Returns:
Status operation
-
int pi_i2s_slots_stop_async(struct pi_device *dev, uint32_t slots, pi_evt_t *event)
Stop slots in TDM mode.
In TDM mode, the same interface is time-multiplexed to transmit data for multiple slots of time. Each slot can send and receive data at the same time in full-duplex mode, and is thus made of one 1 RX channels and 1 TX channel. This function can be called to enable or disable the 2 channels of a slot, for example for muting the channels to reconfigure them. Stopping a slot will first disable it, and will also cancel all pending buffers. If some samples were already present in the current buffer, the buffer is considered finished and its associated event is triggered. The size of the data already sent or received is notified in the buffer event. Since stopping requires waiting for 2 frame periods, this operation can take some time and is asynchronous.
- Parameters:
dev – Pointer to the device structure for the driver instance.
slots – Bitfield of the slots to stop, with one bit per slot. Each slot whose bit is set to 1 will be stopped.
event – The event used to notify the end of transfer.
- Return values:
0 – Success
-1 – Failure
- Returns:
Status operation
-
int pi_i2s_slots_stop(struct pi_device *dev, uint32_t slots)
Stop slots in TDM mode.
In TDM mode, the same interface is time-multiplexed to transmit data for multiple slots of time. Each slot can send and receive data at the same time in full-duplex mode, and is thus made of one 1 RX channels and 1 TX channel. This function can be called to enable or disable the 2 channels of a slot, for example for muting the channels to reconfigure them. Stopping a slot will first disable it, and will also cancel all pending buffers. If some samples were already present in the current buffer, the buffer is considered finished and its associated task is triggered. The size of the data already sent or received is notified in the task. Since stopping requires waiting for 2 frame periods, this operation can take some time and is blocking.
- Parameters:
dev – Pointer to the device structure for the driver instance.
slots – Bitfield of the slots to stop, with one bit per slot. Each slot whose bit is set to 1 will be stopped.
- Return values:
0 – Success
-1 – Failure
- Returns:
Status operation
-
int pi_i2s_channel_read(struct pi_device *dev, int channel, void **mem_block, size_t *size)
Read data from the RX queue of a channel in TDM mode.
Data received by the I2S interface is stored in the RX queue consisting of two memory blocks preallocated by the user and given to the driver in the configuration. Calling this function will return the next available buffer to the caller, which has to use it before the sampling for this buffer starts again.
The data is read in chunks equal to the size of the memory block.
This will return data for the specified channel and must only be used in TDM mode.
If there is no data in the RX queue the function will block waiting for the next RX memory block to fill in.
Due to hardware constraints, the address of the buffer must be aligned on 4 bytes.
- Parameters:
dev – Pointer to the device structure for the driver instance.
channel – ID of the slot, from 0 to the number of channels minus 1.
mem_block – Pointer to the variable storing the address of the RX memory block containing received data.
size – Pointer to the variable storing the number of bytes read.
- Return values:
0 – Success
-1 – Failure
- Returns:
Status operation
-
int pi_i2s_channel_read_async(struct pi_device *dev, int channel, pi_evt_t *event)
Read data asynchronously from the RX queue of a channel in TDM mode.
Data received by the I2S interface is stored in the RX queue consisting of two memory blocks preallocated by the user and given to the driver in the configuration. Calling this function will return the next available buffer to the caller, which has to use it before the sampling for this buffer starts again.
The data is read in chunks equal to the size of the memory block.
This will return data for the specified channel and must only be used in TDM mode.
The specified event will be pushed as soon as data is ready in the RX queue, and the information about the memory block and the size will be available in the event.
Due to hardware constraints, the address of the buffer must be aligned on 4 bytes.
- Parameters:
dev – Pointer to the device structure for the driver instance.
channel – ID of the slot, from 0 to the number of channels minus 1.
event – The event used to notify the end of transfer.
- Return values:
0 – Success
-1 – Failure
- Returns:
Status operation
-
PI_INLINE_I2S_LVL_0 int pi_i2s_frame_read(struct pi_device *dev, uint32_t frame, void **mem_block, size_t *size)
Read data from the RX queue of a frame channel in TDM mode.
Data received by the I2S interface is stored in the RX queue consisting of two memory blocks preallocated by the user and given to the driver in the configuration. Calling this function will return the next available buffer to the caller, which has to use it before the sampling for this buffer starts again.
The data is read in chunks equal to the size of the memory block.
This will return data for the specified channel and must only be used in TDM mode.
If there is no data in the RX queue the function will block waiting for the next RX memory block to fill in.
This function is reading for the whole frame. The returned buffer contains the samples for the whole frame, but the size is the size of one channel.
Due to hardware constraints, the address of the buffer must be aligned on 4 bytes.
- Parameters:
dev – Pointer to the device structure for the driver instance.
frame – A bitfield containing the channels of the part (one bit per channel).
mem_block – Pointer to the variable storing the address of the RX memory block containing received data.
size – Pointer to the variable storing the number of bytes read.
- Return values:
0 – Success
-1 – Failure
- Returns:
Status operation
-
PI_INLINE_I2S_LVL_0 int pi_i2s_frame_read_async(struct pi_device *dev, uint32_t frame, pi_evt_t *event)
Read data asynchronously from the RX queue of a frame channel in TDM mode.
Data received by the I2S interface is stored in the RX queue consisting of two memory blocks preallocated by the user and given to the driver in the configuration. Calling this function will return the next available buffer to the caller, which has to use it before the sampling for this buffer starts again.
The data is read in chunks equal to the size of the memory block.
This will return data for the specified channel and must only be used in TDM mode.
The specified event will be pushed as soon as data is ready in the RX queue, and the information about the memory block and the size will be available in the event.
This function is reading for the whole frame. The returned buffer contains the samples for the whole frame, but the size is the size of one channel.
Due to hardware constraints, the address of the buffer must be aligned on 4 bytes.
- Parameters:
dev – Pointer to the device structure for the driver instance.
frame – A bitfield containing the channels of the part (one bit per channel).
event – The event used to notify the end of transfer.
- Return values:
0 – Success
-1 – Failure
- Returns:
Status operation
-
int pi_i2s_read_status(pi_evt_t *event, void **mem_block, size_t *size)
Read the status of an asynchronous read.
After pi_i2s_read_async or pi_i2s_channel_read_async is called to be notified when a read buffer is available, and the notification is received, the output information can be retrieved by calling this function.
- Parameters:
event – The event used for notification.
mem_block – Pointer to the variable storing the address of the RX memory block containing received data.
size – Pointer to the variable storing the number of bytes read.
- Return values:
0 – Success
-1 – Failure
- Returns:
Status operation
-
int pi_i2s_channel_write(struct pi_device *dev, int channel, void *mem_block, size_t size)
Write data to the TX queue of a channel in TDM mode.
Data to be sent by the I2S interface is stored first in the TX queue consisting of memory blocks preallocated by the user with either pingpong buffers or a memory slab allocator.
In pingpong mode, the driver will automatically alternate between 2 buffers and the user code is supposed to call this function to notify the driver that the specified buffer is ready to be sent. This is used by the driver to report when an underrun or an overrun occurs.
In memory slab allocator mode, the user has to allocate buffers from the memory slab allocator and pass them to the driver by calling this function when they are ready to be sent.
This fonction will block until the specified buffer has been transfered.
This will sent data to the specified channel and must only be used in TDM mode.
- Parameters:
dev – Pointer to the device structure for the driver instance.
channel – ID of the slot, from 0 to the number of channels minus 1.
mem_block – Pointer to the TX memory block containing data to be sent.
size – Number of bytes to write. This value has to be equal or smaller than the size of the memory block.
- Return values:
0 – Success
-1 – Failure
- Returns:
Status operation
-
int pi_i2s_channel_write_async(struct pi_device *dev, int channel, void *mem_block, size_t size, pi_evt_t *event)
Write data asynchronously to the TX queue of a channel in TDM mode.
Data to be sent by the I2S interface is stored first in the TX queue consisting of memory blocks preallocated by the user with either pingpong buffers or a memory slab allocator.
In pingpong mode, the driver will automatically alternate between 2 buffers and the user code is supposed to call this function to notify the driver that the specified buffer is ready to be sent. This is used by the driver to report when an underrun or an overrun occurs.
In memory slab allocator mode, the user has to allocate buffers from the memory slab allocator and pass them to the driver by calling this function when they are ready to be sent.
This will sent data to the specified channel and must only be used in TDM mode.
The specified event will be pushed as soon as data is has been transfered.
- Parameters:
dev – Pointer to the device structure for the driver instance.
channel – ID of the slot, from 0 to the number of channels minus 1.
mem_block – Pointer to the TX memory block containing data to be sent.
size – Number of bytes to write. This value has to be equal or smaller than the size of the memory block.
event – The event used to notify the end of transfer.
- Return values:
0 – Success
-1 – Failure
- Returns:
Status operation
-
PI_INLINE_I2S_LVL_0 int pi_i2s_frame_write(struct pi_device *dev, uint32_t frame, void *mem_block, size_t size)
Write data to the TX queue of a frame channel in TDM mode.
Data to be sent by the I2S interface is stored first in the TX queue consisting of memory blocks preallocated by the user with either pingpong buffers or a memory slab allocator.
In pingpong mode, the driver will automatically alternate between 2 buffers and the user code is supposed to call this function to notify the driver that the specified buffer is ready to be sent. This is used by the driver to report when an underrun or an overrun occurs.
In memory slab allocator mode, the user has to allocate buffers from the memory slab allocator and pass them to the driver by calling this function when they are ready to be sent.
This fonction will block until the specified buffer has been transfered.
This function is writing for the whole frame. The buffer must contain the samples for the whole frame, but the size is the size of one channel.
This will sent data to the specified channel and must only be used in TDM mode.
- Parameters:
dev – Pointer to the device structure for the driver instance.
frame – A bitfield containing the channels of the part (one bit per channel).
mem_block – Pointer to the TX memory block containing data to be sent.
size – Number of bytes to write. This value has to be equal or smaller than the size of the memory block.
- Return values:
0 – Success
-1 – Failure
- Returns:
Status operation
-
int pi_i2s_frame_write_async(struct pi_device *dev, uint32_t frame, void *mem_block, size_t size, pi_evt_t *event)
Write data asynchronously to the TX queue of a frame channel in TDM mode.
Data to be sent by the I2S interface is stored first in the TX queue consisting of memory blocks preallocated by the user with either pingpong buffers or a memory slab allocator.
In pingpong mode, the driver will automatically alternate between 2 buffers and the user code is supposed to call this function to notify the driver that the specified buffer is ready to be sent. This is used by the driver to report when an underrun or an overrun occurs.
In memory slab allocator mode, the user has to allocate buffers from the memory slab allocator and pass them to the driver by calling this function when they are ready to be sent.
This will sent data to the specified channel and must only be used in TDM mode.
This function is writing for the whole frame. The buffer must contain the samples for the whole frame, but the size is the size of one channel.
The specified event will be pushed as soon as data is has been transfered.
- Parameters:
dev – Pointer to the device structure for the driver instance.
frame – A bitfield containing the channels of the part (one bit per channel).
mem_block – Pointer to the TX memory block containing data to be sent.
size – Number of bytes to write. This value has to be equal or smaller than the size of the memory block.
event – The event used to notify the end of transfer.
- Return values:
0 – Success
-1 – Failure
- Returns:
Status operation
-
int pi_i2s_write_status(pi_evt_t *event)
Read the status of an asynchronous write.
After pi_i2s_write_async or pi_i2s_channel_write_async and the notification for the end of transfer is received, return value can be retrieved by calling this function.
- Parameters:
event – The event used for notification.
- Return values:
0 – Success
-1 – Failure
- Returns:
Status operation
Variables
-
pi_device_api_t i2s_api
-
struct pi_i2s_conf
- #include <i2s.h>
Interface configuration options.
Public Members
-
pi_i2s_mode_t mode
SAI interface mode: I2S or PDM. I2S mode further supports 2 submodes depending on ‘channels’ and ‘ws_type’ field:
ws_type=1 and channels=2:standard 2-channel I2S
otherwise, a TDM mode with number of channels from 1 to 16
-
uint32_t frame_clk_freq
Frame clock (WS) frequency, this is sampling rate.
-
uint8_t slot_width
Bit width of a TDM slot (not to be confused with word_size).
-
int8_t mem_word_size
Number of bits representing one data word in memory. If it is -1, this is equal to word_size.
-
uint8_t ws_delay
Sets the distance (in bits) in i2s cycles from the WS rising edge to the first bit of the frame
-
uint8_t channels
Number of words per frame.
-
uint8_t itf
I2S device ID.
-
pi_i2s_opt_t options
Configuration options as defined by PI_I2S_OPT_* constants.
-
uint8_t pdm_direction
Only 2b’ LSB are used, for choosing the mode of the pin SDI and the pin SDO:
SDI - b0: 0-TX, 1-RX
SDO - b1: 0-TX, 1-RX In GAP9, if both are configured as 0, the ouput data will be on the SDO. GAP9 uses term pdm_polarity, which is still kept at HAL level for consistency with the HW registers.
-
uint8_t pdm_diff
In PDM Output mode only: set differential mode on pairs,
bit0: (SDI,WS)
bit1: (SDO,SCK)
-
uint32_t ref_clk_freq
Configure the ref clk fast value.
-
uint8_t ts_evt_id
UDMA Config Event ID for generating the timestamp
-
uint8_t ws_type
Specifies the form of the WS: 0: WS pulse is one bit wide, 1 during first slot, first bit 1: WS pulse is one slot wide, 1 during first slot) 2: WS pulse is half-frame wide, 1 during first half
-
pi_i2s_mode_t mode
-
struct pi_i2s_channel_conf
- #include <i2s.h>
Interface channel configuration options. This configuration has to be used when configuring a channel in TDM mode. This can also be used to configure channels when they are part of a frame. Be careful in that case that some fields are not specific restrictions in this case.
Public Members
-
size_t block_size
Size of one RX/TX memory block(buffer) in bytes. On some chips, this size may have to be set under a maximum size, check the chip-specific section. In frame-based mode, this field should be the same for all channels.
-
pi_mem_slab_t *mem_slab
memory slab to store RX/TX data. In frame-based mode, this field should be the same for all channels.
-
void *pingpong_buffers[2]
Pair of buffers used in double-bufferin mode to capture the incoming samples. In frame-based mode, this field should be the same for all channels.
-
pi_i2s_fmt_t format
Data stream format as defined by PI_I2S_FMT_* constants.
-
uint8_t word_size
Number of bits representing one data word.
-
int8_t mem_word_size
Number of bits representing one data word in memory. If it is -1, this is equal to word_size. In frame-based mode, this field should be the same for all channels.
-
pi_i2s_opt_t options
Configuration options as defined by PI_I2S_OPT_* constants.
-
int8_t stream_id
If different from -1, the slot will be connected to the SFU/FFC/AES block with via stream channel specified by this id:
0-15: SFU
16-17: AES
18-21: FFC If stream_id is -1 (default), the driver will allocate a linear uDMA channel and assign it to this slot to be used to send data to L2 memory (for Rx slots) or get data from L2 memory (for Tx slots).
WARNING: On GAP9, if in SAI Tx direction there are both slots sourced from L2 (stream_id == -1) and slots sourced from streams (stream_id != -1), then all stream slots must be placed before all L2 slots. Otherwise, the correct order of slots in the frame on SDO pad is not guaranteed.
-
uint8_t ts_evt_id
UDMA Config Event ID for generating the timestamp. In frame-based mode, this field should be the same for all channels.
-
uint8_t slot_enable
Specifies if the corresponding slot must be enabled or not. It is by default set to 1.
-
size_t block_size
-
PI_I2S_CH_FMT_DATA_ORDER_MSB