SAMD51 - DAC operation

Go To Last Post
11 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi all.

 

 

Could anyone refer me any DAC example projects or implementation for DAC operation in SAMD51.

 

Because i could find example code for ADC but there is no  reference for DAC ,except atmel start DAC example .

 

Kindly help me with your inputs.

 

 

Regards

Karthi

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Are you saying the atmel start DAC example is not working or?

I tried just adding the sync DAC driver and clock setup for 12MHz, (and 120MHz for GCLK0) in a project for ATSAMD51J19, it works ok.

This is with external voltage reference on PA03 and the clock is using external 32K crystal (both ok by default on the Adafruit Metro M4 express).

 

/Lars

 

Attachment(s): 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi ,

 

We have added async DAC , and DAC clock setup for 12 Mhz, 40 Mhz for   GCLK0 , and the clock is using internal 32K crystal oscillator.

 

We have tried the example code (EXAMPLE_DA.zip),we couldn't get any output waveform.

 

And we have tried our own basic code (BASIC_DA.zip),We read the voltage in  VOUT0 , But there is no response.

 

Here we have attached our code.Kindly check and provide your input.

Attachment(s): 

Karthi

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The DAC uses the Start Conversion event to load data from DATABUF into DATA and start a new conversion. In the SAM D21 case, dac_async_write will write data to the DATABUF register, so the Start Conversion event should be configured properly to use this asynchronous driver.

Looks like the D51 async driver also depends on event control for the DAC. You have configured event input for start conversion but there is no event. If you want to try this without event control then change here

void _dac_async_write_data(struct _dac_async_device *const device, const uint16_t data, const uint8_t ch)
{
    hri_dac_write_DATA_reg(device->hw, ch, data);
}

i.e., this function normally writes to DATABUF, by writing to DATA it can work without input event.
Note to change also the START config, i.e., make sure the DAC "Start Conversion Event Input DAC 0" is not selected.

Also move  the 

dac_async_write(&DAC_0, 0, example_DAC_0, 10);

out of the while loop in main (i.e., do it once, it's done from the callback after that).

BTW, when I try this (Samd51j18a_firmware_Example_DA.zip  modified as mentioned) there is also something not optimal with (maybe) the clock setup, it takes 2 - 15 seconds from reset until there is a signal on VOUT0.
/Lars

 

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

 

Hi thanks for your input,

 

We have have changed the DAC configuration from async to sync.

And we have set the refresh period as 0x2.

 

Now we are able to generate static output voltage using our DAC. But we have observed some issues while testing following cases. 

(CH0 - channel 0 , CH1 - channel 1) 

1. Writing 0 to CH0, 4095 to CH1 

=> VOUT1 =3.3v But VOUT0 is gradually increasing from 0V to 2.2V. 

 

2. Writing 0 to CH0, 0 to CH1 

=> VOUT1 =0v But VOUT0 is gradually increasing from 0V to 2.2V. 

 

3. if VOUT1 is 3.3v, when we write 0 to channel 0, VOUT1 is gradually decreasing to 0. 

If we are writing values in one channel its affecting other channel also. We couldn't find the reason for this issue. 

 

could you please help us on this?

Karthi

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi Karthika,

 

i have some similar problem getting the DAC on the SAMD51 working.

I have the decreasing and increasing, too.

If i am in debugging mode on an breakpoint, both channels working correct.

If i let the code run, both channels output voltages increase or decrease.

 

I read every datasheet page three times and absolutely dont know whats going on.

 

Karthika venkat wrote:
Now we are able to generate static output voltage using our DAC

Did that mean that you only use one DAC channel or both at the same time on the same value ?

Thats some point i never try. I will try that tomorrow.

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Matze_Matthias wrote:
Did that mean that you only use one DAC channel or both at the same time on the same value ? Thats some point i never try. I will try that tomorrow.  

 

 

When we wrote same value in both channel we are able to get desired result but it is based on the order of writing in the channel. Means if i write value in channel 0 first and then channel 1 ,we are able to get proper result. Reverse case is not working fine.

 

 

Karthi

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

OK that sounds interesting.

I am able to generate two different values with restriction. Maybe the Code helps you?

But i see you use the c++ style programming?

 

My restriction is that its not possible to do something other as write values into a loop in the data Register to hold the Output voltages.

Although the REFRESH period is set! If i do something other, the output values increase or decrease to VDD and GND.

 

The same happenes, and thats very interesting if i set the Current Control to 1MSPS. Although my GCLK_DAC is 8 MHz the whole

thing is now set to <= 1,2 MHz (100kSPS) to get the DAC working.

 

Could it be that the DAC isnt able to generate autonom infinity conversions?

 

 

void DAC_Init()

{

REG_MCLK_APBDMASK |= 0x00000200;                   //DAC Bus clock enable

 

REG_GCLK_PCHCTRL42 = 0x0000044;                    //Quelle: 8 MHz GCLK4

 

REG_DAC_DACCTRL0 |= 0x0002;                        //DAC0 Enable

REG_DAC_DACCTRL1 |= 0x0002;                        //DAC1 Enable

REG_DAC_DACCTRL0 |= 0x0200;                        //DAC0 Konfig (REFRESH = 0x2 ;current control = 0 (100 kSPS))

REG_DAC_DACCTRL1 |= 0x0200;                        //DAC1 Konfig (REFRESH = 0x2 ;current control = 0 (100 kSPS))

REG_DAC_CTRLB = 0x06;                              //Vref = internal bandgap reference 2,5 V

REG_DAC_DBGCTRL = 0x01;                            //Debug Control (DAC continous normal operation)

REG_DAC_CTRLA |= 0x02;                             //DAC Enable

 

while( (REG_DAC_STATUS & 0x1) == 0 );              //Wait until DAC0 Ready

while( ((REG_DAC_STATUS & 0x2)>>1) == 0 );         //Wait until DAC1 Ready

REG_DAC_DATA0 = 0x0CCD;                            //2 V = 3277 = 0xCCD

REG_DAC_DATA1 = 0x0666;                            //1 V = 1638 = 0x666

 

while(1)

{

while( (REG_DAC_STATUS & 0x4) != 0x4 );

REG_DAC_DATA0 = 0x0CCD; //2 V = 3277 = 0xCCD

while( (REG_DAC_STATUS & 0x8) != 0x8 );

REG_DAC_DATA1 = 0x0666; //1 V = 1638 = 0x666

}

}

Last Edited: Fri. Jan 11, 2019 - 07:20 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I posted the relevant errata to the other thread:

1.8.2 DAC
The selection of VDDANA as the DAC reference in DAC.CTRLB.REFSEL is non-functional.
Workaround
The VDDANA must be connected externally to a VREF pin and DAC.CTRLB.VREFAU must be selected.

 

only REFAU has worked for me.

 

jeff

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

jcandle wrote:
only REFAU has worked for me.

 

@ jcandle

Did that mean that you tested out the internal bandgap reference too and it doenst work ?

 

For me it would be interesting because my problem is that the automatic refresh doenst work.

I cant testing out the external reference because the pin is not free.

 

A friend of me contacts Microchip during his work. As answear they send him a code-snipped with

VDDANA as DAC reference. Thats so stupid ^^.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

That is my recollection, but it has been a while.  i had the pin available and white wired it, so I did not put much effort into proving it.

jeff