Go Down

Topic: Arduino Due DAC0 problem (not working) (Read 8468 times) previous topic - next topic

duckTyped

Mar 20, 2014, 08:54 pm Last Edit: Mar 20, 2014, 09:47 pm by duckTyped Reason: 1
I got an Arduino Due from a retailer in hopes of driving stereo sound from both DACs.

I'm well aware of the fragile DACs, so for testing I plugged both DAC0 and DAC1 to my oscilloscope (1Mohm inputs) with passive probes at 10× attenuation setting. At 3.3V this is well below the 3mA limit current for DAC lines.

Both seemed to work fine, but at some point DAC0 stopped working. This happened exactly after running code in which I accidentally passed a value > 4095 to analogWrite for DAC0. An example of what I did:

Code: [Select]
void setup() {
  analogWriteResolution(12);
}

void loop() {
  analogWrite(DAC0, (micros() % 4096) * 2);  // Bug, I intended to do "(micros() * 2) % 4096"
  analogWrite(DAC1, micros() % 4096);
}


Now DAC0 is mostly at GND level regardless of what I analogWrite. If I run the code above passing just "micros() % 4096" to both DACs, DAC1 shows a sawtooth wave as expected but DAC0 shows a short negative voltage (what?) when value == 0 and then goes back to GND level.

I'm not sure if the buggy code was the source of the problem, but I can't think of any other way I might have fried DAC0 since I didn't connect it to anything besides my oscilloscope.

It sure seems weird I was able to break the DAC from code and, if it was the case, protection against bad values in the library might be sensible. Though DAC1 is still working perfectly I don't have the guts to run the faulty code against it to test if it was the culprit for fear of breaking it too.

Is the DAC0 really broken or am I missing something? Is it possible that the buggy code was the source of the problem? Am I just incredibly unlucky and got a faulty unit? Any chances the warranty will cover this?

Grumpy_Mike

Quote
Is it possible that the buggy code was the source of the problem?

Absolutely no possibility.

My guess is that you shorted the adjacent pin some time when you connected it to your scope. Although it could have just gone.

Quote
but DAC0 shows a short negative voltage (what?) when value == 0 and then goes back to GND level.

You would get that if there is some AC coupling going on somewhere.

We had a very similar problem a few weeks ago and he replaced the Due and all was fine.

Quote
Any chances the warranty will cover this?

Possibly, ask your suppler.

duckTyped

#2
Mar 24, 2014, 03:39 pm Last Edit: Mar 24, 2014, 04:32 pm by duckTyped Reason: 1

My guess is that you shorted the adjacent pin some time when you connected it to your scope. Although it could have just gone.


Hmmm... how could that happen? I tested directly in the DAC0 female pin header, so no short should have happened. I was specially careful not to scratch the header on the inside, carefully inserting the probe's tip was more than enough to get the signal shown in the oscilloscope.

