How to set up the DAC on arduino due for external triggering (DATRG)

Hi there,

I am using an arduino DUE, and I would like to "Arm" its DAC using a hardware trigger. My use case would be that the arduino receives a trigger from a clock which runs the rest of the setup. As soon as it receives it, it changes the output voltage of the DAC according to some precalculated value. The clock has a period of 9 us, so we have some time to waste, but not that much time.

The most simple way would be to connect an interrupt to a trigger input pin, and then change the output, but that leads to quite some jitter on the output port, so I hope that setting up the hardware properly will make it more stable.

The datasheet seems to suggest that it may be possible to use an external trigger (https://ww1.microchip.com/downloads/en/DeviceDoc/Atmel-11057-32-bit-Cortex-M3-Microcontroller-SAM3X-SAM3A_Datasheet.pdf, page 5)

According to the pinout, the DA trigger it should be accessible under pin D19 (https://docs.arduino.cc/resources/pinouts/A000056-full-pinout.pdf, in the "advanced" section, page 5)

I am guessing it would be a small adoption from this code, (thank you @anatolyk69_gmail.c ), but I don't understand what to change here:

void TC_setup ()
{
  pmc_enable_periph_clk(TC_INTERFACE_ID + 0 *3 + 0); 

  TcChannel * t = &(TC0->TC_CHANNEL)[0];            
  t->TC_CCR = TC_CCR_CLKDIS;                        
  t->TC_IDR = 0xFFFFFFFF;                           
  t->TC_SR;                                         
  t->TC_CMR = TC_CMR_TCCLKS_TIMER_CLOCK1 |          
              TC_CMR_WAVE |                         
              TC_CMR_WAVSEL_UP_RC |                 
              TC_CMR_EEVT_XC0 |     
              TC_CMR_ACPA_CLEAR | TC_CMR_ACPC_CLEAR |
              TC_CMR_BCPB_CLEAR | TC_CMR_BCPC_CLEAR;
  
  t->TC_RC = freq_intc;
  t->TC_RA = freq_intc /2;       
  t->TC_CMR = (t->TC_CMR & 0xFFF0FFFF) | TC_CMR_ACPA_CLEAR | TC_CMR_ACPC_SET; 
  t->TC_CCR = TC_CCR_CLKEN | TC_CCR_SWTRG;    
}

void dac_setup ()
{
  pmc_enable_periph_clk (DACC_INTERFACE_ID) ; // start clocking DAC
  dacc_reset(DACC);
  dacc_set_transfer_mode(DACC, 0);
  dacc_set_power_save(DACC, 0, 0);
  dacc_set_trigger(DACC, 1); /* PROBABLY HERE, but what should I do? */
  dacc_set_channel_selection(DACC, 1);
  dacc_enable_channel(DACC, 1);
  dacc_set_analog_control(DACC, DACC_ACR_IBCTLCH0(0x02) | DACC_ACR_IBCTLCH1(0x02) | DACC_ACR_IBCTLDACCORE(0x01));

  NVIC_DisableIRQ(DACC_IRQn);
  NVIC_ClearPendingIRQ(DACC_IRQn);
}

Would anyone be able to point out how do do this?

If it's unclear what I would like to do, I can also make a small sketch.

kind regards,

Dirk

Hello, @dirkboon

To "arm" the DAC on your Arduino Due using a hardware trigger, follow these steps:

Set up the Timer/Counter (TC) to generate the trigger:

void TC_setup ()
{
  pmc_enable_periph_clk(TC_INTERFACE_ID + 0 * 3 + 0); 
  TcChannel * t = &(TC0->TC_CHANNEL)[0];            
  t->TC_CCR = TC_CCR_CLKDIS;                        
  t->TC_IDR = 0xFFFFFFFF;                           
  t->TC_SR;                                         
  t->TC_CMR = TC_CMR_TCCLKS_TIMER_CLOCK1 |          
              TC_CMR_WAVE |                         
              TC_CMR_WAVSEL_UP_RC |                 
              TC_CMR_EEVT_XC0 |     
              TC_CMR_ACPA_CLEAR | TC_CMR_ACPC_CLEAR |
              TC_CMR_BCPB_CLEAR | TC_CMR_BCPC_CLEAR;
  t->TC_RC = 10000;   // Adjust frequency as needed
  t->TC_RA = 5000;    // Adjust to half period
  t->TC_CCR = TC_CCR_CLKEN | TC_CCR_SWTRG;
}

Configure the DAC to use the external trigger:

void dac_setup ()
{
  pmc_enable_periph_clk(DACC_INTERFACE_ID);
  dacc_reset(DACC);
  dacc_set_transfer_mode(DACC, 0);
  dacc_set_power_save(DACC, 0, 0);
  dacc_set_trigger(DACC, 1); // Enable hardware trigger
  DACC->DACC_MR |= DACC_MR_TRGEN_EN | DACC_MR_TRGSEL(0); // Use TIOA0 as trigger
  dacc_set_channel_selection(DACC, 1);
  dacc_enable_channel(DACC, 1);
  dacc_set_analog_control(DACC, DACC_ACR_IBCTLCH0(0x02) | DACC_ACR_IBCTLCH1(0x02) | DACC_ACR_IBCTLDACCORE(0x01));
}

This sets up TC0 to generate a trigger signal and configures the DAC to respond to this trigger, allowing it to change the output voltage based on the external clock signal.

Best Regard,
florence023

Hi Florence023,

Thank you very much for the code! But if I understand correctly what you do, you generate a trigger on the arduino itself, right? In this line:

DACC->DACC_MR |= DACC_MR_TRGEN_EN | DACC_MR_TRGSEL(0); // Use TIOA0 as trigger

In my case, it's a true external trigger, as in one that is generated by a signal generator. So it's probably even easier to do, right? But what would the command be here?

In case anyone is wondering, I found out that it's relatively simple. The commands can be found here.

To configure the DAC to listen to a hardware trigger (on pin 19), just use:

 dacc_set_trigger(DACC_INTERFACE, 0);

To configure it to output immediately, just use

  dacc_disable_trigger(DACC_INTERFACE);

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