aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGabriel Hart2020-12-18 15:23:31 -0600
committerGabriel Hart2020-12-18 15:23:31 -0600
commitdbe0aaf636ccb78a3cc1281b6a1ea6c662af6756 (patch)
tree59a05a2ba48af2a8c659946b74be50a5570e9ea3
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
-rwxr-xr-xbin/build.sh5
-rwxr-xr-xbin/flash-tiny1616.sh3
-rw-r--r--hwdef-gchart-fet1-t16.h101
-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
-rw-r--r--tk-attiny.h28
13 files changed, 320 insertions, 8 deletions
diff --git a/bin/build.sh b/bin/build.sh
index 3992c38..6c21e30 100755
--- a/bin/build.sh
+++ b/bin/build.sh
@@ -12,10 +12,11 @@ fi
export ATTINY=$1 ; shift
export PROGRAM=$1 ; shift
export MCU=attiny$ATTINY
+export DFP=~/avr/attiny_dfp
export CC=avr-gcc
export OBJCOPY=avr-objcopy
-export CFLAGS="-Wall -g -Os -mmcu=$MCU -c -std=gnu99 -fgnu89-inline -fwhole-program -DATTINY=$ATTINY -I.. -I../.. -I../../.. -fshort-enums"
-export OFLAGS="-Wall -g -Os -mmcu=$MCU"
+export CFLAGS="-Wall -g -Os -mmcu=$MCU -c -std=gnu99 -fgnu89-inline -fwhole-program -DATTINY=$ATTINY -I.. -I../.. -I../../.. -fshort-enums -B $DFP/gcc/dev/$MCU/ -I $DFP/include/"
+export OFLAGS="-Wall -g -Os -mmcu=$MCU -B $DFP/gcc/dev/$MCU/ -I $DFP/include/"
export LDFLAGS="-fgnu89-inline"
export OBJCOPYFLAGS='--set-section-flags=.eeprom=alloc,load --change-section-lma .eeprom=0 --no-change-warnings -O ihex'
export OBJS=$PROGRAM.o
diff --git a/bin/flash-tiny1616.sh b/bin/flash-tiny1616.sh
new file mode 100755
index 0000000..31c8406
--- /dev/null
+++ b/bin/flash-tiny1616.sh
@@ -0,0 +1,3 @@
+#/bin/sh
+FIRMWARE=$1
+avrdude -c jtag2updi -P /dev/ttyUSB0 -p t1616 -u -Uflash:w:$FIRMWARE \ No newline at end of file
diff --git a/hwdef-gchart-fet1-t16.h b/hwdef-gchart-fet1-t16.h
new file mode 100644
index 0000000..3a79586
--- /dev/null
+++ b/hwdef-gchart-fet1-t16.h
@@ -0,0 +1,101 @@
+#ifndef HWDEF_GCH_FET1_T16_H
+#define HWDEF_GCH_FET1_T16_H
+
+/* gChart's custom FET+1 driver layout
+
+PB0 - PWM for FET (TCA - WO0)
+PB1 - PWM for 7135 (TCA - WO1)
+PB2 - Switch pin, internal pullup
+PB3 - Aux LED with 4700 Ohm series resistor
+Read voltage from VCC pin, has diode with ~0.4v drop
+
+*/
+
+
+#define LAYOUT_DEFINED
+
+#ifdef ATTINY
+#undef ATTINY
+#endif
+#define ATTINY 1616
+#include <avr/io.h>
+
+#define PWM_CHANNELS 2
+
+#ifndef SWITCH_PIN
+#define SWITCH_PIN 2
+#define SWITCH_PORT VPORTB.IN
+#define SWITCH_ISC_REG PORTB.PIN2CTRL
+#define SWITCH_VECT PORTB_PORT_vect
+#define SWITCH_INTFLG VPORTB.INTFLAGS
+//#define SWITCH_ISC_REG _SFR_MEM8(&PORTB + 0x10 + SWITCH_PIN)
+#endif
+
+
+// 7135 channel
+#ifndef PWM1_PIN
+#define PWM1_PIN PB1 //
+#define PWM1_LVL TCA0.SINGLE.CMP1 // CMP1 is the output compare register for PB1
+#endif
+
+// FET channel
+#ifndef PWM2_PIN
+#define PWM2_PIN PB0 //
+#define PWM2_LVL TCA0.SINGLE.CMP0 // CMP0 is the output compare register for PB0
+#endif
+
+// average drop across diode on this hardware
+#ifndef VOLTAGE_FUDGE_FACTOR
+#define VOLTAGE_FUDGE_FACTOR 8 // 4 = add 0.20V
+#endif
+
+
+// lighted button
+#ifndef AUXLED_PIN
+#define AUXLED_PIN PIN3_bm
+#define AUXLED_PORT PORTB
+#define AUXLED_CTRL PIN3CTRL
+#endif
+
+
+// with so many pins, doing this all with #ifdefs gets awkward...
+// ... so just hardcode it in each hwdef file instead
+inline void hwdef_setup() {
+
+ // set up the system clock to run at 5 MHz instead of the default 3.33 MHz
+ _PROTECTED_WRITE( CLKCTRL.MCLKCTRLB, CLKCTRL_PDIV_4X_gc | CLKCTRL_PEN_bm );
+
+ //VPORTA.DIR = 0b00000010;
+ VPORTB.DIR = PIN0_bm | PIN1_bm | PIN3_bm;
+ //VPORTC.DIR = 0b00000000;
+
+ // enable pullups on the input pins to reduce power
+ PORTA.PIN0CTRL = PORT_PULLUPEN_bm;
+ PORTA.PIN1CTRL = PORT_PULLUPEN_bm;
+ PORTA.PIN2CTRL = PORT_PULLUPEN_bm;
+ PORTA.PIN3CTRL = PORT_PULLUPEN_bm;
+ PORTA.PIN4CTRL = PORT_PULLUPEN_bm;
+ PORTA.PIN5CTRL = PORT_PULLUPEN_bm;
+ PORTA.PIN6CTRL = PORT_PULLUPEN_bm;
+ PORTA.PIN7CTRL = PORT_PULLUPEN_bm;
+
+ //PORTB.PIN0CTRL = PORT_PULLUPEN_bm; // FET channel
+ //PORTB.PIN1CTRL = PORT_PULLUPEN_bm; // 7135 channel
+ PORTB.PIN2CTRL = PORT_PULLUPEN_bm | PORT_ISC_BOTHEDGES_gc; // switch
+ //PORTB.PIN3CTRL = PORT_PULLUPEN_bm; // Aux LED
+ PORTB.PIN4CTRL = PORT_PULLUPEN_bm;
+ PORTB.PIN5CTRL = PORT_PULLUPEN_bm;
+
+ PORTC.PIN0CTRL = PORT_PULLUPEN_bm;
+ PORTC.PIN1CTRL = PORT_PULLUPEN_bm;
+ PORTC.PIN2CTRL = PORT_PULLUPEN_bm;
+ PORTC.PIN3CTRL = PORT_PULLUPEN_bm;
+
+ // set up the PWM
+ TCA0.SINGLE.CTRLB = TCA_SINGLE_CMP0EN_bm | TCA_SINGLE_CMP1EN_bm | TCA_SINGLE_WGMODE_SINGLESLOPE_gc;
+ TCA0.SINGLE.PER = 255;
+ TCA0.SINGLE.CTRLA = TCA_SINGLE_CLKSEL_DIV1_gc | TCA_SINGLE_ENABLE_bm;
+}
+
+
+#endif
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
}
diff --git a/tk-attiny.h b/tk-attiny.h
index 49f1195..441f177 100644
--- a/tk-attiny.h
+++ b/tk-attiny.h
@@ -71,6 +71,12 @@
#define DELAY_ZERO_TIME 1020
//#define SWITCH_PORT PINA // set this in hwdef
//#define VOLTAGE_ADC_DIDR DIDR0 // set this in hwdef
+#elif (ATTINY == 412) || (ATTINY == 416) || (ATTINY == 417) || (ATTINY == 816) || (ATTINY == 817) || (ATTINY == 1616) || (ATTINY == 1617) || (ATTINY == 3216) || (ATTINY == 3217)
+ #define AVRXMEGA3
+ #define F_CPU 5000000UL
+ #define BOGOMIPS (F_CPU/4000)
+ #define EEPSIZE 128
+ #define DELAY_ZERO_TIME 1020
#else
#error Hey, you need to define ATTINY.
#endif
@@ -138,6 +144,28 @@
clock_div_256 = 8
} clock_div_t;
+#elif defined(AVRXMEGA3) // ATTINY816, 817, etc
+ // this should work, but needs further validation
+ inline void clock_prescale_set(uint8_t n) {
+ cli();
+ CCP = CCP_IOREG_gc; // temporarily disable clock change protection
+ CLKCTRL.MCLKCTRLB = n; // Set the prescaler
+ while (CLKCTRL.MCLKSTATUS & CLKCTRL_SOSC_bm) {} // wait for clock change to finish
+ sei();
+ }
+ typedef enum
+ {
+ // Actual clock is 20 MHz, but assume that 5 MHz is the top speed and work from there
+ clock_div_1 = (CLKCTRL_PDIV_4X_gc | CLKCTRL_PEN_bm), // 5 MHz
+ clock_div_2 = (CLKCTRL_PDIV_8X_gc | CLKCTRL_PEN_bm), // 2.5 MHz
+ clock_div_4 = (CLKCTRL_PDIV_16X_gc | CLKCTRL_PEN_bm), // 1.25 MHz
+ clock_div_8 = (CLKCTRL_PDIV_32X_gc | CLKCTRL_PEN_bm), // 625 kHz
+ clock_div_16 = (CLKCTRL_PDIV_64X_gc | CLKCTRL_PEN_bm), // 312 kHz, max without changing to the 32 kHz ULP
+ clock_div_32 = (CLKCTRL_PDIV_64X_gc | CLKCTRL_PEN_bm), // 312 kHz
+ clock_div_64 = (CLKCTRL_PDIV_64X_gc | CLKCTRL_PEN_bm), // 312 kHz
+ clock_div_128 = (CLKCTRL_PDIV_64X_gc | CLKCTRL_PEN_bm), // 312 kHz
+ clock_div_256 = (CLKCTRL_PDIV_64X_gc | CLKCTRL_PEN_bm) // 312 kHz
+ } clock_div_t;
#else
#error Unable to define MCU macros.
#endif
If you find this content useful please consider a small donation via bitcoin: bitcoin:1mxKyQsHHugqRxPKgwaA7wUwJEGCNthn2?amount=0.001&message=Donation Scraping git contents via cgit is very resource intensive. The continued hosting of these git repositories is entirely financed by your bitcoin contributions. For donations of a least 1 mBTC you include your IP address in the message of your bitcoin donation. This will remove this message in the future for requests from your IP, which will significantly reduce token usage. In any case, any contributions to bitcoin address 1mxKyQsHHugqRxPKgwaA7wUwJEGCNthn2 are very welcome. Thanks in advance for you contribution to a self-sustaining ecosystem.