Arduino Due ADC triggered by PWM

I want to sample the ADC at somewhere between the PWM channel's top and bottom points of its sawtooth waveform for left aligned PWM. The output of the ADC goes to DAC0 on the Due. I have tried to implement this but I don't get any DAC output at all. I did include a 4kOhm resistor in series with the DAC pin.

Also I am using PWMH2 and PWML2 for PWM waves in sync with my PWML4 which is the channel set up in PWM_clockinit();. That part is working fine, so I have not included that bit of the code. This should be a minimal working example.

void setup () {
    PWM_clockinit();
  pwmc_setup();
  adc_setup();
  dac_setup();
}

void dac_setup(){
  PMC->PMC_PCER1 = PMC_PCER1_PID38; // DACC power on
  DACC->DACC_CR = DACC_CR_SWRST;   // Reset DACC
  DACC->DACC_MR = DACC_MR_TRGEN_DIS             //Free run mode
                  | DACC_MR_USER_SEL_CHANNEL0  //selecting DAC0
                  | DACC_MR_STARTUP_8
                  | DACC_MR_MAXS
                  | DACC_MR_REFRESH(1);

  DACC->DACC_IER |= DACC_IER_EOC;
  NVIC_EnableIRQ(DACC_IRQn);         
  DACC->DACC_CHER = DACC_CHER_CH0;   //enable DAC0 (i.e, channel0)
                  
}

void adc_setup(){
   PMC->PMC_PCER1 |= PMC_PCER1_PID37;      // ADC power on
   ADC->ADC_CR = ADC_CR_SWRST;            // Reset ADC
   ADC->ADC_MR |= ADC_MR_TRGEN_EN | ADC_MR_TRGSEL_ADC_TRIG5; 
    //Select hardware trigger and trigger by PWM event line 1

    // Next two lines are concerned with the output of the ADC and subsequent triggers
    ADC->ADC_IER = ADC_IER_EOC7; //Pin A0 = AD7 so channel 7 of the ADC
    NVIC_EnableIRQ(ADC_IRQn); //Enables the ADC interrupt
    ADC->ADC_CHER = ADC_CHER_CH7; //Enable Channel 7 on A0  
       
}

// Under the ADC handler we will include the direct bit manipulated write operation as a status to ensure ADC is being called at the right time
void ADC_Handler()   
{
  if(ADC->ADC_ISR & ADC_ISR_EOC7){  //if data is ready
    PIOC->PIO_CODR = 1 << 1; //Low at pin 33 at the bottom of Due
    result = ADC->ADC_CDR[7]; //store it inside this variable
    result = map(result, 0, 4095, 0, 255); //Map from 12 bits to 8 bits
    analogWrite(DAC0, result); //output at DAC0
  }
}

// Big clock is being used to find the instants to trigger the ADC on PWM event line 1
void PWM_clockinit() {
  // PWM Set-up on pins PC21 (PWML4 = D9)
  PMC->PMC_PCER1 |= PMC_PCER1_PID36;                   // PWM power ON
  PWM->PWM_DIS = PWM_DIS_CHID4;                        // Disable PWM channel 4

  // Select Instance=PWM; Signal=PWML4 (channel 4); I/O Line=PC21; Peripheral type B
  PIOC->PIO_PDR |= PIO_PDR_P21;                          // Set the pin to the peripheral PWM, not the GPIO
  PIOC->PIO_ABSR |= PIO_PC21B_PWML4;                     // Set PWM pin perhipheral type B

  PWM->PWM_CLK = PWM_CLK_PREA(0) | PWM_CLK_DIVA(7);   // Set the PWM clock rate to 2MHz (84MHz/42) (?)
  PWM->PWM_CH_NUM[4].PWM_CMR = PWM_CMR_CPRE_CLKA;       // clock source as CLKA on channel 2
                              
                               
  PWM->PWM_CH_NUM[4].PWM_CPRD = 500;                   // Channel 2 : Set the PWM frequency 2MHz/(2* CPRD) = F ;
  PWM->PWM_CH_NUM[4].PWM_CDTY = 250;                    // Channel 2: Set the PWM duty cycle to x%= (CDTY/ CPRD)  * 100 % 

  PWM->PWM_CMP[4].PWM_CMPV = PWM_CMPV_CV(1500); //The value to be compared with the counter of channel 4 (val btwn 1 - PWM_CPRD)
  PWM->PWM_CMP[4].PWM_CMPM = PWM_CMPM_CEN;      // ENable comparison
  PWM->PWM_ELMR[1] = PWM_ELMR_CSEL4; //Event line triggering per CMPV value of channel 4 (thus CSEL 4)
  

  PWM->PWM_IER1 = PWM_IER1_CHID4;                      // Interrupt on end of counter period (2*CPRD)
  NVIC_EnableIRQ(PWM_IRQn);                            // Enable PWM interrupt

  PWM->PWM_ENA = PWM_ENA_CHID4;                        // Enable PWM Channel 4
}

void PWM_Handler() {
  PWM->PWM_ISR1;      // Clear status register
  
  if (State == Idle) {
      PIOC->PIO_SODR = 1 << 24; // Business monitor set
      digitalWrite(BM,HIGH);
      PIOC -> PIO_CODR = 1 << 13; //R1  RED ON
      PIOC -> PIO_SODR = 1 << 12; //G1  GREEN OFF
      PIOB -> PIO_CODR = 1 << 14; //B1  BLUE OFF
    PWM->PWM_CH_NUM[2].PWM_CDTY = 500;  //100% duty cycle  
      PIOC -> PIO_CODR = 1 << 24;   //Business monitor low
     
    }
  
   if (State == Run) {
      PIOC->PIO_SODR = 1 << 24; // Business monitor set
      PIOC -> PIO_CODR = 1 << 14; //R1 RED OFF
      PIOC -> PIO_SODR = 1 << 13; //G1  GREEN ON
      PIOB -> PIO_CODR = 1 << 14; //B1  BLUE OFF
      PWM->PWM_CH_NUM[2].PWM_CDTY = 100; //1/3rd duty cycle
      PIOC -> PIO_CODR = 1 << 24;
  }
 
}

void loop(){}

Can someone say where I'm going wrong?

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.