gpscalibration/magictimerasused220416.ino

133 lines
5.2 KiB
Arduino
Raw Normal View History

2016-04-23 11:45:59 +00:00
#include <math.h>
void TimersStart() {
uint32_t config = 0;
// Set up the power management controller for TC0 and TC2
pmc_set_writeprotect(false); // Enable write access to power management chip
pmc_enable_periph_clk(ID_TC0); // Turn on power for timer block 0 channel 0
pmc_enable_periph_clk(ID_TC6); // Turn on power for timer block 2 channel 0
// Timer block zero channel zero is connected only to the PPS
// We set it up to load regester RA on each PPS and reset
// So RA will contain the number of clock ticks between two PPS, this
// value should be very stable +/- one tick
config = TC_CMR_TCCLKS_TIMER_CLOCK1 | // Select fast clock MCK/2 = 42 MHz
TC_CMR_ETRGEDG_RISING | // External trigger rising edge on TIOA0
TC_CMR_ABETRG | // Use the TIOA external input line
TC_CMR_LDRA_RISING; // Latch counter value into RA
TC_Configure(TC0, 0, config); // Configure channel 0 of TC0
TC_Start(TC0, 0); // Start timer running
TC0->TC_CHANNEL[0].TC_IER = TC_IER_LDRAS; // Enable the load AR channel 0 interrupt each PPS
TC0->TC_CHANNEL[0].TC_IDR = ~TC_IER_LDRAS; // and disable the rest of the interrupt sources
NVIC_EnableIRQ(TC0_IRQn); // Enable interrupt handler for channel 0
// Timer block 2 channel zero is connected to the OR of the PPS and the RAY event
config = TC_CMR_TCCLKS_TIMER_CLOCK1 | // Select fast clock MCK/2 = 42 MHz
TC_CMR_ETRGEDG_RISING | // External trigger rising edge on TIOA1
TC_CMR_ABETRG | // Use the TIOA external input line
TC_CMR_LDRA_RISING; // Latch counter value into RA
TC_Configure(TC2, 0, config); // Configure channel 0 of TC2
TC_Start(TC2, 0); // Start timer running
TC2->TC_CHANNEL[0].TC_IER = TC_IER_LDRAS; // Enable the load AR channel 0 interrupt each PPS
TC2->TC_CHANNEL[0].TC_IDR = ~TC_IER_LDRAS; // and disable the rest of the interrupt sources
NVIC_EnableIRQ(TC6_IRQn); // Enable interrupt handler for channel 0
// Set up the PIO controller to route input pins for TC0 and TC2
PIO_Configure(PIOC,PIO_INPUT,
PIO_PB25B_TIOA0, // D2 Input
PIO_DEFAULT);
PIO_Configure(PIOC,PIO_INPUT,
PIO_PC25B_TIOA6, // D5 Input
PIO_DEFAULT);
}
// Define some output debug pins to monitor whats going on via my scope
#define PPS_PIN 13 // PPS (Pulse Per Second) and LED
#define EVT_PIN 12 // Cosmic ray event detected
#define FLG_PIN 11 // Debug flag
static uint32_t displ = 1; // Display values in loop
static uint32_t ppsfl = LOW, // PPS Flag boolean
rega0 = 0, // RA reg
stsr0 = 0, // Interrupt status register
ppcnt = 0; // PPS count
static uint32_t event = 0, // Time of the last event (This should be a queue !)
rega1 = 0,
stsr1 = 0;
void TC0_Handler() {
// This ISR is connected only to the PPS (Pulse Per Second) GPS event
// Each time this runs, set the flag to tell the TC6 ISR we have seen it
// This logic only works if the TC0 handler gets called before the TC6 handler
// hence the debug flag which I look at with a scope to be sure.
// I may introduce a small delay line to ensure this is true, so far it is.
//ppsfl = HIGH; // Seen a rising edge on the PPS
//digitalWrite(PPS_PIN,HIGH); // PPS arrived
//digitalWrite(FLG_PIN,ppsfl); // Flag set (for debug)
rega0 = TC0->TC_CHANNEL[0].TC_RA; // Read the RA reg (PPS period)
stsr0 = TC_GetStatus(TC0, 0); // Read status and clear load bits
//event = 0;
ppcnt++; // PPS count
displ = 1; // Display stuff in the loop
}
void TC6_Handler() {
// This ISR is connected to the OR of the event and the PPS
// If the TC0 has seen the PPS it sets the flag high
// and if its high we are seeing the PPS here, but if the
// flag is not set then this is a cosmic ray event.
//if (ppsfl == HIGH) { // Was ther a PPS ?
//ppsfl = LOW; // Yes so we have seen it here
//digitalWrite(PPS_PIN,LOW); // Reset PPS
//digitalWrite(EVT_PIN,LOW); // Not an event
//} else {
//digitalWrite(EVT_PIN,HIGH); // Event detected
//event = TC2->TC_CHANNEL[0].TC_RA;
//}
//digitalWrite(FLG_PIN,ppsfl); // Flag out
//Serial.print("event");
event = TC0->TC_CHANNEL[0].TC_CV; // Read thge RA on channel 1 (PPS period)
stsr1 = TC_GetStatus(TC2, 0); // Read status clear load bits
}
void setup() {
//pinMode(FLG_PIN, OUTPUT); // Pin for the ppsfl flag for debug
//pinMode(EVT_PIN, OUTPUT); // Pin for the cosmic ray event
//pinMode(PPS_PIN, OUTPUT); // Pin for the PPS (LED pin)
Serial.begin(115200); // Start the serial line
TimersStart(); // Start timers
}
void loop() {
if (displ) {
Serial.print("ppcnt: "); Serial.print(ppcnt);Serial.print(", ");
Serial.print("rega0: "); Serial.print(rega0);Serial.print(", ");
Serial.print("event: "); Serial.print(event);
Serial.println("");
displ = 0;
}
}