Skip to main content
ssena.1514
Associate III
November 3, 2023
Solved

HAL_I2C_Mem_Read returns error if used inside ISR

 

Hi,

Currently I am implementing the smbalert functionality for ltc4015 based battery charger.

But when I am using the below mentioned code(commented section) inside isr it is returning communication error.

 

 

//SMBALERT interrupt from ltc4015 to stm32l0

void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)

{

HAL_StatusTypeDef ret;

uint8_t buf[1];

uint8_t read_buf_word[2];

 

smbalert_flag = 1;//set the smbalert_flag

 

//step-1

HAL_GPIO_WritePin(GPIOB, GPIO_PIN_7,GPIO_PIN_RESET);//RESET PIN cleared of PCA9546A

//HAL_Delay(1);//put some delay

HAL_GPIO_WritePin(GPIOB, GPIO_PIN_7,GPIO_PIN_SET);//RESET PIN set of PCA9546A

//HAL_Delay(1);//put some delay

 

//step-2

buf[0] = CONTROL_REG1;

ret = HAL_I2C_Master_Transmit(&hi2c1,PCA9546A_DEVICE_ADDRESS,buf,1,HAL_MAX_DELAY);//select channel 0 for i2c switch

if (ret != HAL_OK)

{

Error_Handler();

}

 

// //read limit_alerts

// ret = HAL_I2C_Mem_Read(&hi2c1,LTC4015_DEVICE_ADDRESS_READ,0x36,I2C_MEMADD_SIZE_8BIT,read_buf_word, 2,HAL_MAX_DELAY);

// if (ret != HAL_OK)

// {

// Error_Handler();

// }

// limit_alert_value = ((uint16_t)read_buf_word[0] | ((uint16_t)read_buf_word[1] << 8));

}

 

 so kindly inform me as soon as possible what could be the possible reason for this. And how to solve this problem.

 

Thanks & Regards

Satyabrata Senapati(vasmed)

This topic has been closed for replies.
Tinnagit
TinnagitBest answer
Senior II
November 3, 2023

OK, if your electrical signal has no problem.
So it's should be about the sequence that you use to interface to PCA9546A.
Like as there is some time reset or time start to ready to use which I saw time reset is about 500ns, it's just a little period  but that chip require this time after reset signal.
 So if you had comment line like this

HAL_GPIO_WritePin(GPIOB, GPIO_PIN_7,GPIO_PIN_RESET);//RESET PIN cleared of PCA9546A

//HAL_Delay(1);//put some delay

HAL_GPIO_WritePin(GPIOB, GPIO_PIN_7,GPIO_PIN_SET);//RESET PIN set of PCA9546A

//HAL_Delay(1);//put some delay

it's sould work fine because PCA9546A has time enough to start itself before you start to interface it.

10 replies

Tinnagit
Senior II
November 3, 2023

it's possible that STM32 was not receive response from your chip which it's maybe happen with electrical signal on SDA and SCL that's not match with I2C signal specification. 

ssena.1514
Associate III
November 3, 2023

But when i am removing the above code from isr the communication is happening perfectly.

that is inside main function.

 

so please inform me why its failing to work inside isr?

am i doing anything wrong here?

 

 

Thanks & Regards

Satyabrata Senapati

Tinnagit
TinnagitBest answer
Senior II
November 3, 2023

OK, if your electrical signal has no problem.
So it's should be about the sequence that you use to interface to PCA9546A.
Like as there is some time reset or time start to ready to use which I saw time reset is about 500ns, it's just a little period  but that chip require this time after reset signal.
 So if you had comment line like this

HAL_GPIO_WritePin(GPIOB, GPIO_PIN_7,GPIO_PIN_RESET);//RESET PIN cleared of PCA9546A

//HAL_Delay(1);//put some delay

HAL_GPIO_WritePin(GPIOB, GPIO_PIN_7,GPIO_PIN_SET);//RESET PIN set of PCA9546A

//HAL_Delay(1);//put some delay

it's sould work fine because PCA9546A has time enough to start itself before you start to interface it.

Karl Yamashita
Principal
November 3, 2023

You can't use HAL_Delay inside of an interrupt. It'll just hang forever there waiting for the HAL tick to increment its counter. When you're inside an interrupt, HAL_IncTick doesn't get called because it too needs to interrupt.

That's why you never ever write code inside an interrupt. Set a flag and exit the interrupt. Then check the flag in main while loop and then call a function to do your I2C code there where you can use HAL_Delay.

If a reply has proven helpful, click on Accept as Solution so that it'll show at top of the post.CAN Jammer an open source CAN bus hacking toolCANableV3 Open Source
Piranha
Principal III
November 4, 2023

If the HAL tick interrupt is set to a higher priority, then the code will not hang. Actually that is a requirement for HAL, because many of it's functions are using timeouts and are supposed to be called from interrupts. Awful design, but that is another story...

Tesla DeLorean
Guru
November 3, 2023

Don't use blocking functions in IRQ / ISR / Callbacks

I2C also isn't designed for concurrent operation, you can't have background and foreground tasks using it at the same time. Have some method to arbitrate ownership so only one task can use it at a time, and if it's not available defer.

Tips, Buy me a coffee, or three.. PayPal Venmo (See Profile) Up vote any posts that you find helpful, it shows what's working..