cancel
Showing results for 
Search instead for 
Did you mean: 

STM32F1 I2C start failure

clark2
Associate II
Posted on February 16, 2016 at 15:57

I am working with an STM32F103RC and trying to develop an I2C master application.  Currently the I2C bus is populated with only this master and an MCP23017 slave.

In my most recent test run the program eventually ended up in a locked loop waiting for SB to set in SR1.  The START bit is set, PE is set, the peripheral clock is enabled, both signals are in the passive state... how is this possible?  Is there a known (yet unpublished) bug in this peripheral which would allow this condition?  The obvious answer is ''yes'' unless I'm missing something.

I realize the prudent thing to do would be to have a timeout test on this wait, but why?

30 REPLIES 30
Radosław
Senior II
Posted on February 20, 2016 at 13:25

Is atomic access is needed in your functions? NO.

BB is not always save. specially when you clear isr flags by '0'.

Still you don't understand INDEX ADDRESSING.

Explain  why code with normall access is smaller from bb access.

STILL sore instructions to BB region need more clocks.

BB access in this situations don't have any advantyges.

Radosław
Senior II
Posted on February 27, 2016 at 16:26

Now is working?  Please give as some  feedback.

clark2
Associate II
Posted on February 27, 2016 at 19:29

I do believe I have won this small battle.  I need to do further testing and clean up the code some.  I think I will also rework it so that it can be built using bitband access or not so that I can run some real tests and evaluate performance and memory usage.  During this debugging process I replaced all the bitband code with ''standard'' memory access and noticed the code grow by about 0.3K...

clark2
Associate II
Posted on February 27, 2016 at 19:33

As to the start bit failing to register intermittently, I changed my pullup resistors from 2K2 to 1K and added a 0.1uF capacitor to the reset lead of the MCP23017 slave.  The problem has not ocurred since.

Posted on February 27, 2016 at 19:46

OK so it does not freeze anymore?

What was the cause?

JW
clark2
Associate II
Posted on February 27, 2016 at 19:57

I can't say for sure, but changing the resistors and adding the capacitor seems to have cured it.  I still need to run it some more to be sure that it is, in fact, cured.  Right now I have a debate going on in my head regarding how to best manage the driver in terms of passing arguments and storing the commands and data, etc.

Radosław
Senior II
Posted on February 27, 2016 at 20:09

>>  During this debugging process I replaced all the bitband code with ''standard'' memory access and noticed the code grow by about 0.3K...

Not posible. You are doing it wrong. BB isn't save access. Be carefull. An use too much pc related access to flash.

You suggest upredicted slave reset?  How long is I2C bus?

clark2
Associate II
Posted on February 27, 2016 at 20:31

I was thinking that an unexpected slave reset may be the cause, but could that possibly cause the master to miss the START sequence and not set the SB bit?  This is causing my brain to cramp a little bit...

The I2C bus is currently 6'' jumper wires from my dev board to a breadboard.

I understand what you are saying about bitband access fetching addresses from flash.  I am fairly new to ARM and need to experiment with various ways to best take advantage of the architecture.  I would rather this thread not digress into a discussion about that.  However, I would point out that ''normal'' memory access still requires an address to be fetched...

I'll just leave this here:

http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.faqs/ka16401.html

Radosław
Senior II
Posted on February 27, 2016 at 20:55

But i do this test many times. BB acces is  5 times longer than normal. 

And still in meny situation few of them can be replaced by 1 normall acces.

In configuration stage all register values are known (usualy '0'). (in any MCU).  So any write acces is posible. 

But this creates additional problem for newbes.  Core is much more faster from that.

For example: After peripheral acces you need add addtional dummy read (AHBENR for example) if next instruction access to this peripheral.

In timer when you generate by software update  you need add dommy read after SR clear.

flyer31
Senior
Posted on February 28, 2016 at 13:16

You have to be aware of the fact, that the STM32 I2C is strictly defined for multi-master I2C, although probably most people would not use this (most people I think would use I2C systems with only one master, then STM32 is either slave or master, but does not change the role during communication...).

Thus they made it like this, that if the SDA is in dominant state (0V), where the master cannot produce a start condtion, then the STM32 immediately will switch back to slave operation.

Such a dominant state (0V) can be enforced by a slave, especially by some ''stupid'' slave without timeout reset ... such a slave would just clock out data on the SDA line, and if by some accident he missed some SCL pulses, he will keep the SDA line low at the end of the transfer.

If you want to resume from this bus block situation, the only possibility in STM32F as far as I know is to switch the SCL GPIO back to normal pin mode (disconnect from alternate function), and then ''manually'' enforce 8-9 clock pulses to be sure to read out all ''stupid hanging slaves'' connected to the I2C. Then the SDA for sure will go to recessive (1 = 3.3V), and then the STM32F will have no problem to start the transfer.

They improved the I2C module for STM32L4 very much, but I am frightened this ''automatic switch back to slave mode'' functionality also in the new STM32L4 I2C module cannot be deactived, so you still also need such a slow ''I2C Reset function'' in STM32L4 for emergency (it is quite a fiddling to program this in a state machine mode without blocking the complete CPU time ... it would be much nicer if there would be a register bit to enforce ''master mode only operation'' - in this case it would be very easy to do this reset, this would just mean to enforce reading one byte from the bus - but of course this would work only in ''enforced master mode'', as the start condition cannot be generated in this case and the STM32 I2C would need some information that he is for sure master (although missing start condition on the bus ...)).