NetBurner 3.5.6
PDF Version

Synchronous Audio Interface (SAI/I2S) Driver for i.MX RT10xx. More...

#include <predef.h>
#include <sim.h>
#include <nbrtos.h>
#include <edma.h>

Go to the source code of this file.

Classes

struct  SAI_rxtx_cfg_t
 Configuration structure for one direction (TX or RX) of the SAI module. More...
 
struct  SAI_cfg_t
 Complete configuration structure for the SAI driver. More...
 
class  SAICtx_t
 Main driver class for SAI peripheral operation. More...
 

Macros

#define SAI_HW_COUNT   3
 
#define SAI_TXBD_COUNT   4
 
#define SAI_RXBD_COUNT   4
 

Typedefs

typedef void(* SAI_BufferDoneFn_t) (void *buffer, int doneInvalid)
 Callback function type for buffer completion notifications.
 

Enumerations

enum  clkSrc_t { CLK_SRC_MCK , CLK_SRC_EXT }
 Clock source selection for SAI bit clock generation. More...
 
enum  clkCh_t { CLK_CH_CH , CLK_CH_RK , CLK_CH_TK }
 Clock channel selection for determining which clock signal to use. More...
 
enum  clkPol_t { CLK_ACTIVE_HIGH , CLK_ACTIVE_LOW }
 Clock polarity configuration. More...
 
enum  frameSyncCh_t { SYNC_CH_CH , SYNC_CH_RX , SYNC_CH_TX }
 Frame synchronization channel selection. More...
 
enum  startCond_t {
  START_CONTINUOUS , START_SYNC_RX_TX , START_FRAME_LOW , START_FRAME_HIGH ,
  START_FRAME_FALLING , START_FRAME_RISING , START_FRAME_LEVEL , START_FRAME_EDGE ,
  START_CMP_0
}
 Starting conditions that trigger SAI data transfers. More...
 
enum  clkGate_t { CLK_GATE_CONTINUOUS , CLK_GATE_FRAME_LOW , CLK_GATE_FRAME_HIGH }
 Clock gating mode for power optimization. More...
 
enum  frameEdge_t { FRAME_SYNC_RISING , FRAME_SYNC_FALLING }
 Frame sync edge that indicates the start of a new frame. More...
 
enum  clkOut_t { CLK_OUT_INPUT , CLK_OUT_CONTINUOUS , CLK_OUT_TRANSFER }
 Bit clock output mode configuration. More...
 
enum  frameSyncOut_t { FRAME_SYNC_INPUT , FRAME_SYNC_NEGATIVE , FRAME_SYNC_POSITIVE }
 Frame synchronization signal output mode. More...
 
enum  dataPacking_t {
  BUFFER_WORD8 , BUFFER_WORD16_LEFT , BUFFER_WORD16_RIGHT , BUFFER_WORD32_LEFT ,
  BUFFER_WORD32_RIGHT
}
 Buffer word format and data justification. More...
 
enum  bitOrder_t { LEAST_SIG_FIRST , MOST_SIG_FIRST }
 Bit transmission order within each word. More...
 
enum  bufferDepletionBehavior_t { DEPLETED_PAUSE , DEPLETED_REPEAT_LAST }
 DMA behavior when all queued buffers are exhausted. More...
 
enum  rxTxSync_t { RXTX_ASYNC , RXTX_SYNC_RX , RXTX_SYNC_TX }
 Synchronization mode between RX and TX channels. More...
 

Variables

SAICtx_t sai
 Global SAI driver instance.
 
I2S Slave Mode Configurations

These configurations set up the SAI as an I2S slave (receives clock from external master). Configurations are available for 8, 16, and 24-bit word widths, with various clock routing:

  • _RK: Uses receive clock (BCLK from RX pins)
  • _TK: Uses transmit clock (BCLK from TX pins)
  • _TKRK: TX uses TX clock, RX uses RX clock (independent clocks)
const SAI_cfg_t SAI_I2S_SLAVE_24_TXRX_RK
 
const SAI_cfg_t SAI_I2S_SLAVE_24_TXRX_TK
 
const SAI_cfg_t SAI_I2S_SLAVE_24_TXRX_TKRK
 
const SAI_cfg_t SAI_I2S_SLAVE_16_TXRX_RK
 
const SAI_cfg_t SAI_I2S_SLAVE_16_TXRX_TK
 
const SAI_cfg_t SAI_I2S_SLAVE_16_TXRX_TKRK
 
const SAI_cfg_t SAI_I2S_SLAVE_8_TXRX_RK
 
const SAI_cfg_t SAI_I2S_SLAVE_8_TXRX_TK
 
const SAI_cfg_t SAI_I2S_SLAVE_8_TXRX_TKRK
 
Left-Justified Slave Mode Configurations

These configurations set up the SAI for left-justified audio format (data starts immediately with frame sync, no delay). Available in 8, 16, and 24-bit variants.

const SAI_cfg_t SAI_LJUST_SLAVE_24_TXRX_RK
 
const SAI_cfg_t SAI_LJUST_SLAVE_24_TXRX_TK
 
const SAI_cfg_t SAI_LJUST_SLAVE_24_TXRX_TKRK
 
