Hello,
I've got a project where none of the I2C ports seem to respond in any way to the settings in the TIMINGR register. I put the I2C clock on a scope and noticed it running way too fast, so I tried different clock divider settings in TIMINGR to no effect, and even just set the register to 0 or ffffffff just to see if there was any change at all.
This is running up-to-date ChibiosOS from github, on an STM32H753. I'm also using the C++ wrapper, in case that matters. I'm using the internal clocks only, no external oscillator connected. I have a Cube project running to validate that all of the hardware is capable of working, via Cube's HAL.
I suspect this is more like a MCU configuration error rather than an Chibios error, but I can't figure it out. Any ideas? Here's a transcript of a debug session where TIMINGR is written to and then doesn't actually change:
Info : Device: STM32H74x/75x
Info : flash size probed value 2048
Info : STM32H flash has dual banks. Bank (0) size is 1024kb, base address is 0x8000000
0x08005ee4 in _idle_thread (p=0x0) at ../ChibiOS/os/rt/src/chsys.c:72
72 static void _idle_thread(void *p) {
(gdb) b hal_i2c_lld.c:989
Breakpoint 1 at 0x80047c8: file ../ChibiOS/os/hal/ports/STM32/LLD/I2Cv3/hal_i2c_lld.c, line 989.
(gdb) monitor reset halt
(gdb) c
Continuing.
Note: automatically using hardware breakpoints for read-only addresses.
Breakpoint 1, i2c_lld_start (i2cp=0x240004f8 <I2CD1>) at ../ChibiOS/os/hal/ports/STM32/LLD/I2Cv3/hal_i2c_lld.c:989
989 dp->TIMINGR = i2cp->config->timingr;
(gdb) p dp
$1 = (I2C_TypeDef *) 0x40005400
(gdb) p *dp
$2 = {CR1 = 49297, CR2 = 0, OAR1 = 0, OAR2 = 0, TIMINGR = 0, TIMEOUTR = 0, ISR = 1, ICR = 0, PECR = 0, RXDR = 0,
TXDR = 0}
(gdb) p i2cp->config->timingr
$3 = 547407071
(gdb) n
992 dp->CR1 |= I2C_CR1_PE;
(gdb) p *dp
$4 = {CR1 = 49297, CR2 = 0, OAR1 = 0, OAR2 = 0, TIMINGR = 0, TIMEOUTR = 0, ISR = 1, ICR = 0, PECR = 0, RXDR = 0,
TXDR = 0}
Alternatively, are there any demo projects for the STM32H7 that include I2C?
STM32H7 I2C
Moderators: barthess, RoccoMarco
- Giovanni
- Site Admin
- Posts: 14382
- Joined: Wed May 27, 2009 8:48 am
- Location: Salerno, Italy
- Has thanked: 1065 times
- Been thanked: 908 times
- Contact:
Re: STM32H7 I2C
Hi,
I have no access to instrumentation right now (and for a while...), the I2Cv3 driver has been used on both L4+ and H7 so I agree that there should be some configuration error somewhere. I would start by checking clock settings in mcuconf.h and their limits, note that you can copy your cube configuration in there.
There is an open bug on that driver but it only affects I2CD4.
Giovanni
I have no access to instrumentation right now (and for a while...), the I2Cv3 driver has been used on both L4+ and H7 so I agree that there should be some configuration error somewhere. I would start by checking clock settings in mcuconf.h and their limits, note that you can copy your cube configuration in there.
There is an open bug on that driver but it only affects I2CD4.
Giovanni
Re: STM32H7 I2C
The register not changing looks as if the module is still in reset or there is a: "you can't change this register if the module is enabled" that the hardware enforces.
You can do
p dp->TIMINGR=24
in the debugger and see if it changes.
consider using /x to get hex printout of the hardware registers. Reads a lot easier.
You can do
p dp->TIMINGR=24
in the debugger and see if it changes.
consider using /x to get hex printout of the hardware registers. Reads a lot easier.
-
- Posts: 7
- Joined: Sun Mar 29, 2020 1:44 am
- Location: Richmond, Virginia, USA
- Been thanked: 1 time
Re: STM32H7 I2C
I figured it out. Rew's tip was really helpful. I found that manually writing to that register was also failing, but then I figured out that if I manually set CR1 to 0, then TIMINGR starts working. So then I went back to my high-level code and realized I wasn't setting the I2CConfig properly. I had just copied CR1 and CR2 out of my Cube project (grabbed from the debugger while the project was running), and this captured the Enabled bit in CR1, which locks out writes to TIMINGR.
Now I've got my I2CConfig.cr1 and cr2 = 0, and I'm able to talk to my device. (I still need to look up those control registers and see what values they should actually have, but at least I've got signs of life now.
The only other oddity that I've noticed is that for both I2C and SPI (and probably anything that uses DMA internally?) I have to do two things:
1) cacheBufferFlush() the buffers before any communication
2) the buffers can't be located in ram0, where most of my objects are. ram1 seems to work.
Is this expected behavior?
Thanks for the great software library! Despite these hardware issues, ChibiOS in a joy to program in compared to anything else I've tried.
Now I've got my I2CConfig.cr1 and cr2 = 0, and I'm able to talk to my device. (I still need to look up those control registers and see what values they should actually have, but at least I've got signs of life now.
The only other oddity that I've noticed is that for both I2C and SPI (and probably anything that uses DMA internally?) I have to do two things:
1) cacheBufferFlush() the buffers before any communication
2) the buffers can't be located in ram0, where most of my objects are. ram1 seems to work.
Is this expected behavior?
Thanks for the great software library! Despite these hardware issues, ChibiOS in a joy to program in compared to anything else I've tried.
- Giovanni
- Site Admin
- Posts: 14382
- Joined: Wed May 27, 2009 8:48 am
- Location: Salerno, Italy
- Has thanked: 1065 times
- Been thanked: 908 times
- Contact:
Re: STM32H7 I2C
Hi,
Correct, cache handling is up to the application code. You need to make sure that your buffers are aligned to 32 bytes (both address and size).
This could help: http://www.chibios.org/dokuwiki/doku.ph ... _dma_guide
Also, look at the /testhal/STM32/multi/SPI demo for examples of buffers alignment and cache handling. Basically, flush before transmitting, invalidate after receiving.
A note about CRx registers in various drivers, often those are both configuration AND control registers, configuration bits should be specified in the configuration structure, control bits are handled by the driver, should be left to zero.
Giovanni
Correct, cache handling is up to the application code. You need to make sure that your buffers are aligned to 32 bytes (both address and size).
This could help: http://www.chibios.org/dokuwiki/doku.ph ... _dma_guide
Also, look at the /testhal/STM32/multi/SPI demo for examples of buffers alignment and cache handling. Basically, flush before transmitting, invalidate after receiving.
A note about CRx registers in various drivers, often those are both configuration AND control registers, configuration bits should be specified in the configuration structure, control bits are handled by the driver, should be left to zero.
Giovanni
-
- Posts: 7
- Joined: Sun Mar 29, 2020 1:44 am
- Location: Richmond, Virginia, USA
- Been thanked: 1 time
Re: STM32H7 I2C
Makes sense, thanks for the tips. I've got an MS5611 barometer fully working now.
How broken is I2CD4 at the moment?
How broken is I2CD4 at the moment?
- Giovanni
- Site Admin
- Posts: 14382
- Joined: Wed May 27, 2009 8:48 am
- Location: Salerno, Italy
- Has thanked: 1065 times
- Been thanked: 908 times
- Contact:
Re: STM32H7 I2C
Hi,
Event and Error interrupt vectors are swapped on L4+, there is already a submitted patch for this, will be fixed in next version, it should be fine on H7.
Giovanni
Event and Error interrupt vectors are swapped on L4+, there is already a submitted patch for this, will be fixed in next version, it should be fine on H7.
Giovanni
Who is online
Users browsing this forum: Google Adsense [Bot] and 10 guests