cancel
Showing results for 
Search instead for 
Did you mean: 

I2C errors with two slave devices

Lex
Associate III

Hi,

I have ST25DV64KC and another ADC chip connected to STM32L071RZT6 on I2C1.

I noticed that reading GPO1 or other registers or MB by HAL_I2C_Mem_Read_IT() fails from time to time. Completions of operations are often timeout (somehow read timeouts more often, i.e. I don't get INT in expected time).

I only read static & dyn registers as well as accessing MB for r/w and tend to think that I don't handle i2c concurrent access properly.

  • Should only function call of HAL_I2C_Mem_Read_IT() or WriteIT() be protected by mutex or I should keep it until I get INT back signalling the end of the requested operation?
  • What should timeout be for reading of static/dyn registers or reading 256 bytes from MB? (configured i2c Fast-mode)
  • Does competing for i2c resources task's priority matters much or elevated priority will sort it out?
  • Could someone suggest a working approach to solve concurrent access on the i2c bus?

Cheers

1 ACCEPTED SOLUTION

Accepted Solutions
Bob S
Principal

If you are using and RTOS and more than one thread/task can access that I2C bus then, yes, you need a mutex to control access. And if you are using the _IT() versions of the HAL functions, you need a semaphore or task notification for the callback to notify the task that the I2C transfer is complete. Something like this pseudo code:

// TASK #1
acquire_i2c1_mutex();
sts = HAL_I2C_MasterTransmit_IT( .... ); // To device #1
acquire_i2c1_semaphore();  // semaphore set in I2C transmit complete callback
release_i2c1_mutex();
 
// TASK #3
acquire_i2c1_mutex();
sts = HAL_I2C_MasterTransmit_IT( .... ); // To device #2a
acquire_i2c1_semaphore();  // semaphore set in I2C transmit complete callback
release_i2c1_mutex();
 
void  HAL_I2C_TxCpltCallback( .. )
{
   if ( hi2c == &hi2c1 ) {
       release_i2c1_semaphore()
   }
}
 

If you are using the _IT() functions there are no (inherent) timeouts. And with I2C devices the only way ANY timeout makes sense is if there are multiple masters that might keep the bus busy and prevent your CPU from getting its turn.

View solution in original post

2 REPLIES 2
S.Ma
Principal

Well since the computer era started last millenia, network printers implementer a queue, aka spooler which funnel all print request in a tidy manner. Mutex may then becomes needless. Apply and adapt to I2C master

Bob S
Principal

If you are using and RTOS and more than one thread/task can access that I2C bus then, yes, you need a mutex to control access. And if you are using the _IT() versions of the HAL functions, you need a semaphore or task notification for the callback to notify the task that the I2C transfer is complete. Something like this pseudo code:

// TASK #1
acquire_i2c1_mutex();
sts = HAL_I2C_MasterTransmit_IT( .... ); // To device #1
acquire_i2c1_semaphore();  // semaphore set in I2C transmit complete callback
release_i2c1_mutex();
 
// TASK #3
acquire_i2c1_mutex();
sts = HAL_I2C_MasterTransmit_IT( .... ); // To device #2a
acquire_i2c1_semaphore();  // semaphore set in I2C transmit complete callback
release_i2c1_mutex();
 
void  HAL_I2C_TxCpltCallback( .. )
{
   if ( hi2c == &hi2c1 ) {
       release_i2c1_semaphore()
   }
}
 

If you are using the _IT() functions there are no (inherent) timeouts. And with I2C devices the only way ANY timeout makes sense is if there are multiple masters that might keep the bus busy and prevent your CPU from getting its turn.