Example

void setup()

{

Serial.begin (57600) ; // was for debugging

adc_setup () ; // setup ADC

pmc_enable_periph_clk (TC_INTERFACE_ID + 0*3+0) ; // clock the TC0 channel 0


TcChannel * t = &(TC0->TC_CHANNEL)[0] ; // pointer to TC0 registers for its channel 0

t->TC_CCR = TC_CCR_CLKDIS ; // disable internal clocking while setup regs

t->TC_IDR = 0xFFFFFFFF ; // disable interrupts

t->TC_SR ; // read int status reg to clear pending

t->TC_CMR = TC_CMR_TCCLKS_TIMER_CLOCK1 | // use TCLK1 (prescale by 2, = 42MHz)

TC_CMR_WAVE | // waveform mode

TC_CMR_WAVSEL_UP_RC | // count-up PWM using RC as threshold

TC_CMR_EEVT_XC0 | // Set external events from XC0 (this setup TIOB as output)

TC_CMR_ACPA_CLEAR | TC_CMR_ACPC_CLEAR |

TC_CMR_BCPB_CLEAR | TC_CMR_BCPC_CLEAR ;

t->TC_RC = 875 ; // counter resets on RC, so sets period in terms of 42MHz clock

t->TC_RA = 440 ; // roughly square wave

t->TC_CMR = (t->TC_CMR & 0xFFF0FFFF) | TC_CMR_ACPA_CLEAR | TC_CMR_ACPC_SET ; // set clear and set from RA and RC compares

t->TC_CCR = TC_CCR_CLKEN | TC_CCR_SWTRG ; // re-enable local clocking and switch to hardware trigger source.


setup_pio_TIOA0 () ; // drive Arduino pin 2 at 48kHz to bring clock out

dac_setup () ; // setup up DAC auto-triggered at 48kHz

REG_PIOC_OER = 0x1 <<22;

REG_PIOB_OER = 0x1 <<27;

}

void setup_pio_TIOA0 () // Configure Ard pin 2 as output from TC0 channel A (copy of trigger event)

{

PIOB->PIO_PDR = PIO_PB25B_TIOA0 ; // disable PIO control

PIOB->PIO_IDR = PIO_PB25B_TIOA0 ; // disable PIO interrupts

PIOB->PIO_ABSR |= PIO_PB25B_TIOA0 ; // switch to B peripheral


}



void dac_setup ()

{

pmc_enable_periph_clk (DACC_INTERFACE_ID) ; // start clocking DAC

DACC->DACC_CR = DACC_CR_SWRST ; // reset DAC


DACC->DACC_MR =

DACC_MR_TRGEN_EN | DACC_MR_TRGSEL (1) | // trigger 1 = TIO output of TC0

(0 << DACC_MR_USER_SEL_Pos) | // select channel 0

DACC_MR_REFRESH (0x0F) | // bit of a guess... I'm assuming refresh not needed at 48kHz

(24 << DACC_MR_STARTUP_Pos) ; // 24 = 1536 cycles which I think is in range 23..45us since DAC clock = 42MHz


DACC->DACC_IDR = 0xFFFFFFFF ; // no interrupts

DACC->DACC_CHER = DACC_CHER_CH0 << 0 ; // enable chan0

}


void dac_write (int val)

{

DACC->DACC_CDR = val & 0xFFF ;

}




void adc_setup ()

{

NVIC_EnableIRQ (ADC_IRQn) ; // enable ADC interrupt vector

ADC->ADC_IDR = 0xFFFFFFFF ; // disable interrupts

ADC->ADC_IER = 0x80 ; // enable AD7 End-Of-Conv interrupt (Arduino pin A0)

ADC->ADC_CHDR = 0xFFFF ; // disable all channels

ADC->ADC_CHER = 0x80 ; // enable just A0

ADC->ADC_CGR = 0x15555555 ; // All gains set to x1

ADC->ADC_COR = 0x00000000 ; // All offsets off

ADC->ADC_MR = (ADC->ADC_MR & 0xFFFFFFF0) | (1 << 1) | ADC_MR_TRGEN ; // 1 = trig source TIO from TC0

}


// Circular buffer, power of two.

#define BUFSIZE 0x400

#define BUFMASK 0x3FF

volatile int samples [BUFSIZE] ;

volatile int sptr = 0 ;

volatile int isr_count = 0 ; // this was for debugging



#ifdef __cplusplus

extern "C"

{

#endif


void ADC_Handler (void)

{

if (ADC->ADC_ISR & ADC_ISR_EOC7) // ensure there was an End-of-Conversion and we read the ISR reg

{

int val = *(ADC->ADC_CDR+7) ; // get conversion result

samples [sptr] = val ; // stick in circular buffer

sptr = (sptr+1) & BUFMASK ; // move pointer

dac_write (0xFFF & ~val) ; // copy inverted to DAC output FIFO

}

isr_count ++ ;

}


#ifdef __cplusplus

}

#endif







void loop()

{

REG_PIOC_SODR = 0x1 << 22; //c22 = 8 pin

REG_PIOB_CODR = 0x1 << 27; //b27=13 pin

delay(1000);

REG_PIOC_CODR = 0x1 << 22; //c22=8 pin

REG_PIOB_SODR = 0x1 << 27; //b27 = 13 pin

delay(1000);

}