aboutsummaryrefslogtreecommitdiff
path: root/spaghetti-monster
diff options
context:
space:
mode:
authorGabriel Hart2020-12-18 15:23:31 -0600
committerGabriel Hart2020-12-18 15:23:31 -0600
commitdbe0aaf636ccb78a3cc1281b6a1ea6c662af6756 (patch)
tree59a05a2ba48af2a8c659946b74be50a5570e9ea3 /spaghetti-monster
parentadded model number to Lume1 FW3X build target (diff)
downloadanduril-dbe0aaf636ccb78a3cc1281b6a1ea6c662af6756.tar.gz
anduril-dbe0aaf636ccb78a3cc1281b6a1ea6c662af6756.tar.bz2
anduril-dbe0aaf636ccb78a3cc1281b6a1ea6c662af6756.zip
Add AVR 1-Series and t1616 board and scripts
Diffstat (limited to 'spaghetti-monster')
-rw-r--r--spaghetti-monster/anduril/BRANDS1
-rw-r--r--spaghetti-monster/anduril/MODELS1
-rw-r--r--spaghetti-monster/anduril/cfg-gchart-fet1-t16.h39
-rw-r--r--spaghetti-monster/anduril/version.h5
-rw-r--r--spaghetti-monster/fsm-adc.c53
-rw-r--r--spaghetti-monster/fsm-main.c9
-rw-r--r--spaghetti-monster/fsm-misc.c54
-rw-r--r--spaghetti-monster/fsm-pcint.c9
-rw-r--r--spaghetti-monster/fsm-wdt.c20
9 files changed, 185 insertions, 6 deletions
diff --git a/spaghetti-monster/anduril/BRANDS b/spaghetti-monster/anduril/BRANDS
index b74ddab..acd385e 100644
--- a/spaghetti-monster/anduril/BRANDS
+++ b/spaghetti-monster/anduril/BRANDS
@@ -7,3 +7,4 @@ Lumintop 0300 - 0399
Fireflies 0400 - 0499
Mateminco 0500 - 0599
Sofirn 0600 - 0699
+gChart 1600 - 1699 \ No newline at end of file
diff --git a/spaghetti-monster/anduril/MODELS b/spaghetti-monster/anduril/MODELS
index 84d6795..4ad4635 100644
--- a/spaghetti-monster/anduril/MODELS
+++ b/spaghetti-monster/anduril/MODELS
@@ -36,5 +36,6 @@ Model numbers:
0611 blf-q8
0612 sofirn-sp36
0621 blf-lantern
+1618 gchart-fet1-t16
Duplicates:
Missing:
diff --git a/spaghetti-monster/anduril/cfg-gchart-fet1-t16.h b/spaghetti-monster/anduril/cfg-gchart-fet1-t16.h
new file mode 100644
index 0000000..42333a4
--- /dev/null
+++ b/spaghetti-monster/anduril/cfg-gchart-fet1-t16.h
@@ -0,0 +1,39 @@
+// gChart's custom FET+1 driver config options for Anduril
+#define MODEL_NUMBER "1618" // Golden Ratio... because I can
+#include "hwdef-gchart-fet1-t16.h"
+// ATTINY: 1616
+
+// the button lights up
+#define USE_INDICATOR_LED
+// the button is visible while main LEDs are on
+#define USE_INDICATOR_LED_WHILE_RAMPING
+// enable blinking indicator LED while off
+#define TICK_DURING_STANDBY
+
+#undef BLINK_AT_RAMP_MIDDLE
+
+// battery readout style (pick one)
+#define BATTCHECK_VpT
+//#define BATTCHECK_8bars // FIXME: breaks build
+//#define BATTCHECK_4bars // FIXME: breaks build
+
+//#undef USE_DYNAMIC_UNDERCLOCKING
+#define USE_DYNAMIC_UNDERCLOCKING
+
+// Mostly borrowed from the D4 for now
+#define RAMP_LENGTH 150
+#define PWM1_LEVELS 1,1,2,2,3,3,4,4,5,6,7,8,9,10,12,13,14,15,17,19,20,22,24,26,29,31,34,36,39,42,45,48,51,55,59,62,66,70,75,79,84,89,93,99,104,110,115,121,127,134,140,147,154,161,168,176,184,192,200,209,217,226,236,245,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,0
+#define PWM2_LEVELS 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,3,4,5,7,8,9,11,12,14,15,17,19,20,22,24,25,27,29,31,33,35,37,39,41,43,45,48,50,52,55,57,59,62,64,67,70,72,75,78,81,84,87,90,93,96,99,102,105,109,112,115,119,122,126,129,133,137,141,144,148,152,156,160,165,169,173,177,182,186,191,195,200,205,209,214,219,224,229,234,239,244,250,255
+#define MAX_1x7135 65
+#define HALFSPEED_LEVEL 14
+#define QUARTERSPEED_LEVEL 6
+
+#define RAMP_SMOOTH_FLOOR 1
+#define RAMP_SMOOTH_CEIL 120
+// 10, 28, 46, [65], 83, 101, 120
+#define RAMP_DISCRETE_FLOOR 10
+#define RAMP_DISCRETE_CEIL RAMP_SMOOTH_CEIL
+#define RAMP_DISCRETE_STEPS 7
+
+// stop panicking at ~30% power
+#define THERM_FASTER_LEVEL 105 \ No newline at end of file
diff --git a/spaghetti-monster/anduril/version.h b/spaghetti-monster/anduril/version.h
index 8cf3c90..5ecfc65 100644
--- a/spaghetti-monster/anduril/version.h
+++ b/spaghetti-monster/anduril/version.h
@@ -1,4 +1 @@
-// this file is replaced automatically by the build script
-// set your own date here if you're not using the build script
-// otherwise, default to first human contact with the moon
-#define VERSION_NUMBER "19690720"
+#define VERSION_NUMBER "20201218"
diff --git a/spaghetti-monster/fsm-adc.c b/spaghetti-monster/fsm-adc.c
index 71ecf65..2818731 100644
--- a/spaghetti-monster/fsm-adc.c
+++ b/spaghetti-monster/fsm-adc.c
@@ -37,6 +37,9 @@ static inline void set_admux_therm() {
#elif (ATTINY == 841) // FIXME: not tested
ADMUXA = ADMUXA_THERM;
ADMUXB = ADMUXB_THERM;
+ #elif defined(AVRXMEGA3) // ATTINY816, 817, etc
+ ADC0.MUXPOS = ADC_MUXPOS_TEMPSENSE_gc; // read temperature
+ ADC0.CTRLC = ADC_SAMPCAP_bm | ADC_PRESC_DIV64_gc | ADC_REFSEL_INTREF_gc; // Internal ADC reference
#else
#error Unrecognized MCU type
#endif
@@ -66,6 +69,15 @@ inline void set_admux_voltage() {
ADMUXA = ADMUXA_VCC;
ADMUXB = ADMUXB_VCC;
#endif
+ #elif defined(AVRXMEGA3) // ATTINY816, 817, etc
+ #ifdef USE_VOLTAGE_DIVIDER // 1.1V / ADC input pin
+ // verify that this is correct!!! untested
+ ADC0.MUXPOS = ADMUX_VOLTAGE_DIVIDER; // read the requested ADC pin
+ ADC0.CTRLC = ADC_SAMPCAP_bm | ADC_PRESC_DIV64_gc | ADC_REFSEL_INTREF_gc; // Use internal ADC reference
+ #else // VCC / 1.1V reference
+ ADC0.MUXPOS = ADC_MUXPOS_INTREF_gc; // read internal reference
+ ADC0.CTRLC = ADC_SAMPCAP_bm | ADC_PRESC_DIV64_gc | ADC_REFSEL_VDDREF_gc; // Vdd (Vcc) be ADC reference
+ #endif
#else
#error Unrecognized MCU type
#endif
@@ -77,6 +89,9 @@ inline void set_admux_voltage() {
inline void ADC_start_measurement() {
#if (ATTINY == 25) || (ATTINY == 45) || (ATTINY == 85) || (ATTINY == 841) || (ATTINY == 1634)
ADCSRA |= (1 << ADSC) | (1 << ADIE);
+ #elif defined(AVRXMEGA3) // ATTINY816, 817, etc
+ ADC0.INTCTRL |= ADC_RESRDY_bm; // enable interrupt
+ ADC0.COMMAND |= ADC_STCONV_bm; // Start the ADC conversions
#else
#error unrecognized MCU type
#endif
@@ -108,13 +123,22 @@ inline void ADC_on()
// enable, start, auto-retrigger, prescale
ADCSRA = (1 << ADEN) | (1 << ADSC) | (1 << ADATE) | ADC_PRSCL;
//ADCSRA |= (1 << ADSC); // start measuring
+ #elif defined(AVRXMEGA3) // ATTINY816, 817, etc
+ set_admux_voltage();
+ VREF.CTRLA |= VREF_ADC0REFSEL_1V1_gc; // Set Vbg ref to 1.1V
+ ADC0.CTRLA = ADC_ENABLE_bm | ADC_FREERUN_bm; // Enabled, free-running (aka, auto-retrigger)
+ ADC0.COMMAND |= ADC_STCONV_bm; // Start the ADC conversions
#else
#error Unrecognized MCU type
#endif
}
inline void ADC_off() {
- ADCSRA &= ~(1<<ADEN); //ADC off
+ #ifdef AVRXMEGA3 // ATTINY816, 817, etc
+ ADC0.CTRLA &= ~(ADC_ENABLE_bm); // disable the ADC
+ #else
+ ADCSRA &= ~(1<<ADEN); //ADC off
+ #endif
}
#ifdef USE_VOLTAGE_DIVIDER
@@ -140,9 +164,16 @@ static inline uint8_t calc_voltage_divider(uint16_t value) {
#define ADC_CYCLES_PER_SECOND 2
#endif
+#ifdef AVRXMEGA3 // ATTINY816, 817, etc
+#define ADC_vect ADC0_RESRDY_vect
+#endif
// happens every time the ADC sampler finishes a measurement
ISR(ADC_vect) {
+ #ifdef AVRXMEGA3 // ATTINY816, 817, etc
+ ADC0.INTFLAGS = ADC_RESRDY_bm; // clear the interrupt
+ #endif
+
if (adc_sample_count) {
uint16_t m; // latest measurement
@@ -150,7 +181,23 @@ ISR(ADC_vect) {
uint8_t channel = adc_channel;
// update the latest value
+ #ifdef AVRXMEGA3 // ATTINY816, 817, etc
+ // Use the factory calibrated values in SIGROW.TEMPSENSE0 and SIGROW.TEMPSENSE1
+ // to calculate a temperature reading in Kelvin, then left-align it.
+ if (channel == 1) { // thermal, convert ADC reading to left-aligned Kelvin
+ int8_t sigrow_offset = SIGROW.TEMPSENSE1; // Read signed value from signature row
+ uint8_t sigrow_gain = SIGROW.TEMPSENSE0; // Read unsigned value from signature row
+ uint32_t temp = ADC0.RES - sigrow_offset;
+ temp *= sigrow_gain; // Result might overflow 16 bit variable (10bit+8bit)
+ temp += 0x80; // Add 1/2 to get correct rounding on division below
+ temp >>= 8; // Divide result to get Kelvin
+ m = (temp << 6); // left align it
+ }
+ else { m = (ADC0.RES << 6); } // voltage, force left-alignment
+
+ #else
m = ADC;
+ #endif
adc_raw[channel] = m;
// lowpass the value
@@ -181,8 +228,12 @@ void adc_deferred() {
// real-world entropy makes this a true random, not pseudo
// Why here instead of the ISR? Because it makes the time-critical ISR
// code a few cycles faster and we don't need crypto-grade randomness.
+ #ifdef AVRXMEGA3 // ATTINY816, 817, etc
+ pseudo_rand_seed += ADC0.RESL; // right aligned, not left... so should be equivalent?
+ #else
pseudo_rand_seed += (ADCL >> 6) + (ADCH << 2);
#endif
+ #endif
// the ADC triggers repeatedly when it's on, but we only need to run the
// voltage and temperature regulation stuff once in a while...so disable
diff --git a/spaghetti-monster/fsm-main.c b/spaghetti-monster/fsm-main.c
index b96bce8..f3c319c 100644
--- a/spaghetti-monster/fsm-main.c
+++ b/spaghetti-monster/fsm-main.c
@@ -23,6 +23,9 @@
#include "fsm-main.h"
#if PWM_CHANNELS == 4
+#ifdef AVRXMEGA3 // ATTINY816, 817, etc
+#error 4-channel PWM not currently set up for the AVR 1-Series
+#endif
// 4th PWM channel requires manually turning the pin on/off via interrupt :(
ISR(TIMER1_OVF_vect) {
//bitClear(PORTB, 3);
@@ -68,7 +71,7 @@ static inline void hw_setup() {
PORTB = (1 << SWITCH_PIN); // e-switch is the only input
PCMSK = (1 << SWITCH_PIN); // pin change interrupt uses this pin
}
-#elif (ATTINY == 1634)
+#elif (ATTINY == 1634) || defined(AVRXMEGA3) // ATTINY816, 817, etc
static inline void hw_setup() {
// this gets tricky with so many pins...
// ... so punt it to the hwdef file
@@ -82,7 +85,11 @@ static inline void hw_setup() {
//#ifdef USE_REBOOT
static inline void prevent_reboot_loop() {
// prevent WDT from rebooting MCU again
+ #ifdef AVRXMEGA3 // ATTINY816, 817, etc
+ RSTCTRL.RSTFR &= ~(RSTCTRL_WDRF_bm); // reset status flag
+ #else
MCUSR &= ~(1<<WDRF); // reset status flag
+ #endif
wdt_disable();
}
//#endif
diff --git a/spaghetti-monster/fsm-misc.c b/spaghetti-monster/fsm-misc.c
index 15cb659..7ba9b45 100644
--- a/spaghetti-monster/fsm-misc.c
+++ b/spaghetti-monster/fsm-misc.c
@@ -110,6 +110,33 @@ uint8_t blink_num(uint8_t num) {
#ifdef USE_INDICATOR_LED
void indicator_led(uint8_t lvl) {
switch (lvl) {
+ #ifdef AVRXMEGA3 // ATTINY816, 817, etc
+ case 0: // indicator off
+ AUXLED_PORT.DIRSET = AUXLED_PIN; // set as output
+ AUXLED_PORT.OUTCLR = AUXLED_PIN; // set output low
+ #ifdef AUXLED2_PIN // second LED mirrors the first
+ AUXLED2_PORT.DIRSET = AUXLED2_PIN; // set as output
+ AUXLED2_PORT.OUTCLR = AUXLED2_PIN; // set output low
+ #endif
+ break;
+ case 1: // indicator low
+ AUXLED_PORT.DIRCLR = AUXLED_PIN; // set as input
+ AUXLED_PORT.AUXLED_CTRL = PORT_PULLUPEN_bm; // enable internal pull-up
+ #ifdef AUXLED2_PIN // second LED mirrors the first
+ AUXLED2_PORT.DIRCLR = AUXLE2D_PIN; // set as input
+ AUXLED2_PORT.AUXLED2_CTRL = PORT_PULLUPEN_bm; // enable internal pull-up
+ #endif
+ break;
+ default: // indicator high
+ AUXLED_PORT.DIRSET = AUXLED_PIN; // set as output
+ AUXLED_PORT.OUTSET = AUXLED_PIN; // set as high
+ #ifdef AUXLED2_PIN // second LED mirrors the first
+ AUXLED2_PORT.DIRSET = AUXLED2_PIN; // set as output
+ AUXLED2_PORT.OUTSET = AUXLED2_PIN; // set as high
+ #endif
+ break;
+
+ #else
case 0: // indicator off
DDRB &= 0xff ^ (1 << AUXLED_PIN);
PORTB &= 0xff ^ (1 << AUXLED_PIN);
@@ -134,6 +161,8 @@ void indicator_led(uint8_t lvl) {
PORTB |= (1 << AUXLED2_PIN);
#endif
break;
+
+ #endif
}
}
@@ -150,6 +179,23 @@ void indicator_led_auto() {
// TODO: Refactor this and RGB LED function to merge code and save space
void button_led_set(uint8_t lvl) {
switch (lvl) {
+
+ #ifdef AVRXMEGA3 // ATTINY816, 817, etc
+ case 0: // LED off
+ BUTTON_LED_PORT.DIRSET = BUTTON_LED_PIN; // set as output
+ BUTTON_LED_PORT.OUTCLR = BUTTON_LED_PIN; // set output low
+ break;
+ case 1: // LED low
+ BUTTON_LED_PORT.DIRCLR = BUTTON_LED_PIN; // set as input
+ BUTTON_LED_PORT.BUTTON_LED_CTRL = PORT_PULLUPEN_bm; // enable internal pull-up
+ break;
+ default: // LED high
+ BUTTON_LED_PORT.DIRSET = BUTTON_LED_PIN; // set as output
+ BUTTON_LED_PORT.OUTSET = BUTTON_LED_PIN; // set as high
+ break;
+
+ #else
+
case 0: // LED off
BUTTON_LED_DDR &= 0xff ^ (1 << BUTTON_LED_PIN);
BUTTON_LED_PUE &= 0xff ^ (1 << BUTTON_LED_PIN);
@@ -165,11 +211,16 @@ void button_led_set(uint8_t lvl) {
BUTTON_LED_PUE |= (1 << BUTTON_LED_PIN);
BUTTON_LED_PORT |= (1 << BUTTON_LED_PIN);
break;
+
+ #endif
}
}
#endif
#ifdef USE_AUX_RGB_LEDS
+#ifdef AVRXMEGA3 // ATTINY816, 817, etc
+#error Function rgb_led_set in fsm-misc is currently not set up for the AVR 1-Series
+#endif
void rgb_led_set(uint8_t value) {
// value: 0b00BBGGRR
uint8_t pins[] = { AUXLED_R_PIN, AUXLED_G_PIN, AUXLED_B_PIN };
@@ -217,6 +268,9 @@ void reboot() {
// reset (WDIF + WDE), no WDIE, fastest (16ms) timing (0000)
// (DS section 8.5.2 and table 8-4)
WDTCSR = 0b10001000;
+ #elif defined(AVRXMEGA3) // ATTINY816, 817, etc
+ CCP = CCP_IOREG_gc; // temporarily disable change protection
+ WDT.CTRLA = WDT_PERIOD_8CLK_gc; // Enable, timeout 8ms
#endif
sei();
wdt_reset();
diff --git a/spaghetti-monster/fsm-pcint.c b/spaghetti-monster/fsm-pcint.c
index 24cc82c..4a3c193 100644
--- a/spaghetti-monster/fsm-pcint.c
+++ b/spaghetti-monster/fsm-pcint.c
@@ -46,6 +46,8 @@ inline void PCINT_on() {
#else
GIMSK |= (1 << SWITCH_PCIE);
#endif
+ #elif defined(AVRXMEGA3) // ATTINY816, 817, etc)
+ SWITCH_ISC_REG |= PORT_ISC_BOTHEDGES_gc;
#else
#error Unrecognized MCU type
#endif
@@ -58,6 +60,8 @@ inline void PCINT_off() {
#elif (ATTINY == 1634)
// disable all pin-change interrupts
GIMSK &= ~(1 << SWITCH_PCIE);
+ #elif defined(AVRXMEGA3) // ATTINY816, 817, etc)
+ SWITCH_ISC_REG &= ~(PORT_ISC_gm);
#else
#error Unrecognized MCU type
#endif
@@ -73,6 +77,11 @@ ISR(PCINT0_vect) {
#endif
irq_pcint = 1;
}
+#elif defined(AVRXMEGA3) // ATTINY816, 817, etc)
+ISR(SWITCH_VECT) {
+ SWITCH_INTFLG |= (1 << SWITCH_PIN); // Write a '1' to clear the interrupt flag
+ irq_pcint = 1;
+}
#else
#error Unrecognized MCU type
#endif
diff --git a/spaghetti-monster/fsm-wdt.c b/spaghetti-monster/fsm-wdt.c
index 9e8d9af..7bb8acc 100644
--- a/spaghetti-monster/fsm-wdt.c
+++ b/spaghetti-monster/fsm-wdt.c
@@ -23,6 +23,10 @@
#include <avr/interrupt.h>
#include <avr/wdt.h>
+// *** Note for the AVRXMEGA3 (1-Series, eg 816 and 817), the WDT
+// is not used for time-based interrupts. A new peripheral, the
+// Periodic Interrupt Timer ("PIT") is used for this purpose.
+
void WDT_on()
{
#if (ATTINY == 25) || (ATTINY == 45) || (ATTINY == 85)
@@ -35,6 +39,10 @@ void WDT_on()
#elif (ATTINY == 1634)
wdt_reset(); // Reset the WDT
WDTCSR = (1<<WDIE); // Enable interrupt every 16ms
+ #elif defined(AVRXMEGA3) // ATTINY816, 817, etc
+ RTC.PITINTCTRL = RTC_PI_bm; // enable the Periodic Interrupt
+ while (RTC.PITSTATUS > 0) {} // make sure the register is ready to be updated
+ RTC.PITCTRLA = RTC_PERIOD_CYC512_gc | RTC_PITEN_bm; // Period = 16ms, enable the PI Timer
#else
#error Unrecognized MCU type
#endif
@@ -53,6 +61,10 @@ inline void WDT_slow()
#elif (ATTINY == 1634)
wdt_reset(); // Reset the WDT
WDTCSR = (1<<WDIE) | STANDBY_TICK_SPEED;
+ #elif defined(AVRXMEGA3) // ATTINY816, 817, etc
+ RTC.PITINTCTRL = RTC_PI_bm; // enable the Periodic Interrupt
+ while (RTC.PITSTATUS > 0) {} // make sure the register is ready to be updated
+ RTC.PITCTRLA = RTC_PERIOD_CYC16384_gc | RTC_PITEN_bm; // Period = 0.5s, enable the PI Timer
#else
#error Unrecognized MCU type
#endif
@@ -75,13 +87,21 @@ inline void WDT_off()
CCP = 0xD8; // enable config changes
WDTCSR = 0; // disable and clear all WDT settings
sei();
+ #elif defined(AVRXMEGA3) // ATTINY816, 817, etc
+ while (RTC.PITSTATUS > 0) {} // make sure the register is ready to be updated
+ RTC.PITCTRLA = 0; // Disable the PI Timer
#else
#error Unrecognized MCU type
#endif
}
// clock tick -- this runs every 16ms (62.5 fps)
+#ifdef AVRXMEGA3 // ATTINY816, 817, etc
+ISR(RTC_PIT_vect) {
+ RTC.PITINTFLAGS = RTC_PI_bm; // clear the PIT interrupt flag
+#else
ISR(WDT_vect) {
+#endif
irq_wdt = 1; // WDT event happened
}