NetBurner 3.5.6
PDF Version

Main driver class for SAI peripheral operation. More...

#include <sai.h>

Public Types

enum  ctxState_t {
  CTX_STATE_STOPPED , CTX_STATE_INIT , CTX_STATE_TX , CTX_STATE_RX ,
  CTX_STATE_TXRX
}
 Current operational state of the SAI driver. More...
 

Public Member Functions

int Init (const SAI_cfg_t &cfg)
 Initialize the SAI hardware and driver context.
 
void Shutdown ()
 Shut down the SAI hardware and release driver resources.
 
int GetMaxTxBuffers ()
 Get the maximum number of transmit buffers that can be queued.
 
int GetMaxRxBuffers ()
 Get the maximum number of receive buffers that can be queued.
 
int getCurrentConfig (SAI_cfg_t &cfg)
 Retrieve the current active configuration.
 
ctxState_t getState () const
 Get the current operational state of the driver.
 
int TransmitBuffer (void *buffer, uint32_t bufferLen, bool waitIfNeeded, bool enableHalfNotify=false)
 Queue a buffer for transmission.
 
int ReadyReceiveBuffer (void *buffer, uint32_t bufferLen, bool waitIfNeeded, bool enableHalfNotify=false)
 Queue a buffer for receiving data.
 
void RegisterTxBufferCB (SAI_BufferDoneFn_t cb)
 Register a callback for transmit buffer completion.
 
void RegisterRxBufferCB (SAI_BufferDoneFn_t cb)
 Register a callback for receive buffer completion.
 
void clrStickyTxError ()
 Clear the sticky transmit error flag.
 
void clrStickyRxError ()
 Clear the sticky receive error flag.
 
uint8_t getStickyTxError ()
 Get the sticky transmit error status.
 
uint8_t getStickyRxError ()
 Get the sticky receive error status.
 
void dump ()
 Dump driver state and statistics to the console.
 

Detailed Description

Main driver class for SAI peripheral operation.

SAICtx_t provides a high-level, buffer-oriented interface to the SAI peripheral. The driver manages DMA transfers, buffer chains, and provides callbacks for buffer completion events.

Driver Features

  • DMA-based transfers: All data movement handled by eDMA for CPU efficiency
  • Buffer queuing: Queue up to SAI_TXBD_COUNT transmit and SAI_RXBD_COUNT receive buffers
  • Circular buffering: Automatic chaining of buffers for continuous streaming
  • Half-transfer notifications: Optional callbacks at 50% buffer completion
  • Error handling: Comprehensive error detection and reporting
  • Thread-safe: Uses semaphores for safe operation from multiple tasks

Driver States

Init()
STOPPED ---------> INIT
^ |
| v
| +----> TX (transmit only)
| |
| +----> RX (receive only)
| |
| +----> TXRX (full duplex)
| |
+---- Shutdown() -+
void Shutdown()
Shut down the SAI hardware and release driver resources.
int Init(const SAI_cfg_t &cfg)
Initialize the SAI hardware and driver context.

Thread Safety

The driver uses internal semaphores to synchronize buffer operations:

  • Multiple tasks can queue buffers safely
  • Callbacks execute in interrupt context
  • Use RTOS primitives in callbacks to signal tasks

Performance Considerations

  • Buffer size affects latency: larger buffers = more latency but less overhead
  • Keep 2-3 buffers queued for gapless streaming
  • Process completed buffers quickly to avoid starvation
  • Use half-transfer callbacks for lower latency processing
Warning
Only one SAICtx_t instance should be used per SAI hardware peripheral. Multiple instances controlling the same hardware will conflict.

Member Enumeration Documentation

◆ ctxState_t

Current operational state of the SAI driver.

Enumerator
CTX_STATE_STOPPED 

Driver is stopped; no transfers active

CTX_STATE_INIT 

Driver initialized but no channels active

CTX_STATE_TX 

Transmit channel active only

CTX_STATE_RX 

Receive channel active only

CTX_STATE_TXRX 

Both transmit and receive channels active (full duplex)

Member Function Documentation

◆ clrStickyRxError()

void SAICtx_t::clrStickyRxError ( )
inline

Clear the sticky receive error flag.

Resets the internal error flag that latches when an RX error occurs. Call this after handling an error condition to re-enable error detection.

◆ clrStickyTxError()

