STM32F4 I2C with DMA
Moderator: RoccoMarco
-
Rick Burnett
- Posts: 150
- Joined: Tue Jan 08, 2013 2:20 pm
STM32F4 I2C with DMA
Hello!
I'm unclear on how to use DMA with I2C. I looked at all the examples in the testhal directory for the 2.6.0 release and I just don't see this being explained.
I want to communicate with a EEPROM using I2C, right now I've implemented the code as I've used it in simple programs but I am getting an ACK error. When I scope the SCL and SDA lines, I see communication happening. I see the STM32 sending out the right stuff and the EEPROM communicating back. When I do a write with read set to 0, I do not get any errors. However, when I try to write and read using
i2cMasterTransmit(&I2CD1, NVRAM_ADDRESS, i2c_txbuf, 2, i2c_rxbuf, 4);
I then get an ACK error. NVRAM_ADDRESS is correct, its 7 bit (I've used this code before). Calling this with that 4 replaced to 0 generates no errors.
When I watch the waveform on the scope, I see some flickering after the first ACK. I am not sure if what I am seeing is my other threads interrupting this one (which they should, as they are the ADC thread and a timer that I need to be very accurate).
My thought was, if I moved this to DMA, then the interrupts would not affect the transfer.
Any thoughts on what I could be doing wrong?
I'm unclear on how to use DMA with I2C. I looked at all the examples in the testhal directory for the 2.6.0 release and I just don't see this being explained.
I want to communicate with a EEPROM using I2C, right now I've implemented the code as I've used it in simple programs but I am getting an ACK error. When I scope the SCL and SDA lines, I see communication happening. I see the STM32 sending out the right stuff and the EEPROM communicating back. When I do a write with read set to 0, I do not get any errors. However, when I try to write and read using
i2cMasterTransmit(&I2CD1, NVRAM_ADDRESS, i2c_txbuf, 2, i2c_rxbuf, 4);
I then get an ACK error. NVRAM_ADDRESS is correct, its 7 bit (I've used this code before). Calling this with that 4 replaced to 0 generates no errors.
When I watch the waveform on the scope, I see some flickering after the first ACK. I am not sure if what I am seeing is my other threads interrupting this one (which they should, as they are the ADC thread and a timer that I need to be very accurate).
My thought was, if I moved this to DMA, then the interrupts would not affect the transfer.
Any thoughts on what I could be doing wrong?
-
Rick Burnett
- Posts: 150
- Joined: Tue Jan 08, 2013 2:20 pm
Re: STM32F4 I2C with DMA
I should also note, this is a custom board. There also appears to be a bit of ringing around zero state, maybe I need to clean that up (I just shut off the ADC and the timer and still getting that Ack error on read).
- Giovanni
- Site Admin
- Posts: 14892
- Joined: Wed May 27, 2009 8:48 am
- Has thanked: 1202 times
- Been thanked: 996 times
Re: STM32F4 I2C with DMA
Hi,
The I2C driver uses DMA internally but some interrupts are still generated. Note that the early STM32 I2C peripherals is "problematic", often you need to put I2C IRQ priorities at level 4, above the other peripherals.
STM32 F0 and F3 are not affected by this.
Also see this article: http://www.chibios.org/dokuwiki/doku.ph ... e_shooting
Giovanni
edit: clarified the sentence
The I2C driver uses DMA internally but some interrupts are still generated. Note that the early STM32 I2C peripherals is "problematic", often you need to put I2C IRQ priorities at level 4, above the other peripherals.
STM32 F0 and F3 are not affected by this.
Also see this article: http://www.chibios.org/dokuwiki/doku.ph ... e_shooting
Giovanni
edit: clarified the sentence
-
Rick Burnett
- Posts: 150
- Joined: Tue Jan 08, 2013 2:20 pm
Re: STM32F4 I2C with DMA
Are you saying I2C1 as compared to I2C2 and I2C3 is problematic? If so, on my next board revision I can certainly change to one of the others.
I switched out the 1.5k resistors I had for 4.7k to clean up the ringing and it did that. I also made sure I had the pins set correctly from the page you posted (which they were correct already, but reset them in code again just to be SURE).
What I am seeing is that the signals from the STM32F4 look fine. The ack response from the 24LC64T is looking VERY weak and short. This is probably why I am not getting an ACK signal back. I'm trying to wrap my head around how the ACK is getting generated, how the hand off to the bus is working. I know I've used this exact part before in this configuration, although I was using 2.4 codebase. Time to start checking power and ground levels to this EEPROM.
I switched out the 1.5k resistors I had for 4.7k to clean up the ringing and it did that. I also made sure I had the pins set correctly from the page you posted (which they were correct already, but reset them in code again just to be SURE).
What I am seeing is that the signals from the STM32F4 look fine. The ack response from the 24LC64T is looking VERY weak and short. This is probably why I am not getting an ACK signal back. I'm trying to wrap my head around how the ACK is getting generated, how the hand off to the bus is working. I know I've used this exact part before in this configuration, although I was using 2.4 codebase. Time to start checking power and ground levels to this EEPROM.
- Giovanni
- Site Admin
- Posts: 14892
- Joined: Wed May 27, 2009 8:48 am
- Has thanked: 1202 times
- Been thanked: 996 times
Re: STM32F4 I2C with DMA
I meant that the I2C peripherals are problematic on early STM32s, all of them. F0 and F3 have a new peripheral.
Giovanni
Giovanni
-
Rick Burnett
- Posts: 150
- Joined: Tue Jan 08, 2013 2:20 pm
Re: STM32F4 I2C with DMA
Ahhh! I'm using the F427 which is newer, but maybe not new enough they fixed problems. I've shut everything else off in the code just to see what was happening, still not working. Reading other posts, I see others having similar issues and the selected resistance making a HUGE difference in what worked and what didn't. Guess I will have to experiment with that since nothing else jumping out at me. All voltages look good.
-
Rick Burnett
- Posts: 150
- Joined: Tue Jan 08, 2013 2:20 pm
Re: STM32F4 I2C with DMA
Interesting,
So the first call I do:
Generates no error. But, if I call this a second time, it will generate error 4, no (I2CD_ACK_FAILURE).
So then I added this before the second call:
And now it works. Is there something I need to call to block for me until the I2C is ready to work again?
So the first call I do:
Code: Select all
status = i2cMasterTransmitTimeout(&I2CD1, NVRAM_ADDRESS, i2c_txbuf, 6, i2c_rxbuf, 0,tmo)Generates no error. But, if I call this a second time, it will generate error 4, no (I2CD_ACK_FAILURE).
So then I added this before the second call:
Code: Select all
chThdSleep(1000);And now it works. Is there something I need to call to block for me until the I2C is ready to work again?
- Giovanni
- Site Admin
- Posts: 14892
- Joined: Wed May 27, 2009 8:48 am
- Has thanked: 1202 times
- Been thanked: 996 times
Re: STM32F4 I2C with DMA
It should not be necessary to block, the function should do that itself, there is a polled phase right at beginning.
What version are you using? 2.6.6?
Giovanni
What version are you using? 2.6.6?
Giovanni
-
Rick Burnett
- Posts: 150
- Joined: Tue Jan 08, 2013 2:20 pm
-
Rick Burnett
- Posts: 150
- Joined: Tue Jan 08, 2013 2:20 pm
Re: STM32F4 I2C with DMA
I went through and rechecked my code, make sure I was pulling from 2.6.6 everything (as I did have a few local copies of some things that should not have been local), and still see the same problem. If I don't but the sleep in there, I get an ACK error and it does not do whatever I asked.
This working when I was using the 2.4.0 code base, as I tested the exact same circuit topology on the same pins on a different board I made. (I had copied the code, that's why I was surprised when it didn't work.)
This working when I was using the 2.4.0 code base, as I tested the exact same circuit topology on the same pins on a different board I made. (I had copied the code, that's why I was surprised when it didn't work.)