Go Down

Topic: Changing pin numbers and timers in PWM code and timer interrupts (Read 552 times) previous topic - next topic

cyborg5

A huge thanks to MartinL for all of his help in helping me implement PWM and timer interrupts.

I still have a few questions because I don't really understand the code very well.

I have a preliminary version of my infrared library IRLib2 that now supports SAMD21. For output I can effectively set the frequency of the PWM and turn it off and on as needed to send IR signals. For sending I'm using TCC1, GCLK4, and pin D9 and it works fine. But I would like to give the user the option to use different timers different clocks and different output pins.

For input I'm also generating a timer interrupt every 50 microseconds using TC3 and GCLK0. Again I would like to have the flexibility to allow the user to edit the library easily to use a different TC and GCLK.

My first question is in what file are all of the definitions for these registers and bit patterns defined. The sample code you posted here is really helpful but I can't modify it if I don't know what's possible. I've heard talk of the file called "SAM.h" but I don't know if that's what I'm looking for. Also where specifically what I find the file I'm looking for on a Windows installation of the standard Arduino.cc IDE?

Next question: What are the differences if any between the various GCLK clocks? Are any of them reserved for Arduino infrastructure? It so happens that I'm using GCLK4 and GCLK0 four sending and receiving respectively just because that's what the sample code that I found here with using. In both instances I am using the standard 48 MHz clock with a divisor of 1 so it would seem to be I could use the same clock for both purposes. Is this a valid assumption? Why would I want to use 2 different clocks?

Next question: What are the restrictions if any and code changes if any to use a different pins number for PWM? The code that you posted in this message…
http://forum.arduino.cc/index.php?topic=346731.msg2933550#msg2933550

Contains among other things the following lines…
Code: [Select]
// Enable the port multiplexer for the PWM channel on pin D9 
  PORT->Group[g_APinDescription[9].ulPort].PINCFG[g_APinDescription[9].ulPin].bit.PMUXEN = 1;
 
  // Connect the TCC1 timer to the port outputs - port pins are paired odd PMUO and even PMUXE
  // F & E peripherals specify the timers: TCC0, TCC1 and TCC2
  PORT->Group[g_APinDescription[9].ulPort].PMUX[g_APinDescription[9].ulPin >> 1].reg |= PORT_PMUX_PMUXO_E;

Is it just a matter of changing the "9" to a different pins number or are there other considerations? I want to give the user the flexibility to specify just about any possible pin for PWM output without doing anything to mess up the normally Arduino infrastructure. What pin numbers are legal and how significant are the code changes to have a different pin number?

Again many thanks to MartinL and other participants in his threads for providing such excellent sample code and clear explanations.

AloyseTech

Take a look here if you want to see every defined register and much more.

cyborg5

Many thanks. If anyone else is curious, I managed to find the on my hard drive once I knew what to look for. It is located on a Windows PC at

C:\Users\Your_Name\AppData\Local\Arduino15\packages\arduino\tools\CMSIS-Atmel\1.1.0\CMSIS\Device\ATMEL\samd21\include


MartinL

Hi cyborg5

Quote
Next question: What are the differences if any between the various GCLK clocks? Are any of them reserved for Arduino infrastructure? It so happens that I'm using GCLK4 and GCLK0 four sending and receiving respectively just because that's what the sample code that I found here with using. In both instances I am using the standard 48 MHz clock with a divisor of 1 so it would seem to be I could use the same clock for both purposes. Is this a valid assumption? Why would I want to use 2 different clocks?
Yes, GCLKs 0 to 3 are used by the Arduino core code, this leaves GCLKs 4 to 7 to use as you wish. If you're using the 48MHz clock for you timers then it's possible to use GCLK0 that's already running at this frequency.

Quote
Next question: What are the restrictions if any and code changes if any to use a different pins number for PWM? The code that you posted in this message…
Yes there are restrictions, as only certain pins are capable of outputting the TCC timer outputs used for PWM. Each of the SAMD21's pins can be either GPIO or switch to a number of peripheral devices labelled: A - H. Which perhipherals are available on what pin is shown in the Port Multiplexing Table in the SAMD21's datasheet.

Quote
I want to give the user the flexibility to specify just about any possible pin for PWM output without doing anything to mess up the normally Arduino infrastructure. What pin numbers are legal and how significant are the code changes to have a different pin number?
Provided the given pin can support the TCC timer then the code changes are minimal, just a matter of changing the pin number in the brackets [], specifying the correct peripheral function (A-H) and whether the port pin is odd or even, e.g. digital pin D6 = PA20 = even, digital pin D7 = PA21 = odd. Odd or even relates to the PAxx value. 


cyborg5

This is all great information. Many thanks.

Now that I've found the include files with all those register definitions, that in conjunction with the datasheet should get me to most of my remaining questions. Of course the more I understand about this system, the more things that come up :-)

So far I've just been doing a lot of cut and paste from your examples and others but I really would like to know how it all works.

One more question:  can you point me to a reference or somewhere in the datasheet explaining what he registers or bits need to be checked in a "while (…)" loop for synchronization purposes? So far I've just been doing cut and paste but I would like to understand it better myself.


MartinL

More information about synchronization can be found in the SAMD21 Datasheet under the Clock System section: Synchronous and Asychronous Clocks and Register Synchronization.

It took me a while to understand synchronization and how it's used, as the datasheet doesn't provide any examples.

Peripherals are driven by an APB/AHB clock domain that controls their register interface, as well as an asynchronous generic clock domain used to drive the peripheral itself. Some peripheral registers require that these clocks are synchronized before they can be read from or written to.

There are two types of register synchronization:

Common synchronizer register synchronization used on the GCLK, WDT, RTC, EIC, TC, ADC, AC and DAC modules.

Distributed synchronizer register synchronization used on the SERCOM USART, SERCOM SPI, SERCOM I2C, I2S, TCC, USB modules.

As far a I can see, the main difference between them is that failure to synchronize using the common synchronizer comes the dire possibility of stalling the peripheral bus, whereas using the distributed synchronizer the value is merely discarded. The other differences are that the common synchronizer allows for continous read synchronization, while the distributed synchronizer works on a per register basis, so it's possible to write to a number of registers before confirming if synchronization has occured.

Go Up