MTB CAT1 Peripheral driver library
TDM/I2S (Time Division Multiplexing/Inter-IC Sound)

General Description

Note
IP Supported: TDM
Device Categories: CAT1B. Please refer Device Catalog. Configures audio TDM/I2S.

The functions and other declarations used in this driver are in cy_tdm.h. You can include cy_pdl.h (ModusToolbox only) to get access to all functions and declarations in the PDL.

Features:

Configuration Considerations

To set up a TDM driver, initialize the TDM Transmitter module in accordance with a configuration structure.

To set up TDM, provide the configuration parameters in the cy_stc_tdm_config_t structure.

For example, for Tx configuration, set txEnabled to true, configure txDmaTrigger (depending on whether DMA is going to be used or not), set extClk (if an external clock is used), provide clkDiv, masterMode, sckPolarity, fsyncPolarity, channelSize, wordSize, either i2sMode or TDM (based on Mode setting), fifoTriggerLevel (when the Trig interrupt will be used) and format A similar setup is for the Rx configuration.

To initialize the TDM block, call the Cy_AudioTDM_Init function, providing the filled cy_stc_tdm_config_t structure. Before starting the transmission, enable the Tx Cy_AudioTDM_EnableTx, then fill the first Tx data frame by calling Cy_AudioTDM_WriteTxData. Then call the Cy_AudioTDM_ActivateTx. For the reception the sequence is the same except for filling the first data frame.

For example:

/* Scenario: Setup a duplex 16-bit TDM interface */
cy_stc_tdm_config_tx_t tdm_lpbk_tx_config =
{
.enable = true,
.masterMode = CY_TDM_DEVICE_MASTER,
.wordSize = CY_TDM_SIZE_16,
.format = CY_TDM_LEFT,
.clkDiv = 16,
.sckPolarity = CY_TDM_CLK,
.fsyncPolarity = CY_TDM_SIGN,
.fsyncFormat = CY_TDM_CH_PERIOD,
.channelNum = 2,
.channelSize = 16,
.fifoTriggerLevel = 36,
.chEn = 0x3,
.signalInput = 0,
.i2sMode = true,
};
cy_stc_tdm_config_rx_t tdm_lpbk_rx_config =
{
.enable = true,
.masterMode = CY_TDM_DEVICE_SLAVE,
.wordSize = CY_TDM_SIZE_16,
.signExtend = CY_ZERO_EXTEND,
.format = CY_TDM_LEFT,
.clkDiv = 16,
.sckPolarity = CY_TDM_CLK,
.fsyncPolarity = CY_TDM_SIGN,
.lateSample = false,
.fsyncFormat = CY_TDM_CH_PERIOD,
.channelNum = 2,
.channelSize = 16,
.fifoTriggerLevel = 32,
.chEn = 0x3,
.signalInput = 0,
.i2sMode = true,
};
const cy_stc_tdm_config_t tdm_lpbk_config =
{
.tx_config = &tdm_lpbk_tx_config,
.rx_config = &tdm_lpbk_rx_config,
};
if(CY_TDM_SUCCESS != Cy_AudioTDM_Init(TDM_STRUCT0, &tdm_lpbk_config))
{
/* Insert error handling */
}
/* Clear possible pending interrupts */
Cy_AudioTDM_ClearTxInterrupt(TDM_STRUCT0_TX, CY_TDM_INTR_TX_MASK);
Cy_AudioTDM_ClearRxInterrupt(TDM_STRUCT0_RX, CY_TDM_INTR_RX_MASK);
/* Enable interrupts */
Cy_AudioTDM_SetTxInterruptMask(TDM_STRUCT0_TX, CY_TDM_INTR_TX_MASK);
Cy_AudioTDM_SetRxInterruptMask(TDM_STRUCT0_RX, CY_TDM_INTR_RX_MASK);
/* Enable the TDM interface */
Cy_AudioTDM_EnableRx(TDM_STRUCT0_RX);
Cy_AudioTDM_EnableTx(TDM_STRUCT0_TX);

If you use a DMA, the DMA channel should be previously configured. The TDM interrupts (if applicable) can be enabled by calling Cy_AudioTDM_SetTxInterruptMask.

For example, if the trigger interrupt is used during operation, the ISR should call the Cy_AudioTDM_WriteTxData as many times as required for your FIFO payload, but not more than the FIFO size. Then call Cy_AudioTDM_ClearTxInterrupt with appropriate parameters.

If a DMA is used and the DMA channel is properly configured - no CPU activity (or any application code) is needed for I2S/TDM operation.

The I2S frame appears as:

i2s_frame.png

This is an example for the channel length = 32. A similar case exists for the rest channel length configuration, with one limitation: the word length should be less than or equal to the channel length. See the datasheet of your device for more details.

MISRA-C Compliance

The TDM driver has the following specific deviations:

MISRA Rule Rule Class (Required/Advisory) Rule Description Description of Deviation(s)
10.3 R A composite expression of the "essentially unsigned" type is being cast to a different type category. The value got from the bitfield physically cannot exceed the enumeration that describes this bitfield. So, the code is safe by design.
11.4 A A cast should not be performed between a pointer to object type and a different pointer to object type.
20.3 R The validity of values passed to library functions shall be checked. This violation is not caused by code changes, i.e. is not a regression.

Changelog

VersionChangesReason for Change
1.0 Initial version

API Reference

 Interrupt Masks
 
 Data Structures
 
 Enumerated Types
 
 Macros
 
 Functions