External ADC & DMA

ChibiOS public support forum for topics related to the STMicroelectronics STM32 family of micro-controllers.

Moderator: RoccoMarco

User avatar
Skadi
Posts: 60
Joined: Fri Apr 17, 2015 5:10 pm
Has thanked: 4 times
Been thanked: 3 times

External ADC & DMA

Post by Skadi »

Hi,

I'm trying to read out an external 14 Bit ADC which is connected to 14 GPIO pins, of different ports. Can anyone tell me how to read in e.g. 100 samples? It's the first time I'm dealing with DMA and I'm a little bit confused by the DMA examples I have found so far and the usage of the corresponding functions.

I'm using ChibiOS version 16.1.2 and a STM32F429 customized board.

THX
mobyfab
Posts: 484
Joined: Sat Nov 19, 2011 6:47 pm
Has thanked: 21 times
Been thanked: 31 times

Re: External ADC & DMA

Post by mobyfab »

First you need to check which DMA has access to GPIO, then you have to configure it: channel/stream, source (gpio register), destination (memory), trigger (can be software or a timer), data width (16bit).

This is pretty much what you need, except the direction has to be reversed: viewtopic.php?t=2419

In details:
http://www.st.com/content/ccc/resource/ ... 169730.pdf
Last edited by mobyfab on Fri Jan 20, 2017 11:47 am, edited 2 times in total.
User avatar
Skadi
Posts: 60
Joined: Fri Apr 17, 2015 5:10 pm
Has thanked: 4 times
Been thanked: 3 times

Re: External ADC & DMA

Post by Skadi »

Hi,

thank you. I will go throug the recomended post.

THX
mobyfab
Posts: 484
Joined: Sat Nov 19, 2011 6:47 pm
Has thanked: 21 times
Been thanked: 31 times

Re: External ADC & DMA

Post by mobyfab »

Something like that (untested)

Code: Select all

#define STM32_TIM_CR2_CCDS                  (1U << 3)

static GPTConfig gptcfg =
{
    200000, /* timer clock.*/
    NULL     /* Timer callback.*/
};

int main(void) {

  uint16_t buffer[] = {0x000C,0x000C,0x000C};

  halInit();
  chSysInit();
 
  gptStart(&GPTD2, &gptcfg);
  GPTD2.tim->CR2 |= STM32_TIM_CR2_CCDS;
  gptStartContinuous(&GPTD2, 25); // dT = 200,000 / 25 = 8,000Hz

  // Allocate the stream
  if (dmaStreamAllocate( STM32_DMA2_STREAM5, 0, NULL, NULL ))
    chSysHalt();

  // Set the source Address
  dmaStreamSetPeripheral( STM32_DMA2_STREAM5, GPIOF->IDR );

  // Set the destination address
  dmaStreamSetMemory0( STM32_DMA2_STREAM5, buffer );

  // set the size of the output buffer
  dmaStreamSetTransactionSize( STM32_DMA2_STREAM5, sizeof(buffer)*sizeof(buffer[0]) );

  // config 16-bit HWORD transfers, peripheral to memory,
  // fixed source address, inc dest address
  dmaStreamSetMode( STM32_DMA2_STREAM5,
                    STM32_DMA_CR_PL(0) | STM32_DMA_CR_PSIZE_HWORD |
                    STM32_DMA_CR_MSIZE_HWORD | STM32_DMA_CR_DIR_P2M |
                    STM32_DMA_CR_MINC | STM32_DMA_CR_CIRC |
                    STM32_DMA_CR_CHSEL(6));

  dmaStreamSetFIFO(STM32_DMA2_STREAM5, 0);
  dmaStreamEnable(STM32_DMA2_STREAM5);

  while (TRUE) {
    chThdSleepMilliseconds(500);
  }
}
User avatar
Giovanni
Site Admin
Posts: 14892
Joined: Wed May 27, 2009 8:48 am
Has thanked: 1202 times
Been thanked: 996 times

Re: External ADC & DMA

Post by Giovanni »

hi,

Having pins on different ports probably make DMA use not possible. You don't have a single "source" location.

Giovanni
mobyfab
Posts: 484
Joined: Sat Nov 19, 2011 6:47 pm
Has thanked: 21 times
Been thanked: 31 times

Re: External ADC & DMA

Post by mobyfab »

Indeed, I missed that.

You need to have them on a single port, or you need more DMA channels (one per port), and some logic to get the proper result. (which defies the use of DMA...)
User avatar
HDKLog
Posts: 45
Joined: Thu Aug 18, 2016 12:36 am
Has thanked: 1 time
Been thanked: 3 times

Re: External ADC & DMA

Post by HDKLog »

Some Parallel to serial converter can help(for ex: 74F676)... or use ADC with Serial output not Parallel.


Regards, Harry.
User avatar
Skadi
Posts: 60
Joined: Fri Apr 17, 2015 5:10 pm
Has thanked: 4 times
Been thanked: 3 times

Re: External ADC & DMA

Post by Skadi »

Hi,

thank you for the replies.

@ HDKLog: a parallel to serial converter isn't an option. The ADC has a sample frequency of 30 MHz ;-).

I'm still confused. Especially how to configure the DMA. As mobyfab has mentioned, I have to check which DMA has access to GPIO. I need access to PORT B and E. But I can't find any listing. I have searched in the reference manual and the datasheet. But I can't find anything which DMA is responible for which PORT. Further the ADC has a data output clock which is connected to GPIOB 5, how can I make use of this clock?

Sorry for my, maybe stupid questions, but I'm really confused by code examples in the web.
User avatar
Giovanni
Site Admin
Posts: 14892
Joined: Wed May 27, 2009 8:48 am
Has thanked: 1202 times
Been thanked: 996 times

Re: External ADC & DMA

Post by Giovanni »

See "2.1 System Architecture" in the RM, there is the diagram with bus masters and slaves.

Giovanni
User avatar
Skadi
Posts: 60
Joined: Fri Apr 17, 2015 5:10 pm
Has thanked: 4 times
Been thanked: 3 times

Re: External ADC & DMA

Post by Skadi »

Hi Giovanni,

thanks for your reply. By having a look at figure 2 (page 62 in the RM) i can see just DMA2 has accsess to the peripherals (GPIO).
Looking at table 43 (page 310 in the RM) there are just TIM1 and TIM8 available for a DMA2 request.

Thus I have to connect my external trigger signal (provided from the ADC) to a PIN which has accsess to TIM1 or TIM8. Because PB15 has just access to TIM12, which can not be used for a DMA2 request (and TIM1_CH1N and TIM8_CH3Nare denote complementary outputs).

Is that correct, or have I still missed something?

BR
Post Reply