I2C implementation based on freeRTOS OS
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2021-10-26 11:02 AM
Hello,
I'm using STM32WB55 in conjunction with freeRTOS OS
I found a very good I2C BARE-METAL working example located at:
..\STM32Cube\Repository\STM32Cube_FW_WB_V1.12.1\Projects\P-NUCLEO-WB55.Nucleo\Examples\I2C\I2C_TwoBoards_AdvComIT
I'm looking for a similar I2C Example, however based on and using
freeRTOS implementation
Thanks In Advance,
Micha
Solved! Go to Solution.
- Labels:
-
FreeRTOS
-
I2C
-
STM32WB series
Accepted Solutions
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2021-10-27 9:44 PM
Hi KnafB,
Thanks you very much for your GREAT advise :smiling_face_with_smiling_eyes: !!!
The original I2C example is based on HAL functions: HAL_I2C_Master_Transmit_IT() and HAL_I2C_Master_Receive_IT
I added freeRTOS with CMSIS_V2 (from CubeMX) + one I2C task, copy the I2C functionality from Main loop to the I2C task, DONE - ALL work like a charm !!!
Many Thanks
Best Regards,
Micha
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2021-10-27 7:20 AM
The FreeRTOS middleware is just the RTOS kernel, i.e. scheduler + synchronisation objects, no peripherals API. So you just use HAL as in the above example from a FreeRTOS task. HAL is not aware of RTOS, so the timing might be different (when the task is not running).
hth
KnarfB
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2021-10-27 12:03 PM
Hi KnarfB,
Thanks for your reply
Will create an I2C Task then try to perform HAL_I2C_*** procedure
Best Regards,
Micha
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2021-10-27 12:15 PM
Right. Keep in mind that the blocking HAL functions like HAL_I2C_Master_Transmit (with timeout) are not RTOS friendly because they don't "tell" the RTOS that they are busy waiting (=MCU using) for a condition. If you need more efficiency, you might want to use the non-blocking _IT or _DMA HAL functions and implement the interrupt&completion callbacks such that they e.g. return data in a FreeRTOS queue. This efficiency comes with more code complexity, so do it only when really needed.
hth
KnarfB
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2021-10-27 9:44 PM
Hi KnafB,
Thanks you very much for your GREAT advise :smiling_face_with_smiling_eyes: !!!
The original I2C example is based on HAL functions: HAL_I2C_Master_Transmit_IT() and HAL_I2C_Master_Receive_IT
I added freeRTOS with CMSIS_V2 (from CubeMX) + one I2C task, copy the I2C functionality from Main loop to the I2C task, DONE - ALL work like a charm !!!
Many Thanks
Best Regards,
Micha
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2022-09-30 3:33 AM
But still it's not clear what you did. If possible please post that part you edited.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2022-10-01 8:54 PM
In general I, on I2C Master side which is based on freeRTOS and also based on ST example named: I2C_TwoBoards_AdvComIT, I created two I2C functions (I2C_master_write_to_slave() and I2C_master_read_from_slave()) then able to call them whenever I2C communication is needed for either Send or Receive within any freeRTOS task
If you are using CubeMX to auto generate tour code please double check that on both Master and Slave sides, this line is defined correctly: :�? #define I2C_ADDRESS 0x1F�? (seems like CubeMX bug)
Besides it is advised to use Logic Analyzer with I2C protocol capabilities (I’m using the excellent Saleae Logic Analyzer)
Kind Regards,
Micha
void I2C_master_write_to_slave()
{
hTxNumData = TXBUFFERSIZE;
hRxNumData = 2; /*RXBUFFERSIZE;*/
/* Update bTransferRequest to send buffer write request for Slave */
bTransferRequest = MASTER_REQ_WRITE;
/*##-2- Master sends write request for slave #############################*/
do
{
if(HAL_I2C_Master_Transmit_IT(&hi2c3, (uint16_t)(I2C_ADDRESS), (uint8_t*)&bTransferRequest, 1)!= HAL_OK)
{
Error_Handler();
}
while (HAL_I2C_GetState(&hi2c3) != HAL_I2C_STATE_READY)
{
}
}
while(HAL_I2C_GetError(&hi2c3) == HAL_I2C_ERROR_AF);
/*##-3- Master sends number of data to be written ########################*/
do
{
if(HAL_I2C_Master_Transmit_IT(&hi2c3, (uint16_t)(I2C_ADDRESS),(uint8_t*)&hTxNumData, 2)!= HAL_OK)
{
Error_Handler();
}
while (HAL_I2C_GetState(&hi2c3) != HAL_I2C_STATE_READY)
{
}
/* When Acknowledge failure occurs (Slave don't acknowledge it's address)
Master restarts communication */
}
while(HAL_I2C_GetError(&hi2c3) == HAL_I2C_ERROR_AF);
//****************************************************************************
memcpy((uint8_t *)aTxBuffer, (uint8_t *)&LEDs_arr[0].green, sizeof(LEDs_arr)); // copy pre-definind LEDs_arr to aTxBuffer[]
//****************************************************************************
/*##-4- Master sends aTxBuffer to slave ##################################*/
do
{
if(HAL_I2C_Master_Transmit_IT(&hi2c3, (uint16_t)(I2C_ADDRESS), (uint8_t*)aTxBuffer, TXBUFFERSIZE)!= HAL_OK)
{
Error_Handler();
}
while (HAL_I2C_GetState(&hi2c3) != HAL_I2C_STATE_READY)
{
}
}
while(HAL_I2C_GetError(&hi2c3) == HAL_I2C_ERROR_AF);
osDelay(3);
}
void I2C_master_read_from_slave()
{
/* Update bTransferRequest to send buffer read request for Slave */
// After received INT from slave on EXTI12 (PC12) (as TouchPad detection) then read and send Touch-Pad data from Slave to I2C Master
bTransferRequest = MASTER_REQ_READ;
/*##-5- Master sends read request for slave ##############################*/
do
{
if(HAL_I2C_Master_Transmit_IT(&hi2c3, (uint16_t)(I2C_ADDRESS), (uint8_t*)&bTransferRequest, 1)!= HAL_OK)
{
Error_Handler();
}
while (HAL_I2C_GetState(&hi2c3) != HAL_I2C_STATE_READY)
{
}
}
while(HAL_I2C_GetError(&hi2c3) == HAL_I2C_ERROR_AF);
/*##-6- Master sends number of data to be read ###########################*/
do
{
if(HAL_I2C_Master_Transmit_IT(&hi2c3, (uint16_t)(I2C_ADDRESS), (uint8_t*)&hRxNumData, 2)!= HAL_OK)
{
Error_Handler();
}
while (HAL_I2C_GetState(&hi2c3) != HAL_I2C_STATE_READY)
{
}
}
while(HAL_I2C_GetError(&hi2c3) == HAL_I2C_ERROR_AF);
/*##-7- Master receives aRxBuffer from slave #############################*/
do
{
if(HAL_I2C_Master_Receive_IT(&hi2c3, (uint16_t)(I2C_ADDRESS),(uint8_t*)aRxBuffer, 2/*RXBUFFERSIZE*/)!= HAL_OK)
{
Error_Handler();
}
while (HAL_I2C_GetState(&hi2c3) != HAL_I2C_STATE_READY)
{
}
}
while(HAL_I2C_GetError(&hi2c3) == HAL_I2C_ERROR_AF);
osDelay(3);
// check which TouchPad Key was received from Touch&LEDs pcb via I2C protocol ?
if ((aRxBuffer[0] == 0xA5) /*&& (aRxBuffer[1] == 0x5A)*/ )
{
set_bars_color(…..);
}
}
