HAL I2C How to Use ¶
- group I2C_How_To_Use
-
How to use the I2C HAL module driver ¶
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.
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
Configure the communication Clock Timing, Own Address1, Master Addressing mode by calling HAL_I2C_SetConfig().
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).
For I2Cx IO and IO MEM operations, three operation modes, polling, interrupt and dma are available within this driver.
Polling mode IO operation
Transmit in master mode an amount of data in blocking mode using HAL_I2C_MASTER_Transmit()
Receive in master mode an amount of data in blocking mode using HAL_I2C_MASTER_Receive()
Transmit in slave mode an amount of data in blocking mode using HAL_I2C_SLAVE_Transmit()
Receive in slave mode an amount of data in blocking mode using HAL_I2C_SLAVE_Receive()
Polling mode IO MEM operation
Write an amount of data in blocking mode to a specific memory address using HAL_I2C_MASTER_MemWrite()
Read an amount of data in blocking mode from a specific memory address using HAL_I2C_MASTER_MemRead()
Interrupt mode IO operation
Transmit in master mode an amount of data in non-blocking mode using HAL_I2C_MASTER_Transmit_IT()
At transmission end of transfer, HAL_I2C_MASTER_TxCpltCallback() is executed and user can add his own code by overriding this weak callback function or by registering a callback function.
Receive in master mode an amount of data in non-blocking mode using HAL_I2C_MASTER_Receive_IT()
At reception end of transfer, HAL_I2C_MASTER_RxCpltCallback() is executed and user can add his own code by overriding this weak callback function or by registering a callback function.
Transmit in slave mode an amount of data in non-blocking mode using HAL_I2C_SLAVE_Transmit_IT()
At transmission end of transfer, HAL_I2C_SLAVE_TxCpltCallback() is executed and user can add his own code by overriding this weak callback function or by registering a callback function.
Receive in slave mode an amount of data in non-blocking mode using HAL_I2C_SLAVE_Receive_IT()
At reception end of transfer, HAL_I2C_SLAVE_RxCpltCallback() 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.
Abort a master or memory I2C process communication with interrupt using HAL_I2C_MASTER_Abort_IT()
End of abort process, HAL_I2C_AbortCpltCallback() is executed and user can add his own code by overriding this weak callback function or by registering a callback function.
Discard a slave I2C process communication using HAL_I2C_SLAVE_Abort_IT(). This action informs master to generate a Stop condition to discard the communication.
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_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_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:
Sequential transmit in master mode an amount of data in non-blocking mode using HAL_I2C_MASTER_SEQ_Transmit_IT() or using HAL_I2C_MASTER_SEQ_Transmit_DMA().
At transmission end of current frame transfer, HAL_I2C_MASTER_TxCpltCallback() is executed and user can add his own code by overriding this weak callback function or by registering a callback function.
Sequential receive in master I2C mode an amount of data in non-blocking mode using HAL_I2C_MASTER_SEQ_Receive_IT() or using HAL_I2C_MASTER_SEQ_Receive_DMA()
At reception end of current frame transfer, HAL_I2C_MASTER_RxCpltCallback() is executed and user can add his own code by overriding this weak callback function or by registering a callback function.
Abort a master or memory IT or DMA I2C process communication with interrupt using HAL_I2C_MASTER_Abort_IT()
End of abort process, HAL_I2C_AbortCpltCallback() is executed and user can add his own code by overriding this weak callback function or by registering a callback function.
Enable/disable the Address listen mode in slave I2C mode with HAL_I2C_SLAVE_EnableListen_IT() and HAL_I2C_SLAVE_DisableListen_IT()
When address slave I2C match, HAL_I2C_SLAVE_AddrCallback() is executed and users can add their own code to check the address Match Code and the transmission direction request by master(Write/Read).
At Listen mode end HAL_I2C_SLAVE_ListenCpltCallback() is executed and user can add his own code by overriding this weak callback function or by registering a callback function.
Sequential transmit in slave I2C mode an amount of data in non-blocking mode using HAL_I2C_SLAVE_SEQ_Transmit_IT() or using HAL_I2C_SLAVE_SEQ_Transmit_DMA()
At transmission end of current frame transfer, HAL_I2C_SLAVE_TxCpltCallback() is executed and user can add his own code by overriding this weak callback function or by registering a callback function.
Sequential receive in slave I2C mode an amount of data in non-blocking mode using HAL_I2C_SLAVE_SEQ_Receive_IT() or using HAL_I2C_SLAVE_SEQ_Receive_DMA()
At reception end of current frame transfer, HAL_I2C_SLAVE_RxCpltCallback() 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.
Discard a slave I2C process communication using HAL_I2C_SLAVE_Abort_IT() macro. This action informs master to generate a Stop condition to discard the communication.
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
Transmit in master mode an amount of data in non-blocking mode (DMA) using HAL_I2C_MASTER_Transmit_DMA()
At transmission end of transfer, HAL_I2C_MASTER_TxCpltCallback() is executed and user can add his own code by overriding this weak callback function or by registering a callback function.
Receive in master mode an amount of data in non-blocking mode (DMA) using HAL_I2C_MASTER_Receive_DMA()
At reception end of transfer, HAL_I2C_MASTER_RxCpltCallback() is executed and user can add his own code by overriding this weak callback function or by registering a callback function.
Transmit in slave mode an amount of data in non-blocking mode (DMA) using HAL_I2C_SLAVE_Transmit_DMA()
At transmission end of transfer, HAL_I2C_SLAVE_TxCpltCallback() is executed and user can add his own code by overriding this weak callback function or by registering a callback function.
Receive in slave mode an amount of data in non-blocking mode (DMA) using HAL_I2C_SLAVE_Receive_DMA()
At reception end of transfer, HAL_I2C_SLAVE_RxCpltCallback() 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.
Abort a master or memory I2C process communication with interrupt using HAL_I2C_MASTER_Abort_IT()
End of abort process, HAL_I2C_AbortCpltCallback() is executed and user can add his own code by overriding this weak callback function or by registering a callback function.
Discard a slave I2C process communication using HAL_I2C_SLAVE_Abort_IT() macro. This action informs master to generate a Stop condition to discard the communication.
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.
Callback registration definition in Interrupt
When the compilation define USE_HAL_I2C_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
MASTER_TxCpltCallback
MASTER_RxCpltCallback
SLAVE_TxCpltCallback
SLAVE_RxCpltCallback
MASTER_MemTxCpltCallback
MASTER_MemRxCpltCallback
ListenCpltCallback
AddrMatchCallback
AbortCpltCallback
ErrorCallback
If one needs to unregister a callback, register the default callback via the registration function.
By default, after the HAL_I2C_Init() and when the state is HAL_I2C_STATE_INIT, all callbacks are set to the corresponding default weak functions.
Callbacks can be registered in handle global_state HAL_I2C_STATE_INIT and HAL_I2C_STATE_IDLE.
When the compilation define USE_HAL_I2C_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 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() and HAL_I2C_ReleaseBus() are not available.