0
\$\begingroup\$

I am working on a project that requires the ADC, and I want to use the DMA. 

I have been able to get the adc to work using the sync drivers (I haven't tried async), but when I use the DMA no conversion seems to be happening.  The callback is never ran, and now values are put into the buffer besides 0.

I am using the Samd21ja18A on the Xplained Pro board

Here is my adc configuration:

enter image description here

enter image description here

Here's My DMA configuration enter image description here

Here is the setup and callback enter image description here

Any help would be greatly appreciated, this has been driving me crazy.

\$\endgroup\$

1 Answer 1

2
\$\begingroup\$

You need to enable the DMA priority level in the DMAC config that has been selected as the channel's Channel Arbitration Level.

In your example, channel priority 1 has been selected. So priority 1 needs to be enabled in the DMAC. The values in the Atmel START config headers are:

// <o> Channel Arbitration Level
// <0=> Channel priority 0
// <1=> Channel priority 1
// <2=> Channel priority 2
// <3=> Channel priority 3
// <i> Defines the arbitration level for this channel
// <id> dmac_lvl_1
#define CONF_DMAC_LVL_1 1

// <q> Priority Level 1
// <i> Indicates whether Priority Level 1 is enabled or not
// <id> dmac_lvlen1
#define CONF_DMAC_LVLEN1 1

I think the idea is that you can dynamically turn on and off different DMA priority levels, for example to temporarily disable low priority DMA. They all default to off. So all DMA channels will sit in the PEND state until their priority is enabled and the DMA arbiter gives them DMAC access.

Another problem is you are configuring DMA channel 1. Check CONF_DMA_ADC_CHANNEL in the generated headers. It's probably 0, not 1, and you should be configuring channel 0. There doesn't seem to be any way to know or test this value. One needs to generate code, find the value, then configure the appropriate channel, and then hope the value doesn't change when the project is regenerated or edited.

Also the code for adc_dma_read() in Atmel's example has bug. The size argument is not in bytes, it's in the DMA beat size, which is two bytes for the ADC.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.