cancel
Showing results for 
Search instead for 
Did you mean: 

Need help on Periph_to_mem DMA transfer started from an interrupt

Posted on May 15, 2013 at 19:00

I need advice on the following problem.

I have to connect an external hardware generating 32-bit values at a continuous rate of 1536 kHz to a GPIO port of a Cortex M4F CPU, that of the STM32F4 Discovery board, which I am using as a proof of concept before committing for the production of the final PCB.

I had thought to use the DMA to fill a 512-entry buffer, in double buffered mode, alerting the CPU when one of the two flip-flop buffers is filled. This seems to not present problems.

What I am not sure is how to communicate to the DMA controller that a new sample is ready on the GPIO port. First of all, can the DMA be used this way ? IOW, can it be controlled by an EXTI interrupt generated by a pin of a GPIO port (of course not the same port where the samples are arriving from).

To summarize, the flow should be this :

- A new 32-bit sample is set on the pins of a GPIO port.

- A pin of another port is toggled to tell to the DMA controller to read that value and to deposit it in  memory, incrementing the memory address.

- When the count of samples reaches 512, a buffer switch happens, and an interrupt is generated to the CPU, which will then process the just filled buffer. So what I need is a way to trigger a DMA request by toggling a pin of a GPIO port. Is this possible ?

A snippet of code on how to initialize the NVIC and the DMA controllers would be much appreciated, thanks.
11 REPLIES 11
Posted on May 15, 2013 at 19:55

Yeah, that's going to be hard to pull off.

How are you going to get 32-bits from the GPIO? The IDR for the different banks isn't contiguous in memory.

You might want to consider serializing the data at 49.152 MHz, run things synchronously. Perhaps using a CPLD, FPGA or FIFO to mitigate the requirements of each device.

Perhaps you can abuse the DCMI to stream in the data.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Posted on May 15, 2013 at 23:09

Clive,

  thanks for the answer. While I am (somewhat) proficient ad DSP (and this is a DSP application), I am rather inexpert about ARM microprocessors.

What I am trying to do is to receive a continuous stream of 32-bit data from an external hardware, then putting them in a buffer in memory. I do not fully understand your remark about the IDR...

As I had imagined it, the DMA controller should read the 32 pins of a GPIO port carrying the new data, then move it into memory, incrementing the destination memory address...

Are you perhaps telling me that the DMA cannot read the 32 bits of the GPIO port all together, but instead it is only capable of reading 16 bits at a time ? If this is the case, well, we are still in time to revise the architecture of the external hardware, so that to send the 32-bit values in two chunks of 16 bits each...

Supposing this is the case, it rests open my initial question... is it possible to trigger a DMA request by toggling a bit of a GPIO port ? How ?  Thanks.

 

Posted on May 16, 2013 at 01:12

It's not so much an ARM issue, as an STM32 implementation issue.

No, I do not believe you have a 32-bit wide lane from the GPIO, they are banked in 16-bit blocks, and the IDR (input data registers) between the banks are not contiguous. You need sit down with the RM0090 reference manual and review it carefully.

No, I don't think there is a slick way to trigger external DMA events (DRQ,DACK of olden days). The timer units might be able to be configured to do this, but it would take a lot of effort to prove.

The DCMI unit provides some mechanism to be driven by external sources, again would require analysis and review on your part.

If you can run everything synchronously from this same 1.536 MHz clock (input via HSE, or some multiple there of, then piped out via MCOx pins perhaps, or TIMx CHx), you could pace things internally at the desired rate, with may be some phase compensation. ie DMA paced in lock step with source.

Also you could stream the data in serially, which I'd hazard would be relatively simple to implement in logic.

1.536 MHz is beyond the advisable interrupt/EXTI rate.

FIFO/FPGA devices could be attached via the FSMC, the 8/16-bit external memory interface.
Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Posted on May 16, 2013 at 11:27

Clive,

  thanks again. It looks like I have to talk to the developers of the hardware that will be interfaced with the STM32F4 to find together an alternative solution...

Just a final question... do you think that programming one of the timers as a counter, with a reload value of -1, then using it to count pulses sent to a GPIO pin, and using it to trigger a DMA request could possibly work as a dirty trick to have a DMA transfer each time a pulse comes to that GPIO pin ?  Thanks.

Posted on May 16, 2013 at 16:04

It might be possible to use a timer in input compare mode, generating a CCx or TRIG, and a DMA unit/stream/channel. It might be hard to confirm the timing/latency of the transfer wrt to the pulse, and it's only going to be 16-bit wide. I don't have to time/resources to develop this for you.

A common, synchronous, clocking scheme would be something to seriously consider.

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
dthedens23
Associate II
Posted on May 17, 2013 at 17:53

DMA is not the problem.  The problem is you have an event occur at 1.5 Mhz.

given the 12 cycles for ISR stacking, about the same for unstacking, then say 20 cycles or more to read the GPIO and stash the data, you should be able to see how much of the CPU is going to be used.  DMA is not really the answer since you have to use a peripheral interrupt to start the DMA, so it really is not a good option.

If I had such a requirement I would choose a LPC34xx dual core.  The M0 core could be gathering data and pass the M4 a message (interrupt) informing the M4 that there is a new buffer.  the M4 can then process the data while the M0 is gathering the next buffer.

Posted on May 17, 2013 at 18:29

In the context provided the ''interrupt'' represents an external stimulus for a DMA transaction, a DRQ

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
Posted on May 17, 2013 at 19:23

> DMA is not the problem.  The problem is you have an event occur at 1.5 Mhz.

> given the 12 cycles for ISR stacking, about the same for unstacking, then say 20 cycles or more to

> read the GPIO and stash the data, you should be able to see how much of the CPU is going to be

> used.  DMA is not really the answer since you have to use a peripheral interrupt to start the DMA, > so it really is not a good option.

Well, as Clive already explained, in this context interrupt means just a way to trigger a DMA transfer. There is no Interrupt Service Routine that is executed, nor context saving.

Just as a test, I programmed ADC1 + ADC2 of the STMF32M4 to sample at 12-bit, 1.615 MHz, with DMA transfer, double buffered, and I was able to do a lot of processing on the sampled data, without errors nor overflows. My intent is to replace the ADC1 + ADC2 sampling with an external sampling at 72+ MHz, then reduced to 1.536 MHz with a DDC in a FPGA.

The problem is how to bring those data into the M4, using the DMA as I have done with ADC1 / ADC2.

 

zzdz2
Associate II
Posted on May 18, 2013 at 08:43

I plan to do something similar but with a FIFO, no FPGA.

I hope it should be possible to use timer to clock the fifo and trigger dma.

In theory it looks quite simple.

IMO you just need to do it in reverse, STM32 as a master generating data clock/request.