PWM DAC at pins MOSI, SCK and MISO doesn't work

Using the not connected pins MOSI (pin19), SCK(pin20) and MISO(pin21) as digital outputs works fine:

pinMode(MOSI, OUTPUT); digitalWrite(MOSI, value);

But using these pins as PWM DAC doesn't work however: analogWrite(MOSI, value); // this doesn't work

Can this be fixed in the next Arduino version?

Those are digital pins so you’ll never get an analog signal out of them… Nothing to fix.

dlabun: Those are digital pins so you'll never get an analog signal out of them... Nothing to fix.

All digital pins (except d2 and d7) have PWM output, which can be used as DAC.

My apologies, I saw DAC and thought you meant an analog signal.

If you look at the Zero product page under Inputs and Output it does state: "Pins that can be used for PWM output are: 3, 4, 5, 6, 8, 9, 10, 11, 12, 13 using analogWrite() function". I have no answer as to why that is other than the fact that those pins are intended strictly for SPI usage.

The analogWrite() function doesn't work with the pins on the SPI header. The pin definitions for these pins in the Zero's "variant.cpp" file state: not on PWM.

// 22..24 - SPI pins (ICSP:MISO,SCK,MOSI)
  // ----------------------
  { PORTA, 12, PIO_SERCOM_ALT, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_12 }, // MISO: SERCOM4/PAD[0]
  { PORTB, 10, PIO_SERCOM_ALT, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_10 }, // MOSI: SERCOM4/PAD[2]
  { PORTB, 11, PIO_SERCOM_ALT, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_11 }, // SCK: SERCOM4/PAD[3]

That's not to say you can't use these pins for PWM though. It's possible to get PWM output, but this requires register manipulation.

MartinL: The analogWrite() function doesn't work with the pins on the SPI header. The pin definitions for these pins in the Zero's "variant.cpp" file state: not on PWM.

// 22..24 - SPI pins (ICSP:MISO,SCK,MOSI)
  // ----------------------
  { PORTA, 12, PIO_SERCOM_ALT, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_12 }, // MISO: SERCOM4/PAD[0]
  { PORTB, 10, PIO_SERCOM_ALT, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_10 }, // MOSI: SERCOM4/PAD[2]
  { PORTB, 11, PIO_SERCOM_ALT, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_11 }, // SCK: SERCOM4/PAD[3]

That's not to say you can't use these pins for PWM though. It's possible to get PWM output, but this requires register manipulation.

Can I use PWM by simply changing the variant.cpp? I don't like register manipulating.

Can this be solved in the next Arduino version? These pins can be used as digital I/O pins too, so in the same way, using as PWM should be possible too.

Can I use PWM by simply changing the variant.cpp?

It turns out that the MOSI and SCK pins can be multiplexed to timer 5, which isn't allocated to any other pins. MISO however, uses the same timers as analogWrite() on D6 and D11. The following code changes to the "variant.cpp" file will give you analogWrite() on the MOSI and SCK pins:

// 22..24 - SPI pins (ICSP:MISO,SCK,MOSI)
  // ----------------------
  { PORTA, 12, PIO_SERCOM_ALT, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_12 }, // MISO: SERCOM4/PAD[0]
  { PORTB, 10, PIO_SERCOM_ALT, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER), No_ADC_Channel, PWM5_CH0, TC5_CH0, EXTERNAL_INT_10 }, // MOSI: SERCOM4/PAD[2]
  { PORTB, 11, PIO_SERCOM_ALT, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER), No_ADC_Channel, PWM5_CH1, TC5_CH1, EXTERNAL_INT_11 }, // SCK: SERCOM4/PAD[3]

MartinL: It turns out that the MOSI and SCK pins can be multiplexed to timer 5, which isn't allocated to any other pins. MISO however, uses the same timers as analogWrite() on D6 and D11. The following code changes to the "variant.cpp" file will give you analogWrite() on the MOSI and SCK pins:

// 22..24 - SPI pins (ICSP:MISO,SCK,MOSI)
  // ----------------------
  { PORTA, 12, PIO_SERCOM_ALT, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_12 }, // MISO: SERCOM4/PAD[0]
  { PORTB, 10, PIO_SERCOM_ALT, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER), No_ADC_Channel, PWM5_CH0, TC5_CH0, EXTERNAL_INT_10 }, // MOSI: SERCOM4/PAD[2]
  { PORTB, 11, PIO_SERCOM_ALT, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER), No_ADC_Channel, PWM5_CH1, TC5_CH1, EXTERNAL_INT_11 }, // SCK: SERCOM4/PAD[3]

Thanks, I will try that!

MartinL:
It turns out that the MOSI and SCK pins can be multiplexed to timer 5, which isn’t allocated to any other pins. MISO however, uses the same timers as analogWrite() on D6 and D11. The following code changes to the “variant.cpp” file will give you analogWrite() on the MOSI and SCK pins:

// 22..24 - SPI pins (ICSP:MISO,SCK,MOSI)

// ----------------------
  { PORTA, 12, PIO_SERCOM_ALT, PIN_ATTR_DIGITAL, No_ADC_Channel, NOT_ON_PWM, NOT_ON_TIMER, EXTERNAL_INT_12 }, // MISO: SERCOM4/PAD[0]
  { PORTB, 10, PIO_SERCOM_ALT, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER), No_ADC_Channel, PWM5_CH0, TC5_CH0, EXTERNAL_INT_10 }, // MOSI: SERCOM4/PAD[2]
  { PORTB, 11, PIO_SERCOM_ALT, (PIN_ATTR_DIGITAL|PIN_ATTR_PWM|PIN_ATTR_TIMER), No_ADC_Channel, PWM5_CH1, TC5_CH1, EXTERNAL_INT_11 }, // SCK: SERCOM4/PAD[3]

I can’t find any variant.cpp file on my computer (Arduino version 1.6.7.), but I can program the Arduino Zero well. Where is it?

On my Windows machine it's currently located here: C:\Users\Computer\AppData\Local\Arduino15\packages\arduino\hardware\samd\1.6.4\variants\arduino_zero\variant.cpp.

MartinL: On my Windows machine it's currently located here: C:\Users\Computer\AppData\Local\Arduino15\packages\arduino\hardware\samd\1.6.4\variants\arduino_zero\variant.cpp.

I have Windows XP and there is no variant.cpp :confused: How it that possible? (I made these files visible in exporer).

Can you find this directory ?

C:\Users*[YOUR_USERNAME]\AppData**Local*\Arduino15\packages\arduino\hardware\samd\

Sometimes, the arduino15 directory is in the Roaming directory, instead of Local :

C:\Users*[YOUR_USERNAME]\AppData**Roaming*\Arduino15\packages\arduino\hardware\samd\

AloyseTech: Can you find this directory ?

C:\Users*[YOUR_USERNAME]\AppData**Local*\Arduino15\packages\arduino\hardware\samd\

Sometimes, the arduino15 directory is in the Roaming directory, instead of Local :

C:\Users*[YOUR_USERNAME]\AppData**Roaming*\Arduino15\packages\arduino\hardware\samd\

No, nothing like this, there is no variant.cpp file.

avandalen:
No, nothing like this, there is no variant.cpp file.

I have a new laptop now (Windows 10), variant.cpp is at:
C:\Users\Albert\AppData\Local\Arduino15\packages\arduino\hardware\samd\1.6.6\variants\arduino_zero\variant.cpp