I2C slave not working properly in STM32 - Page 1
Forum section: electronics / general

author: BorisRap
author_rank: Contributor
timestamp: November 14, 2022, 09:47:32 am
content: Hello, I'm trying to do a simple I2C slave device with a STM32F030C6T6. The idea is just to read and write some registers.I'm doing it withCode:HAL_I2C_EnableListen_IT(&hi2c1);because I had problems in the past usingCode:HAL_I2C_Slave_Receive_IT(hi2c, pData, Size);andCode:HAL_I2C_Slave_Transmit_IT(hi2c, pData, Size);at the same time.In the protocol I "designed" to communicate with this device you do a write to indicate what register you want to access and then you do a read or a write depending on if you want to read it or write it.So after the first write I have to expect both a read and a write.I read a few tutorials and I came up with this:Code:#include "main.h"I2C_HandleTypeDef hi2c1;uint8_t txc =0;uint8_t i2cd1 = 88;int main(void){SystemClock_Config();MX_GPIO_Init();MX_I2C1_Init();HAL_I2C_EnableListen_IT(&hi2c1);while(1){HAL_Delay(10);if(txc == 1){txc = 0;HAL_I2C_EnableListen_IT(&hi2c1);}}}static void MX_I2C1_Init(void){/* USER CODE BEGIN I2C1_Init 0 *//* USER CODE END I2C1_Init 0 *//* USER CODE BEGIN I2C1_Init 1 *//* USER CODE END I2C1_Init 1 */hi2c1.Instance = I2C1;hi2c1.Init.Timing = 0x2000090E;hi2c1.Init.OwnAddress1 = 78;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();}/** Configure Analogue filter*/if (HAL_I2CEx_ConfigAnalogFilter(&hi2c1, I2C_ANALOGFILTER_ENABLE) != HAL_OK){Error_Handler();}/** Configure Digital filter*/if (HAL_I2CEx_ConfigDigitalFilter(&hi2c1, 0) != HAL_OK){Error_Handler();}/* USER CODE BEGIN I2C1_Init 2 *//* USER CODE END I2C1_Init 2 */}void HAL_I2C_SlaveTxCpltCallback(I2C_HandleTypeDef *hi2c){txc = 1;}void HAL_I2C_SlaveRxCpltCallback(I2C_HandleTypeDef *hi2c){txc = 1;}void HAL_I2C_AddrCallback(I2C_HandleTypeDef *hi2c, uint8_t TransferDirection, uint16_t AddrMatchCode){if(AddrMatchCode == 78){if(TransferDirection == I2C_DIRECTION_RECEIVE){//READHAL_I2C_Slave_Seq_Transmit_IT(&hi2c1, &i2cd1, 1, I2C_FIRST_AND_LAST_FRAME);}else if(TransferDirection == I2C_DIRECTION_TRANSMIT){//WRITEHAL_I2C_Slave_Seq_Receive_IT(&hi2c1, &i2cd1, 1, I2C_LAST_FRAME);}}}void HAL_I2C_ListenCpltCallback(I2C_HandleTypeDef *hi2c){//HAL_I2C_EnableListen_IT(&hi2c1);}void HAL_I2C_ErrorCallback(I2C_HandleTypeDef *hi2c){HAL_I2C_Init(&hi2c1);HAL_I2C_EnableListen_IT(&hi2c1);HAL_GPIO_WritePin(OUT_LLC_EN_GPIO_Port, OUT_LED_Pin, 1);}(Some code has been excluded for simplicity)I'm using a MCP2221 usb to I2C adapter to send the messages from c# code in my computer.I'm also using a ISO1541DR I2C isolator.The hardware is very simple, just the uC with the SDA and SCL connected to the ISO. Everything correctly decoupled and 4.7k pullups in bith SDA and SCL both sides of the ISO.The receiving part works perfectly. I can send data from the computer to the STM it's received correctly and the STM starts another listing cycle, everything perfect.When I'm trying to execute a read on the STM it doesn't work. The computer returns error code 0 (ok), the data I receive on the computer is always 255 and the led turns on (meaning the ErrorCalback function is executed).EditI looked at the error code after the ErrorCallback execution and it iserror code 8 (Overrun error)While debugging,HAL_I2C_Slave_Seq_Transmit_IT(&hi2c1, &i2cd1, 1, I2C_FIRST_AND_LAST_FRAME);this line is executed with error code0and then it just fails.Additional info:I've been copying the methods of some tutorials, but I realized that in my system I have to putClock No Stretch ModetoEnabledfor it to work (at least the receiving part) if I set it to Disabled It doesn't work at allFull disclaimer: I don't know very well what I'm doing.I leave some images of CcubeIDE configuration.Thank you!UpdateI read that Overrun can only occur when clock stretching is disabled. So I removed the ISO1541DR and enabled clock stretching and now it works just fine.There is some problem when clock stretching is on and I'm using the ISO simultaneously.