cancel
Showing results for 
Search instead for 
Did you mean: 

FreeRTOS on STM32G0B1: Unable to use as I2C Slave

minhaj97haider
Associate

Hello, good afternoon.

I have two Nucleo boards STM32G071RB that I have written an I2C interface for. It is basically a command interface, where Master sends a command, and polls the slave later to get the response. I have tested my application thoroughly, it is working great between these two Dev Boards.

Now for the actual work, I am replacing the slave with an internally developed board based on STM32G0B1, running FreeRTOS (I am fairly new to RTOS). Between the RTOS G0B1 Slave and the G071 Master, I see the Master send the slave address; The slave reads its address and holds the clock line low permanently; It does not trigger AddressCpltCallback, allowing me to receive the data. Sometimes the Oscilloscope would show 16-20 bits on the SDA/SCL lines instead of the usual 8-9 (not sure what setting i messed with to get that), but end result remains the same, after these bits, Slave will hold the SCL low indefinitely. Any ideas where I went wrong could help, thanks.

 

MASTER BOARD:

 

 

static void MX_I2C1_Init(void) { p_i2c->p_i2cHandle.Instance = I2C1; p_i2c->p_i2cHandle.Init.Timing = 0x00100413; p_i2c->p_i2cHandle.Init.OwnAddress1 = I2C_ADDRESS; p_i2c->p_i2cHandle.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT; p_i2c->p_i2cHandle.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE; p_i2c->p_i2cHandle.Init.OwnAddress2 = 0; p_i2c->p_i2cHandle.Init.OwnAddress2Masks = I2C_OA2_NOMASK; p_i2c->p_i2cHandle.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE; p_i2c->p_i2cHandle.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE; if (HAL_I2C_Init(&p_i2c->p_i2cHandle) != HAL_OK) Error_Handler(); if (HAL_I2CEx_ConfigAnalogFilter(&p_i2c->p_i2cHandle, I2C_ANALOGFILTER_ENABLE) != HAL_OK) Error_Handler(); if (HAL_I2CEx_ConfigDigitalFilter(&p_i2c->p_i2cHandle, 0) != HAL_OK) Error_Handler(); HAL_I2CEx_EnableFastModePlus(I2C_FASTMODEPLUS_I2C1); } int main(void) { HAL_Init(); SystemClock_Config(); MX_GPIO_Init(); BSP_LED_Init(LED4); BSP_PB_Init(BUTTON_USER,BUTTON_MODE_GPIO); StmI2cControl_Init(4000, i2c_MasterRxProcess); //Sets User variables to zero, calls MX_I2C1_Init() while (1) { while (BSP_PB_GetState(BUTTON_USER) != GPIO_PIN_RESET) { BSP_LED_On(LED4); HAL_Delay( (100*ubMasterDutyCycle)/(ubMasterFrequency) ); BSP_LED_Off(LED4); HAL_Delay( (100*(10-ubMasterDutyCycle))/(ubMasterFrequency) ); } while (BSP_PB_GetState(BUTTON_USER) != GPIO_PIN_SET); p_i2cItf->pf_sendCommand(0U, command, &msg_data, 1U);//Parses data and calls TransmitSeq HAL_Delay(1000); p_i2cItf->pf_pollSlave(); } } HAL_StatusTypeDef StmI2cControl_TransmitSeq(void) { assert(NULL != p_i2c); HAL_StatusTypeDef RetVal = HAL_OK; p_i2c->size_Tx = 1; RetVal = HAL_I2C_Master_Seq_Transmit_IT(&p_i2c->p_i2cHandle, I2C_ADDRESS, p_i2c->aTxMsg, 6U, I2C_LAST_FRAME); return RetVal; } void HAL_I2C_MasterTxCpltCallback(I2C_HandleTypeDef *I2cHandle) { i2cBuffer_AddRecord(p_i2c->aTxMsg); }
View more

 

 

SLAVE BOARD (FreeRTOS):

 

void MX_I2C1_Init(void) { hi2c1.Instance = I2C1; hi2c1.Init.Timing = 0x00100413; hi2c1.Init.OwnAddress1 = 0x20; hi2c1.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT; hi2c1.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE; hi2c1.Init.OwnAddress2 = 0; hi2c1.Init.OwnAddress2Masks = I2C_OA2_NOMASK; hi2c1.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE; hi2c1.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE; if (HAL_I2C_Init(&hi2c1) != HAL_OK) Error_Handler(); if (HAL_I2CEx_ConfigAnalogFilter(&hi2c1, I2C_ANALOGFILTER_ENABLE) != HAL_OK) Error_Handler(); if (HAL_I2CEx_ConfigDigitalFilter(&hi2c1, 0) != HAL_OK) Error_Handler(); HAL_I2CEx_EnableFastModePlus(I2C_FASTMODEPLUS_I2C1); } void StmI2CControl_InitI2CSlave(void) { p_slave_stm_i2c = &stmI2C; p_slave_stm_i2c->i2c_interface.p_i2c_obj = &stmI2C; p_slave_stm_i2c->p_i2c_handle = &hi2c1; /* Create the queues and assign handles */ p_slave_stm_i2c->rx_queue_handle = osMessageQueueNew(I2C_QUEUE_LENGTH, sizeof(i2c_msg_t), &rx_queueAttributes); p_slave_stm_i2c->tx_queue_handle = osMessageQueueNew(I2C_QUEUE_LENGTH, sizeof(i2c_msg_t), &tx_queueAttributes); p_slave_stm_i2c->cmd_queue_handle = osMessageQueueNew(I2C_QUEUE_LENGTH, sizeof(i2c_msg_t), &cmd_queueAttributes); p_slave_stm_i2c->i2c_interface.pf_slave_transmit_it = (I2CInterface_Slave_Transmit_IT_t)StmI2CInterface_SlaveTransmit; p_slave_stm_i2c->i2c_interface.pf_slave_receive_it = (I2CInterface_Slave_Receive_IT_t)StmI2CInterface_SlaveReceive; i2c_cmd_taskHandle = osThreadNew(StmI2CControl_handleReceiveCmd, NULL, &i2c_cmd_task_attributes); //Enable Slave Listen, for when Master sends Slave address on I2C Bus if(HAL_I2C_EnableListen_IT(p_slave_stm_i2c->p_i2c_handle) != HAL_OK) Error_Handler(); HAL_NVIC_SetPriority(I2C1_IRQn, 3, 0); HAL_NVIC_EnableIRQ(I2C1_IRQn); } HAL_StatusTypeDef StmI2CInterface_SlaveReceive(void) { assert(p_slave_stm_i2c != NULL); HAL_StatusTypeDef RetVal = HAL_I2C_Slave_Seq_Receive_IT(p_slave_stm_i2c->p_i2c_handle, &rx_i2c_msg.pui8_raw_msg[0], 6U, I2C_LAST_FRAME_NO_STOP); return RetVal; } void HAL_I2C_ListenCpltCallback(I2C_HandleTypeDef *hi2c) { if(HAL_I2C_EnableListen_IT(hi2c) != HAL_OK) Error_Handler(); } void HAL_I2C_AddrCallback(I2C_HandleTypeDef *hi2c, uint8_t TransferDirection, uint16_t AddrMatchCode) { UNUSED(AddrMatchCode); UNUSED(hi2c); /* Master is transmitting */ if(TransferDirection == I2C_DIRECTION_TRANSMIT) { if(p_slave_stm_i2c->i2c_interface.pf_slave_receive_it() != HAL_OK) Error_Handler(); } else //Slave will transmit data { if(p_slave_stm_i2c->i2c_interface.pf_slave_transmit_it() != HAL_OK) Error_Handler(); } } void HAL_I2C_SlaveRxCpltCallback(I2C_HandleTypeDef *hi2c) { UNUSED(hi2c); assert(NULL != p_slave_stm_i2c); if(rx_i2c_msg.ui8_msg_type == i2c_mT_Reset_Slave) { //Flush Slave Buffer StmI2cControl_flushCmdBuffer(); } else if (osMessageQueuePut(p_slave_stm_i2c->rx_queue_handle, &rx_i2c_msg, 0, 0) != osOK) Error_Handler(); return; }
View more

 

 

My guess so far is that the I2C Interrupt is still disabled. Maybe I need to enable it through some RTOS function? Much thanks for your help.

In the attached images, A1 (top) is Data, A2 (bottom) is clock.

 

1 REPLY 1
Roger SHIVELY
ST Employee

Hello @minhaj97haider 

 

This post has been escalated to the ST Online Support Team for additional assistance.

 

We'll contact you directly.

 

Regards,

Roger