HAL I2C How to Use

group I2C_How_To_Use

How to use the I2C HAL module driver

  1. Declare a hal_i2c_handle_t handle structure and initialize the I2Cx driver with an I2C HW instance by calling the HAL_I2C_Init() . The I2Cx clock is enabled inside the HAL_I2C_Init() if USE_HAL_I2C_CLK_ENABLE_MODEL > HAL_CLK_ENABLE_NO.

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

    • Enable the I2Cx clock if USE_HAL_I2C_CLK_ENABLE_MODEL = HAL_CLK_ENABLE_NO

    • I2Cx pins configuration :

      • Enable the clock for the I2Cx GPIOs

        • Configure I2Cx pins as alternate function open-drain

      • NVIC configuration if you need to use interrupt process

        • Configure the I2Cx interrupt priority

        • Enable the NVIC I2Cx IRQ Channel

      • DMA configuration if you need to use DMA process

        • Declare a hal_dma_handle_t handle structure for the Transmit or Receive channel

        • Enable the DMAx clock

        • Configure the DMA transfer parameters for each direction, Transmit or Receive

        • Associate the initialized DMA handle to the hi2c DMA Tx or Rx handle respectively using HAL_I2C_SetTxDMA or HAL_I2C_SetRxDMA

        • For each DMA channel (Tx and Rx), configure the corresponding NVIC line priority and enable it

  3. Configure the communication Clock Timing, Own Address1, Master Addressing mode by calling HAL_I2C_SetConfig.

  4. Configure and/or enable advanced features. For instances, HAL_I2C_EnableAnalogFilter, HAL_I2C_SetDigitalFilter, HAL_I2C_SetConfigOwnAddress2, HAL_I2C_EnableOwnAddress2, etc. All these advanced configurations are optional (not mandatory).

  5. For I2Cx IO and IO MEM operations, three operation modes, polling, interrupt and dma are available within this driver.

    • Polling mode IO operation

    • Polling mode IO MEM operation

    • Interrupt mode IO operation

    • Interrupt mode or DMA mode IO sequential operation These interfaces allow to manage a sequential transfer with a repeated start condition when a direction change during transfer. A specific option field manage the different steps of a sequential transfer through hal_i2c_xfer_opt_t and are listed below

      • HAL_I2C_XFER_FIRST_AND_LAST_FRAME: No sequential, functional is same as associated interfaces in no sequential mode.

      • HAL_I2C_XFER_FIRST_FRAME: Sequential, this option allows to manage a sequence with start condition, address and data to transfer without a final stop condition.

      • HAL_I2C_XFER_FIRST_AND_NEXT_FRAME: Sequential (master only), this option allows to manage a sequence with start condition, address and data to transfer without a final stop condition, an then permit a call the same master sequential interface several times (like HAL_I2C_MASTER_SEQ_Transmit_IT() then HAL_I2C_MASTER_SEQ_Transmit_IT() or HAL_I2C_MASTER_SEQ_Transmit_DMA() then HAL_I2C_MASTER_SEQ_Transmit_DMA() )

      • HAL_I2C_XFER_NEXT_FRAME: Sequential, this option allows to manage a sequence with a restart condition, address and with new data to transfer if the direction change or manage only the new data to transfer if no direction change and without a final stop condition in both cases.

      • HAL_I2C_XFER_LAST_FRAME: Sequential, this option allows to manage a sequence with a restart condition, address and with new data to transfer if the direction change or manage only the new data to transfer if no direction change and with a final stop condition in both cases.

      • HAL_I2C_XFER_LAST_FRAME_NO_STOP: Sequential (master only), this option allows to manage a restart condition after several call of the same master sequential interface several times (link with option HAL_I2C_XFER_FIRST_AND_NEXT_FRAME). User can transfer several bytes one by one using :

        • HAL_I2C_MASTER_SEQ_Transmit_IT

        • HAL_I2C_MASTER_SEQ_Receive_IT

        • HAL_I2C_MASTER_SEQ_Transmit_DMA

        • HAL_I2C_MASTER_SEQ_Receive_DMA with option HAL_I2C_XFER_FIRST_AND_NEXT_FRAME then HAL_I2C_XFER_NEXT_FRAME. Then usage of this option HAL_I2C_XFER_LAST_FRAME_NO_STOP at the last Transmit or Receive sequence permit to call the opposite interface Receive or Transmit without stopping the communication and so generate a restart condition.

      • HAL_I2C_XFER_OTHER_FRAME: Sequential (master only), this option allows to manage a restart condition after each call of the same master sequential interface. User can transfer several bytes one by one with a restart with slave address between each byte using

        • HAL_I2C_MASTER_SEQ_Transmit_IT

        • HAL_I2C_MASTER_SEQ_Receive_IT

        • HAL_I2C_MASTER_SEQ_Transmit_DMA

        • HAL_I2C_MASTER_SEQ_Receive_DMA with option HAL_I2C_XFER_FIRST_FRAME then HAL_I2C_XFER_OTHER_FRAME. Then usage of this option HAL_I2C_XFER_OTHER_AND_LAST_FRAME at the last frame to help automatic generation of STOP condition.

    • Different sequential I2C interfaces are listed below:

    • Interrupt mode IO MEM operation

      • Write an amount of data in non-blocking mode with interrupt to a specific memory address using HAL_I2C_MASTER_MemWrite_IT()

      • At Memory end of write transfer, HAL_I2C_MASTER_MemTxCpltCallback() is executed and user can add his own code by overriding this weak callback function or by registering a callback function.

      • Read an amount of data in non-blocking mode with interrupt from a specific memory address using HAL_I2C_MASTER_MemRead_IT()

      • At Memory end of read transfer, HAL_I2C_MASTER_MemRxCpltCallback() is executed and user can add his own code by overriding this weak callback function or by registering a callback function.

      • In case of transfer error, HAL_I2C_ErrorCallback() function is executed and user can add his own code by overriding this weak callback function or by registering a callback function.

    • DMA mode IO operation

    • DMA mode IO MEM operation

      • Write an amount of data in non-blocking mode with DMA to a specific memory address using HAL_I2C_MASTER_MemWrite_DMA()

      • At Memory end of write transfer, HAL_I2C_MASTER_MemTxCpltCallback() is executed and user can add his own code by overriding this weak callback function or by registering a callback function.

      • Read an amount of data in non-blocking mode with DMA from a specific memory address using HAL_I2C_MASTER_MemRead_DMA()

      • At Memory end of read transfer, HAL_I2C_MASTER_MemRxCpltCallback() is executed and user can add his own code by overriding this weak callback function or by registering a callback function.

      • In case of transfer error, HAL_I2C_ErrorCallback() function is executed and user can add his own code by overriding this weak callback function or by registering a callback function.

  6. Callback registration

    • When the compilation flag USE_HAL_I2C_REGISTER_CALLBACKS is set to 1, it allows the user to configure dynamically the driver callbacks instead of weak functions. Functions allows to register callbacks:

    • When the compilation flag USE_HAL_I2C_REGISTER_CALLBACKS is set to 0 or not defined, the callback registration feature is not available and all callbacks are set to the corresponding weak functions.

  7. Acquire/Release the i2c bus

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

      • HAL_I2C_AcquireBus for acquire the bus or wait for it.

      • HAL_I2C_ReleaseBus for releasing the bus.

    • When the compilation flag USE_HAL_MUTEX is set to 0 or not defined, HAL_I2C_AcquireBus/HAL_I2C_ReleaseBus are not available.