AnsweredAssumed Answered

STM32F103REY I2C master receiver issue when 2 bytes, interrupt driver

Question asked by fab on Jan 24, 2013
Latest reply on Jan 25, 2013 by fab

I have an issue while 2 STM32F103REY are connected through i2c, 7bits addressing.

It works good in the following cases:
     master transmitter
     master receiver for 1 byte
     master receiver for n bytes, n >=2
Not ok for master receiver for 2 bytes.

The driver used is a custom one. It uses interrupt.
Surprisingly, the "AN2824 I2C master programming examples (DMA, interrupts, polling)" describe no examples with master receiver based on interrupt ?
There are only DMA and polling examples for this cases. Does it means no robust solution is possible with interrupt ?

The issue happens during a first 2 bytes reception but is only seen on the next reception.
3 interrupts occurs to read 3 bytes instead of 2 interrupts to read 2 bytes.
The unexpected extra read data is lost, as not read before the next reception (it is unexpected).

- Based on the errata sheet, I guess the best matched issue is the one reported as "Some software events must be managed before the current byte is
being transferred" and applying to EV6_1.
 I have tried in the handler interrupt routines to "Stretch SCL line between ADDR bit is cleared and ACK is cleared"
but without success.
                    //GPIOB_CRL 0x40010C00
                    //GPIOB_ODR 0x40010C00 + 0xC
                    //GPIOB_BSRR 0x40010C00 + 0x10

                    // set SCL gpio7, CNF7[1:0] bit 31-30 to 01: General purpose output Open-drain
             // no change of the GPIO mode as it is corretcly setup
                    uint32_t bsrr = *(volatile uint32_t *) 0x40010C00;
                    bsrr &= 0x7FFFFFFF;
                    bsrr |= 0x70000000;
                    *(volatile uint32_t *) 0x40010C00 = bsrr;
                    // clear bit7
                    *(volatile uint32_t *) 0x40010C10 |= (1<<(16+7));//same result with *(volatile uint32_t *) 0x40010C0C &= 0xFFFFFF7F
but the bit7 is stuck at 1 and this do nothing while is effective on an un-used IO.
So I guess the I2C interface continue to drive SCL to 1 and the software request to  go low level is then not efficient ?
My investigation to change the GPIO alternate through AFIO, conclude that this is not possible during communication.
I'd like clear code examples on how to do that.

- I then try to  mask interrupt as mentionned in AN2824 for the polling case but here during the interrupt handler. This was not efficient too.

I have looked for information on the forum without success.
Maybe there was a post, as user lanchon wrote "I've posted master mode i2c code that works and a couple of posts detailing limitations of the i2c macrocell, look them up if you want" but I have found nothing like this.

Also I guess even if some of the issues described in the errata sheet have not been seen, they have to be workaround for robustness. Regarding the un-sucess  for the first one, no clear synthesis for the whole and not enough detailed how to do (no code) for me, I really need your help.

Thanks in advance