cancel
Showing results for 
Search instead for 
Did you mean: 

HAL_I2C_Mem_Read returns error if used inside ISR

ssena.1514
Associate III

 

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)

1 ACCEPTED SOLUTION

Accepted Solutions

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.

View solution in original post

10 REPLIES 10
Tinnagit
Senior II

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. 

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

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
Lead II

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 you find my answers useful, click the accept button so that way others can see the solution.

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
Up vote any posts that you find helpful, it shows what's working..

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...

Is it depend on Interrupt priority?
and SystemTick can count over every interrupt if it's setted to highest priority. 

You mean if the GPIO interrupt is set to a lower priority because System tick is already set at the highest priority. Even then, the OP should still not be doing any processing in the interrupt.

If you find my answers useful, click the accept button so that way others can see the solution.

No, it's going to continue process follow order of priority after SystemTick was done.