Page 3 of 4

Re: External ADC & DMA

Posted: Fri Feb 10, 2017 11:31 am
by Skadi
Hi,

at least I managed to run the debug mode successfully. To be hornest, which ChibiStudio it is pretty simple, as long you know which cfg file you have to use :D.

So I will try to figure out why the DMA doesn't work ;) .

BR

Re: External ADC & DMA

Posted: Fri Feb 10, 2017 2:33 pm
by Giovanni
I suggest to examine the TIM and DMA registers and verify that the state is what you expect.

Giovanni

Re: External ADC & DMA

Posted: Fri Feb 17, 2017 2:59 pm
by Skadi
Hi,

I still have problems to get the DMA working.

With the debugger I was able to chek if the timer is running, and it is.

- TIM1EN in RCC_APB2ENR is set
- DMA2EN in RCC_AHB1ENR is set
- CEN in TIM1_CR1 is set

I also enabled the DMA interrupts, Transfer complete interrupt, Half transfer interrupt enable and Transfer error interrupt. None of this interrupts is set high during operation.

By having a look on the number of data items to be transferred in register DMA_S2NDTR the amount is just decreased by 1. Althoug I use dmaWaitCompletion(STM32_DMA2_STREAM2), which should wait until the number of date to transfere (NDT) should be zero, no waiting/decrementation of NDT is performed.

Here is the code for the timer configuration.

Code: Select all

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

     rccEnableTIM1(FALSE);
     rccResetTIM1();

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

     // 6  (TS): Trigger selection: Input 2 (TI2FP2)
     // 4 (SMS): Reset Mode
     TIM1->SMCR |= 0x0064;

     // CC2 is mapped on TI2 -> input capture
     TIM1->CCMR1 |= 0x0100;

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

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

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

     TIM1->CR2 |= STM32_TIM_CR2_CCDS;

     // Enable Counter
     TIM1->CR1 |= STM32_TIM_CR1_CEN;



And that's the code for 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, &GPIOB->IDR);

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

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


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

  dmaStreamSetFIFO(STM32_DMA2_STREAM2, 0);
  dmaStreamEnable(STM32_DMA2_STREAM2);

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


Maybe someone can help me.

BR

Re: External ADC & DMA

Posted: Tue Feb 21, 2017 5:22 pm
by Skadi
Hi guys,

the last days I spent quite a lot of hours to fix the DMA. Now it seems to work :P ! To relax the timing issues I temporarily use a ADC - clock frequency of 5 MHz.

Currently I just checked the sign bit of the ADC sampling a sinusodial input signal. Here is a picture of the sign bit data flow: Sign Bit


Also a screenshot of the received data. The sign bit is red framed. Received


To fix the DMA I had to disable the Circular mode, which was enabled. By not using the Circular mode, the DMA is disabled when the data items to be transferred in register DMA_SxNDTR are zero.

But more important is to use allocate aligned memory. Therfore I used the following lines.

Code: Select all

uint16_t samples = 100;

 static struct memory_heap *dma_heap;
  static uint16_t *buffer;

  chHeapObjectInit(dma_heap, (void*)0x20000000, 0x7D0);

  buffer =  chHeapAlloc(dma_heap, 2*samples);

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

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

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

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



The only thing I do not really know if the memory allocation is correct. The memory heap is initilized at the start address of the SRAM - Block 1. The heap size is 2000 (0x7D0). Afterwards I allocate a a heap block of 200 (2*samples). But when I'm looking at the memory address (DMA2_S2M0AR) the address is larger than 0x2000 07D0. The memory 0 address is 0x2000 8288.

So it looks something went wrong at my memory allocation :? . But at least I can say the timer works. And I hope soon the DMA too :D .

Re: External ADC & DMA

Posted: Tue Feb 21, 2017 5:34 pm
by Giovanni
Hi,

Is the heap object initialized?

Giovanni

Re: External ADC & DMA

Posted: Tue Feb 21, 2017 5:45 pm
by Skadi
Hi Giovanni,

I added the following line after the initialization (chHeapObjectInit).

Code: Select all

 if (dma_heap == NULL) {
    palSetPad(GPIOB, 6);
    }


PB6 is connected to a LED. The LED is illuminated, so it seems the heap object is not initialized. Have I forgot any command to perform a successful initialization? Or is the use of the address prohibited (which makes no sense in my opinion)?

Re: External ADC & DMA

Posted: Tue Feb 21, 2017 5:47 pm
by Giovanni
You are passing a pointer to nothing to the function, correct it as follow:

Code: Select all

  static struct memory_heap dma_heap;
  chHeapObjectInit(&dma_heap, (void*)0x20000000, 0x7D0);


Giovanni

Re: External ADC & DMA

Posted: Tue Feb 21, 2017 6:26 pm
by Skadi
Thank you Giovanni!

Now it looks good. The memory 0 address is now 0x2000 0008.

Just a comprehension question, for me it looks like the SRAM is accessed as bytes. Because the memory 0 address starts at 0x2000 0008 and not at a multiple of 16 (0xF). Or are 8 bit just an offset of the start address?

BR

Re: External ADC & DMA

Posted: Wed Feb 22, 2017 11:30 am
by rew
Skadi wrote:Just a comprehension question, for me it looks like the SRAM is accessed as bytes. Because the memory 0 address starts at 0x2000 0008 and not at a multiple of 16 (0xF). Or are 8 bit just an offset of the start address?

You are mixing bytes, bits and different numbers. 16 is not 0xf, but 0x10. you say "8 bit" when you mean "8 bytes", I think.

You have initialized a heap objecct at 0x2000 0000. That requires a bit of accounting that goes at 0x2000 0000 - 0x2000 0007. The first allocation gives 0x2000 0008.

Re: External ADC & DMA

Posted: Wed Feb 22, 2017 12:27 pm
by Skadi
rew wrote:You are mixing bytes, bits and different numbers. 16 is not 0xf, but 0x10. you say "8 bit" when you mean "8 bytes", I think.


Hi, you are right. What I have meant was 15 -> 0xF. And also those "8 bit" (0x2000 0008) is just a nibble (4 bits).

rew wrote:That requires a bit of accounting that goes at 0x2000 0000 - 0x2000 0007.


Thank you, that was the answer I wanted to hear ;) .