Timer Interrupts on Due

Thanks to "stimmer" I got the right frequency of 1HZ or Period of 1sec, luckily. My next step is to use the "Serial Monitor" to change the frequency.

When I use the following approach. And put something in the command line it starts to blink but it is not the exact frequency. Afterwards, when I put another amount in the command line, the frequency does not change.

What do you suggest to read from the Serial monitor to change the frequency?

Thank you.

volatile boolean l;


void TC0_Handler()
{
    long dummy=REG_TC0_SR0; // vital - reading this clears some flag
                            // otherwise you get infinite interrupts
    l= !l;
}

void setup(){
  Serial.begin(9600);
  pinMode(13,OUTPUT);
  pinMode(2,OUTPUT);    // port B pin 25  
  analogWrite(2,255);   // sets up some other registers I haven't worked out yet
  REG_PIOB_PDR = 1<<25; // disable PIO, enable peripheral
  REG_PIOB_ABSR= 1<<25; // select peripheral B
  REG_TC0_CMR0=0b00000000000010011100010000000000; // set channel mode register (see datasheet)
  REG_TC0_CCR0=0b101;    // start counter
  REG_TC0_IER0=0b00010000; // enable interrupt on counter=rc
  REG_TC0_IDR0=0b11101111; // disable other interrupts

  NVIC_EnableIRQ(TC0_IRQn); // enable TC0 interrupts

}


void loop(){
    
       digitalWrite(13,l);

          if (Serial.available() > 0) {

int x = Serial.read();

REG_TC0_RC0 = x*pow(10,6);  // counter period      ----  POW (base, exponent)     .5 ==> almost 1sec   10^8 = 0x5F5E100   

}
       
       
}

stimmer: I think I'm getting somewhere with this... try this:

volatile boolean l;

