Potentiometer Interrupt

Took a look at the code you provided in the previous reply, and tried to implement something.

what I didn't understand is why the DAC stopped operating when an interrupt was fired. I thought that since the DMA was supplying data to the DAC it would function in parallel with other processes. (or have I just missed something coding wise?)

The attach image is a scope shot of what I am referring to (the interrupt runs for the duration of the high pulse).

Is it not possible to simultaneously operate the DAC (with the DMA) and do a separate operation (ex. read an adc channel) within an Interrupt?

volatile uint8_t bufn, Oldbufn, bufn_dac;
const uint16_t bufsize = 128;            
const uint8_t bufnumber = 2;             
const uint8_t _bufnumber = bufnumber - 1;
volatile uint16_t buf[bufnumber][bufsize] = 
                  {
                    {//DATA (included in attachement)},
                     {//DATA (included in attachment)}
                          
                  };




void setup()
{
    
  
    pinMode(13,OUTPUT);                                                                       //DEBUG
    pinMode(12,OUTPUT);                                                                       //DEBUG
    pinMode(10,OUTPUT);                                                                       //DEBUG
    pinMode(9,OUTPUT);                                                                        //DEBUG
    pinMode(8,OUTPUT);                                                                        //DEBUG
    pinMode(7,OUTPUT);                                                                        //DEBUG
    pinMode(4,OUTPUT);                                                                        //DEBUG

   
      pmc_set_writeprotect(false);
      pmc_enable_periph_clk(ID_TC4); 
  
      TC_Configure(TC1, 1, TC_CMR_WAVE | TC_CMR_WAVSEL_UP_RC | TC_CMR_TCCLKS_TIMER_CLOCK2);
      TC_SetRC(TC1, 1, 47250);                                                                     
      TC_Start(TC1, 1);                                                                          //Timer counter started later
  
      TC1->TC_CHANNEL[1].TC_IER=TC_IER_CPCS;                                                      // IER = interrupt enable register
      TC1->TC_CHANNEL[1].TC_IDR=~TC_IER_CPCS;                                                     // IDR = interrupt disable register
  
      NVIC_EnableIRQ(TC4_IRQn);
   
     
      dac_setup();
      adc_setup();
 
}


void loop()
{

  REG_PIOB_SODR |= (0x01 << 27);
  REG_PIOB_CODR |= (0x01 << 27);
}




//************************************Handlers***************************************************\\
//Timer Interupt handler 
void TC4_Handler()
{
   TC1->TC_CHANNEL[1].TC_SR;                                                //check status of interupt
 
   REG_PIOC_SODR |= (0x01 << 22); // Turn on the LED
   for(int i = 0; i < 512; i++)
   {  
       while ((ADC->ADC_ISR & 0x40)== 0){}                                //Wait for end of conversion on channel 6 (or input A1 on arduino due)
      ADC->ADC_CDR[6]; //get data from channel 6 and add it to the total
       

   }
   REG_PIOC_CODR |= (0x01 << 22); // Turn off the LED using the CODR register
           
}

void DACC_Handler() {   // DACC_ISR_HANDLER()         // move Sinus/PDC/DMA pointers to next buffer

  //if ( DACC->DACC_ISR & DACC_ISR_ENDTX) {           // Useless because the only one

  bufn_dac = (bufn_dac + 1) & _bufnumber;
  DACC->DACC_TNPR = (uint32_t)buf[bufn_dac];
  DACC->DACC_TNCR = bufsize;
  
  
}


//************************************SETUP FUNCTIONS***************************************************\\
void adc_setup()
{
   //ADC
   pmc_enable_periph_clk(ID_ADC);                                                             // To use peripheral, we must enable clock distributon to it
   adc_init(ADC, SystemCoreClock, ADC_FREQ_MAX, ADC_STARTUP_FAST);                            // initialize, set maximum posibble speed
   adc_disable_interrupt(ADC, 0xFFFFFFFF);
   adc_set_resolution(ADC, ADC_12_BITS);
   adc_configure_power_save(ADC, 0, 0);                                                      // Disable sleep
   adc_configure_timing(ADC, 0, ADC_SETTLING_TIME_3, 1); // Set timings - standard values
   adc_set_bias_current(ADC, 1);                                                             // Bias current - maximum performance over current consumption
   adc_stop_sequencer(ADC);                                                                  // not using it
   adc_disable_tag(ADC);                                                                     // it has to do with sequencer, not using it
   adc_disable_ts(ADC);                                                                      // disable temperature sensor
   adc_disable_channel_differential_input(ADC, ADC_CHANNEL_6);  
   adc_configure_trigger(ADC, ADC_TRIG_SW, 1);                                               // triggering from software, freerunning mode
   adc_disable_all_channel(ADC);  
   adc_enable_channel(ADC, ADC_CHANNEL_6);                                                   // one channel enabled (pin A1 on arduino due)
     
}


void dac_setup()
{
   pmc_enable_periph_clk(DACC_INTERFACE_ID);            // start clocking DAC
   DACC->DACC_CR = DACC_CR_SWRST;                       // reset DAC

   DACC->DACC_MR =  DACC_MR_TRGEN_DIS;  
   DACC->DACC_MR = (1 << DACC_MR_USER_SEL_Pos);         // select channel 1
    
   DACC->DACC_IDR = 0xFFFFFFFF;                         // no interrupts
   //DACC->DACC_CHER = DACC_CHER_CH0 << 0;               // enable chan0
   DACC->DACC_CHER = DACC_CHER_CH1 << 0;                // enable chan1

   DACC->DACC_IDR = ~DACC_IDR_ENDTX;
   DACC->DACC_IER = DACC_IER_ENDTX;                    // TXBUFE works too !!!
   //NVIC_SetPriority(DACC_IRQn, 0xFF);
   NVIC_EnableIRQ(DACC_IRQn);
   DACC->DACC_CHER = DACC_CHER_CH0 | DACC_CHER_CH1;    // enable channels 1 = DAC1 and 0 = DAC0
   

  /*************   configure PDC/DMA  for DAC *******************/
  DACC->DACC_TPR  = (uint32_t)buf[0];                 // DMA buffer
  DACC->DACC_TCR  = bufsize;
  DACC->DACC_TNPR = (uint32_t)buf[1];                 // next DMA buffer
  DACC->DACC_TNCR =  bufsize;
  bufn_dac = 1;
  DACC->DACC_PTCR = DACC_PTCR_TXTEN;                  // Enable PDC Transmit channel request
}
//END SETUP FUNCTIONS

Apologizes for having to attach the full code separately...I exceed 9000 characters.

EDIT: After further looking at the code I think I understand what is going on...Correct me if I am wrong, but the DAC keeps operating until it has reached the end of the buffer (regardless of if an interrupt has fired or not), however, if an interrupt has fired and the end of the buffer is reached during the interrupt, the system must wait till the interrupt finishes before sending the address of the next buffer. (and hence the DAC outputs nothing during that time).

Is it possible to code this in such a way where the DMA is always supplied with the next buffer address? (a way that could perhaps be coded once in the setup?)

DMADAC.ino (8.09 KB)