void SAICtx_t::clrStickyTxError ( )
inline

Clear the sticky transmit error flag.

Resets the internal error flag that latches when a TX error occurs. Call this after handling an error condition to re-enable error detection.

◆ dump()

void SAICtx_t::dump ( )

Dump driver state and statistics to the console.

Prints detailed information about the driver's current state, including:

  • Configuration parameters
  • DMA status
  • Buffer queue status
  • Error counts
  • Transfer statistics

Useful for debugging and performance analysis.

// Dump SAI driver state
sai.dump();

◆ getCurrentConfig()

int SAICtx_t::getCurrentConfig ( SAI_cfg_t & cfg)

Retrieve the current active configuration.

Reads back the current hardware configuration and populates the provided configuration structure. Useful for verifying settings or creating a modified configuration based on the current state.

Parameters
[out]cfgConfiguration structure to populate with current settings.
Returns
0 on success
Negative on failure (driver not initialized)
SAI_cfg_t currentConfig;
if (sai.getCurrentConfig(currentConfig) == 0) {
iprintf("TX Clock: %lu Hz\n", currentConfig.txClkFreq);
}
Complete configuration structure for the SAI driver.
Definition sai.h:563
uint32_t txClkFreq
Definition sai.h:569

◆ GetMaxRxBuffers()

int SAICtx_t::GetMaxRxBuffers ( )
inline

Get the maximum number of receive buffers that can be queued.

Returns
Maximum number of RX buffers (SAI_RXBD_COUNT)

◆ GetMaxTxBuffers()

int SAICtx_t::GetMaxTxBuffers ( )
inline

Get the maximum number of transmit buffers that can be queued.

Returns
Maximum number of TX buffers (SAI_TXBD_COUNT)

◆ getState()

ctxState_t SAICtx_t::getState ( ) const
inline

Get the current operational state of the driver.

Returns
Current driver state (CTX_STATE_STOPPED, CTX_STATE_INIT, etc.)
if (sai.getState() == SAICtx_t::CTX_STATE_TXRX) {
iprintf("Full duplex operation active\n");
}
@ CTX_STATE_TXRX
Definition sai.h:743

◆ getStickyRxError()

uint8_t SAICtx_t::getStickyRxError ( )
inline

Get the sticky receive error status.

Returns the latched error code from the most recent RX error. The value persists until cleared with clrStickyRxError().

Returns
Error code (non-zero indicates an error occurred)

◆ getStickyTxError()

uint8_t SAICtx_t::getStickyTxError ( )
inline

Get the sticky transmit error status.

Returns the latched error code from the most recent TX error. The value persists until cleared with clrStickyTxError().

Returns
Error code (non-zero indicates an error occurred)

◆ Init()

int SAICtx_t::Init ( const SAI_cfg_t & cfg)

Initialize the SAI hardware and driver context.

Configures the SAI peripheral according to the provided configuration, sets up DMA channels, and prepares the driver for buffer operations.

Parameters
[in]cfgConfiguration structure specifying all SAI parameters. Use one of the predefined configurations (SAI_I2S_SLAVE_*) or create a custom configuration.
Returns
0 on success
Negative error code on failure:
  • Configuration validation errors
  • Clock initialization errors
  • DMA allocation errors
  • Hardware initialization errors
Note
Must be called before any buffer operations.
Calling Init() on an already initialized driver will fail unless Shutdown() is called first.
if (sai.Init(config) < 0) {
iprintf("SAI initialization failed\n");
return;
}
const SAI_cfg_t SAI_I2S_SLAVE_24_TXRX_RK

◆ ReadyReceiveBuffer()

int SAICtx_t::ReadyReceiveBuffer ( void * buffer,
uint32_t bufferLen,
bool waitIfNeeded,
bool enableHalfNotify = false )

Queue a buffer for receiving data.

Provides a buffer to the SAI driver to be filled with received data. The buffer will be added to the receive queue and automatically filled when data arrives. Up to SAI_RXBD_COUNT buffers can be queued simultaneously.

