SAMD21 oneshot timer (no ASF)

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

I'm moving from Arduino project to AVR studio 7. I encounter some issues when implementing the oneshot timer:

 


#define PORTA					0




 PM->APBCMASK.reg |= PM_APBCMASK_EVSYS | PM_APBCMASK_TCC1;           // Switch on the event system peripheral

 ////////////////////////////////////////////////////////////////////////////////////////
 // Genric Clock Initialisation
 ////////////////////////////////////////////////////////////////////////////////////////

 GCLK->CLKCTRL.reg = GCLK_CLKCTRL_CLKEN |         // Enable the generic clock...
 GCLK_CLKCTRL_GEN_GCLK0 |						  // ....on GCLK0 at 48MHz
 GCLK_CLKCTRL_ID_TCC0_TCC1;						  // Feed the GCLK0 to TCC0 and TCC1
 while (GCLK->STATUS.bit.SYNCBUSY);               // Wait for synchronization

 // PA08
 PORT->Group[PORTA].PINCFG[8].bit.PMUXEN = 1;
 PORT->Group[PORTA].PMUX[8 >> 1].reg |= PORT_PMUX_PMUXE_E;

 TCC1->CTRLA.reg = TC_CTRLA_PRESCALER_DIV8 |        // Set prescaler to 8, 48MHz/8 = 6MHz
 TC_CTRLA_PRESCSYNC_PRESC;                          // Set the reset/reload to trigger on prescaler clock

 TCC1->CTRLBSET.reg = TCC_CTRLBSET_ONESHOT | TCC_CTRLBSET_DIR;         // Enable one shot an count down

 while (TCC1->SYNCBUSY.bit.CTRLB);                   // Wait for synchronization

 TCC1->DRVCTRL.reg |= TCC_DRVCTRL_NRE0;              // Continue to drive the output on TCC1/WO[2] when timer has stopped (rather than becoming tri-state)
 //TCC1->DRVCTRL.reg |= TCC_DRVCTRL_INVEN0;          // Invert the output to generate an active low pulse on TCC1/WO[2]

 TCC1->WAVE.reg = TCC_WAVE_WAVEGEN_NPWM;             // Set-up TCC1 timer for Normal (single slope) PWM mode (NPWM)
 while (TCC1->SYNCBUSY.bit.WAVE)                     // Wait for synchronization

 TCC1->PER.reg = 60000;                              // Set-up the PER (period) register for 5ms pulse period
 while (TCC1->SYNCBUSY.bit.PER);                     // Wait for synchronization

 TCC1->CC[0].reg = 30000;                            // Set-up the CC (counter compare), channel 2 register for 5ms pulse width
 while (TCC1->SYNCBUSY.bit.CC0);                     // Wait for synchronization

 TCC1->CTRLA.bit.ENABLE = 1;                         // Enable timer TCC1
 while (TCC1->SYNCBUSY.bit.ENABLE);                  // Wait for synchronization

 

Trying to trigger the oneshot with:

 

if(TCC1->STATUS.bit.STOP)                                                   // Check if the previous pulse is complete
{
    TCC1->CTRLBSET.reg = TCC_CTRLBSET_CMD_RETRIGGER;                          // Retrigger the timer's One/Multi-Shot pulse
    while (TCC1->SYNCBUSY.bit.CTRLB);                                         // Wait for synchronization
}

 

The clock has been configured according: DFLL48M 48 MHz Initialization.

 

For some reason this doesn't work as it used to do in my Arduino project, am I missing something? Do I have to set PA08 as output manually?

This topic has a solution.
Last Edited: Tue. Oct 20, 2020 - 12:11 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

MarcelH wrote:
moving from Arduino project to AVR (sic) studio 7

You mean "Atmel Studio": The SAM D21 is not an AVR - that's why they stopped calling it "AVR Studio".

 

Anyhow, Atmel Studio can import Arduino Projects - have you checked if SAM D21 is supported for that ?

 

https://www.youtube.com/watch?v=...

 

EDIT

 

The video uses a UNO, but the text description says Arduino Zero is supported - that's a SAM D21

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
Last Edited: Mon. Oct 19, 2020 - 03:43 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

MarcelH wrote:
this doesn't work as it used to do in my Arduino project

So what does it do?

 

What debugging have you done?

 

MarcelH wrote:
The clock has been configured according: DFLL48M 48 MHz Initialization.

at 48MHz, you'll need some waitstates ...

Top Tips:

  1. How to properly post source code - see: https://www.avrfreaks.net/comment... - also how to properly include images/pictures
  2. "Garbage" characters on a serial terminal are (almost?) invariably due to wrong baud rate - see: https://learn.sparkfun.com/tutorials/serial-communication
  3. Wrong baud rate is usually due to not running at the speed you thought; check by blinking a LED to see if you get the speed you expected
  4. Difference between a crystal, and a crystal oscillatorhttps://www.avrfreaks.net/comment...
  5. When your question is resolved, mark the solution: https://www.avrfreaks.net/comment...
  6. Beginner's "Getting Started" tips: https://www.avrfreaks.net/comment...
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

awneil, thanks for your reply. You are absolutely right about AVR studio, of course I meant Atmel Studio blush

About the Arduino import, yes I'm aware of this feature, but I would like to build up the functions myself without the Arduino overhead, since mostly I was using hardware functions of the SAMD21 already. Then about the wait states, I've included one wait state during the clock initialization (this already comes with the example project):

 


/* ----------------------------------------------------------------------------------------------
* 1) Set Flash wait states for 48 MHz (per Table 37-40 in data sheet)
*/

NVMCTRL->CTRLB.bit.RWS = 1;		/* 1 wait state required @ 3.3V & 48MHz */

/* ----------------------------------------------------------------------------------------------
* 2) Enable XOSC32K clock (External on-board 32.768kHz oscillator), will be used as DFLL48M reference.
*/

 

What does work is the digital input if I read input state manually, I'm also able to change the digital output. Also a TCC2 PWM timer works and outputs signal on PA16. I understand your point about debugging, but still struggeling with that, I will try to see if the timer does count.

 

Last Edited: Mon. Oct 19, 2020 - 06:14 PM
This reply has been marked as the solution. 
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The solution:

PORT->Group[PORTA].PMUX[8 >> 1].reg |= PORT_PMUX_PMUXE_F;

Instead of using:

PORT->Group[PORTA].PMUX[8 >> 1].reg |= PORT_PMUX_PMUXE_E;