Forums

C5502 DMA Interrupt latency and DMACSAC reliability

Started by Chri...@hydrix.com May 23, 2012
Hi,

I'm having problems with the use of DMA to control transmission through a serial port. Specifically, the generation of frame/half-frame interrupts and the reliability of the DMACSAC register.

I've set a buffer of 40 x 16-bit elements that are used in a ping-pong style to serialise data to a codec; I'm relying on the frame/half-frame interrupt signals to tell me when to swap buffers for writing to (i.e. I write into the inactive buffer).

This has worked well in the past, and still appears ok with receiving through the same serial port. The problem I'm seeing is that the interrupts appear delayed by some time and are therefore not reliable; sometimes I will be writing into the active buffer accidentally and corrupting the output stream.

To debug this, I added logging to the interrupt handler to take note of the current source address (i.e. contents of DMACSAC) at the time of the interrupt; it should obviously be either the first element (array[0]) or the first element of the second half (array[20]). It is not. It is always alternating between array[16] and array[36]. This suggests some kind of offset, but by logging every change to the DMACSAC register I can see that the only addresses it ever shows are from array[16] and array[39].

I've attached here a snapshot of the DMA registers just after set-up. DMA channels 2 (base 0xc40) & 4 (base 0xc80) are receive channels, and it can be seen that the destination address start and DMACDAC are the same at this time (0xc46 & 0xc4d, and 0xc86 & 0xc8d) . Channels 3 & 5 are transmit channels and the source address start and DMACSAC values are different, even after initialisation. As said, those starting values (0xc6c & 0xcac) never go below these values, or match the start address (0xc64 & 0xca4).

--
0xC40 020D 43C9 000E 0000 6000 0000 337E 0000
0xC48 0028 0001 0000 0000 6000 337E 08C9 0000

0xC60 0601 13CA 000E 0000 33CE 0000 6004 0000
0xC68 0028 0001 0000 0000 33EE 6004 0000 0CB3

0xC80 020D 4381 000E 0000 5000 0000 322A 0000
0xC88 0050 0001 0000 0000 5000 322A 0000 0000

0xCA0 0601 1382 000E 0000 32CA 0000 5004 0000
0xCA8 0050 0001 0000 0000 32EA 5004 0000 0000
--

I've tried the same logging of the DMACDAC registers on the receive channels at frame/half-frame interrupts and they behave exactly as expected - always either array[0] or array[20].

(a) Is there latency in the DMA interrupts under any conditions?

(b) Is my reading of the DMACSAC valid, or are there issues with this?

(c) Is there anything else wrong here?
Chris,

Do you have other interrupts in the system? The main cause of interrupt latency is the servicing of other interrupts. Beware also long sections in your main loop where interrupts are disabled.

The DMA starts cranking right after the addresses are written, so it is hard to see their initial values.

Do you have a logic analyzer? That can be useful for detecting offsets in timing without changing your code.

Regards,
Bill
> -----Original Message-----
> From: c... [mailto:c...] On Behalf Of
> C...@hydrix.com
> Sent: Thursday, May 03, 2012 10:47 PM
> To: c...
> Subject: [c55x] C5502 DMA Interrupt latency and DMACSAC reliability
>
> Hi,
>
> I'm having problems with the use of DMA to control transmission through a
> serial port. Specifically, the generation of frame/half-frame interrupts and
> the reliability of the DMACSAC register.
>
> I've set a buffer of 40 x 16-bit elements that are used in a ping-pong style
> to serialise data to a codec; I'm relying on the frame/half-frame interrupt
> signals to tell me when to swap buffers for writing to (i.e. I write into the
> inactive buffer).
>
> This has worked well in the past, and still appears ok with receiving through
> the same serial port. The problem I'm seeing is that the interrupts appear
> delayed by some time and are therefore not reliable; sometimes I will be
> writing into the active buffer accidentally and corrupting the output stream.
>
> To debug this, I added logging to the interrupt handler to take note of the
> current source address (i.e. contents of DMACSAC) at the time of the
> interrupt; it should obviously be either the first element (array[0]) or the
> first element of the second half (array[20]). It is not. It is always
> alternating between array[16] and array[36]. This suggests some kind of
> offset, but by logging every change to the DMACSAC register I can see that the
> only addresses it ever shows are from array[16] and array[39].
>
> I've attached here a snapshot of the DMA registers just after set-up. DMA
> channels 2 (base 0xc40) & 4 (base 0xc80) are receive channels, and it can be
> seen that the destination address start and DMACDAC are the same at this time
> (0xc46 & 0xc4d, and 0xc86 & 0xc8d) . Channels 3 & 5 are transmit channels and
> the source address start and DMACSAC values are different, even after
> initialisation. As said, those starting values (0xc6c & 0xcac) never go below
> these values, or match the start address (0xc64 & 0xca4).
>
> --
> 0xC40 020D 43C9 000E 0000 6000 0000 337E 0000
> 0xC48 0028 0001 0000 0000 6000 337E 08C9 0000
>
> 0xC60 0601 13CA 000E 0000 33CE 0000 6004 0000
> 0xC68 0028 0001 0000 0000 33EE 6004 0000 0CB3
>
> 0xC80 020D 4381 000E 0000 5000 0000 322A 0000
> 0xC88 0050 0001 0000 0000 5000 322A 0000 0000
>
> 0xCA0 0601 1382 000E 0000 32CA 0000 5004 0000
> 0xCA8 0050 0001 0000 0000 32EA 5004 0000 0000
> --
>
> I've tried the same logging of the DMACDAC registers on the receive channels
> at frame/half-frame interrupts and they behave exactly as expected - always
> either array[0] or array[20].
>
> (a) Is there latency in the DMA interrupts under any conditions?
>
> (b) Is my reading of the DMACSAC valid, or are there issues with this?
>
> (c) Is there anything else wrong here?
>
>