void TC0_Handler() {     long dummy=REG_TC0_SR0; // vital - reading this clears some flag                             // otherwise you get infinite interrupts     l= !l; }

void setup(){   pinMode(13,OUTPUT);   pinMode(2,OUTPUT);    // port B pin 25    analogWrite(2,255);   // sets up some other registers I haven't worked out yet   REG_PIOB_PDR = 1<<25; // disable PIO, enable peripheral   REG_PIOB_ABSR= 1<<25; // select peripheral B   REG_TC0_WPMR=0x54494D00; // enable write to registers   REG_TC0_CMR0=0b00000000000010011100010000000000; // set channel mode register (see datasheet)   REG_TC0_RC0=100000000; // counter period   REG_TC0_RA0=30000000;  // PWM value   REG_TC0_CCR0=0b101;    // start counter   REG_TC0_IER0=0b00010000; // enable interrupt on counter=rc   REG_TC0_IDR0=0b11101111; // disable other interrupts

  NVIC_EnableIRQ(TC0_IRQn); // enable TC0 interrupts

}

void loop(){       digitalWrite(13,l); }



The timer controls the output of pin 2 and the interrupt toggles a flag which is output on pin 13.

Could you please somebody kindly explain me the Handler part and "!l" please?

I cannot find such section on the data sheet.

Thanks.

A “Handler” is a default callback function, in this case, called when the timer is triggered.
In order to “reset” the timer, and let’s say, “tell the uController that you handled the callback”, you must reset a flag (the one in the first line), otherwise, it would get into a infinite loop, as the flag is not erased.

If you wish, you can use my library, where all timers are fully implemented: GitHub - ivanseidel/DueTimer: ⏳ Timer Library fully implemented for Arduino DUE

Hope it helps! (Library is commented, so it might help…)

Hey guys,

I am trying to get the timer interrupt works. I used your library, also I tried using without library, but if I set the frequency for 200kHz, I always get a waveform on oscilloscope with the half frequency, so 100kHz. Is that right? I couldn't get 1MHz as someone said in a post before, the maximum was 585kHz, when I set the frequency for 2MHz.

Someone can help me?

Thanks

//Chirp wave output

//#include 

#define TAM 4095

int frequency = 1000000;
volatile int i = 0;

void waveGenerate(){
  dacc_write_conversion_data(DACC_INTERFACE, (i=!i)*4095);
  //dacc_write_conversion_data(DACC_INTERFACE, sinWave[i++]);
  //if(i==4096)
  //  i=0;
}

void setup(){
  Serial.begin(9600);
  pinMode(DAC0, OUTPUT);
  analogWriteResolution(12);
  pmc_enable_periph_clk(DACC_INTERFACE_ID);
  dacc_reset(DACC_INTERFACE);
  dacc_set_transfer_mode(DACC_INTERFACE, 0); 
  dacc_set_power_save(DACC_INTERFACE, 0, 1); //Sleep mode = 0 (Normal Mode), Fast Wake Up = 1 (Enabled)
  dacc_set_timing(DACC_INTERFACE, 0x0, 1, 0x0); //REFRESH 0x0, MAXS = 1 (Max Speed Mode Enabled), STARTUP = 0 (0 periods of DACClock)
  
  dacc_set_writeprotect(DACC_INTERFACE, 0); //Disable 
  dacc_set_analog_control(DACC_INTERFACE, DACC_ACR_IBCTLCH0(0x02) |
                   DACC_ACR_IBCTLCH1(0x02) |
                   DACC_ACR_IBCTLDACCORE(0x01));
  dacc_disable_trigger(DACC_INTERFACE);
  dacc_set_channel_selection(DACC_INTERFACE, 0);
  dacc_enable_channel(DACC_INTERFACE, 0);
  

  Timer4.attachInterrupt(waveGenerate).setFrequency(frequency).start();
}

void loop(){

}

rgbp: Hey guys,

I am trying to get the timer interrupt works. I used your library, also I tried using without library, but if I set the frequency for 200kHz, I always get a waveform on oscilloscope with the half frequency, so 100kHz. Is that right? I couldn't get 1MHz as someone said in a post before, the maximum was 585kHz, when I set the frequency for 2MHz.

Someone can help me?

Thanks

//Chirp wave output

//#include

define TAM 4095

int frequency = 1000000; volatile int i = 0;

void waveGenerate(){  dacc_write_conversion_data(DACC_INTERFACE, (i=!i)*4095);  //dacc_write_conversion_data(DACC_INTERFACE, sinWave[i++]);  //if(i==4096)  //  i=0; }

void setup(){  Serial.begin(9600);  pinMode(DAC0, OUTPUT);  analogWriteResolution(12);  pmc_enable_periph_clk(DACC_INTERFACE_ID);  dacc_reset(DACC_INTERFACE);  dacc_set_transfer_mode(DACC_INTERFACE, 0);  dacc_set_power_save(DACC_INTERFACE, 0, 1); //Sleep mode = 0 (Normal Mode), Fast Wake Up = 1 (Enabled)  dacc_set_timing(DACC_INTERFACE, 0x0, 1, 0x0); //REFRESH 0x0, MAXS = 1 (Max Speed Mode Enabled), STARTUP = 0 (0 periods of DACClock)    dacc_set_writeprotect(DACC_INTERFACE, 0); //Disable  dacc_set_analog_control(DACC_INTERFACE, DACC_ACR_IBCTLCH0(0x02) |                   DACC_ACR_IBCTLCH1(0x02) |                   DACC_ACR_IBCTLDACCORE(0x01));  dacc_disable_trigger(DACC_INTERFACE);  dacc_set_channel_selection(DACC_INTERFACE, 0);  dacc_enable_channel(DACC_INTERFACE, 0);  

 Timer4.attachInterrupt(waveGenerate).setFrequency(frequency).start(); }

void loop(){

}

Notice that: Setting timer interrupt for 1hz (for example), would generate 1seccond of HIGH and 1 seccond of LOW, read as 0.5hz (1/2 of the interrupt frequency) If you set it to 200khz, than you would be setting High 100.000 times per seccond, and low 100.000times per seccond. witch is 100.000hz (100khz, or, half of 200khz) =]

ivanseidel: A "Handler" is a default callback function, in this case, called when the timer is triggered. In order to "reset" the timer, and let's say, "tell the uController that you handled the callback", you must reset a flag (the one in the first line), otherwise, it would get into a infinite loop, as the flag is not erased.

If you wish, you can use my library, where all timers are fully implemented: https://github.com/ivanseidel/DueTimer

Hope it helps! (Library is commented, so it might help...)

Thanks for your response.

Actually I have used your header file + Simple timer but I dunno why pin 13 does not blink. Should I change it somewhere?

I merge two files as I couldn't use them separately as follows.

/*
DueTimer.h - DueTimer header file, definition of methods and attributes...
For instructions, go to https://github.com/ivanseidel/DueTimer

Created by Ivan Seidel Gomes, March, 2013.
Released into the public domain.
*/

#ifdef __arm__

#ifndef DueTimer_h
#define DueTimer_h

#include "Arduino.h"

#include 

class DueTimer
{
protected:
int timer; // Stores the object timer id (to access Timer struct array)
static int _frequency[9]; // Stores the object timer frequency (to access know current timer period, frequency...)

static uint8_t bestClock(uint32_t frequency, uint32_t& retRC); // Picks the best clock to lower the error

public:
struct Timer
{
Tc *tc;
uint32_t channel;
IRQn_Type irq;
};

static DueTimer getAvaliable();

static const Timer Timers[9]; // Store timer configuration (static, as it's fix for every object)
static void (*callbacks[9])(); // Needs to be public, because the handlers are outside class

DueTimer(int _timer);
DueTimer attachInterrupt(void (*isr)());
DueTimer detachInterrupt();
DueTimer start(long microseconds = -1);
DueTimer stop();
DueTimer setFrequency(long frequency);
DueTimer setPeriod(long microseconds);


long getFrequency();
long getPeriod();
};

extern DueTimer Timer; // Just to call Timer.getAvaliable instead of Timer::getAvaliable()

extern DueTimer Timer0;
extern DueTimer Timer1;
extern DueTimer Timer2;
extern DueTimer Timer3;
extern DueTimer Timer4;
extern DueTimer Timer5;
extern DueTimer Timer6;
extern DueTimer Timer7;
extern DueTimer Timer8;

#endif

#else
#pragma message("Ops! Trying to include DueTimer on another device?")
#endif








/////////


int myLed = 13;

bool ledOn = false;
void myHandler(){
ledOn = !ledOn;

digitalWrite(myLed, ledOn); // Led on, off, on, off...
}

void setup(){
pinMode(myLed, OUTPUT);

Timer3.attachInterrupt(myHandler);
Timer3.start(50000); // Calls every 50ms
}

void loop(){

while(1){
// I'm stuck in here! help me...
}

}

Hi, Apparently you have only included the header file... no implementation is made to the class DueTimer. Why did you added the header to the code, instead of including the library? Did it compiled? Did you installed the library correcly, and examples are on the examples menu of arduino IDE? Ivan

ivanseidel: Hi, Apparently you have only included the header file... no implementation is made to the class DueTimer. Why did you added the header to the code, instead of including the library? Did it compiled? Did you installed the library correcly, and examples are on the examples menu of arduino IDE? Ivan

Dear Ivan,

Let me explain you what exactly I do. I go to the Simple Timer and copy and paste it in a new Arduino page and save on my desktop. (It has the header #include )

Thereafter, I go to the header file and save it on the desktop as well beside the Simple Timer.

But when I run it has the following error:

fatal error: DueTimer.h: No such file or directory compilation terminated.

Can you please kindly advise me about this?

Thanks.

Henrimontreal, you are only getting the header - you need all the code which is packaged up as a library and placed within the Arduino IDE Library folder prior to writing your program. See http://learn.adafruit.com/adafruit-all-about-arduino-libraries-install-use on libraries and how they are used. Then you can get the timer library, install it like in the tutorial, then your code will not give such error(s). Putting the .h file on your desktop is not enough.

[quote author=Sebastian Vik link=topic=130423.msg984328#msg984328 date=1352148520] Using this code, you can set a timer for any of the ISRs TC0_Handler through TC8_Handler, see table of parameters below. It is possible to use the timers without a physically mapped pin, such as TC1 channel 0 (TC3_Handler) shown here:

volatile boolean l;

//TC1 ch 0
void TC3_Handler()
{
        TC_GetStatus(TC1, 0);
        digitalWrite(13, l = !l);
}

void startTimer(Tc *tc, uint32_t channel, IRQn_Type irq, uint32_t frequency) {
        pmc_set_writeprotect(false);
        pmc_enable_periph_clk((uint32_t)irq);
        TC_Configure(tc, channel, TC_CMR_WAVE | TC_CMR_WAVSEL_UP_RC | TC_CMR_TCCLKS_TIMER_CLOCK4);
        uint32_t rc = VARIANT_MCK/128/frequency; //128 because we selected TIMER_CLOCK4 above
        TC_SetRA(tc, channel, rc/2); //50% high, 50% low
        TC_SetRC(tc, channel, rc);
        TC_Start(tc, channel);
        tc->TC_CHANNEL[channel].TC_IER=TC_IER_CPCS;
        tc->TC_CHANNEL[channel].TC_IDR=~TC_IER_CPCS;
        NVIC_EnableIRQ(irq);
}

void setup(){
        pinMode(13,OUTPUT);
        startTimer(TC1, 0, TC3_IRQn, 4); //TC1 channel 0, the IRQ for that channel and the desired frequency
}

void loop(){
}

Here is the table of parameters:

| ISR/IRQ | TC | Channel | Due pins | | - | - | - | - | | TC0 | TC0 | 0 | 2, 13 | | TC1 | TC0 | 1 | 60, 61 | | TC2 | TC0 | 2 | 58 | | TC3 | TC1 | 0 | none <- this line in the example above | | TC4 | TC1 | 1 | none | | TC5 | TC1 | 2 | none | | TC6 | TC2 | 0 | 4, 5 | | TC7 | TC2 | 1 | 3, 10 | | TC8 | TC2 | 2 | 11, 12 |

[/quote]

As you said:

TC6 TC2 0 4, 5

but when I change TC to TC2 and choose channel 0 and choose either 4 or 5 pin it does not blink!

Do I need to change the clock as well? Actually we do not have clock 6!!!

Can you please explain me how can I get frequency from the other channels and timers please?

Thanks!

TheKitty: Henrimontreal, you are only getting the header - you need all the code which is packaged up as a library and placed within the Arduino IDE Library folder prior to writing your program. See http://learn.adafruit.com/adafruit-all-about-arduino-libraries-install-use on libraries and how they are used. Then you can get the timer library, install it like in the tutorial, then your code will not give such error(s). Putting the .h file on your desktop is not enough.

Well, this is so strange! Even though, I copy them into the Arduino's Library as well as the same folder on my desktop. I still have the same error! :astonished: I am so frustrated! :stuck_out_tongue_closed_eyes:

henrimontreal:

TheKitty: Henrimontreal, you are only getting the header - you need all the code which is packaged up as a library and placed within the Arduino IDE Library folder prior to writing your program. See http://learn.adafruit.com/adafruit-all-about-arduino-libraries-install-use on libraries and how they are used. Then you can get the timer library, install it like in the tutorial, then your code will not give such error(s). Putting the .h file on your desktop is not enough.

Well, this is so strange! Even though, I copy them into the Arduino's Library as well as the same folder on my desktop. I still have the same error! :astonished: I am so frustrated! :stuck_out_tongue_closed_eyes:

Hi, I have sent a new commit to GitHub, with a new organization to facilitate installation. Please, download egain (https://github.com/ivanseidel/DueTimer/archive/master.zip) the files, and install as explained on Arduino site.

Thanks, Ivan Seidel

Thanks guys for this mission. I got 1 MHz working on the DUE, but I found that digitalWrite is slow. So it messes up my tc_handler. Doesn't leave it anymore. And I need to write in the ISR, maximum control every microsecond. You have a fast alternative for digitalWrite ?

MarXoft: Thanks guys for this mission. I got 1 MHz working on the DUE, but I found that digitalWrite is slow. So it messes up my tc_handler. Doesn't leave it anymore. And I need to write in the ISR, maximum control every microsecond. You have a fast alternative for digitalWrite ?

after configuring the pin, you can easily do as it follows:

Output HIGH on PIN 0 of port D: REG_PIOD_SODR = 0x01; ( equivalent to: 0b0000000000000001);

Output low on PIN 0 of port D: REG_PIOD_CODR = 0x01; ( equivalent to: 0b0000000000000001);

And, to configure PIN 0 of port D as output pin: REG_PIOD_OER = 0x01; ( equivalent to: 0b0000000000000001);

Notice, that even digital pins are buffered, so, trying to read this register, will return NULL or some random value...

Also, writing more than one pin on the register will cause NO problem.

Also, to know wich port the pin relates with, read the arduino description, right on top, there is an link to check this...

There is one other easy way of doing this, but i'm without a computer right now...

MarXoft: Thanks guys for this mission. I got 1 MHz working on the DUE, but I found that digitalWrite is slow. So it messes up my tc_handler. Doesn't leave it anymore. And I need to write in the ISR, maximum control every microsecond. You have a fast alternative for digitalWrite ?

digitalWriteDirect() will work faster than 1MHz, although it may be a challenge to get it that fast in an interrupt due to overhead. Try it anyway.

inline void digitalWriteDirect(int pin, boolean val){
  if(val) g_APinDescription[pin].pPort -> PIO_SODR = g_APinDescription[pin].ulPin;
  else    g_APinDescription[pin].pPort -> PIO_CODR = g_APinDescription[pin].ulPin;
}

inline int digitalReadDirect(int pin){
  return !!(g_APinDescription[pin].pPort -> PIO_PDSR & g_APinDescription[pin].ulPin);
}

Thanks for the fast reply. When I have the time I'll try.

-= Keep the good work goin' =-

mnpumar: [quote author=Sebastian Vik link=topic=130423.msg984328#msg984328 date=1352148520] Using this code, you can set a timer for any of the ISRs TC0_Handler through TC8_Handler, see table of parameters below. It is possible to use the timers without a physically mapped pin, such as TC1 channel 0 (TC3_Handler) shown here:

volatile boolean l;

//TC1 ch 0 void TC3_Handler() {        TC_GetStatus(TC1, 0);        digitalWrite(13, l = !l); }

void startTimer(Tc *tc, uint32_t channel, IRQn_Type irq, uint32_t frequency) {        pmc_set_writeprotect(false);        pmc_enable_periph_clk((uint32_t)irq);        TC_Configure(tc, channel, TC_CMR_WAVE | TC_CMR_WAVSEL_UP_RC | TC_CMR_TCCLKS_TIMER_CLOCK4);        uint32_t rc = VARIANT_MCK/128/frequency; //128 because we selected TIMER_CLOCK4 above        TC_SetRA(tc, channel, rc/2); //50% high, 50% low        TC_SetRC(tc, channel, rc);        TC_Start(tc, channel);        tc->TC_CHANNEL[channel].TC_IER=TC_IER_CPCS;        tc->TC_CHANNEL[channel].TC_IDR=~TC_IER_CPCS;        NVIC_EnableIRQ(irq); }

void setup(){        pinMode(13,OUTPUT);        startTimer(TC1, 0, TC3_IRQn, 4); //TC1 channel 0, the IRQ for that channel and the desired frequency }

void loop(){ }




Here is the table of parameters:


| ISR/IRQ | TC | Channel | Due pins |
| - | - | - | - |
| TC0 | TC0 | 0 | 2, 13 |
| TC1 | TC0 | 1 | 60, 61 |
| TC2 | TC0 | 2 | 58 |
| TC3 | TC1 | 0 | none <- this line in the example above |
| TC4 | TC1 | 1 | none |
| TC5 | TC1 | 2 | none |
| TC6 | TC2 | 0 | 4, 5 |
| TC7 | TC2 | 1 | 3, 10 |
| TC8 | TC2 | 2 | 11, 12 |

Noob question here, could someone please explain the inputs to the startTimer function? What is channel, and how do we use the frequency input? Also, what are the pins in the table for? [/quote]

Can anyone kindly answer to the following question please? How can we disable the Timer by turning off the PWM? (Outside of Timer Function)

henrimontreal:

mnpumar: [quote author=Sebastian Vik link=topic=130423.msg984328#msg984328 date=1352148520] Using this code, you can set a timer for any of the ISRs TC0_Handler through TC8_Handler, see table of parameters below. It is possible to use the timers without a physically mapped pin, such as TC1 channel 0 (TC3_Handler) shown here:

volatile boolean l;

//TC1 ch 0 void TC3_Handler() {        TC_GetStatus(TC1, 0);        digitalWrite(13, l = !l); }

void startTimer(Tc *tc, uint32_t channel, IRQn_Type irq, uint32_t frequency) {        pmc_set_writeprotect(false);        pmc_enable_periph_clk((uint32_t)irq);        TC_Configure(tc, channel, TC_CMR_WAVE | TC_CMR_WAVSEL_UP_RC | TC_CMR_TCCLKS_TIMER_CLOCK4);        uint32_t rc = VARIANT_MCK/128/frequency; //128 because we selected TIMER_CLOCK4 above        TC_SetRA(tc, channel, rc/2); //50% high, 50% low        TC_SetRC(tc, channel, rc);        TC_Start(tc, channel);        tc->TC_CHANNEL[channel].TC_IER=TC_IER_CPCS;        tc->TC_CHANNEL[channel].TC_IDR=~TC_IER_CPCS;        NVIC_EnableIRQ(irq); }

void setup(){        pinMode(13,OUTPUT);        startTimer(TC1, 0, TC3_IRQn, 4); //TC1 channel 0, the IRQ for that channel and the desired frequency }

void loop(){ }




Here is the table of parameters:


| ISR/IRQ | TC | Channel | Due pins |
| - | - | - | - |
| TC0 | TC0 | 0 | 2, 13 |
| TC1 | TC0 | 1 | 60, 61 |
| TC2 | TC0 | 2 | 58 |
| TC3 | TC1 | 0 | none <- this line in the example above |
| TC4 | TC1 | 1 | none |
| TC5 | TC1 | 2 | none |
| TC6 | TC2 | 0 | 4, 5 |
| TC7 | TC2 | 1 | 3, 10 |
| TC8 | TC2 | 2 | 11, 12 |


Noob question here, could someone please explain the inputs to the startTimer function? What is channel, and how do we use the frequency input? Also, what are the pins in the table for?

Can anyone kindly answer to the following question please? How can we disable the Timer by turning off the PWM? (Outside of Timer Function)

[/quote]

Hi,

If it's really needed to understand the code, i suggest you looking at the Datasheet, that is the best place to get those explanations since every uController is different.

But, if you just want to use timers on arduino Due, install the DueTimer library: github.com/ivanseidel/DueTimer

Regards, Ivan

[quote author=Sebastian Vik link=topic=130423.msg984328#msg984328 date=1352148520] Using this code, you can set a timer for any of the ISRs TC0_Handler through TC8_Handler, see table of parameters below. It is possible to use the timers without a physically mapped pin, such as TC1 channel 0 (TC3_Handler) shown here:

volatile boolean l;

//TC1 ch 0
void TC3_Handler()
{
        TC_GetStatus(TC1, 0);
        digitalWrite(13, l = !l);
}

void startTimer(Tc *tc, uint32_t channel, IRQn_Type irq, uint32_t frequency) {
        pmc_set_writeprotect(false);
        pmc_enable_periph_clk((uint32_t)irq);
        TC_Configure(tc, channel, TC_CMR_WAVE | TC_CMR_WAVSEL_UP_RC | TC_CMR_TCCLKS_TIMER_CLOCK4);
        uint32_t rc = VARIANT_MCK/128/frequency; //128 because we selected TIMER_CLOCK4 above
        TC_SetRA(tc, channel, rc/2); //50% high, 50% low
        TC_SetRC(tc, channel, rc);
        TC_Start(tc, channel);
        tc->TC_CHANNEL[channel].TC_IER=TC_IER_CPCS;
        tc->TC_CHANNEL[channel].TC_IDR=~TC_IER_CPCS;
        NVIC_EnableIRQ(irq);
}

void setup(){
        pinMode(13,OUTPUT);
        startTimer(TC1, 0, TC3_IRQn, 4); //TC1 channel 0, the IRQ for that channel and the desired frequency
}

void loop(){
}

Here is the table of parameters:

| ISR/IRQ | TC | Channel | Due pins | | - | - | - | - | | TC0 | TC0 | 0 | 2, 13 | | TC1 | TC0 | 1 | 60, 61 | | TC2 | TC0 | 2 | 58 | | TC3 | TC1 | 0 | none <- this line in the example above | | TC4 | TC1 | 1 | none | | TC5 | TC1 | 2 | none | | TC6 | TC2 | 0 | 4, 5 | | TC7 | TC2 | 1 | 3, 10 | | TC8 | TC2 | 2 | 11, 12 |

[/quote]

I'm a bit confused about the code for the startTimer function.

-What is the purpose of TC3_Handler() and how does it interact with startTimer()? -Once startTimer() is called, how do I stop the timer(how do I disable PWM)? -There's a few lines that I don't understand in startTimer():

        TC_Configure(tc, channel, TC_CMR_WAVE | TC_CMR_WAVSEL_UP_RC | TC_CMR_TCCLKS_TIMER_CLOCK4); <--- How does TC_Configure() work? Where can I find reference about this?
        uint32_t rc = VARIANT_MCK/128/frequency; <---------- is VARIANT_MCK the frequency of arduino DUE(84MHz)? What does rc do?
        TC_SetRA(tc, channel, rc/2); //50% high, 50% low<----sets the duty cycle? 
        TC_SetRC(tc, channel, rc);<---------- what is this line for?
        TC_Start(tc, channel);<---------------enables PWM? How does it work?
        tc->TC_CHANNEL[channel].TC_IER=TC_IER_CPCS;<----------What does this line do?
        tc->TC_CHANNEL[channel].TC_IDR=~TC_IER_CPCS;<--------What does this line do?
        NVIC_EnableIRQ(irq); <-----enables interrupt?

StartTimer starts the timer. this function needs to be called once. after Starttimer is finished, the (hardware) timer keeps running on it's own, without any need for code. the timer counts up to a certain value, then generates an interrupt, starts with 0 and continues counting.

TC3_handler is called each time the interrupt of Timer/Counter TC3 (=timer 1 channel 0) is generated by the timer. "TC3_handler" is a pre-determined functionname just like "setup" and "loop" because TC3_handler is called for each interrupt, it is called as often as the timer hits that "certain value". The lower that value the more often the TC3_handler is executed.

TC_Configure(tc, channel, TC_CMR_WAVE | TC_CMR_WAVSEL_UP_RC | TC_CMR_TCCLKS_TIMER_CLOCK4); Read the datasheet paragraph 37.7.11, fields WAVE, WAVSEL, TCCLKS. TC_configure just sets bits in the TC_CMR register that belongs to TC3 (= Timer 1 channel 0 )

uint32_t rc = VARIANT_MCK/128/frequency; <---------- is VARIANT_MCK the frequency of arduino DUE(84MHz)? What does rc do? Serial.Println(VARIANT_MCK,DEC) will enlighten. spoiler : yes rc is the value the timer counts towards. it is that "certain value" I mentioned above.

TC_SetRA(tc, channel, rc/2); //50% high, 50% low<----sets the duty cycle? yes, see datasheet 37.6.11.1, for instance.

TC_SetRC(tc, channel, rc);<---------- what is this line for? it sets the value the timer counts towards. so it defines the frequency of the interrupts generated by the timer

TC_Start(tc, channel);<---------------enables PWM? How does it work? no, it starts the timer. the timer begins incrementing now.

tc->TC_CHANNEL[channel].TC_IER=TC_IER_CPCS;<----------What does this line do? I'm not sure but I think it sets the flag that specifies an interrupt is desired when timer = rc. IER = interrupt Enable Register

tc->TC_CHANNEL[channel].TC_IDR=~TC_IER_CPCS;<--------What does this line do? IDR = interrupt disable register, all other interrupt-types supported by TC3 are disabled and will not occur.

NVIC_EnableIRQ(irq); <-----enables interrupt? yes. it is the overall enabler, allowing interrupts to be generated by TC3.