AN4590 & 2 Channel Ping-Pong

取消
显示结果 
显示  仅  | 搜索替代 
您的意思是: 
已解决

AN4590 & 2 Channel Ping-Pong

跳至解决方案
1,886 次查看
marcohess
Contributor II

I am a little confused or simply don't understand AN4590.

I have a system with a K22F where I have 2 ADC channels both sampled at 40kHz rate. On the FRDM-K22F, I used both ADC0 and ADC1 both triggered by PDB and pushing samples into a ping pong buffer.

On my custom board, we decided to go with those two channels on the same ADC0 (because we need the ADC1 for a bunch of different channels and a much different sampling rate).

I originally aimed to setup the ADC with the Trigger A and the Trigger B mechanism for the different channel selections and was thinking that the DMA would transfer the results as before.

I now found out that the DMA can only trigger from the ADC interrupt and can't distinguish between A & B results.

So I am now trying to get to grips with what AN4590 is all about but I can't see how I can do what I think I need.

What I think I need is two channels sampled right after each other and then each channel result put in a ping-pong buffer for further signal processing.

In my previous setup, used the KSDK and has setup two DMA channels (one for each ADC). I used the following (simplified) code for each channel:

EDMA_DRV_Init( &edma_state, &edma_config );

EDMA_DRV_RequestChannel( SYS_DMA_CHAN_ADC0_A,

                                                   kDmaRequestMux0ADC0,

                                                  &edma_chn_state_adc0_A );

EDMA_DRV_ConfigLoopTransfer( &edma_chn_state_adc0_A,

                                          edma_transfer_descriptors_adc0_A,

                                          kEDMAPeripheralToMemory,

                                          (uint32_t)&ADC0_RA,

                                          (uint32_t)&edma_buffer_adc0_A,

                                          2, /* size to be transferred on every DMA write/read */

                                          2, /* bytesOnEachRequest */

                                          sizeof( edma_buffer_adc0_A ), /* Total length of Memory in bytes */

                                          2 /* Num Descriptors */);

EDMA_DRV_InstallCallback( &edma_chn_state_adc0_A,

                                       edma_callback_adc0_A,

                                       &edma_chn_state_adc0_A );

EDMA_DRV_StartChannel( &edma_chn_state_adc0_A );

Following AN4590 for what I understand from it, I need a DMA channel to transfer the channel selection to the ADC. Then the PDB triggers the ADC and then the DMA tranfers the result. But it looks like the ADC channels are interleaved in the result buffer. This would make it quite awkward for the subsequent processing and I have to copy out the data into separate buffers. Kind of defeats the purpose of the DMA.

How do I set the DMA up so the two different ADC channels end up in different ping pong buffers?

Can someone point out the sort of building blocks in terms of DMA channels and how they are setup and linked to each other to achieve this dual ping pong buffer?

标签 (1)
标记 (4)
0 项奖励
回复
1 解答
1,193 次查看
mjbcswitzerland
Specialist V

Marco

I haven't studied AN4590 in any detail but I think that it is showing standard single channel ADC->DMA operation.

The uTasker project has a similar operation - see chapter 2 of http://www.utasker.com/docs/uTasker/uTaskerADC.pdf

You may not learn any more from it but it has some different style diagrams that may help some understanding/discussion. If you look at figure 2 it is showing the single ADC channel case but, as you know, you can configure the PDM to trigger 2 channels (A and B) in a single ADC (one after the other). As you point out, using the ADC conversion as DMA trigger results in the samples interleaved in the output buffer which is not usually very practical.

However I would suggest looking at using the PDB IDLY flag match as DMA trigger rather than the ADC conversion flag. This way you can configure two DMA channels to be triggered at the same point in the sampling cycle; one writing channel A value to buffer 0 and the other writing channel B value to buffer 1.

You just need to set the two channel delays to complete both channel samples, followed by the IDLY delay to clear the values. I think that you can even set the IDLY to fire during one of the conversions - you just need to ensure that there is never an ADC overflow (should be virtually impossible using DMA) since this will stop the operation (with an error bit set somewhere). Although it should be possible to clear the error bit to start operation again I haven't found that this works (and nor has anyone else who I know who works with such modes...).

Regards

Mark

http://www.utasker.com/kinetis.html

在原帖中查看解决方案

0 项奖励
回复
2 回复数
1,194 次查看
mjbcswitzerland
Specialist V

Marco

I haven't studied AN4590 in any detail but I think that it is showing standard single channel ADC->DMA operation.

The uTasker project has a similar operation - see chapter 2 of http://www.utasker.com/docs/uTasker/uTaskerADC.pdf

You may not learn any more from it but it has some different style diagrams that may help some understanding/discussion. If you look at figure 2 it is showing the single ADC channel case but, as you know, you can configure the PDM to trigger 2 channels (A and B) in a single ADC (one after the other). As you point out, using the ADC conversion as DMA trigger results in the samples interleaved in the output buffer which is not usually very practical.

However I would suggest looking at using the PDB IDLY flag match as DMA trigger rather than the ADC conversion flag. This way you can configure two DMA channels to be triggered at the same point in the sampling cycle; one writing channel A value to buffer 0 and the other writing channel B value to buffer 1.

You just need to set the two channel delays to complete both channel samples, followed by the IDLY delay to clear the values. I think that you can even set the IDLY to fire during one of the conversions - you just need to ensure that there is never an ADC overflow (should be virtually impossible using DMA) since this will stop the operation (with an error bit set somewhere). Although it should be possible to clear the error bit to start operation again I haven't found that this works (and nor has anyone else who I know who works with such modes...).

Regards

Mark

http://www.utasker.com/kinetis.html

0 项奖励
回复
1,193 次查看
marcohess
Contributor II

Thanks Mark,

That is the outside the box thinking pointer that I needed.

I managed to get 2 DMA channels to trigger from the one PDB interrupt one pulling the A data and the other pulling the B data in their own ping-pong buffers.

Cheers,

Marco

0 项奖励
回复