From 156884bc0282457c6f3aa0b8b5926a1ca27488f1 Mon Sep 17 00:00:00 2001 From: Cristian Maglie Date: Wed, 29 Jun 2016 17:20:37 +0200 Subject: [PATCH 1/3] Fixed whitespaces, removed some prefixes from variables names --- cores/arduino/wiring_analog.c | 148 +++++++++++++++------------------- 1 file changed, 65 insertions(+), 83 deletions(-) diff --git a/cores/arduino/wiring_analog.c b/cores/arduino/wiring_analog.c index e148aba4a..917485d73 100644 --- a/cores/arduino/wiring_analog.c +++ b/cores/arduino/wiring_analog.c @@ -53,47 +53,36 @@ static void syncTCC(Tcc* TCCx) { while (TCCx->SYNCBUSY.reg & TCC_SYNCBUSY_MASK); } -void analogReadResolution( int res ) +void analogReadResolution(int res) { - _readResolution = res ; - if (res > 10) - { + _readResolution = res; + if (res > 10) { ADC->CTRLB.bit.RESSEL = ADC_CTRLB_RESSEL_12BIT_Val; _ADCResolution = 12; - } - else if (res > 8) - { + } else if (res > 8) { ADC->CTRLB.bit.RESSEL = ADC_CTRLB_RESSEL_10BIT_Val; _ADCResolution = 10; - } - else - { + } else { ADC->CTRLB.bit.RESSEL = ADC_CTRLB_RESSEL_8BIT_Val; _ADCResolution = 8; } syncADC(); } -void analogWriteResolution( int res ) +void analogWriteResolution(int res) { - _writeResolution = res ; + _writeResolution = res; } -static inline uint32_t mapResolution( uint32_t value, uint32_t from, uint32_t to ) +static inline uint32_t mapResolution(uint32_t value, uint32_t from, uint32_t to) { - if ( from == to ) - { - return value ; + if (from == to) { + return value; } - - if ( from > to ) - { - return value >> (from-to) ; - } - else - { - return value << (to-from) ; + if (from > to) { + return value >> (from-to); } + return value << (to-from); } /* @@ -102,10 +91,10 @@ static inline uint32_t mapResolution( uint32_t value, uint32_t from, uint32_t to * * Warning : On Arduino Zero board the input/output voltage for SAMD21G18 is 3.3 volts maximum */ -void analogReference( eAnalogReference ulMode ) +void analogReference(eAnalogReference mode) { syncADC(); - switch ( ulMode ) + switch (mode) { case AR_INTERNAL: case AR_INTERNAL2V23: @@ -136,19 +125,17 @@ void analogReference( eAnalogReference ulMode ) } } -uint32_t analogRead( uint32_t ulPin ) +uint32_t analogRead(uint32_t pin) { uint32_t valueRead = 0; - if ( ulPin < A0 ) - { - ulPin += A0 ; + if (pin < A0) { + pin += A0; } - pinPeripheral(ulPin, PIO_ANALOG); + pinPeripheral(pin, PIO_ANALOG); - if (ulPin == A0) // Disable DAC, if analogWrite(A0,dval) used previously the DAC is enabled - { + if (pin == A0) { // Disable DAC, if analogWrite(A0,dval) used previously the DAC is enabled syncDAC(); DAC->CTRLA.bit.ENABLE = 0x00; // Disable DAC //DAC->CTRLB.bit.EOEN = 0x00; // The DAC output is turned off. @@ -156,7 +143,7 @@ uint32_t analogRead( uint32_t ulPin ) } syncADC(); - ADC->INPUTCTRL.bit.MUXPOS = g_APinDescription[ulPin].ulADCChannelNumber; // Selection for the positive ADC input + ADC->INPUTCTRL.bit.MUXPOS = g_APinDescription[pin].ulADCChannelNumber; // Selection for the positive ADC input // Control A /* @@ -185,7 +172,7 @@ uint32_t analogRead( uint32_t ulPin ) ADC->SWTRIG.bit.START = 1; // Store the value - while ( ADC->INTFLAG.bit.RESRDY == 0 ); // Waiting for conversion to complete + while (ADC->INTFLAG.bit.RESRDY == 0); // Waiting for conversion to complete valueRead = ADC->RESULT.reg; syncADC(); @@ -200,90 +187,88 @@ uint32_t analogRead( uint32_t ulPin ) // hardware support. These are defined in the appropriate // pins_*.c file. For the rest of the pins, we default // to digital output. -void analogWrite( uint32_t ulPin, uint32_t ulValue ) +void analogWrite(uint32_t pin, uint32_t value) { - uint32_t attr = g_APinDescription[ulPin].ulPinAttribute ; + uint32_t attr = g_APinDescription[pin].ulPinAttribute; - if ( (attr & PIN_ATTR_ANALOG) == PIN_ATTR_ANALOG ) + if ((attr & PIN_ATTR_ANALOG) == PIN_ATTR_ANALOG) { - if ( ulPin != PIN_A0 ) // Only 1 DAC on A0 (PA02) - { + // DAC handling code + + if (pin != PIN_A0) { // Only 1 DAC on A0 (PA02) return; } - ulValue = mapResolution(ulValue, _writeResolution, 10); + value = mapResolution(value, _writeResolution, 10); syncDAC(); - DAC->DATA.reg = ulValue & 0x3FF; // DAC on 10 bits. + DAC->DATA.reg = value & 0x3FF; // DAC on 10 bits. syncDAC(); DAC->CTRLA.bit.ENABLE = 0x01; // Enable DAC syncDAC(); - return ; + return; } - if ( (attr & PIN_ATTR_PWM) == PIN_ATTR_PWM ) + if ((attr & PIN_ATTR_PWM) == PIN_ATTR_PWM) { if (attr & PIN_ATTR_TIMER) { #if !(ARDUINO_SAMD_VARIANT_COMPLIANCE >= 10603) // Compatibility for cores based on SAMD core <=1.6.2 - if (g_APinDescription[ulPin].ulPinType == PIO_TIMER_ALT) { - pinPeripheral(ulPin, PIO_TIMER_ALT); + if (g_APinDescription[pin].ulPinType == PIO_TIMER_ALT) { + pinPeripheral(pin, PIO_TIMER_ALT); } else #endif { - pinPeripheral(ulPin, PIO_TIMER); + pinPeripheral(pin, PIO_TIMER); } } else { // We suppose that attr has PIN_ATTR_TIMER_ALT bit set... - pinPeripheral(ulPin, PIO_TIMER_ALT); + pinPeripheral(pin, PIO_TIMER_ALT); } - Tc* TCx = 0 ; - Tcc* TCCx = 0 ; - uint8_t Channelx = GetTCChannelNumber( g_APinDescription[ulPin].ulPWMChannel ) ; - if ( GetTCNumber( g_APinDescription[ulPin].ulPWMChannel ) >= TCC_INST_NUM ) - { - TCx = (Tc*) GetTC( g_APinDescription[ulPin].ulPWMChannel ) ; - } - else - { - TCCx = (Tcc*) GetTC( g_APinDescription[ulPin].ulPWMChannel ) ; + Tc* TCx = NULL; + Tcc* TCCx = NULL; + uint8_t Channelx = GetTCChannelNumber(g_APinDescription[pin].ulPWMChannel); + if (GetTCNumber(g_APinDescription[pin].ulPWMChannel) >= TCC_INST_NUM) { + TCx = (Tc*) GetTC(g_APinDescription[pin].ulPWMChannel); + } else { + TCCx = (Tcc*) GetTC(g_APinDescription[pin].ulPWMChannel); } // Enable clocks according to TCCx instance to use - switch ( GetTCNumber( g_APinDescription[ulPin].ulPWMChannel ) ) + switch (GetTCNumber(g_APinDescription[pin].ulPWMChannel)) { case 0: // TCC0 case 1: // TCC1 // Enable GCLK for TCC0 and TCC1 (timer counter input clock) - GCLK->CLKCTRL.reg = (uint16_t) (GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN_GCLK0 | GCLK_CLKCTRL_ID( GCM_TCC0_TCC1 )) ; - break ; + GCLK->CLKCTRL.reg = (uint16_t) (GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN_GCLK0 | GCLK_CLKCTRL_ID(GCM_TCC0_TCC1)); + break; case 2: // TCC2 case 3: // TC3 // Enable GCLK for TCC2 and TC3 (timer counter input clock) - GCLK->CLKCTRL.reg = (uint16_t) (GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN_GCLK0 | GCLK_CLKCTRL_ID( GCM_TCC2_TC3 )) ; - break ; + GCLK->CLKCTRL.reg = (uint16_t) (GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN_GCLK0 | GCLK_CLKCTRL_ID(GCM_TCC2_TC3)); + break; case 4: // TC4 case 5: // TC5 // Enable GCLK for TC4 and TC5 (timer counter input clock) - GCLK->CLKCTRL.reg = (uint16_t) (GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN_GCLK0 | GCLK_CLKCTRL_ID( GCM_TC4_TC5 )); - break ; + GCLK->CLKCTRL.reg = (uint16_t) (GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN_GCLK0 | GCLK_CLKCTRL_ID(GCM_TC4_TC5)); + break; case 6: // TC6 (not available on Zero) case 7: // TC7 (not available on Zero) // Enable GCLK for TC6 and TC7 (timer counter input clock) - GCLK->CLKCTRL.reg = (uint16_t) (GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN_GCLK0 | GCLK_CLKCTRL_ID( GCM_TC6_TC7 )); - break ; + GCLK->CLKCTRL.reg = (uint16_t) (GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN_GCLK0 | GCLK_CLKCTRL_ID(GCM_TC6_TC7)); + break; } - while ( GCLK->STATUS.bit.SYNCBUSY == 1 ) ; + while (GCLK->STATUS.bit.SYNCBUSY == 1); - ulValue = mapResolution(ulValue, _writeResolution, 8); + value = mapResolution(value, _writeResolution, 8); // Set PORT - if ( TCx ) + if (TCx) { // -- Configure TC @@ -295,7 +280,7 @@ void analogWrite( uint32_t ulPin, uint32_t ulValue ) // Set TCx as normal PWM TCx->COUNT8.CTRLA.reg |= TC_CTRLA_WAVEGEN_NPWM; // Set TCx in waveform mode Normal PWM - TCx->COUNT8.CC[Channelx].reg = (uint8_t) ulValue; + TCx->COUNT8.CC[Channelx].reg = (uint8_t) value; syncTC_8(TCx); // Set PER to maximum counter value (resolution : 0xFF) TCx->COUNT8.PER.reg = 0xFF; @@ -314,29 +299,26 @@ void analogWrite( uint32_t ulPin, uint32_t ulValue ) TCCx->WAVE.reg |= TCC_WAVE_WAVEGEN_NPWM; syncTCC(TCCx); // Set TCx in waveform mode Normal PWM - TCCx->CC[Channelx].reg = (uint32_t)ulValue; + TCCx->CC[Channelx].reg = (uint32_t)value; syncTCC(TCCx); // Set PER to maximum counter value (resolution : 0xFF) TCCx->PER.reg = 0xFF; syncTCC(TCCx); // Enable TCCx - TCCx->CTRLA.reg |= TCC_CTRLA_ENABLE ; + TCCx->CTRLA.reg |= TCC_CTRLA_ENABLE; syncTCC(TCCx); } - return ; + return; } // -- Defaults to digital write - pinMode( ulPin, OUTPUT ) ; - ulValue = mapResolution(ulValue, _writeResolution, 8); - if ( ulValue < 128 ) - { - digitalWrite( ulPin, LOW ) ; - } - else - { - digitalWrite( ulPin, HIGH ) ; + pinMode(pin, OUTPUT); + value = mapResolution(value, _writeResolution, 8); + if (value < 128) { + digitalWrite(pin, LOW); + } else { + digitalWrite(pin, HIGH); } } From f221d1f1bdb3bfd87ca3f20520f67bef9450619e Mon Sep 17 00:00:00 2001 From: Cristian Maglie Date: Thu, 30 Jun 2016 10:44:24 +0200 Subject: [PATCH 2/3] Fixed PWM frequency glitch --- CHANGELOG | 1 + cores/arduino/wiring_analog.c | 181 ++++++++++++++++------------------ 2 files changed, 88 insertions(+), 94 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 75293318b..e0f4f6f05 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -3,6 +3,7 @@ SAMD CORE * Fixed Serial.flush() blocking before any writes. Thanks @hangmoh * Added snprintf_P to avr/pgmspace.h stub. Thanks @jantje * Another small fix to String iterators. Thanks @Ivan-Perez @Chris--A +* Fixed glitch in PWM generation that may happen when calling analogWrite() SAMD CORE 1.6.6 2016.05.19 diff --git a/cores/arduino/wiring_analog.c b/cores/arduino/wiring_analog.c index 917485d73..4ef07f51b 100644 --- a/cores/arduino/wiring_analog.c +++ b/cores/arduino/wiring_analog.c @@ -189,7 +189,8 @@ uint32_t analogRead(uint32_t pin) // to digital output. void analogWrite(uint32_t pin, uint32_t value) { - uint32_t attr = g_APinDescription[pin].ulPinAttribute; + PinDescription pinDesc = g_APinDescription[pin]; + uint32_t attr = pinDesc.ulPinAttribute; if ((attr & PIN_ATTR_ANALOG) == PIN_ATTR_ANALOG) { @@ -211,104 +212,96 @@ void analogWrite(uint32_t pin, uint32_t value) if ((attr & PIN_ATTR_PWM) == PIN_ATTR_PWM) { - if (attr & PIN_ATTR_TIMER) { - #if !(ARDUINO_SAMD_VARIANT_COMPLIANCE >= 10603) - // Compatibility for cores based on SAMD core <=1.6.2 - if (g_APinDescription[pin].ulPinType == PIO_TIMER_ALT) { + value = mapResolution(value, _writeResolution, 8); + + uint32_t tcNum = GetTCNumber(pinDesc.ulPWMChannel); + uint8_t tcChannel = GetTCChannelNumber(pinDesc.ulPWMChannel); + static bool tcEnabled[TCC_INST_NUM+TC_INST_NUM]; + + if (!tcEnabled[tcNum]) { + tcEnabled[tcNum] = true; + + if (attr & PIN_ATTR_TIMER) { + #if !(ARDUINO_SAMD_VARIANT_COMPLIANCE >= 10603) + // Compatibility for cores based on SAMD core <=1.6.2 + if (pinDesc.ulPinType == PIO_TIMER_ALT) { + pinPeripheral(pin, PIO_TIMER_ALT); + } else + #endif + { + pinPeripheral(pin, PIO_TIMER); + } + } else { + // We suppose that attr has PIN_ATTR_TIMER_ALT bit set... pinPeripheral(pin, PIO_TIMER_ALT); - } else - #endif - { - pinPeripheral(pin, PIO_TIMER); } - } else { - // We suppose that attr has PIN_ATTR_TIMER_ALT bit set... - pinPeripheral(pin, PIO_TIMER_ALT); - } - Tc* TCx = NULL; - Tcc* TCCx = NULL; - uint8_t Channelx = GetTCChannelNumber(g_APinDescription[pin].ulPWMChannel); - if (GetTCNumber(g_APinDescription[pin].ulPWMChannel) >= TCC_INST_NUM) { - TCx = (Tc*) GetTC(g_APinDescription[pin].ulPWMChannel); + uint16_t GCLK_CLKCTRL_IDs[] = { + GCLK_CLKCTRL_ID(GCM_TCC0_TCC1), // TCC0 + GCLK_CLKCTRL_ID(GCM_TCC0_TCC1), // TCC1 + GCLK_CLKCTRL_ID(GCM_TCC2_TC3), // TCC2 + GCLK_CLKCTRL_ID(GCM_TCC2_TC3), // TC3 + GCLK_CLKCTRL_ID(GCM_TC4_TC5), // TC4 + GCLK_CLKCTRL_ID(GCM_TC4_TC5), // TC5 + GCLK_CLKCTRL_ID(GCM_TC6_TC7), // TC6 + GCLK_CLKCTRL_ID(GCM_TC6_TC7), // TC7 + }; + GCLK->CLKCTRL.reg = (uint16_t) (GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN_GCLK0 | GCLK_CLKCTRL_IDs[tcNum]); + while (GCLK->STATUS.bit.SYNCBUSY == 1); + + // Set PORT + if (tcNum >= TCC_INST_NUM) { + // -- Configure TC + Tc* TCx = (Tc*) GetTC(pinDesc.ulPWMChannel); + // Disable TCx + TCx->COUNT8.CTRLA.bit.ENABLE = 0; + syncTC_8(TCx); + // Set Timer counter Mode to 8 bits, normal PWM + TCx->COUNT8.CTRLA.reg |= TC_CTRLA_MODE_COUNT8 | TC_CTRLA_WAVEGEN_NPWM; + syncTC_8(TCx); + // Set the initial value + TCx->COUNT8.CC[tcChannel].reg = (uint8_t) value; + syncTC_8(TCx); + // Set PER to maximum counter value (resolution : 0xFF) + TCx->COUNT8.PER.reg = 0xFF; + syncTC_8(TCx); + // Enable TCx + TCx->COUNT8.CTRLA.bit.ENABLE = 1; + syncTC_8(TCx); + } else { + // -- Configure TCC + Tcc* TCCx = (Tcc*) GetTC(pinDesc.ulPWMChannel); + // Disable TCCx + TCCx->CTRLA.bit.ENABLE = 0; + syncTCC(TCCx); + // Set TCx as normal PWM + TCCx->WAVE.reg |= TCC_WAVE_WAVEGEN_NPWM; + syncTCC(TCCx); + // Set the initial value + TCCx->CC[tcChannel].reg = (uint32_t) value; + syncTCC(TCCx); + // Set PER to maximum counter value (resolution : 0xFF) + TCCx->PER.reg = 0xFF; + syncTCC(TCCx); + // Enable TCCx + TCCx->CTRLA.bit.ENABLE = 1; + syncTCC(TCCx); + } } else { - TCCx = (Tcc*) GetTC(g_APinDescription[pin].ulPWMChannel); - } - - // Enable clocks according to TCCx instance to use - switch (GetTCNumber(g_APinDescription[pin].ulPWMChannel)) - { - case 0: // TCC0 - case 1: // TCC1 - // Enable GCLK for TCC0 and TCC1 (timer counter input clock) - GCLK->CLKCTRL.reg = (uint16_t) (GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN_GCLK0 | GCLK_CLKCTRL_ID(GCM_TCC0_TCC1)); - break; - - case 2: // TCC2 - case 3: // TC3 - // Enable GCLK for TCC2 and TC3 (timer counter input clock) - GCLK->CLKCTRL.reg = (uint16_t) (GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN_GCLK0 | GCLK_CLKCTRL_ID(GCM_TCC2_TC3)); - break; - - case 4: // TC4 - case 5: // TC5 - // Enable GCLK for TC4 and TC5 (timer counter input clock) - GCLK->CLKCTRL.reg = (uint16_t) (GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN_GCLK0 | GCLK_CLKCTRL_ID(GCM_TC4_TC5)); - break; - - case 6: // TC6 (not available on Zero) - case 7: // TC7 (not available on Zero) - // Enable GCLK for TC6 and TC7 (timer counter input clock) - GCLK->CLKCTRL.reg = (uint16_t) (GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN_GCLK0 | GCLK_CLKCTRL_ID(GCM_TC6_TC7)); - break; - } - - while (GCLK->STATUS.bit.SYNCBUSY == 1); - - value = mapResolution(value, _writeResolution, 8); - - // Set PORT - if (TCx) - { - // -- Configure TC - - // Disable TCx - TCx->COUNT8.CTRLA.reg &= ~TC_CTRLA_ENABLE; - syncTC_8(TCx); - // Set Timer counter Mode to 8 bits - TCx->COUNT8.CTRLA.reg |= TC_CTRLA_MODE_COUNT8; - // Set TCx as normal PWM - TCx->COUNT8.CTRLA.reg |= TC_CTRLA_WAVEGEN_NPWM; - // Set TCx in waveform mode Normal PWM - TCx->COUNT8.CC[Channelx].reg = (uint8_t) value; - syncTC_8(TCx); - // Set PER to maximum counter value (resolution : 0xFF) - TCx->COUNT8.PER.reg = 0xFF; - syncTC_8(TCx); - // Enable TCx - TCx->COUNT8.CTRLA.reg |= TC_CTRLA_ENABLE; - syncTC_8(TCx); - } - else - { - // -- Configure TCC - // Disable TCCx - TCCx->CTRLA.reg &= ~TCC_CTRLA_ENABLE; - syncTCC(TCCx); - // Set TCx as normal PWM - TCCx->WAVE.reg |= TCC_WAVE_WAVEGEN_NPWM; - syncTCC(TCCx); - // Set TCx in waveform mode Normal PWM - TCCx->CC[Channelx].reg = (uint32_t)value; - syncTCC(TCCx); - // Set PER to maximum counter value (resolution : 0xFF) - TCCx->PER.reg = 0xFF; - syncTCC(TCCx); - // Enable TCCx - TCCx->CTRLA.reg |= TCC_CTRLA_ENABLE; - syncTCC(TCCx); + if (tcNum >= TCC_INST_NUM) { + Tc* TCx = (Tc*) GetTC(pinDesc.ulPWMChannel); + TCx->COUNT8.CC[tcChannel].reg = (uint8_t) value; + syncTC_8(TCx); + } else { + Tcc* TCCx = (Tcc*) GetTC(pinDesc.ulPWMChannel); + TCCx->CTRLBSET.bit.LUPD = 1; + syncTCC(TCCx); + TCCx->CCB[tcChannel].reg = (uint32_t) value; + syncTCC(TCCx); + TCCx->CTRLBCLR.bit.LUPD = 1; + syncTCC(TCCx); + } } - return; } From c9f315b9b25b70f475c91fa3b315c2e37fa12f32 Mon Sep 17 00:00:00 2001 From: Cristian Maglie Date: Thu, 30 Jun 2016 18:39:08 +0200 Subject: [PATCH 3/3] Set PWM frequency to 732.4Hz --- CHANGELOG | 1 + cores/arduino/wiring_analog.c | 7 +++++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index e0f4f6f05..53b0c2d8f 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -4,6 +4,7 @@ SAMD CORE * Added snprintf_P to avr/pgmspace.h stub. Thanks @jantje * Another small fix to String iterators. Thanks @Ivan-Perez @Chris--A * Fixed glitch in PWM generation that may happen when calling analogWrite() +* PWM frequency is now 732.4Hz (before it was 187500.0Hz) SAMD CORE 1.6.6 2016.05.19 diff --git a/cores/arduino/wiring_analog.c b/cores/arduino/wiring_analog.c index 4ef07f51b..b87dccca2 100644 --- a/cores/arduino/wiring_analog.c +++ b/cores/arduino/wiring_analog.c @@ -256,8 +256,8 @@ void analogWrite(uint32_t pin, uint32_t value) // Disable TCx TCx->COUNT8.CTRLA.bit.ENABLE = 0; syncTC_8(TCx); - // Set Timer counter Mode to 8 bits, normal PWM - TCx->COUNT8.CTRLA.reg |= TC_CTRLA_MODE_COUNT8 | TC_CTRLA_WAVEGEN_NPWM; + // Set Timer counter Mode to 8 bits, normal PWM, prescaler 1/256 + TCx->COUNT8.CTRLA.reg |= TC_CTRLA_MODE_COUNT8 | TC_CTRLA_WAVEGEN_NPWM | TC_CTRLA_PRESCALER_DIV256; syncTC_8(TCx); // Set the initial value TCx->COUNT8.CC[tcChannel].reg = (uint8_t) value; @@ -274,6 +274,9 @@ void analogWrite(uint32_t pin, uint32_t value) // Disable TCCx TCCx->CTRLA.bit.ENABLE = 0; syncTCC(TCCx); + // Set prescaler to 1/256 + TCCx->CTRLA.reg |= TCC_CTRLA_PRESCALER_DIV256; + syncTCC(TCCx); // Set TCx as normal PWM TCCx->WAVE.reg |= TCC_WAVE_WAVEGEN_NPWM; syncTCC(TCCx);