Just to make sure my procedure is correct (I don't want to break anything else): I just attached the alligator clip in my probe to a GND pin in Arduino Due via a jumper cable and then inserted the probe's tip in DAC0.

MarkT

Given how sensitive these pins seem to be I would recommend adding 1k series
resistance to them as a matter of routine to reduce the chance of damage...
[ I will NOT respond to personal messages, I WILL delete them, use the forum please ]

Grumpy_Mike

Quote
Just to make sure my procedure is correct (I don't want to break anything else): I just attached the alligator clip in my probe to a GND pin in Arduino Due via a jumper cable and then inserted the probe's tip in DAC0.

Yes that procedure sounds safe enough.
Is your scope correctly grounded and is your ground a good connection to the earth ( the actual soil )?
On my scopes the probes would not reach inside the pins, but I have seen others that could.

dlloyd

Quote
I'm well aware of the fragile DACs, so for testing I plugged both DAC0 and DAC1 to my oscilloscope (1Mohm inputs) with passive probes at 10× attenuation setting. At 3.3V this is well below the 3mA limit current for DAC lines.



Now, I'm thinking its possible to exceed the max ratings of the DAC outputs even with 10x setting. Checking through the SAM3X datasheet for "pf" reveals that other than I2C, other outputs specified have 50 pF or much less max loading ... but I couldn't find anything specified for the DAC outputs. 

Of course, changing the DAC output instantly from 0V to max or max to 0 are worst case scenarios (for impedance). From now on, I'll clip the probe to a 1K resistor in series (as MarkT suggested) the next time I test these (or any) outputs on the Due, even though I haven't had any problems so far.

stimmer

Just to add to the confusion, I tried shunting the output of DAC1 through various low resistances for a few seconds whilst it was outputting a sine wave, before eventually shorting it to ground for a second. It still works! :~

Has anyone managed to blow DAC1? All the failures I've seen have been on DAC0. I am now convinced it's a problem with the SAM3X silicon rather than anything we are doing wrong.
Due VGA library - http://arduino.cc/forum/index.php/topic,150517.0.html

MarkT

Are the two signals routed differently on the PCB perhaps?  Near the DC-DC converter IC?
[ I will NOT respond to personal messages, I WILL delete them, use the forum please ]

duckTyped

#8
Mar 25, 2014, 02:10 am Last Edit: Mar 25, 2014, 03:50 am by duckTyped Reason: 1

Given how sensitive these pins seem to be I would recommend adding 1k series
resistance to them as a matter of routine to reduce the chance of damage...


Seems sensible to do, just in case. I'd actually add a resistance greater than 1.1k? (3.3v/1.1k? = 3mA, the maximum rating.)

Future DAC0 owners, add at least an 1.2k? series resistor!


Is your scope correctly grounded and is your ground a good connection to the earth ( the actual soil )?


My scope is correctly grounded through "Schuko" sockets to the mains ground connection, which I assume is properly grounded (or at least I hope my building complies with safety regulations :P)


Now, I'm thinking its possible to exceed the max ratings of the DAC outputs even with 10x setting.


My oscilloscope inputs are also labelled as 1M? + ?22pF which as far as I know should add to the probe's impedance. I might be wrong here, but even at ? frequency it should be safe because of the 1M? resistance, right?


Are the two signals routed differently on the PCB perhaps?  Near the DC-DC converter IC?


Just checked Due's official PCB and both signals are routed side by side.

dlloyd

RE: DACC Analog Current Register (DACC_ACR)
Bits 9,8 (IBCTLDACCORE) Bias Current Control for DAC Core
Bits 3,2 (IBCTLCH1) Analog Output Current Control for channel 1
Bits 1,0 (IBCTLCH0) Analog Output Current Control for channel 0

I've checked the status of this register and found that several unused bits have changed when both outputs are off. Although these bits are undocumented or unused, shouldn't they always read 0?

DACC_ACR bit:                    9876543210
With any one or both outputs on:  100001010  <-- normal mode as per datasheet
With both outputs off:            110101010  <-- bits 7 and 5 are high


Code as above but with DACC_ACR status on serial monitor:
Code: [Select]

void setup() {
  analogWriteResolution(12);
  Serial.begin(115200);
}

void loop() {
  //analogWrite(DAC0, (micros() % 4096) * 2);  // Bug, I intended to do "(micros() * 2) % 4096"
  //analogWrite(DAC1, micros() % 4096);

  Serial.println (REG_DACC_ACR, BIN);
  delay (1000);
}

dlloyd

#10
Mar 25, 2014, 04:37 am Last Edit: Mar 25, 2014, 03:54 pm by dlloyd Reason: 1
Note:  IBCTLCHx  Allows to adapt the slew rate of the analog output. (from datasheet).
It seems strange that the SAM3X's DAC outputs have slew rate control with 4 possibilities but the datasheet only documents "01" as being normal mode. I'm now wondering if bits 0 to 3 in the DACC_ACR register remain stable during enabling, disabling or writing to DAC0 and DAC1 channels.

EDIT (addendum): Re Section 45.7, Table 45-3
Reset of the DACC_ACR is 0x00000000 ... it is not held in this state when DAC channels are deactivated. Is this used or is this necessary? Just some questions ... I do not have the experience, debugging hardware, nor time to investigate further (sorry).

dlloyd

#11
Mar 25, 2014, 06:17 pm Last Edit: Mar 26, 2014, 01:07 am by dlloyd Reason: 1
OK, so I investigated a "bit" further...

In the code below, a workaround is on line 3.
When line 3 is commented out, the DACC_ACR register will have binary status 110101010 until the user's sketch runs the analogWrite() command (for example when i = 3), upon which time the DACC_ACR register changes to and remains at 100001010 (as per datasheet).

Code: [Select]
void setup() {
  analogWriteResolution(12);
  //dacc_set_analog_control(DACC, DACC_ACR_IBCTLCH0(0x02) | DACC_ACR_IBCTLCH1(0x02) | DACC_ACR_IBCTLDACCORE(0x01));
  Serial.begin(115200);
}

void loop() {
  for (int i = 0; i <= 5; i++) {
    if (i == 3)
    {
      analogWrite(DAC0, (micros() % 4096) * 2);
      analogWrite(DAC1, micros() % 4096);
    }
    Serial.print ("When i = ");
    Serial.print (i);
    Serial.print (", REG_DACC_ACR = ");
    Serial.println (REG_DACC_ACR, BIN);
    delay (1000);
  }
}

dlloyd

#12
Mar 26, 2014, 08:47 pm Last Edit: Mar 26, 2014, 09:01 pm by dlloyd Reason: 1
The undefined/unused bits 7 and 5 in the DACC_ACR register are being set high after executing a software reset (REG_DACC_CR = 0x1).  After checking all readable registers in the DACC software interface after software reset (SWRST), I've added the results to the register mapping table below for comparison:

Table 45-3. Register Mapping   (pg 1373)         Binary Reading
                                                         After
Register                       Name       Reset           SWRST
Mode Register                  DACC_MR    0x00000000          0
Channel Status Register        DACC_CHSR  0x00000000          0
Interrupt Mask Register        DACC_IMR   0x00000000          0
Interrupt Status Register      DACC_ISR   0x00000000       1100
Analog Current Register        DACC_ACR   0x00000000  110101010
Write Protect Mode Register    DACC_WPMR  0x00000000          0
Write Protect Status Register  DACC_WPSR  0x00000000          0

Is software reset working correctly on the ACR and ISR register?

Magician

Quite interesting. I decided to test software reset on my board, and here is result:
Quote
REG_DACC_MR = 43
   REG_DACC_CHSR = 1
   REG_DACC_IMR = 4
   REG_DACC_ISR = 2
   REG_DACC_ACR = 10A
   REG_DACC_WPMR = 0
   REG_DACC_WPSR = 0

   REG_DACC_MR = 0
   REG_DACC_CHSR = 0
   REG_DACC_IMR = 0
   REG_DACC_ISR = 0
   REG_DACC_ACR = 1AA
   REG_DACC_WPMR = 0
   REG_DACC_WPSR = 0

   REG_DACC_MR = 43
   REG_DACC_CHSR = 1
   REG_DACC_IMR = 4
   REG_DACC_ISR = 2
   REG_DACC_ACR = 10A
   REG_DACC_WPMR = 0
   REG_DACC_WPSR = 0
First block is normal status (function sine generator 1k), second block - after software reset, and third one after setting DACC back calling initializing subroutine. Nothing breaks , fortunately. My results slightly different on ISR, but the same regarding ACR register. IMHO, 1AA = 110101010 - is default configuration, and it's not clear what is the purpose of the bits 5 & 7.
May be good question for Atmel technical support team.

dlloyd

Quote
May be good question for Atmel technical support team.

I agree. Perhaps the Arduino developers are already aware of this.

I couldn't resist just directly writing 0x0 to the ACR register using REG_DACC_ACR = 0x0;
... this worked as the read back status would become 0x0 (unchartered territory).

On the DAC0 and DAC1 pins, I then confirmed full voltage swing with an external 100K resistor, so it looks like the outputs are now placed in high impedance mode.

Using REG_DACC_ACR = 0x0; to replace line 3 in the script I posted earlier worked OK. The only difference now is that the ACR register status will initially read 0x0 (reset) until the first analogWrite is run, then it becomes 0x10A as expected.

Arduino, which uses the software reset command of the control register (SWRST) never resets the ACR as per Table 45-3.

Go Up