HAL SAI How to Use

group SAI_How_To_Use

How to use the HAL SAI driver

The HAL SAI driver can be used as follows:

  1. Declare a hal_sai_handle_t handle structure and initialize the SAIx driver with a SAI HW block by calling the HAL_SAI_Init() . The SAIx clock is enabled inside the HAL_SAI_Init() if USE_HAL_SAI_CLK_ENABLE_MODEL > HAL_CLK_ENABLE_NO.

  2. Configure the low level hardware (GPIO, CLOCK, NVIC, DMA…):

    • Enable the SAIx clock if USE_HAL_SAI_CLK_ENABLE_MODEL = HAL_CLK_ENABLE_NO.

    • SAIx pins configuration:

      • Enable the clock for the SAIx GPIOs

      • Configure SAIx pins as alternate function pull-up

    • NVIC configuration if you need to use interrupt process

      • Configure the SAIx interrupt priority.

      • Enable the NVIC SAIx IRQ handle.

    • DMA configuration if you need to use DMA process

      • Declare a DMA handle structure for the Tx/Rx stream.

      • Enable the DMAx interface clock.

      • Configure the declared DMA handle structure with the required Tx/Rx parameters.

      • Configure the DMA Tx/Rx Stream.

      • Associate the initialized DMA handle to the SAI DMA Tx/Rx handle.

      • Configure the priority and enable the NVIC for the transfer complete interrupt on the DMA Tx/Rx Stream.

    • SAI kernel clock has to be activated and selected.

  3. Configure the minimal configuration needed for the SAI driver by calling HAL_SAI_SetConfig() .

  4. Configure and/or enable advanced features. For instance, HAL_SAI_SetCompanding() or HAL_SAI_EnableOutputDrive() . All these advanced configurations are optional (not mandatory).

    • In master Tx mode: enabling the audio block immediately generates the bit clock for the external slaves even if there is no data in the FIFO. However, FS signal generation is conditioned by the presence of data in the FIFO.

    • In master Rx mode: enabling the audio block immediately generates the bit clock and FS signal for the external slaves.

    • It is mandatory to respect the following conditions in order to avoid bad SAI behavior:

      • First bit Offset <= (Slot size - Data size)

      • Data size <= Slot size

      • Number of Slots x Slot size = Frame length

      • The number of slots must be even when HAL_SAI_FS_CHANNEL_IDENTIFICATION is selected.

    • PDM interface can be activated through HAL_SAI_EnablePdm() function. Please note that PDM interface is only available for SAI1 block A. PDM microphone delays can be tuned with HAL_SAI_SetPdmMicDelay() function.

  5. Operation modes

  6. Callbacks definition in Interrupt or DMA mode:

    When the compilation define USE_HAL_SAI_REGISTER_CALLBACKS is set to 1, the user can configure dynamically the driver callbacks, via its own method:

Callback name

Default value

Callback registration function

TxHalfCpltCallback

HAL_SAI_TxHalfCpltCallback()

HAL_SAI_RegisterTxHalfCpltCallback()

TxCpltCallback

HAL_SAI_TxCpltCallback()

HAL_SAI_RegisterTxCpltCallback()

RxHalfCpltCallback

HAL_SAI_RxHalfCpltCallback()

HAL_SAI_RegisterRxHalfCpltCallback()

RxCpltCallback

HAL_SAI_RxCpltCallback()

HAL_SAI_RegisterRxCpltCallback()

MuteCallback

HAL_SAI_MuteCallback()

HAL_SAI_RegisterMuteCallback()

ErrorCallback

HAL_SAI_ErrorCallback()

HAL_SAI_RegisterErrorCallback()

AbortCpltCallback

HAL_SAI_AbortCpltCallback()

HAL_SAI_RegisterAbortCpltCallback()

If one needs to unregister a callback, register the default callback via the registration function.

By default, after the HAL_SAI_Init() and when the state is HAL_SAI_STATE_INIT , all callbacks are set to the corresponding default weak functions.

Callbacks can be registered in handle global_state HAL_SAI_STATE_INIT and HAL_SAI_STATE_IDLE .

When the compilation define USE_HAL_SAI_REGISTER_CALLBACKS is set to 0 or not defined, the callback registration feature is not available and weak callbacks are used, represented by the default value in the table above.

Acquire/Release the SAI bus

When the compilation flag USE_HAL_MUTEX is set to 1, it allows the user to acquire/reserve the whole SAI bus for executing process. The HAL Acquire/Release are based on the HAL OS abstraction layer (stm32_hal_os.c/.h osal): HAL_SAI_AcquireBus() for acquire the bus or wait for it. HAL_SAI_ReleaseBus() for releasing the bus. When the compilation flag USE_HAL_MUTEX is set to 0 or not defined, HAL_SAI_AcquireBus() /HAL_SAI_ReleaseBus() are not available.