AnsweredAssumed Answered

ADC -> DMA with no libraries

Question asked by novak.matej on Dec 6, 2011
Latest reply on Dec 6, 2011 by novak.matej
Hi,

I'm trying to implement a sensor network. I know that I must use DMA to be able to work with multiple ADC channels. Since this is a school assignment, I'm not allowed to use any libraries.
For some reason I'm only able to read the first channel. The second one is constant zero. How do I even define that the ADC channel 3 is supposed to go to DMA channel 2 ?

Here's a snippet of my code:
[CODE]

int32_t temperature;  //globals
uint32_t degree;

void ADC_Configuration(void){

RCC->APB2RSTR |= ADC_RESET;        //reset
RCC->APB2RSTR &= ~ADC_RESET;    //cancel reset

ADC1->CR2       |= ADC_SWSTART;     //set start by SW
ADC1->SMPR1   |= ADC_SMP_16;    //sample 28.5 on channel 16
ADC1->SMPR2   |= ADC_SMP_3;        //sample 7.5 on channel 3
ADC1->SQR3      |= ADC_SQR;          //channel 16 first, channel 3 second
ADC1->CR2      |= ADC_CALIB_RST;    //reset calib,  ADON - start

ADC1->CR2      |= ADC_DMA_EN;    //DMA

while (ADC1->CR2 & 0x8);         //wait for ADC to reset calibration

ADC1->CR2      |= ADC_START_CALIB; //start calibration

while (ADC1->CR2 & ADC_START_CALIB); //wait for ADC to start calibration

ADC1->CR2      |= ADC_TSVREFE;  //TSVREFE, ADON start
//jeste treba udelat DMA
}

/*----------------------------------------------------------------------------
  DMA Configuration
 *----------------------------------------------------------------------------*/
void DMA_Configuration(void){

DMA1_Channel1->CPAR = (uint32_t)&(ADC1->DR);
DMA1_Channel1->CMAR = (uint32_t)&temperature;
DMA1_Channel1->CNDTR = 0x1;
DMA1_Channel1->CCR = 0x1A20;
DMA1_Channel1->CCR |= 0x1;

DMA1_Channel2->CPAR = (uint32_t)&(ADC1->DR);
DMA1_Channel2->CMAR = (uint32_t)&degree;
DMA1_Channel2->CNDTR = 0x1;
DMA1_Channel2->CCR = 0x1A20;
DMA1_Channel2->CCR |= 0x1;

}

int32_t ReadTemp(void){
     int32_t temp;
    uint32_t deg;
    int32_t v25 = 1738;
    int32_t avg_slope = 56;
    int32_t constant = 250000;
    int32_t magnify = 10000;


    //temp = (int32_t) degree;
    temp = (int32_t) temperature;  // THIS ONE WORKS, BUT IF I CHANGE IT TO DEGREE, IT BECOMES CONSTANTS ZERO
    if (temp == v25) return constant;

        temp = v25 - temp;
        temp = temp*magnify;
        temp =temp/avg_slope;
        temp = temp + constant;
        return temp;
}

int main (void) {

  int32_t    temper;
  float value;
    
  RCC_Configuration(); //note that I do send clk to ADC and DMA
  GPIO_Configuration();
  USART_Configuration();
  buffer_Init();                                  // init RX / TX buffers
  DMA_Configuration();
  ADC_Configuration();
 

  ADC1->CR2      |= ADC_SWST_EXTTRIG;                               
  temper = ReadTemp();                                 //clear the first measurement, which is always a bit off

  while (1) {                                     // Loop forever
    char string[7];    
        
    Delay(4000);
    ADC1->CR2      |= ADC_SWST_EXTTRIG;
      

    temper = ReadTemp();
    ADC1->CR2      |= 0x1;
    value = (float)temper;
    value = value/10000;

    snprintf(string, SIZE, "%f", value);
    SendString(string);
    SendChar(0xD);
    SendChar(0xA);

    Delay(4000);

    
  }
}

[/CODE]

Any help would be appreciated.

Outcomes