Faster / Stabler Interrupt on Timer Match on the Due

So after trying to get my Arduino Due oscilloscope to work with interrupts at high speeds I finally figured out a method of creating an Interrupt on Timer Match.

First I will show you the OLD method that I found on elsewhere in this forum from 2012.

This method is limited to about 600Khz of ADC samples before the chip freezes

void initTimer(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_CLOCK1);
  uint32_t rc = VARIANT_MCK/2/frequency; //2 because we selected TIMER_CLOCK1 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);
}

The new method below can do about double that at 1.2Mhz. While the method above initializes the SAM3X8E's internal wave generator at 50% duty cycle set to trigger an interrupt upon the rising edge on the wave, my "new" method is simply sets up a timer and when the timer matches a register's stored value, triggers an interrupt...simpler...faster...stabler...

/*
tc         Timer Counter, TC0, TC1, TC2
channel    Timer Channel, 0 - 2
irq        IRQ, take your timer counter #, multiply by 3 + timer channel = TC#_IRQn
frequency  interrupt frequency per second
*/
void initTimer(Tc *tc, uint32_t channel, IRQn_Type irq, uint32_t frequency)
{
  pmc_set_writeprotect(false); //remove write protection on registers
  pmc_enable_periph_clk((uint32_t)irq); //we need a clock?
  TC_Configure(tc, channel, TC_CMR_TCCLKS_TIMER_CLOCK1 | TC_CMR_CPCTRG); //set clock rate (CLOCK1 is MCK/2) and reset counter register C on match
  tc->TC_CHANNEL[channel].TC_IER |= TC_IER_CPCS; //enable interrupt on timer match with register C
  tc->TC_CHANNEL[channel].TC_RC   = (VARIANT_MCK >> 1) / frequency; //interrupt occurs every x interations of the timer counter
  TC_Start(tc, channel); //start timer counter
  NVIC_EnableIRQ(irq); //enable Nested Vector Interrupt Controller
}

You can use any of the timers, 0,1,2 and any channel of those timers, 0,1,2

ISR/IRQ	TC      Channel	Due pins
TC0	TC0	0	2, 13
TC1	TC0	1	60, 61
TC2	TC0	2	58
TC3	TC1	0	none  <-| 
TC4	TC1	1	none  <-| Use these timers, they are not connected to any pins
TC5	TC1	2	none  <-| 
TC6	TC2	0	4, 5
TC7	TC2	1	3, 10
TC8	TC2	2	11, 12

To call the ISR, just use this code

void TC3_Handler() //our ISR for Timer Counter 3 (TC1 Channel 0)
{
  TC1->TC_CHANNEL[0].TC_SR; //This replaces TC_GetStatus(TC1, 0); (which is slow) and is required inside the ISR
}

Example

initTimer(TC1, 0, TC3_IRQn, 1000000); //1Mhz Interrupt

To Stop it
tc->TC_CHANNEL[channel].TC_IDR=TC_IER_CPCS; //disable interrupt

To Start it
tc->TC_CHANNEL[channel].TC_IER=TC_IER_CPCS; //enable interrupt
tc->TC_CHANNEL[channel].TC_IDR=~TC_IER_CPCS;//remove disable interrupt

Anyway, hope this helps anyone:/ ...If this is not new...delete it...