2012-11-14 05:02 PM
I am working on an i2c driver that utilizes DMA for the master transmits.
Everything seems to be set fine because I get hundreds of successful transactions but every once in a while, I issue a transaction but never get the DMA interrupt. I have both interrupts set for success and error and I get the success interrupt after just about every transaction. Every once in a while, I miss the interrupt. I put some counters in the event handler to make sure that I get the expected interrupts and I do, but I never get an error interrupt and I miss that one success. It seems to be only on the larger transfers, 268 bytes. The smaller ones all succeed and most of the 268 bytes ones succeed but I would say that once every 30 seconds of flooding the bus with transactions, the DMA doesn't interrupt. The priority of the DMA is set to 2. Can anyone shed some light on what may be going on?2012-11-15 03:35 AM
Sounds a bit like a flash device.
So are you not seeing a DMA TC interrupt? How are you recovering from that? Is there any indication from the DMA controller that the address/count end up where they should? Or is there and error/bus condition reported by the DMA, or I2C ACK failure or something? If a flash device, is there any commonality in the addresses at which this failure is noted.2012-11-15 07:20 AM
I am not accessing a flash, i'm writing to another controller, which just drops the data when it receives it.
Correct, no TC interrupt. The thing that bothers me is that I don't see a TE interrupt either. Checking the DMA register, it shows a remaining byte count, which is not the same value from test case to test case. I turned off all other tx requests except for the 268 byte ones and the hardware has been running fine since. So, it appears that multiple writes are causing the issue. If I have a buffer with data in it and the DMA is ongoing, and someone writes to that buffer again, would that cause the DMA to stop and not generate an error interrupt? Thanks for your time.2012-11-15 10:45 PM
2012-11-16 05:59 AM
I didn't think the writing to the memory buffer would cause an issue, however, copying the data to a temp buffer and setting the DMA to pull from that buffer seemed to solve the issue at first, but, I saw it hang again this morning.
I can't post code, unfortunately, but, a tx request consists of the following:
Obtaining a semaphore
Setting the Start condition
Setting up the DMA in the
I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED
IRQ and disabling the i2c I2C_IT_EVT interrupts.
DMA IRQ enables i2c I2C_IT_EVT interrupts so we can get the event interrupts again.
Release the semaphore after setting the stop bit in the
I2C_EVENT_MASTER_BYTE_TRANSMITTED
IRQ
This will run for hours and hours (10+) sending buffer after buffer. When I do get the failure, what I see is the DMA IRQ never fires because it stops with bytes left. Here are the registers:
DMA_CCR6 EN = 1 TCIE = 1 HTIE = 0 TEIE = 0 DIR = 0 CIRC = 0 PINC = 0 MINC = 0 PSIZE = 0 PL = 2 MEM2MEM = 0 DMA_CNDTR6 NDT = 0x010C DMA_CPAR6 0x40005410 DMA_CMAR6 0x2000155CWhat happens from here is I sit in a loop trying to get the semaphore which fails.
Any help figuring out what may stop the DMA with no error interrupt would be appreciated. I did have the error interrupt enabled (I don't in this register dump), but it never fired. Thanks for your time.From: waclawek.jan
Posted: Friday, November 16, 2012 7:45 AMSubject: Missing DMA interrupt after I2C transmit > I turned off all other tx requests except for the 268 byte ones > and the hardware has been running fine since. > If I have a buffer with data in it and the DMA is ongoing, and someone writes to that > buffer again, would that cause the DMA to stop and not generate an error interrupt? Writing to memory being read from DMA shoudln't cause any error (unless some heavy silicon bug, but I doubt that). OTOH, writing to DMA registers while a transfer is in progress, could quite well cause various ''funny'' effects. How exactly are you performing ''tx requests''? Any code to show? JW2012-11-16 07:00 AM
Are you sure your target device is accepting data? From the decription it sounds like you are not getting an ACK after sending a data byte. The I2C logic will stall and your DMA will never complete. The problem may well be in your peripheral and not the STM32 I2C.
To debug this you may have to run without DMA. That way you can check the BTF flag after every transmit. Jack Peacock2012-11-16 07:26 AM
I have a high level of confidence in the target peripheral because it has been in service for a long time and is designed as a test interface which does nothing but drop the data when it receives it, but, I will check just to make sure.
Thanks.2012-11-16 10:34 AM
2012-11-19 12:58 AM
> I can't post code, unfortunately, but, a tx request consists of the following:
The first thing to do when searching for
roots of some problem is to
cut down the code to absolute m
inimum exhibiting the problem, or to write a minimal test program. You surely cou
ld then post that.
I
don't say it's always possible, but usually is and helps you to understand the nature of problem, too. Often
, while constructing
/testing minimal code,
the cause of problem is found
by the original aut
hor of question.
> Here are the registers: What device?>
TEIE = 0Why?
> DIR = 0Why?
>
MINC = 0
Why?
JW2012-11-19 06:44 AM
Hi Jan,
Thanks for the reply. You are correct about stripping down the code. I'm not the original author so a good portion of my time has been spent understanding the top to bottom flow that the I2C and DMA are a small part of. But, you raise some very interesting questions. The original author never implemented a DMA error handler so I have since put on in, but, I don't hit the breakpoint when my transfer fails. What is interesting is why the DIR and MINC bits seem to be set wrong. On the TX, I would expect the DIR bit to indicate a memory to peripheral direction and the MINC bit should be set and the PINC bit should be clear. Seems to me that if the MINC is cleared, then it would make sense that the DMA would stop mid transfer and we would not see an error. I checked the code and it does set these to the correct values when the DMA is setup, and, the setup code is semaphore protected. I think this is a very good place to stare at for a while. Thanks Jan!