Parameters
bufferPointer to the buffer to be filled with received data. MUST be 32-byte aligned.
bufferLenLength of the buffer in bytes. MUST be a multiple of 32 bytes.
waitIfNeededIf true, blocks until space is available in the queue. If false, returns immediately with error if queue is full.
enableHalfNotifyIf true, callback will be invoked at 50% buffer fill (with doneInvalid=0) in addition to full completion.
Returns
0 on success
Negative error code on failure:
  • Buffer not aligned correctly
  • Buffer size not valid
  • Queue full (if waitIfNeeded is false)
  • Driver not initialized or RX not enabled
Warning
The buffer must remain valid and unchanged until the completion callback indicates it is done (doneInvalid > 0).
Note
For continuous reception, queue the next buffer before the previous one completes to avoid losing data.
// Declare aligned buffer
alignas(32) uint8_t rxBuf[1024];
// Queue for reception
if (sai.ReadyReceiveBuffer(rxBuf, sizeof(rxBuf), true) < 0) {
iprintf("Failed to queue RX buffer\n");
}

◆ RegisterRxBufferCB()

void SAICtx_t::RegisterRxBufferCB ( SAI_BufferDoneFn_t cb)

Register a callback for receive buffer completion.

Sets the function to be called when a receive buffer is filled or encounters an error. The callback executes in interrupt context.

Parameters
cbCallback function pointer, or NULL to disable callbacks.
Note
Only one callback can be registered at a time.
The callback executes in interrupt context - keep it brief!
void rxComplete(void *buffer, int status) {
if (status > 0) {
// Buffer filled successfully
ProcessAudioData(buffer);
}
}
sai.RegisterRxBufferCB(rxComplete);

◆ RegisterTxBufferCB()

void SAICtx_t::RegisterTxBufferCB ( SAI_BufferDoneFn_t cb)

Register a callback for transmit buffer completion.

Sets the function to be called when a transmit buffer completes or encounters an error. The callback executes in interrupt context.

Parameters
cbCallback function pointer, or NULL to disable callbacks.
Note
Only one callback can be registered at a time. Calling this function replaces any previously registered callback.
The callback executes in interrupt context - keep it brief!
void txComplete(void *buffer, int status) {
if (status > 0) {
// Buffer transmitted successfully
OSSemPost(&txDoneSem);
}
}
sai.RegisterTxBufferCB(txComplete);

◆ Shutdown()

void SAICtx_t::Shutdown ( )

Shut down the SAI hardware and release driver resources.

Stops all transfers, disables the SAI peripheral, releases DMA channels, and returns the driver to the stopped state.

Warning
Any buffers currently queued or in process will be abandoned. Ensure all important data is processed before calling Shutdown().
Note
After shutdown, Init() must be called again before using the driver.
sai.Shutdown();
iprintf("SAI driver stopped\n");

◆ TransmitBuffer()

int SAICtx_t::TransmitBuffer ( void * buffer,
uint32_t bufferLen,
bool waitIfNeeded,
bool enableHalfNotify = false )

Queue a buffer for transmission.

Hands a buffer to the SAI driver for transmission. The buffer will be added to the transmit queue and automatically transmitted when its turn comes. Up to SAI_TXBD_COUNT buffers can be queued simultaneously.

Parameters
bufferPointer to the buffer containing data to transmit. MUST be 32-byte aligned (use alignas(32) or attribute((aligned(32)))).
bufferLenLength of the buffer in bytes. MUST be a multiple of 32 bytes. Must also align with word width (1, 2, or 4 byte multiples).
waitIfNeededIf true, blocks until space is available in the queue. If false, returns immediately with error if queue is full.
enableHalfNotifyIf true, callback will be invoked at 50% buffer completion (with doneInvalid=0) in addition to full completion.
Returns
0 on success
Negative error code on failure:
  • Buffer not aligned correctly
  • Buffer size not valid
  • Queue full (if waitIfNeeded is false)
  • Driver not initialized or TX not enabled
Warning
The buffer must remain valid and unchanged until the completion callback indicates it is done (doneInvalid > 0).
Do not modify the buffer contents while it is queued or being transmitted.
Note
For continuous streaming, queue the next buffer before the previous one completes to avoid gaps in transmission.
// Declare aligned buffer
alignas(32) uint8_t txBuf[1024];
// Fill buffer with audio data
FillAudioBuffer(txBuf, sizeof(txBuf));
// Queue for transmission
if (sai.TransmitBuffer(txBuf, sizeof(txBuf), true) < 0) {
iprintf("Failed to queue TX buffer\n");
}

The documentation for this class was generated from the following file: