External ADC & DMA

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

Moderators: barthess, RoccoMarco

User avatar
Giovanni
Site Admin
Posts: 13074
Joined: Wed May 27, 2009 8:48 am
Location: Salerno, Italy
Has thanked: 758 times
Been thanked: 637 times
Contact:

Re: External ADC & DMA

Postby Giovanni » Mon Feb 06, 2017 3:30 pm

It looks that way.

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

Postby Skadi » Mon Feb 06, 2017 5:26 pm

So, I changed the input capture pin to PA9 which has access to TIM1_CH2.

I configured the timer 1 input capture as follow:

Code: Select all

// CC1 channel is configured as input, IC1 is mapped on TI2
GPTD1.tim->CCMR1 |= STM32_TIM_CCMR1_CC1S(1);   

// ADC Latch data on the falling edge of CLKOUT
GPTD1.tim->CCER |= STM32_TIM_CCER_CC1P;        // CC1NP reset value is 0 -> falling edge (CC1NP/CC1P = b01)

// CC1 DMA request enabled
GPTD1.tim->DIER |= STM32_TIM_DIER_CC1DE;

// Capture enabled       
GPTD1.tim->CCER |= STM32_TIM_CCER_CC1E;



The DMA - code is based on mobyfab's example code.

Code: Select all

 
 
 uint16_t buffer[100];

  // Allocate the stream (TIM1_CH2 --> Stream 6)
  dmaStreamAllocate( STM32_DMA2_STREAM6, 0, NULL, NULL );      

  // Set the source Address
  dmaStreamSetPeripheral( STM32_DMA2_STREAM6, GPIOB->IDR );

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

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

  // config 16-bit HWORD transfers, peripheral to memory,
  // fixed source address, inc dest address
  // channel 0 is used, TIM1_CH2 @ Stream 6
  dmaStreamSetMode( STM32_DMA2_STREAM6,
                    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(0));

  dmaStreamSetFIFO(STM32_DMA2_STREAM6, 0);

  dmaStreamEnable(STM32_DMA2_STREAM6);



I attached a sine wave to the ADC input and checked the sign bit, which should consists of the same amount of 1 and 0 (for positive and negative half-cycle) but that's not the case.

Do I still forget something?

BR

User avatar
Giovanni
Site Admin
Posts: 13074
Joined: Wed May 27, 2009 8:48 am
Location: Salerno, Italy
Has thanked: 758 times
Been thanked: 637 times
Contact:

Re: External ADC & DMA

Postby Giovanni » Mon Feb 06, 2017 7:08 pm

You need to pass the address of IDR not the value, there could be other errors.

First verify if the timer is working as expected, I don't see it but I imagine you enabled its clock, you are the one with the debugger :)

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

Postby Skadi » Tue Feb 07, 2017 6:19 pm

Hi Giovanni,

I passed the address of IDR.

Code: Select all

 dmaStreamSetPeripheral( STM32_DMA2_STREAM6, &GPIOB->IDR);


I'm still struggling to set up the DMA. Maybe the timer is not working as you indicated.

Giovanni wrote:First verify if the timer is working as expected, I don't see it but I imagine you enabled its clock, you are the one with the debugger :)


I'm not able to attach a debugger. The controller is programmed by SWD. In mcuconf.h, #define STM32_GPT_USE_TIM1 is set TRUE and I also set HAL_USE_GPT TRUE in halconf.h, if that is meant by enabling the clock.

I havn't used gptStart(&GPTD1, &gptcfg); because &gptcfg sets/needs a certain frequency. The timer frequency should be the external clock provided by the ADC. But maybe I'm completely wrong :oops:

User avatar
Giovanni
Site Admin
Posts: 13074
Joined: Wed May 27, 2009 8:48 am
Location: Salerno, Italy
Has thanked: 758 times
Been thanked: 637 times
Contact:

Re: External ADC & DMA

Postby Giovanni » Tue Feb 07, 2017 6:58 pm

Hi,

If you don't start GPT then the clock is not enabled, those macros just enable timers for GPT use.

You need to use the macros in stm32_rcc.h in order to manage peripheral clocks.

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

Postby Skadi » Tue Feb 07, 2017 8:01 pm

Hi Giovanni,

thank you for your fast reply. I will have a look at stm32_rcc.h :D. Is there a possebility to check if my TIMER is set correct without a debugger e.g. by toggle a pad?

BR

User avatar
Giovanni
Site Admin
Posts: 13074
Joined: Wed May 27, 2009 8:48 am
Location: Salerno, Italy
Has thanked: 758 times
Been thanked: 637 times
Contact:

Re: External ADC & DMA

Postby Giovanni » Tue Feb 07, 2017 10:23 pm

You could program it to toggle an output like the PWM driver does.

Giovanni

mobyfab
Posts: 452
Joined: Sat Nov 19, 2011 6:47 pm
Location: Versailles, France
Has thanked: 12 times
Been thanked: 18 times

