2013-01-03 07:15 AM
Hi,
I hope someone can help.
I have got the I2C1 peripheral working fine with the above chip, but when I try and initialize the I2C2 peripheral, the busy flag is always set. Does anyone have any ideas?
My code:
RCC->APB2ENR |= 0x00000008; // Enable GPIOB clock
GPIOB->CRL = 0xFF444434; // Set GPIOB configuration register low (pins PB6 and PB7 for I2C1)
GPIOB->CRH = 0xBBB4FF44; // Set GPIOB configuration register high (pins PB10 and PB11 for I2C2)
// I2C 1 Initialize (works fine)
RCC->APB1ENR |= 0x00200000; // Enable i2c 1 clock
I2C1->CR1 = 0x0480; // Set acknowledge enable
I2C1->CR2 = 0x0138; // Set clock frequency and error interrupt enabled
I2C1->CCR = 0x0119; // Set i2c standard mode and duty cycle 100khz
I2C1->TRISE = 0x0039; // Set maximum rise
I2C1->CR1 |= 0x0001; // Enable i2c 1
// I2C 2 Initialize
RCC->APB1ENR |= 0x00400000; // Enable i2c 2 clock <--------- After this line is called the BUSY flag of SR2 is set and remains so
I2C2->CR1 = 0x0480; // Set acknowledge enable
I2C2->CR2 = 0x0138; // Set clock frequency and error interrupt enabled
I2C2->CCR = 0x0119; // Set i2c standard mode and duty cycle 100khz
I2C2->TRISE = 0x0039; // Set maximum rise
I2C2->CR1 |= 0x0001; // Enable i2c 2
Many Thanks.
2013-01-03 09:46 PM
After enabling its clock and before writing to its registers, try to reset the I2C module through its respective reset bit in RCC.
JW2013-01-04 01:19 AM
Hi JW,
That was it,
many many thanks. Not sure why you
have to do this on
I2C2, not I2C1, but
in
serted th
e lines
RCC->APB1RSTR |= 0x00400000; // Reset i2c peripheral
RCC->APB1RSTR &= 0xFFBFFFFF;
after the clock enable and it worke
d.
M
uch apprec
iated.
2013-01-04 01:19 AM
Hi JW,
That was it,
many many thanks. Not sure why you
have to do this on
I2C2, not I2C1, but
in
serted th
e lines
RCC->APB1RSTR |= 0x00400000; // Reset i2c peripheral
RCC->APB1RSTR &= 0xFFBFFFFF;
after the clock enable and it worke
d.
M
uch apprec
iated.
2013-01-04 02:29 AM
I observed the same on STM32F407. After initializing (without the reset), the I2C module was ''hanging'' after setting the START bit (as master) without generating the START condition. When I manually grounded one of the SDA/SCL pins (I don't remember which one), the module came alive and continued working properly.
I'd say, this is a silicon bug. I guess some of its internal status registers are not reset properly during system reset or are not kept in reset while the PE bit in I2C_CR1 is zero; ''wiggling'' the I2C's module IOs (SDA/SCL) by switching the IO matrix might be involved in the error mechanism, too. The ''library'' - which I despise thus don't use - contains the reset as part of the module init (as it does for most if not all modules), which sort of covers up the bug for the presumable majority using the ''library''. However, unless I missed the documentation explicitly say out that reset is required as part of the initialization, I still say it IS a bug. It would be nice to hear 's comment on this. JW2013-01-07 06:34 AM
I don't think it's silicon issue. Most likely there are some glitches on the SDA/SCL lines that cause the I2C module to detect a ''busy'' status on the bus. It will do so whenever any of the two lines is ''low'', and will wait for the STOP condition to reset the ''busy'' status.
When initializing the GPIOs it is very important to avoid pulling SDA/SCL low even temporarily.2015-02-20 07:12 AM
I Agree. Pulling them low is rude but it works excellent. It's the SCL Pin.
Regards