Skip to content

Instantly share code, notes, and snippets.

@dwblair
Created July 6, 2016 19:39
Show Gist options
  • Save dwblair/9b93f0b74981d380177c583cda85d892 to your computer and use it in GitHub Desktop.
Save dwblair/9b93f0b74981d380177c583cda85d892 to your computer and use it in GitHub Desktop.
#include <SPI.h>
#include <SD.h>
// Set the pins used
#define cardSelect 4
#define switchPin 12
File logfile;
bool stopPin = true;
// blink out an error code
void error(uint8_t errno) {
while(1) {
uint8_t i;
for (i=0; i<errno; i++) {
digitalWrite(13, HIGH);
delay(200);
digitalWrite(13, LOW);
delay(200);
}
for (i=errno; i<10; i++) {
delay(500);
}
}
}
// This line is not needed if you have Adafruit SAMD board package 1.6.2+
// #define Serial SerialUSB
void setup() {
analogReadResolution(12);
// ---- PWM
REG_GCLK_GENDIV = GCLK_GENDIV_DIV(3) | // Divide the 48MHz clock source by divisor 3: 48MHz/3=16MHz
GCLK_GENDIV_ID(4); // Select Generic Clock (GCLK) 4
while (GCLK->STATUS.bit.SYNCBUSY); // Wait for synchronization
REG_GCLK_GENCTRL = GCLK_GENCTRL_IDC | // Set the duty cycle to 50/50 HIGH/LOW
GCLK_GENCTRL_GENEN | // Enable GCLK4
GCLK_GENCTRL_SRC_DFLL48M | // Set the 48MHz clock source
GCLK_GENCTRL_ID(4); // Select GCLK4
while (GCLK->STATUS.bit.SYNCBUSY); // Wait for synchronization
// Enable the port multiplexer for the 4 PWM channels: timer TCC0 outputs
const uint8_t CHANNELS = 4;
const uint8_t pwmPins[] = { 2, 5, 6, 7 };
for (uint8_t i = 0; i < CHANNELS; i++)
{
PORT->Group[g_APinDescription[pwmPins[i]].ulPort].PINCFG[g_APinDescription[pwmPins[i]].ulPin].bit.PMUXEN = 1;
}
// Connect the TCC0 timer to the port outputs - port pins are paired odd PMUO and even PMUXE
// F & E specify the timers: TCC0, TCC1 and TCC2
PORT->Group[g_APinDescription[2].ulPort].PMUX[g_APinDescription[2].ulPin >> 1].reg = PORT_PMUX_PMUXO_F | PORT_PMUX_PMUXE_F;
PORT->Group[g_APinDescription[6].ulPort].PMUX[g_APinDescription[6].ulPin >> 1].reg = PORT_PMUX_PMUXO_F | PORT_PMUX_PMUXE_F;
// Feed GCLK4 to TCC0 and TCC1
REG_GCLK_CLKCTRL = GCLK_CLKCTRL_CLKEN | // Enable GCLK4 to TCC0 and TCC1
GCLK_CLKCTRL_GEN_GCLK4 | // Select GCLK4
GCLK_CLKCTRL_ID_TCC0_TCC1; // Feed GCLK4 to TCC0 and TCC1
while (GCLK->STATUS.bit.SYNCBUSY); // Wait for synchronization
// Dual slope PWM operation: timers countinuously count up to PER register value then down 0
REG_TCC0_WAVE |= TCC_WAVE_POL(0xF) | // Reverse the output polarity on all TCC0 outputs
TCC_WAVE_WAVEGEN_DSBOTTOM; // Setup dual slope PWM on TCC0
while (TCC0->SYNCBUSY.bit.WAVE); // Wait for synchronization
// Each timer counts up to a maximum or TOP value set by the PER register,
// this determines the frequency of the PWM operation:
// 400 = 20kHz; 800= 10 kHz; 4000 = 2 kHz
REG_TCC0_PER = 800; // Set the frequency of the PWM on TCC0 to X khz
while(TCC0->SYNCBUSY.bit.PER);
// The CCBx register value corresponds to the pulsewidth in microseconds (us)
REG_TCC0_CCB0 = 200; // TCC0 CCB0 - 50% duty cycle on D2
while(TCC0->SYNCBUSY.bit.CCB0);
REG_TCC0_CCB1 = 200; // TCC0 CCB1 - 50% duty cycle on D5
while(TCC0->SYNCBUSY.bit.CCB1);
REG_TCC0_CCB2 = 200; // TCC0 CCB2 - 50% duty cycle on D6
while(TCC0->SYNCBUSY.bit.CCB2);
REG_TCC0_CCB3 = 200; // TCC0 CCB3 - 50% duty cycle on D7
while(TCC0->SYNCBUSY.bit.CCB3);
// Divide the 16MHz signal by 1 giving 16MHz (62.5ns) TCC0 timer tick and enable the outputs
REG_TCC0_CTRLA |= TCC_CTRLA_PRESCALER_DIV1 | // Divide GCLK4 by 1
TCC_CTRLA_ENABLE; // Enable the TCC0 output
while (TCC0->SYNCBUSY.bit.ENABLE); // Wait for synchronization
// ----------- LOGGING
// connect at 115200 so we can read the GPS fast enough and echo without dropping chars
// also spit it out
Serial.begin(9600);
Serial.println("\r\nAnalog logger test");
pinMode(13, OUTPUT);
// see if the card is present and can be initialized:
if (!SD.begin(cardSelect)) {
Serial.println("Card init. failed!");
error(2);
}
char filename[15];
strcpy(filename, "ANALOG00.TXT");
for (uint8_t i = 0; i < 100; i++) {
filename[6] = '0' + i/10;
filename[7] = '0' + i%10;
// create if does not exist, do not open existing, write, sync after write
if (! SD.exists(filename)) {
break;
}
}
logfile = SD.open(filename, FILE_WRITE);
if( ! logfile ) {
Serial.print("Couldnt create ");
Serial.println(filename);
error(3);
}
Serial.print("Writing to ");
Serial.println(filename);
pinMode(13, OUTPUT);
pinMode(8, OUTPUT);
Serial.println("Ready!");
pinMode(switchPin, INPUT_PULLUP);
logfile.println("time, A0, A1");
Serial.println("time, A0, A2");
}
uint8_t i=0;
void loop() {
while(stopPin != false){
digitalWrite(8, HIGH);
logfile.print(millis()); logfile.print(", "); logfile.print(analogRead(0)); logfile.print(", "); logfile.println(analogRead(1));
Serial.print(millis()); Serial.print(", "); Serial.print(analogRead(0)); Serial.print(", "); Serial.println(analogRead(1));
digitalWrite(8, LOW);
stopPin = digitalRead(switchPin);
delay(100);
}
logfile.flush();
error(5); // flash 5 times to indicate stop condition
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment