Pin D0 on my Xiao SAMD21 is 0.8v, well below my Mosfet's Threshold

Hello all,

I was migrating a project from ATTiny85’s to SAMD21’s and had to spin boards while I awaited my new Xiaos.

Because of this, the boards were made with the assumption that D0 would behave like the other digital pins.

I am PWM controlling two mosfets with a threshold of 1.35v.

So the mosfet on D1 behaves properly while the mosfet on D0 does not. D1 outputs ~3.3v while D0 outputs ~0.8v

I can spin up new boards to use different pins, but that will take weeks. I know D0 is the DAC. Do I need to set the digital voltage somehow?


D0 (PA02) works like all other digital pins. You could check, if the Pin mode is set properly as GPIO. The PMUXEN bit (bit 0) at the Pin condfiguration register for PA02 address 0x41004400 (PORT base) + 0x42 (for PA02) must be 0. If that is fine, check the wiring of your board.

Think I found my answer:

Then you have to reconfigure that Pin as GPIO by clearing the PMUXEN bit. I know that the Pin can be used as GPIO.

I’ve tried every permutation of the following line, 00, 01, 02, both 0 and 1, and nothing changes.

PORT->Group[g_APinDescription[00].ulPort].PINCFG[g_APinDescription[00].ulPin].bit.PMUXEN = 1;

here’s the code in question

const byte ledPin0 = 0;
const byte ledPin1 = 1;
const byte interruptPin = A2;
volatile float i=0;

void setup() {
  pinMode(ledPin0, OUTPUT);
  pinMode(ledPin1, OUTPUT);
  pinMode(interruptPin, INPUT_PULLUP);
  attachInterrupt(2, blink, CHANGE);
  PORT->Group[g_APinDescription[02].ulPort].PINCFG[g_APinDescription[02].ulPin].bit.PMUXEN = 0;


void loop() {

void blink() {
  if (digitalRead(interruptPin) == HIGH) {
    if (i<254) {
      for (i = 0; i < 255; i = i + .15) {
        analogWrite(ledPin0, i);
        analogWrite(ledPin1, i);
      analogWrite(ledPin0, 255);
      analogWrite(ledPin1, 255);
  } else {
    analogWrite(ledPin0, 0);
    analogWrite(ledPin1, 0);

Here’s my respin of the board. The pins 0, 1, 2 have been bumped over to 1, 2, 3

Pin 3 is a switch, Pin 2 is one mosfet, Pin 1 is the other. Formerly Pin 2, Pin 1, and Pin 0, respectively.

PMUXEN must be set to 0 for GPIO mode. Setting it to 1 disables GPIO mode. See the data sheet, chapter 23.8.13 about the PINCFG register.

As I stated clearly, I tried every permutation. Nothing worked.

I know that the pin can be configured properly. I coded that myself. I do not know how these Arduino macros generate an address. The code I use is below, where pin is just the number of the pin. For PA02 this would be 2 for the pin number and 0 for the pin group. The PORT, PINCFG and PMUXEN are from the Atmel include files,

void mp_hal_clr_pin_mux(mp_hal_pin_obj_t pin) {
    int pin_grp = pin / 32;
    PORT->Group[pin_grp].PINCFG[pin % 32].bit.PMUXEN = 0; // Disable Mux

Can you check whether g_APinDescription[00].ulPort is 0 and g_APinDescription[00].ulPin is 2?

P.S.: That’s a piece of code from the MicroPython firmware.

PA02 (A0) does not have any timers associated with it, so a PWM on that pin will need to be done in software indirectly. I believe the Arduino analogWrite() command

  • checks if pin is analog out, if so uses it. [Clearing PMUXEN should cause this check to fail]
  • checks if pin can have a HW timer/PWM attached - if so configures the timer for that pin to generate a PWM  [not timer for PA02 (A0) so this fails]
  • else sets digital output (high or low) based on desired value 

You can see the reference in (my linux directory)

Thanks Ricksorensen!

That’s right. I did not check whether PA02 is PWM-capable using the timers. It is not. But you should be able to use it for digital out.

Hi , Are you certain about the interrupt pin configuration? Are you getting the interrupts ?
just curious. watching this thread.
GL :slight_smile: