-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 2df752b
Showing
18 changed files
with
883 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
Compatible with SAMC21, more description will be added soon, check examples to use the code. Its still in alpha. | ||
|
||
This is to make SAMC21 functions faster same way as the SAMD21 speeduino, however it is not yet complete nor tested on a board as i am still waiting for one. Some features are also missing, while you can take advantage of two ADCs. | ||
|
||
|
||
With centered analog read you can have relative ground on A0 which is half of supply voltage to compare against. | ||
|
||
Function descriptions and time they take: | ||
Simplified: | ||
|
||
AnalogBegin(); - starts the ADC0 and attaches it to clock number 3. You can add one number inside to set resolution, deffault is 12 bit, possible are 8 10 and 12, then if you add one it will enable mode that centers values at half of the supply voltage, which now appears at pin A0, so you have negative and positive values, and after if you add 1 ADC will run in a freerun mode - it will keep taking reads again and again. Full form is AnalogBegin(Resolution, Centering, Freerun) ~ 30us | ||
|
||
AnalogBegin0(); - starts ADC0 | ||
|
||
AnalogBegin1(); - starts ADC1 | ||
|
||
FastAnalogRead(pin); - Attaches the Analog pin and reads it, returns an integer. ~ 3us | ||
|
||
AttachADC0(pin, centering) - Attaches to an analog pin and sets gain ~ 20us | ||
|
||
AttachADC1(pin, centering) - Attaches to an analog pin and sets gain ~ 20us | ||
|
||
Analog0Collect() - Reads and collects an analog value from last attached pin to ADC0 ~ 3us, but bit less than FastAnalogRead | ||
|
||
Analog1Collect() - Reads and collects an analog value from last attached pin to ADC1 ~ 3us, but bit less than FastAnalogRead | ||
|
||
PWMBegin(pin, frequency) - begins running a pin at a specified frequency while attaching it to clock 8, minimum is 1 hz - calls PWMSetup. ~ 87us | ||
|
||
PWMDuty(pin, dutycycle) - Sets the duty cycle at a specified number, in fractions. ~ 7us | ||
|
||
PWMFrequency(pin, frequency) - changes the frequency, minimum 1 hz, if the pin previously had lower frequency selected may cause issues. ~40us | ||
|
||
PWMSetup(pin, frequency, clock, Interrupts) - enables PWM, at a specidied pin, frequency which can go down to 0.00281 but it changes clock divisions, use clock 3-8. Enabling interrupts will make it call to Tch(); where you return duty cycle so it changes every cycle. ~ 124us, ~ 80us with frequency above 1hz | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
#include "Snowduino.h" | ||
|
||
|
||
const int ADCpin = 2; //Pin for ADC, 0 cant be used in IDACRed mode as it has the DAC tied to it. AO can be used for ref GND for sound card with sound pin to ADCpin. On zero, 2 stands for A1 | ||
int PWMpin = 13; //PWM pin, 13 is usually connected to LED so you can see it working. | ||
|
||
const float Frequency = 10.0f; //PWM frequency, higher the frequency lower resolution. Wont work below 0.00281 hz wont work | ||
const int ADCDiv = 5; //Set up dividor of time for ADC, with high PWM frequencies high values may let the Duty period only to change every few cycles, while too low values may lead to less stable output. Up to 255. | ||
const int Samples = 1; //Ammount of ADC samples, can be 1, 2, 4, 8, 16, 32, 64, 128, 256, 512 or 1028 | ||
int gain = 1; //1, 2, 4, 8, 16, 32, multiplier of input, only goes up to 16 in ICADRef mode | ||
const int res = 12; //Set up Resolution of the ADC, 8 or 10 or 12 bits | ||
|
||
/* Calibration */ | ||
int16_t minv = -2048; //Minimum meassured value of the input signal, make sure the value doesnt go below | ||
int16_t maxv = 2047; //Maximum meassured value og the input signal | ||
|
||
/* DAC AREF */ | ||
const bool IDACRef = 1; //Use DAC as a reference instead of GND | ||
const int BaseV = 512; //0-1024 base voltage, 512 works the best as VCC/2 | ||
|
||
const bool Interrupt = 1; //Enable PWM Interrupts | ||
|
||
const int ADCClk = 3; //Selects ADC clock generator, both to be between 3-8 | ||
const int PWMClk = 4; //Selects PWM clock generator, they cant be the same. | ||
|
||
//Not to be changed | ||
int16_t Range; //Value dividor here Select between 3-8 | ||
int16_t Analog; //Analog read values go here | ||
int Period; //Time period calculated here | ||
|
||
|
||
void setup() { | ||
|
||
|
||
Range = (maxv - minv); | ||
Period = PWMSetup(PWMpin, Frequency, PWMClk, 1); //Sets up PWM | ||
ADC0Setup(IDACRef, res, Samples, ADCClk, ADCDiv, BaseV, 0, 0); | ||
AttachADC0(ADCpin, IDACRef); | ||
|
||
|
||
} | ||
|
||
|
||
//Shared TCC handler | ||
int Tch() { | ||
ADC0->INTFLAG.reg = ADC_INTFLAG_RESRDY; //Wait for new analog value to be ready | ||
Analog = ADC0->RESULT.reg; //Write it down | ||
ADC0->SWTRIG.bit.START = true; //Start reading again | ||
return (Period * (Analog - minv) / Range); //Value to be set for next Period | ||
} | ||
|
||
|
||
/* Repeating code */ | ||
void loop() { | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
#include "Snowduino.h" | ||
|
||
int pin = 13; | ||
float frequency = 2.0f; | ||
|
||
|
||
void setup() { | ||
PWMBegin(pin, frequency); | ||
} | ||
|
||
void loop() { | ||
PWMDuty(13, 0.2f); //second number is the duty cycle fraction | ||
delay(10000); | ||
PWMFrequency(13, 20.0f); | ||
PWMDuty(13, 0.8f); | ||
delay(10000); | ||
PWMFrequency(13, 2.0f); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
#include "Snowduino.h" | ||
|
||
void setup() { | ||
Analog0Begin(); | ||
AttachADC0(2, 1); | ||
Serial.begin(9600); | ||
} | ||
|
||
void loop() { | ||
Serial.println(Analog0Collect()); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
|
||
#include "Snowduino.h" | ||
|
||
|
||
|
||
void setup() { | ||
AnalogBegin(); | ||
Serial.begin(115200); | ||
} | ||
|
||
|
||
|
||
/* Repeating code */ | ||
void loop() { | ||
Serial.println(FastAnalogRead(0)); | ||
} | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
name=Snowduino | ||
version=0.0.1 | ||
author=Bexin Bexin#1128 | ||
maintainer=Bexin [email protected] | ||
sentence=A library with faster commands for SAMC21 | ||
paragraph=Faster ADC and PWM | ||
category=Optimalization | ||
url=https://github.com/Bexin3/FastDuino | ||
architectures=samd | ||
includes=Snowduino.h | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,203 @@ | ||
#include "ADCSetup.h" | ||
|
||
bool mp = 0; | ||
int16_t anv = 0; | ||
|
||
|
||
|
||
void ADC0Setup(bool DacRef, int Res, int Samp, int ADCClk, int ADCDiv, int BaseV, bool Freerun, bool PreDiv) { | ||
|
||
/* genericClockSetup(ADCClk, ADCDiv); //Sets up ADC clock and divides it | ||
AttachClock(ADCClk, 0x1E); | ||
if (DacRef) { | ||
DACSetup(BaseV); //Setup DAC if needed | ||
}; | ||
*/ | ||
ADC0->CALIB.reg = ADC_CALIB_BIASCOMP(0x7) | ADC_CALIB_BIASREFBUF(0x7); | ||
|
||
ADC0->REFCTRL.bit.REFSEL = ADC_REFCTRL_REFSEL_INTVCC1_Val; | ||
|
||
|
||
|
||
if (PreDiv) { | ||
if (Res == 8) { | ||
ADC0->CTRLB.bit.PRESCALER = ADC_CTRLB_PRESCALER_DIV2_Val; | ||
ADC0->CTRLC.bit.RESSEL = ADC_CTRLC_RESSEL_8BIT_Val; | ||
} else if (Res == 10) { | ||
ADC0->CTRLB.bit.PRESCALER = ADC_CTRLB_PRESCALER_DIV2_Val; | ||
ADC0->CTRLC.bit.RESSEL = ADC_CTRLC_RESSEL_10BIT_Val; | ||
} else if (Res == 12) { | ||
ADC0->CTRLB.bit.PRESCALER = ADC_CTRLB_PRESCALER_DIV2_Val; | ||
ADC0->CTRLC.bit.RESSEL = ADC_CTRLC_RESSEL_12BIT_Val; | ||
} else { | ||
Serial.println("Unsupported resolution, change the value res to 8 10 or 12"); | ||
}; | ||
} else { | ||
if (Res == 8) { | ||
ADC0->CTRLB.bit.PRESCALER = ADC_CTRLB_PRESCALER_DIV2_Val; | ||
ADC0->CTRLC.bit.RESSEL = ADC_CTRLC_RESSEL_8BIT_Val; | ||
} else if (Res == 10) { | ||
ADC0->CTRLB.bit.PRESCALER = ADC_CTRLB_PRESCALER_DIV2_Val; | ||
ADC0->CTRLC.bit.RESSEL = ADC_CTRLC_RESSEL_10BIT_Val; | ||
} else if (Res == 12) { | ||
ADC0->CTRLB.bit.PRESCALER = ADC_CTRLB_PRESCALER_DIV8_Val; | ||
ADC0->CTRLC.bit.RESSEL = ADC_CTRLC_RESSEL_12BIT_Val; | ||
} else { | ||
Serial.println("Unsupported resolution, change the value res to 8 10 or 12"); | ||
}; | ||
}; | ||
|
||
if (DacRef) { | ||
ADC0->CTRLC.bit.DIFFMODE = 1; | ||
}; | ||
|
||
|
||
ADC0->AVGCTRL.bit.SAMPLENUM = log2(Samp); | ||
|
||
ADC0->CTRLC.bit.FREERUN = 0; | ||
|
||
ADC0->CTRLA.bit.ENABLE = 1; | ||
|
||
|
||
} | ||
|
||
|
||
void AttachADC0(int ADCpin, bool IDACRefon) { | ||
|
||
if (IDACRefon) { | ||
ADC0->INPUTCTRL.bit.MUXNEG = 0; | ||
ADC0->INPUTCTRL.bit.MUXPOS = ADCpin; | ||
} else { | ||
ADC0->INPUTCTRL.bit.MUXNEG = 0x18; | ||
ADC0->INPUTCTRL.bit.MUXPOS = ADCpin; | ||
}; | ||
|
||
} | ||
|
||
void AnalogBegin(int resolution, bool midphase, bool Freerun) { | ||
Analog0Begin(resolution, midphase, Freerun); | ||
} | ||
void Analog0Begin(int resolution, bool midphase, bool Freerun) { | ||
|
||
ADC0Setup(midphase, resolution, 1, 3, 1, 512, Freerun, 1); | ||
mp = midphase; | ||
|
||
} | ||
|
||
|
||
int Analog0Collect() { | ||
ADC0->SWTRIG.bit.START = true; //Start reading again | ||
while (ADC0->INTFLAG.reg == ADC_INTFLAG_RESRDY) {}; //Wait for new analog value to be ready | ||
anv = ADC0->RESULT.reg; | ||
return(anv); | ||
} | ||
|
||
|
||
int FastAnalogRead(int pin) { | ||
if (mp) { | ||
ADC0->INPUTCTRL.bit.MUXNEG = 0; | ||
ADC0->INPUTCTRL.bit.MUXPOS = pin; | ||
} else { | ||
ADC0->INPUTCTRL.bit.MUXNEG = 0x18; | ||
ADC0->INPUTCTRL.bit.MUXPOS = pin; | ||
}; | ||
//while (ADC->STATUS.bit.SYNCBUSY) {}; | ||
ADC0->SWTRIG.bit.START = true; //Start reading again | ||
while (ADC0->INTFLAG.reg == ADC_INTFLAG_RESRDY) {}; //Wait for new analog value to be ready | ||
anv = ADC0->RESULT.reg; | ||
return(anv); //Write it down | ||
} | ||
|
||
|
||
|
||
|
||
|
||
|
||
void ADC1Setup(bool DacRef, int Res, int Samp, int ADCClk, int ADCDiv, int BaseV, bool Freerun, bool PreDiv) { | ||
|
||
/* genericClockSetup(ADCClk, ADCDiv); //Sets up ADC clock and divides it | ||
AttachClock(ADCClk, 0x1E); | ||
if (DacRef) { | ||
DACSetup(BaseV); //Setup DAC if needed | ||
}; | ||
*/ | ||
ADC1->CALIB.reg = ADC_CALIB_BIASCOMP(0x7) | ADC_CALIB_BIASREFBUF(0x7); | ||
|
||
ADC1->REFCTRL.bit.REFSEL = ADC_REFCTRL_REFSEL_INTVCC1_Val; | ||
|
||
|
||
|
||
if (PreDiv) { | ||
if (Res == 8) { | ||
ADC1->CTRLB.bit.PRESCALER = ADC_CTRLB_PRESCALER_DIV2_Val; | ||
ADC1->CTRLC.bit.RESSEL = ADC_CTRLC_RESSEL_8BIT_Val; | ||
} else if (Res == 10) { | ||
ADC1->CTRLB.bit.PRESCALER = ADC_CTRLB_PRESCALER_DIV2_Val; | ||
ADC1->CTRLC.bit.RESSEL = ADC_CTRLC_RESSEL_10BIT_Val; | ||
} else if (Res == 12) { | ||
ADC1->CTRLB.bit.PRESCALER = ADC_CTRLB_PRESCALER_DIV2_Val; | ||
ADC1->CTRLC.bit.RESSEL = ADC_CTRLC_RESSEL_12BIT_Val; | ||
} else { | ||
Serial.println("Unsupported resolution, change the value res to 8 10 or 12"); | ||
}; | ||
} else { | ||
if (Res == 8) { | ||
ADC1->CTRLB.bit.PRESCALER = ADC_CTRLB_PRESCALER_DIV2_Val; | ||
ADC1->CTRLC.bit.RESSEL = ADC_CTRLC_RESSEL_8BIT_Val; | ||
} else if (Res == 10) { | ||
ADC1->CTRLB.bit.PRESCALER = ADC_CTRLB_PRESCALER_DIV2_Val; | ||
ADC1->CTRLC.bit.RESSEL = ADC_CTRLC_RESSEL_10BIT_Val; | ||
} else if (Res == 12) { | ||
ADC1->CTRLB.bit.PRESCALER = ADC_CTRLB_PRESCALER_DIV8_Val; | ||
ADC1->CTRLC.bit.RESSEL = ADC_CTRLC_RESSEL_12BIT_Val; | ||
} else { | ||
Serial.println("Unsupported resolution, change the value res to 8 10 or 12"); | ||
}; | ||
}; | ||
|
||
if (DacRef) { | ||
ADC1->CTRLC.bit.DIFFMODE = 1; | ||
}; | ||
|
||
|
||
ADC1->AVGCTRL.bit.SAMPLENUM = log2(Samp); | ||
|
||
ADC1->CTRLC.bit.FREERUN = 0; | ||
|
||
ADC1->CTRLA.bit.ENABLE = 1; | ||
|
||
|
||
} | ||
|
||
|
||
void AttachADC1(int ADCpin, bool IDACRefon) { | ||
|
||
if (IDACRefon) { | ||
ADC1->INPUTCTRL.bit.MUXNEG = 0; | ||
ADC1->INPUTCTRL.bit.MUXPOS = ADCpin; | ||
} else { | ||
ADC1->INPUTCTRL.bit.MUXNEG = 0x18; | ||
ADC1->INPUTCTRL.bit.MUXPOS = ADCpin; | ||
}; | ||
|
||
} | ||
|
||
|
||
void Analog1Begin(int resolution, bool midphase, bool Freerun) { | ||
|
||
ADC1Setup(midphase, resolution, 1, 3, 1, 512, Freerun, 1); | ||
mp = midphase; | ||
|
||
} | ||
|
||
|
||
int Analog1Collect() { | ||
ADC1->SWTRIG.bit.START = true; //Start reading again | ||
while (ADC1->INTFLAG.reg == ADC_INTFLAG_RESRDY) {}; //Wait for new analog value to be ready | ||
anv = ADC1->RESULT.reg; | ||
return(anv); | ||
} | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
#ifndef ADCSetup_h | ||
#define ADCSetup_h | ||
|
||
#include <Arduino.h> | ||
|
||
void ADC0Setup(bool DacRef, int Res, int Samp, int ADCClk, int ADCDiv, int BaseV, bool Freerun, bool PreDiv); | ||
void ADC1Setup(bool DacRef, int Res, int Samp, int ADCClk, int ADCDiv, int BaseV, bool Freerun, bool PreDiv); | ||
void genericClockSetup(int clk, int dFactor); | ||
void AttachClock(int clk, int clkid); | ||
void AttachADC0(int ADCpin = 0, bool IDACRefon = 0); | ||
void AttachADC1(int ADCpin = 0, bool IDACRefon = 0); | ||
void DACSetup(int BaseV); | ||
void AnalogBegin(int resolution = 12, bool midphase = 0, bool Freerun = 0); | ||
void Analog0Begin(int resolution = 12, bool midphase = 0, bool Freerun = 0); | ||
void Analog1Begin(int resolution = 12, bool midphase = 0, bool Freerun = 0); | ||
int FastAnalogRead(int pin); | ||
int Analog0Collect(); | ||
int Analog1Collect(); | ||
|
||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
#include "ClockSetup.h" | ||
|
||
void genericClockSetup(int clk, int dFactor) { | ||
|
||
|
||
GCLK->GENCTRL[clk].bit.IDC; | ||
GCLK->GENCTRL[clk].bit.DIV = dFactor; | ||
GCLK->GENCTRL[clk].bit.GENEN; | ||
GCLK->GENCTRL[clk].bit.SRC = GCLK_GENCTRL_SRC_OSC48M_Val; | ||
|
||
|
||
} | ||
|
||
|
||
|
||
void AttachClock(int clk, int clkid) { | ||
GCLK->PCHCTRL[clkid].bit.GEN = clk; | ||
} |
Oops, something went wrong.