High level interface for interacting with the Time Division Multiplexed controller (TDM).
The TDM 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 number of channels can all be configured.
Initialize an TDM instance using the cyhal_tdm_init and provide the transmit (tx) and/or receive (rx) pins. Call cyhal_tdm_start_tx and/or cyhal_tdm_start_rx to enable transmit and/or receive functionality as desired.
See Snippet 1: TDM Initialization and Configuration for example initialization as transmit or receive.
The sclk frequency is determined as sclk = sample_rate_hz * channel_length * num_channels
. 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, channel count, channel mask, word length, and sclk frequency will be used for both.
This snippet initializes an TDM resource for transmit or receive and assigns the pins.
Initializing as TDM transmitter
Initializing as TDM receiver
This snippet shows how to transmit data using cyhal_tdm_write_async when the entire sample is available at once.
This snippet shows how to transmit data using cyhal_tdm_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_tdm_read_async.
Code examples (Github)
API Reference | |
TDM HAL Results | |
TDM specific return codes. | |
Data Structures | |
struct | cyhal_tdm_pins_t |
Pins to use for one TDM direction. More... | |
struct | cyhal_tdm_config_t |
TDM Configuration. More... | |
Typedefs | |
typedef void(* | cyhal_tdm_event_callback_t) (void *callback_arg, cyhal_tdm_event_t event) |
Handler for TDM event callbacks. | |
Enumerations | |
enum | cyhal_tdm_event_t { CYHAL_TDM_TX_NOT_FULL = 1 << 0, CYHAL_TDM_TX_HALF_EMPTY = 1 << 1, CYHAL_TDM_TX_EMPTY = 1 << 2, CYHAL_TDM_TX_OVERFLOW = 1 << 3, CYHAL_TDM_TX_UNDERFLOW = 1 << 4, CYHAL_TDM_ASYNC_TX_COMPLETE = 1 << 5, CYHAL_TDM_RX_NOT_EMPTY = 1 << 6, CYHAL_TDM_RX_HALF_FULL = 1 << 7, CYHAL_TDM_RX_FULL = 1 << 8, CYHAL_TDM_RX_OVERFLOW = 1 << 9, CYHAL_TDM_RX_UNDERFLOW = 1 << 10, CYHAL_TDM_ASYNC_RX_COMPLETE = 1 << 11 } |
TDM events. More... | |
enum | cyhal_tdm_output_t { CYHAL_TDM_TRIGGER_RX_HALF_FULL, CYHAL_TDM_TRIGGER_TX_HALF_EMPTY } |
Selections for TDM output signals. More... | |
enum | cyhal_tdm_word_select_width_t { CYHAL_TDM_WS_SINGLE, CYHAL_TDM_WS_FULL } |
Word select pulse width. More... | |
Functions | |
cy_rslt_t | cyhal_tdm_init (cyhal_tdm_t *obj, const cyhal_tdm_pins_t *tx_pins, const cyhal_tdm_pins_t *rx_pins, const cyhal_tdm_config_t *config, cyhal_clock_t *clk) |
Initialize the TDM peripheral. More... | |
cy_rslt_t | cyhal_tdm_init_cfg (cyhal_tdm_t *obj, const cyhal_tdm_configurator_t *cfg) |
Initialize the TDM peripheral using a configurator generated configuration struct. More... | |
void | cyhal_tdm_free (cyhal_tdm_t *obj) |
Deinitialize the tdm object. More... | |
cy_rslt_t | cyhal_tdm_set_sample_rate (cyhal_tdm_t *obj, uint32_t sample_rate_hz) |
Set the TDM sample rate. More... | |
cy_rslt_t | cyhal_tdm_start_tx (cyhal_tdm_t *obj) |
Starts transmitting data. More... | |
cy_rslt_t | cyhal_tdm_stop_tx (cyhal_tdm_t *obj) |
Stops transmitting data. More... | |
cy_rslt_t | cyhal_tdm_clear_tx (cyhal_tdm_t *obj) |
Clears the tx hardware buffer. More... | |
cy_rslt_t | cyhal_tdm_start_rx (cyhal_tdm_t *obj) |
Starts receiving data. More... | |
cy_rslt_t | cyhal_tdm_stop_rx (cyhal_tdm_t *obj) |
Stops receiving data. More... | |
cy_rslt_t | cyhal_tdm_clear_rx (cyhal_tdm_t *obj) |
Clears the rx hardware buffer. More... | |
cy_rslt_t | cyhal_tdm_read (cyhal_tdm_t *obj, void *data, size_t *length) |
Read data synchronously. More... | |
cy_rslt_t | cyhal_tdm_write (cyhal_tdm_t *obj, const void *data, size_t *length) |
Send data synchronously. More... | |
bool | cyhal_tdm_is_tx_enabled (cyhal_tdm_t *obj) |
Checks if the transmit functionality is enabled for the specified TDM peripheral (regardless of whether data is currently queued for transmission). More... | |
bool | cyhal_tdm_is_rx_enabled (cyhal_tdm_t *obj) |
Checks if the receive functionality is enabled for the specified TDM peripheral (regardless of whether any unread data has been received). More... | |
bool | cyhal_tdm_is_tx_busy (cyhal_tdm_t *obj) |
Checks if the specified TDM peripheral is transmitting data, including if a pending async transfer is waiting to write more data to the transmit buffer. More... | |
bool | cyhal_tdm_is_rx_busy (cyhal_tdm_t *obj) |
Checks if the specified TDM peripheral has received data that has not yet been read out of the hardware buffer. More... | |
cy_rslt_t | cyhal_tdm_read_async (cyhal_tdm_t *obj, void *rx, size_t rx_length) |
Start TDM asynchronous read. More... | |
cy_rslt_t | cyhal_tdm_write_async (cyhal_tdm_t *obj, const void *tx, size_t tx_length) |
Start TDM asynchronous write. More... | |
cy_rslt_t | cyhal_tdm_set_async_mode (cyhal_tdm_t *obj, cyhal_async_mode_t mode, uint8_t dma_priority) |
Set the mechanism that is used to perform TDM asynchronous transfers. More... | |
bool | cyhal_tdm_is_read_pending (cyhal_tdm_t *obj) |
Checks if the specified TDM peripheral is in the process of reading data from the hardware buffer into RAM. More... | |
bool | cyhal_tdm_is_write_pending (cyhal_tdm_t *obj) |
Checks if the specified TDM peripheral is in the process of writing data into the hardware buffer. More... | |
cy_rslt_t | cyhal_tdm_abort_read_async (cyhal_tdm_t *obj) |
Abort TDM asynchronous read. More... | |
cy_rslt_t | cyhal_tdm_abort_write_async (cyhal_tdm_t *obj) |
Abort TDM asynchronous write. More... | |
void | cyhal_tdm_register_callback (cyhal_tdm_t *obj, cyhal_tdm_event_callback_t callback, void *callback_arg) |
Register a TDM callback handler. More... | |
void | cyhal_tdm_enable_event (cyhal_tdm_t *obj, cyhal_tdm_event_t event, uint8_t intr_priority, bool enable) |
Configure TDM events. More... | |
cy_rslt_t | cyhal_tdm_enable_output (cyhal_tdm_t *obj, cyhal_tdm_output_t output, cyhal_source_t *source) |
Enables the specified output signal. More... | |
cy_rslt_t | cyhal_tdm_disable_output (cyhal_tdm_t *obj, cyhal_tdm_output_t output) |
Disables the specified output signal. More... | |
struct cyhal_tdm_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_tdm_config_t |
Data Fields | ||
---|---|---|
bool | is_tx_slave | Configure TX to operate as slave (true) or master (false) |
cyhal_tdm_word_select_width_t | tx_ws_width | Word select pulse width for TX direction. |
bool | is_rx_slave | Configure RX to operate as slave (true) or master (false) |
cyhal_tdm_word_select_width_t | rx_ws_width | Word select pulse width for RX direction. |
uint32_t | mclk_hz |
Frequency, in hertz, of the master clock if it is provided by an external pin. If at least one mclk pin is not NC, this must be nonzero. If both mclk pins are NC, this must be zero. |
uint8_t | channel_length |
Number of bits in each channel. See the implementation specific documentation for supported values. |
uint8_t | num_channels |
Number of channels. Must be a value between 1 and 32. Not all implementations support all channel counts; see the implementation specific documentation for details. |
uint32_t | channel_mask |
Determines which channels are enabled. Disabled channels still participate in the time slicing, but the contents of a disabled channel are silently discarded (for Rx) or sent as all 0's (for Tx). This is a mask, with each bit corresponding to the enabled state of one channel. Not all implementations permit masking of arbitrary channel combinations. See the implementation specific documentation for details. |
uint8_t | word_length |
Number of bits in each word. Must be less than or equal to channel_length. If word_length < 32, the excess bits will be padded with 0's. |
uint32_t | sample_rate_hz | Sample rate in Hz. |
enum cyhal_tdm_event_t |
TDM events.
enum cyhal_tdm_output_t |
cy_rslt_t cyhal_tdm_init | ( | cyhal_tdm_t * | obj, |
const cyhal_tdm_pins_t * | tx_pins, | ||
const cyhal_tdm_pins_t * | rx_pins, | ||
const cyhal_tdm_config_t * | config, | ||
cyhal_clock_t * | clk | ||
) |
Initialize the TDM peripheral.
It sets the default parameters for TDM 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 a TDM object. The caller must allocate the memory for this object but the init function will initialize its contents. |
[in] | tx_pins | Pins for TDM transmit. If NULL, transmit functionality will be disabled. |
[in] | rx_pins | Pins for TDM 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_tdm_init_cfg | ( | cyhal_tdm_t * | obj, |
const cyhal_tdm_configurator_t * | cfg | ||
) |
Initialize the TDM peripheral using a configurator generated configuration struct.
[out] | obj | Pointer to a TDM 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_tdm_free | ( | cyhal_tdm_t * | obj | ) |
Deinitialize the tdm object.
[in,out] | obj | The tdm object |
cy_rslt_t cyhal_tdm_set_sample_rate | ( | cyhal_tdm_t * | obj, |
uint32_t | sample_rate_hz | ||
) |
Set the TDM sample rate.
[in] | obj | The TDM object |
[in] | sample_rate_hz | Sample rate in Hz |
cy_rslt_t cyhal_tdm_start_tx | ( | cyhal_tdm_t * | obj | ) |
Starts transmitting data.
Transmission will continue until it is stopped by calling cyhal_tdm_stop_tx.
[in] | obj | The TDM object |
cy_rslt_t cyhal_tdm_stop_tx | ( | cyhal_tdm_t * | obj | ) |
Stops transmitting data.
This immediately terminates data transmission.
[in] | obj | The TDM object |
cy_rslt_t cyhal_tdm_clear_tx | ( | cyhal_tdm_t * | obj | ) |
Clears the tx hardware buffer.
[in] | obj | The tdm peripheral |
cy_rslt_t cyhal_tdm_start_rx | ( | cyhal_tdm_t * | obj | ) |
Starts receiving data.
Data will continue to be received until it is stopped by calling cyhal_tdm_stop_rx.
[in] | obj | The TDM object |
cy_rslt_t cyhal_tdm_stop_rx | ( | cyhal_tdm_t * | obj | ) |
Stops receiving data.
This immediately terminates data receipt.
[in] | obj | The TDM object |
cy_rslt_t cyhal_tdm_clear_rx | ( | cyhal_tdm_t * | obj | ) |
Clears the rx hardware buffer.
[in] | obj | The tdm peripheral |
cy_rslt_t cyhal_tdm_read | ( | cyhal_tdm_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 TDM object |
[out] | data | The buffer for receiving |
[in,out] | length | Number of words to (as configured in cyhal_tdm_config_t.word_length) read, updated with the number actually read |
cy_rslt_t cyhal_tdm_write | ( | cyhal_tdm_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 TDM object |
[in] | data | The buffer for sending |
[in,out] | length | Number of words to write (as configured in cyhal_tdm_config_t.word_length, updated with the number actually written |
bool cyhal_tdm_is_tx_enabled | ( | cyhal_tdm_t * | obj | ) |
Checks if the transmit functionality is enabled for the specified TDM peripheral (regardless of whether data is currently queued for transmission).
The transmit functionality can be enabled by calling cyhal_tdm_start_tx and disabled by calling cyhal_tdm_stop_tx
[in] | obj | The TDM peripheral to check |
bool cyhal_tdm_is_rx_enabled | ( | cyhal_tdm_t * | obj | ) |
Checks if the receive functionality is enabled for the specified TDM peripheral (regardless of whether any unread data has been received).
The receive functionality can be enabled by calling cyhal_tdm_start_rx and disabled by calling cyhal_tdm_stop_rx
[in] | obj | The TDM peripheral to check |
bool cyhal_tdm_is_tx_busy | ( | cyhal_tdm_t * | obj | ) |
Checks if the specified TDM peripheral is transmitting data, including if a pending async transfer is waiting to write more data to the transmit buffer.
[in] | obj | The TDM peripheral to check |
bool cyhal_tdm_is_rx_busy | ( | cyhal_tdm_t * | obj | ) |
Checks if the specified TDM 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 TDM peripheral to check |
cy_rslt_t cyhal_tdm_read_async | ( | cyhal_tdm_t * | obj, |
void * | rx, | ||
size_t | rx_length | ||
) |
Start TDM 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_TDM_ASYNC_RX_COMPLETE event will be raised. See cyhal_tdm_register_callback and cyhal_tdm_enable_event.
cyhal_tdm_set_async_mode can be used to control whether this uses DMA or a SW (CPU-driven) transfer.
[in] | obj | The TDM object |
[out] | rx | The receive buffer. |
[in] | rx_length | Number of words (as configured in cyhal_tdm_config_t.word_length) to read. |
cy_rslt_t cyhal_tdm_write_async | ( | cyhal_tdm_t * | obj, |
const void * | tx, | ||
size_t | tx_length | ||
) |
Start TDM 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_TDM_ASYNC_TX_COMPLETE event will be raised. See cyhal_tdm_register_callback and cyhal_tdm_enable_event.
cyhal_tdm_set_async_mode can be used to control whether this uses DMA or a SW (CPU-driven) transfer.
[in] | obj | The TDM object |
[in] | tx | The transmit buffer. |
[in] | tx_length | The number of words to transmit. |
cy_rslt_t cyhal_tdm_set_async_mode | ( | cyhal_tdm_t * | obj, |
cyhal_async_mode_t | mode, | ||
uint8_t | dma_priority | ||
) |
Set the mechanism that is used to perform TDM asynchronous transfers.
The default is SW.
[in] | obj | The TDM 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_tdm_is_read_pending | ( | cyhal_tdm_t * | obj | ) |
Checks if the specified TDM peripheral is in the process of reading data from the hardware buffer into RAM.
[in] | obj | The TDM peripheral to check |
bool cyhal_tdm_is_write_pending | ( | cyhal_tdm_t * | obj | ) |
Checks if the specified TDM peripheral is in the process of writing data into the hardware buffer.
[in] | obj | The TDM peripheral to check |
cy_rslt_t cyhal_tdm_abort_read_async | ( | cyhal_tdm_t * | obj | ) |
Abort TDM 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 TDM object |
cy_rslt_t cyhal_tdm_abort_write_async | ( | cyhal_tdm_t * | obj | ) |
Abort TDM 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 TDM object |
void cyhal_tdm_register_callback | ( | cyhal_tdm_t * | obj, |
cyhal_tdm_event_callback_t | callback, | ||
void * | callback_arg | ||
) |
Register a TDM callback handler.
This function will be called when one of the events enabled by cyhal_tdm_enable_event occurs.
[in] | obj | The TDM 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_tdm_enable_event | ( | cyhal_tdm_t * | obj, |
cyhal_tdm_event_t | event, | ||
uint8_t | intr_priority, | ||
bool | enable | ||
) |
Configure TDM events.
When an enabled event occurs, the function specified by cyhal_tdm_register_callback will be called.
[in] | obj | The TDM object |
[in] | event | The TDM 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_tdm_enable_output | ( | cyhal_tdm_t * | obj, |
cyhal_tdm_output_t | output, | ||
cyhal_source_t * | source | ||
) |
Enables the specified output signal.
[in] | obj | The TDM 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_tdm_disable_output | ( | cyhal_tdm_t * | obj, |
cyhal_tdm_output_t | output | ||
) |
Disables the specified output signal.
[in] | obj | The TDM object |
[in] | output | Which output signal to disable |