Re: External ADC & DMA

Postby mobyfab » Wed Feb 08, 2017 11:56 am


thor.thau
Posts: 17
Joined: Thu Jul 07, 2016 12:37 pm
Has thanked: 2 times
Been thanked: 7 times

Re: External ADC & DMA

Postby thor.thau » Wed Feb 08, 2017 4:41 pm

Skadi wrote:I'm not able to attach a debugger. The controller is programmed by SWD.


It is possible to debug through the microcontrollers SWD interface. I am using ST Link V2 and J-Link EDU debuggers. There are lots of explanations available on the internet for connecting a debugger JTAG interface to a board and microcontroller with a SWD interface.
Thor Thau
Embedded software developer

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

Postby Skadi » Thu Feb 09, 2017 8:45 pm

Hi,

at first , thank you for the replies.

@ thor.thau: yes, it seems it should be possible to debug via a SWD interface. I'm using ST Link V2 in combination with ChibiStudio. I'm able to establish an GBD server connection. But if it comes to run the controller in debug mode (via ChibiStudio) differnt kinds of failures pop up. I configured the debugger according to Link.

@ mobyfab: Thanks for the link. I already had a look on it, and the example for the STM32F429 - RECEPTION is almost the same I'm dealing with. I had a look on the associated example files provided by ST. A part of the code is added below:

Code: Select all

  /* Initialize Timer for Reset mode (reset and starts the counter) */
  sSlaveConfig.SlaveMode      = TIM_SLAVEMODE_TRIGGER;
  sSlaveConfig.InputTrigger    = TIMx_TS_TIxFPx;
  sSlaveConfig.TriggerPolarity   = TIM_TRIGGERPOLARITY_FALLING;
  sSlaveConfig.TriggerPrescaler  = TIM_TRIGGERPRESCALER_DIV1;
  sSlaveConfig.TriggerFilter    = TIM_TRIG_FILTER;


I'm already confused by the comment "Initialize Timer for Reset mode" and the chosen slave moder "TIM_SLAVEMODE_TRIGGER".
By set the reset mode SMS in register SMCR would set to 100 and is sensitive to a rising edge, so it seems to me, the configured trigger polarity (two lines below) has no effect. Thus I used SMS = 110, the trigger mode (i tried both without success).

I ended up with the following configurations.

Code: Select all

     
     // TIM1_CH2
     palSetPadMode(GPIOA, 9, PAL_MODE_ALTERNATE(1));

     // enable TIMER1 clock
     RCC->APB2ENR |= RCC_APB2ENR_TIM1EN;

     // enable  DMA2 clock
     RCC->AHB1ENR |= RCC_AHB1ENR_DMA2EN;

     // 8 (ETP): External trigger polarity -> Falling Edge
     // 6  (TS): Trigger selection: Input 2 (TI2FP2)
     // 6 (SMS): Trigger Mode
     TIM1->SMCR |= 0x8066;

     // CC1 is mapped on TI2 -> input capture
     TIM1->CCMR1 |= 0x0002;

     // Polarity: falling edge
     TIM1->CCER |= STM32_TIM_CCER_CC1P;

     // CC1 capture enabled
     TIM1->CCER |= STM32_TIM_CCER_CC1E;

     // CC1 DMA request enabled
     TIM1->DIER |= STM32_TIM_DIER_CC1DE;


I changed the DMA stream by means of using Stream 2 Channel 6. Further I pass the address of the first memory element, because the destination address is incremented by the DMA.

Code: Select all

  uint16_t buffer[100];

  // Allocate the stream
  dmaStreamAllocate( STM32_DMA2_STREAM2, 0, NULL, NULL );

  // Set the source Address
  dmaStreamSetPeripheral( STM32_DMA2_STREAM2, (uint16_t *)&(GPIOB->IDR));

  // Set the destination address
  dmaStreamSetMemory0( STM32_DMA2_STREAM2, (uint16_t *)&(buffer[0]));

  // set the size of the output buffer
  dmaStreamSetTransactionSize( STM32_DMA2_STREAM2, sizeof(buffer) );

  // config 16-bit HWORD transfers, peripheral to memory,
  // fixed source address, inc dest address
  dmaStreamSetMode( STM32_DMA2_STREAM2,
                    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_STREAM2, 0);

  dmaStreamEnable(STM32_DMA2_STREAM2);
  dmaWaitCompletion(STM32_DMA2_STREAM2);

  dmaStreamDisable(STM32_DMA2_STREAM2);
  dmaStreamRelease(STM32_DMA2_STREAM2);
 
  // --> Transfer to computer
 


Unfortunatly I'm not able to figure out where I made an error (propably errors :? ). I will try to get the debugger working. Maybe somone spot an obvious mistake in the meanwhile... :oops: :oops:

Thx and BR


Return to “STM32 Support”

Who is online

Users browsing this forum: No registered users and 10 guests