cancel
Showing results for 
Search instead for 
Did you mean: 

SMbus HAL driver in Busy state after Error

Luke_abc
Associate III

Hi,

HAL Version 1.10

I am using SMBus in my system to communicate with the smart battery.

On an Arbitration loss error, the ARLO flag is set and the "HAL_SMBUS_ER_IRQHandler" is called. The IRQ handler clears the ARLO flag but the "hsmbus->State" remains in HAL_SMBUS_STATE_MASTER_BUSY_TX. 

This does not let the application to call the HAL_SMBUS_Master_Transmit_IT() api again as this api checks for the "hsmbus->State" for HAL_SMBUS_STATE_READY state. How do you expect the application to clear this flag and how can the the application call HAL_SMBUS_Master_Transmit_IT() again ? 

I could use HAL_SMBUS_DeInit() and HAL_SMBUS_Init() to clear the HAL state, but this does not seem right to me. Could you please suggest the right approach ?

Luke_abc_1-1696783875659.png

 

 

 

6 REPLIES 6
Karl Yamashita
Lead III

I have not worked on SMBus specifically but maybe try this?

void HAL_SMBUS_ErrorCallback(SMBUS_HandleTypeDef *hsmbus)
{
	uint32_t error;

	error = HAL_SMBUS_GetError(hsmbus);

	if((error & HAL_SMBUS_ERROR_ARLO) == HAL_SMBUS_ERROR_ARLO)
	{
		// set a flag to let user know there was an Arbitration error so user can try to send data again later.
		smbusArloErrorFlag = 1;
		// reset state to Error None
		hsmbus->State = HAL_SMBUS_ERROR_NONE; 
	}
}
Tips and Tricks with TimerCallback https://www.youtube.com/@eebykarl
If you find my solution useful, please click the Accept as Solution so others see the solution.
Bob S
Principal

It has been several years since I used the SMBus libs, and on a G4xx not H7.  Looks like you are not using the ST SMBus Cube Expansion code, but writing your own layer above the HAL SMBus driver, is that right?

My experience was with the SMBUS/PMBus Cube Expansion code (AN4502) - so you might take a look at that and see how they recovered.  Specifically the STACK_SMBUS_HostCommand(), HAL_SMBUS_ErrorCallback() and related code in stm32_SMBUS_stack.c. 

Pavel A.
Evangelist III

@BobSCHMITZ The picture in the OP is exactly from AN4502. 

Bob S
Principal

> The picture in the OP is exactly from AN4502

@Pavel A.your are right, of course.

That still leaves the question of whether this person is using the code that comes along with the app note (cube_smbus).  It appears to me that they are not, but I could be mistaken there as well since I base that on their mention of HAL_SMBUS_Master_Transmit_IT().  That function is not (usually) called directly from user code when using the AN4502 provided code.  So I don't know if they are writing their own, or trying to debug the cube_smbus code.

Luke_abc
Associate III

Hi @Bob S @Karl Yamashita @Pavel A. ,

Thank you for your replies.

I am using SMBus Expansion code. The application layer was getting error and the reason found was HAL_SMBUS_Master_Transmit_IT() returning HAL_BUSY after an SMBUS error occurs (explained in the post).

The expansion code does not seem to do anything to recover for SMBus HAL driver after an error. I have noticed that if a NACK error (HAL_SMBUS_ERROR_ACKF) happens, another ISR happens for STOPF and this clears the HAL SMSUS driver state in function SMBUS_Master_ISR(). But, I have not seen this for errors   HAL_SMBUS_ERROR_BERR, HAL_SMBUS_ERROR_BUSTIMEOUT and HAL_SMBUS_ERROR_ARLO.

 

Luke_abc_1-1697820541525.png

 

 

 

Pavel A.
Evangelist III

The expansion code does not seem to do anything to recover for SMBus HAL driver after an error.

The smbus library looks like a proper level to handle recovery. IMHO you can file a #bugreport

While waiting for resolution you can do some quick and dirty fix to keep your project going.