HAL I3C How to Use

group I3C_How_To_Use

How to use the I3C HAL

Use the I3C HAL driver as follows:

1. Declare

2. Initialize

  • Initialize the I3Cx driver with an I3C HW instance by calling HAL_I3C_Init().

  • The I3Cx clock is enabled inside HAL_I3C_Init() if USE_HAL_I3C_CLK_ENABLE_MODEL > HAL_CLK_ENABLE_NO.

3. Configure low-level hardware

  • Enable the I3Cx clock if USE_HAL_I3C_CLK_ENABLE_MODEL = HAL_CLK_ENABLE_NO.

  • I3Cx pin configuration:

    • Enable the clock for the I3Cx GPIOs.

    • Configure I3C pins as alternate function push-pull with no-pull.

  • NVIC configuration for interrupt processing:

    • Configure the I3Cx interrupt priority.

    • Enable the NVIC I3C IRQ Channel.

  • DMA configuration for DMA processing:

    • Declare a hal_dma_handle_t handle structure for the Control Register (CR) management channel.

    • Declare a hal_dma_handle_t handle structure for the transmit channel.

    • Declare a hal_dma_handle_t handle structure for the receive channel.

    • Enable the DMAx interface clock.

    • Configure the DMA handle parameters.

    • Configure the DMA Control Register (CR) channel.

    • Configure the DMA Tx channel.

    • Configure the DMA Rx channel.

    • Associate the initialized DMA handle with the hi3c DMA CR, Tx, or Rx as necessary.

    • Configure the priority and enable the NVIC for the transfer complete interrupt on the DMA CR, Tx or Rx instance.

4. Configure communication mode

5. Configure FIFOs (optional)

6. Target advanced features

6.1 ENTDAA payload configuration

Before initiating any ENTDAA, the target must configure the target payload of the ENTDAA by using HAL_I3C_TGT_SetPayloadENTDAAConfig().

6.2 Target Hot-Join (interrupt mode)

Request a Hot-Join in target mode: HAL_I3C_TGT_HotJoinReq_IT(). At completion, HAL_I3C_TGT_HotJoinCallback() is executed, and user code can add custom handling by overriding this weak callback function or by registering a callback function.

6.3 Target In-Band Interrupt (interrupt mode)

Request an In-Band Interrupt in target mode: HAL_I3C_TGT_IBIReq_IT() At completion, HAL_I3C_NotifyCallback() is executed, and user code can add custom handling by overriding this weak callback function or by registering a callback function.

6.4 Target Controller-Role request (interrupt mode)

Request a Controller Role in target mode: HAL_I3C_TGT_ControlRoleReq_IT() At completion, HAL_I3C_NotifyCallback() is executed, and user code can add custom handling by overriding this weak callback function or by registering a callback function.

6.5 Target Wakeup capability

To manage the wakeup capability, use HAL_I3C_TGT_ActivateNotification() or HAL_I3C_TGT_DeactivateNotification() to enable or disable the wakeup interrupt. At wakeup detection, the associated HAL_I3C_NotifyCallback() is executed.

7. Controller advanced features

7.1 Dynamic Address Assignment procedure

  • Before initiating any IO operation, launch an assignment of the different target dynamic addresses by using HAL_I3C_CTRL_DynAddrAssign() in polling mode or HAL_I3C_CTRL_DynAddrAssign_IT() in interrupt mode. This procedure is named Enter Dynamic Address Assignment (ENTDAA CCC command).

  • For the initiation of ENTDAA procedure, each target connected and powered on the I3C bus must respond to this particular Command Common Code (CCC) by sending its proper Payload (an amount of 48-bits which contain the target characteristics). Each time a target responds to ENTDAA sequence, the controller application is informed through HAL_I3C_CTRL_TgtReqDynAddrCallback() of the reception of the target payload.

  • Then send an associated dynamic address through HAL_I3C_CTRL_SetDynAddr(). This procedure loops automatically in hardware side until a target responds to repeated ENTDAA sequence.

  • The controller application is informed of the end of the procedure at reception of HAL_I3C_CTRL_DAACpltCallback().

  • Then retrieve ENTDAA payload information through HAL_I3C_CTRL_Get_ENTDAA_Payload_Info().

  • At the end of the procedure, the function HAL_I3C_CTRL_SetConfigBusDevices() must be called to store the target capabilities in the hardware register, including dynamic address, IBI support with or without additional data byte, Controller-Role request support, or controller automatic stop transfer after IBI.

7.3 Device ready checks

7.4 Bus arbitration generation

7.5 Reset pattern insertion

The controller app must enable the reset pattern configuration using HAL_I3C_CTRL_EnableResetPattern() before calling HAL_I3C_CTRL_Transfer(). To have a standard STOP emitted at the end of a frame containing a RSTACT CCC command, the application must disable the reset pattern configuration using HAL_I3C_CTRL_DisableResetPattern() before calling HAL_I3C_CTRL_Transfer(). Use HAL_I3C_CTRL_IsEnabledResetPattern() to check Reset pattern configuration.

7.6 Pattern generation

8. Controller IO operations

8.1 Prepare transfer context

Before initiating any IO operation, prepare the frame descriptors in the transfer context with their associated buffer allocation. It is purely software; no I3C handle is needed. Respect the following steps:

8.2 Controller polling IO operation (blocking)

  • Start a controller-mode transfer of a Common Command Code in a direct or direct receive CCC with defbyte or private data in an I2C or I3C communication: HAL_I3C_CTRL_Transfer().

8.3 Controller DMA and interrupt mode IO operation

9. Target IO operations

9.1 Target polling IO operation (blocking)

9.2 Target DMA and Interrupt mode IO operation

10. Notifications and asynchronous events

To get asynchronous events, use HAL_I3C_CTRL_ActivateNotification() or HAL_I3C_TGT_ActivateNotification(). Each time one or more events are detected by hardware, HAL_I3C_NotifyCallback() is executed, and user code can add custom handling by overriding this weak callback function or by registering a callback function. Then retrieve specific associated event data through HAL_I3C_GetCCCInfo().

11. Error management

In case of transfer error, HAL_I3C_ErrorCallback() is executed, and user code can add custom handling by overriding this weak callback function or by registering a callback function.

12. Abort operation

Abort an I3C communication process with interrupt using HAL_I3C_Abort_IT(). At the end of the abort process, HAL_I3C_AbortCpltCallback() is executed, and user code can add custom handling by overriding this weak callback function or by registering a callback function.

13. Callback registration

The compilation flag USE_HAL_I3C_REGISTER_CALLBACKS allows dynamic configuration of the driver callbacks via dedicated registration APIs, instead of relying on weak default functions.

Notes:

  • To unregister and restore the default weak callback, re-register the corresponding default function.

  • By default, after HAL_I3C_Init() and when the state is HAL_I3C_STATE_INIT, all callbacks are set to their default weak implementations.

  • Register callbacks when handle global_state is HAL_I3C_STATE_INIT or HAL_I3C_STATE_IDLE.

  • When USE_HAL_I3C_REGISTER_CALLBACKS is set to 0 or not defined, the callback registration feature is not available and weak callbacks are used.

14. Acquire/Release the I3C bus

  • When the compilation flag USE_HAL_MUTEX is set to 1, it allows the user to acquire/reserve the whole I3C bus for executing a process. The HAL Acquire/Release are based on the HAL OS abstraction layer (stm32_hal_os.c/.h osal):

  • When the compilation flag USE_HAL_MUTEX is set to 0 or not defined, HAL_I3C_AcquireBus() and HAL_I3C_ReleaseBus() are not available.