const SAI_cfg_t SAI_LJUST_SLAVE_16_TXRX_RK
 
const SAI_cfg_t SAI_LJUST_SLAVE_16_TXRX_TK
 
const SAI_cfg_t SAI_LJUST_SLAVE_16_TXRX_TKRK
 
const SAI_cfg_t SAI_LJUST_SLAVE_8_TXRX_RK
 
const SAI_cfg_t SAI_LJUST_SLAVE_8_TXRX_TK
 
const SAI_cfg_t SAI_LJUST_SLAVE_8_TXRX_TKRK
 

Detailed Description

Synchronous Audio Interface (SAI/I2S) Driver for i.MX RT10xx.

This module provides a comprehensive driver for the SAI (Synchronous Audio Interface) peripheral on NXP i.MX RT10xx series microcontrollers. The SAI is commonly used for I2S (Inter-IC Sound) audio data transfer but can be configured for various synchronous serial protocols.

Key Features

  • Full-duplex operation: Simultaneous transmit and receive capability
  • DMA-driven transfers: Efficient buffer management using eDMA
  • Flexible clocking: Multiple clock sources and synchronization modes
  • Protocol support: I2S, left-justified, right-justified formats
  • Word widths: 8, 16, 24, and 32-bit samples supported
  • Buffer chaining: Queue multiple buffers for continuous streaming
  • Event callbacks: User notifications for buffer completion

Driver Architecture

Application Layer
|
v
┌──────────────────────────────────────┐
SAICtx_t Driver API │
│ - Init/Shutdown │
│ - TransmitBuffer/ReceiveBuffer │
│ - Callback Registration │
└──────────┬───────────────────────────┘
|
v
┌──────────────────────────────────────┐
│ DMA Buffer Management │
│ - Buffer Descriptors (TCD) │
│ - Circular Buffer Chains │
│ - Half/Full Transfer Interrupts │
└──────────┬───────────────────────────┘
|
v
┌──────────────────────────────────────┐
│ SAI Hardware Peripheral │
│ - Transmitter (TX) │
│ - Receiver (RX) │
│ - Clock Generation │
│ - Frame Synchronization │
└──────────────────────────────────────┘
Main driver class for SAI peripheral operation.
Definition sai.h:731

Usage Example

#include <sai.h>
// Define aligned buffers (32-byte alignment required)
alignas(32) uint8_t txBuffer[1024];
alignas(32) uint8_t rxBuffer[1024];
// Buffer completion callback
void audioBufferDone(void *buffer, int status) {
if (status > 0) {
// Buffer fully transferred
iprintf("Buffer %p complete\n", buffer);
} else if (status == 0) {
// Half transfer (if enabled)
iprintf("Buffer %p half complete\n", buffer);
} else {
// Error occurred
iprintf("Buffer %p error: %d\n", buffer, status);
}
}
void setupAudio() {
// Use predefined I2S slave configuration
// Initialize the SAI driver
if (sai.Init(config) < 0) {
iprintf("SAI init failed\n");
return;
}
// Register callbacks
sai.RegisterTxBufferCB(audioBufferDone);
sai.RegisterRxBufferCB(audioBufferDone);
// Queue transmit buffer
sai.TransmitBuffer(txBuffer, sizeof(txBuffer), true);
// Queue receive buffer
sai.ReadyReceiveBuffer(rxBuffer, sizeof(rxBuffer), true);
}
void RegisterRxBufferCB(SAI_BufferDoneFn_t cb)
Register a callback for receive buffer completion.
void RegisterTxBufferCB(SAI_BufferDoneFn_t cb)
Register a callback for transmit buffer completion.
int ReadyReceiveBuffer(void *buffer, uint32_t bufferLen, bool waitIfNeeded, bool enableHalfNotify=false)
Queue a buffer for receiving data.
int Init(const SAI_cfg_t &cfg)
Initialize the SAI hardware and driver context.
int TransmitBuffer(void *buffer, uint32_t bufferLen, bool waitIfNeeded, bool enableHalfNotify=false)
Queue a buffer for transmission.
SAICtx_t sai
Global SAI driver instance.
const SAI_cfg_t SAI_I2S_SLAVE_24_TXRX_RK
Synchronous Audio Interface (SAI/I2S) Driver for i.MX RT10xx.
Complete configuration structure for the SAI driver.
Definition sai.h:563

Buffer Management

Buffers must meet the following requirements:

  • Alignment: 32-byte aligned (use alignas(32) or attribute((aligned(32))))
  • Size: Multiple of 32 bytes
  • Length: Appropriate for word width (1, 2, or 4 byte multiples)
  • Persistence: Must remain valid until callback indicates completion

Clock and Synchronization

The SAI supports various clocking and synchronization modes:

  • Asynchronous: TX and RX use independent clocks
  • Synchronous with RX: Both use RX clock/frame sync
  • Synchronous with TX: Both use TX clock/frame sync

Clock sources can be:

  • Master clock (MCK) divided
  • External clock input
  • Shared between TX/RX
Warning
This driver uses DMA for all transfers. Ensure buffers remain valid and are not accessed by the CPU until the completion callback is invoked.
Note
The SAI peripheral is referred to as I2S in NXP documentation and hardware registers, but this is a misnomer - it supports multiple protocols.