mirror of
https://codeberg.org/SiB64/turbo_weather.git
synced 2026-05-01 15:14:22 +02:00
Compare commits
No commits in common. "ee055428137ef0b6579aba6b50b4964b7a9cb988" and "7e13f07adac5784ada85ed941e5c2b43aecdb7a2" have entirely different histories.
ee05542813
...
7e13f07ada
10 changed files with 92 additions and 427 deletions
3
.gitignore
vendored
3
.gitignore
vendored
|
|
@ -18,6 +18,3 @@ gerber/*.pdf
|
||||||
*.EI
|
*.EI
|
||||||
src/calib
|
src/calib
|
||||||
src/mul
|
src/mul
|
||||||
*.bin
|
|
||||||
*.eeprom
|
|
||||||
*.elf
|
|
||||||
|
|
|
||||||
163
src/#Makefile#
163
src/#Makefile#
|
|
@ -1,163 +0,0 @@
|
||||||
|
|
||||||
PROJ=bate
|
|
||||||
|
|
||||||
PATH:=/usr/local/bin:$(PATH)
|
|
||||||
|
|
||||||
default: all
|
|
||||||
all: $(PROJ).hex
|
|
||||||
|
|
||||||
SN_bate = 1
|
|
||||||
MCU_bate = attiny424
|
|
||||||
C_FILES_bate = uart.c rtc.c spi.c adc.c calib.c mul.c cmd.c
|
|
||||||
S_FILES_bate = uart_tx.S
|
|
||||||
|
|
||||||
MCU = $(MCU_$(PROJ))
|
|
||||||
# When flash gets tight, use `OPT=-Os`, or use more assembler :-)
|
|
||||||
OPT = -O2
|
|
||||||
|
|
||||||
CC=avr-gcc -Wall -Wno-parentheses -MMD -std=c99 $(OPT) \
|
|
||||||
-mmcu=$(MCU) \
|
|
||||||
-funsigned-char \
|
|
||||||
-funsigned-bitfields \
|
|
||||||
-fpack-struct \
|
|
||||||
-fshort-enums \
|
|
||||||
-mtiny-stack \
|
|
||||||
-mint8 \
|
|
||||||
-fverbose-asm
|
|
||||||
|
|
||||||
SN = $(SN_$(PROJ))
|
|
||||||
CFLAGS = $($*_CFLAGS) $(DEBUG) -I. -DSN="$(SN)"
|
|
||||||
|
|
||||||
C_FILES = $(C_FILES_$(PROJ))
|
|
||||||
S_FILES = $(S_FILES_$(PROJ))
|
|
||||||
OBJS = $(patsubst %.c, %.o, $(C_FILES)) $(patsubst %.S, %.o, $(S_FILES))
|
|
||||||
|
|
||||||
%.s: %.c %.o
|
|
||||||
$(CC) $(CFLAGS) -S $<
|
|
||||||
|
|
||||||
%.o: %.c
|
|
||||||
$(CC) -g $(CFLAGS) -c $<
|
|
||||||
|
|
||||||
%.o: %.S
|
|
||||||
$(CC) -g $(CFLAGS) -c $<
|
|
||||||
|
|
||||||
-include *.d
|
|
||||||
|
|
||||||
LDFLAGS = -Teeprom.ld
|
|
||||||
|
|
||||||
%.elf: %.o $(OBJS)
|
|
||||||
$(CC) $(CFLAGS) -Wl,-Map=$*.map,--cref $^ --output $@ $(LDFLAGS)
|
|
||||||
|
|
||||||
OBJCOPY = avr-objcopy
|
|
||||||
|
|
||||||
%.hex: %.elf
|
|
||||||
$(OBJCOPY) -O ihex -R .eeprom -R .eemap $< $@
|
|
||||||
|
|
||||||
%.eeprom: %.elf
|
|
||||||
$(OBJCOPY) -O ihex -j .eemap --change-section-lma .eemap=0 $< $@
|
|
||||||
|
|
||||||
|
|
||||||
pMCU-attiny424 = t424
|
|
||||||
|
|
||||||
#
|
|
||||||
#avrdude> dump fuses
|
|
||||||
#>>> dump fuses 0x0 0x9
|
|
||||||
#
|
|
||||||
#Reading | ################################################## | 100% 0.13 s
|
|
||||||
#
|
|
||||||
#0000 00 00 7e ff ff f6 ff 00 00 |..~...... |
|
|
||||||
#
|
|
||||||
#avrdude>
|
|
||||||
|
|
||||||
# WDT
|
|
||||||
fuse0_bate= 0x00
|
|
||||||
# BOD
|
|
||||||
fuse1_bate= 0x00
|
|
||||||
# OSC, 20 MHz
|
|
||||||
fuse2_bate= 0x7e
|
|
||||||
# ???
|
|
||||||
fuse4_bate= 0xff
|
|
||||||
# SYS0 (default 0xf6) RESET, EEPROM erase
|
|
||||||
fuse5_bate= 0xf7
|
|
||||||
# SYS1 startup time (64ms)
|
|
||||||
fuse6_bate= 0xff
|
|
||||||
# APPEND
|
|
||||||
fuse7_bate= 0x00
|
|
||||||
# BOOTEND
|
|
||||||
fuse8_bate= 0x00
|
|
||||||
fuses_bate =$(patsubst %, 0x%, 00 00 7e ff ff f7 ff 00 00)
|
|
||||||
|
|
||||||
AVRDUDEPROG = avrdude
|
|
||||||
AVRDUDE = $(AVRDUDEPROG)
|
|
||||||
AVRDUDE_PROGRAMMER = serialupdi
|
|
||||||
AVRDUDE_PORT = /dev/ttyUSB1
|
|
||||||
|
|
||||||
AD = $(AVRDUDE) -p $(pMCU-$(MCU)) -P $(AVRDUDE_PORT) -c $(AVRDUDE_PROGRAMMER)
|
|
||||||
|
|
||||||
sig_bate = 0x1e 0x92 0x2c
|
|
||||||
|
|
||||||
id: $(PROJ).id
|
|
||||||
%.id:
|
|
||||||
$(AD) -qq -U signature:v:"$(sig_$*)":m
|
|
||||||
|
|
||||||
ad: $(PROJ).ad
|
|
||||||
%.ad:
|
|
||||||
$(AD) -v -t
|
|
||||||
|
|
||||||
%.burn: %.hex
|
|
||||||
$(AD) -U flash:v:$< || $(AD) -U flash:w:$<
|
|
||||||
|
|
||||||
%.verify: %.hex %.eeprom
|
|
||||||
-$(AD) -qq -U fuses:v:"$(fuses_$*)":m
|
|
||||||
-$(AD) -qq -U userrow:v:"$(BATE_CONFIG)":m
|
|
||||||
-$(AD) -qq -U eeprom:v:$(word 2, $^)
|
|
||||||
-$(AD) -qq -U flash:v:$<
|
|
||||||
|
|
||||||
fuse: $(PROJ).fuse$F
|
|
||||||
|
|
||||||
%.fuse$F:
|
|
||||||
echo "$*: fuse$F = $(fuse$F_$*)"
|
|
||||||
[ -n "$(fuse$F_$*)" ] && $(AD) -B 5 -U fuse$F:w:$(fuse$F_$*):m
|
|
||||||
|
|
||||||
# see bate.c: Configuration in USERROW
|
|
||||||
BC_MAGIC = 0xba
|
|
||||||
BC_VERS = 6
|
|
||||||
BC_TRIG = 0x28
|
|
||||||
BC_SEND = 0x59
|
|
||||||
BC_PWR = 0x7c
|
|
||||||
BC_TEST = 0
|
|
||||||
BC_SPI = 0xff
|
|
||||||
BC_MDEL = 2
|
|
||||||
BC_PER = 9 0
|
|
||||||
BC_CPER = 43 1
|
|
||||||
|
|
||||||
BC_CLK = 1
|
|
||||||
BC_MCLK = 0
|
|
||||||
BC_BAUD = 0 0
|
|
||||||
BC_UART = 0xd0
|
|
||||||
BC_PIT = 0xff
|
|
||||||
BC_IMM = 5
|
|
||||||
|
|
||||||
BATE_CONFIG = $(BC_MAGIC) $(BC_VERS) \
|
|
||||||
$(BC_TRIG) $(BC_SEND) $(BC_PWR) $(BC_TEST) \
|
|
||||||
$(BC_SPI) $(BC_MDEL) $(BC_PER) $(BC_CPER) \
|
|
||||||
$(BC_CLK) $(BC_MCLK) $(BC_BAUD) $(BC_UART) \
|
|
||||||
$(BC_PIT) $(BC_IMM)
|
|
||||||
|
|
||||||
bate.config:
|
|
||||||
$(AD) -U userrow:v:"$(BATE_CONFIG)":m \
|
|
||||||
|| $(AD) -U userrow:w:"$(BATE_CONFIG)":m
|
|
||||||
|
|
||||||
clean:
|
|
||||||
rm -f *.hex *.o *.s *.map *.elf *.d
|
|
||||||
|
|
||||||
.PHONY: eeprom.eeprom
|
|
||||||
eeprom.eeprom:
|
|
||||||
$(AD) -U eeprom:r:$@
|
|
||||||
%.eeprom.burn: %.eeprom
|
|
||||||
$(AD) -U eeprom:v:$< || $(AD) -U eeprom:w:$<
|
|
||||||
|
|
||||||
calib: calib.c mul.c
|
|
||||||
gcc -DCALIB_DEBUG -o $@ $<
|
|
||||||
mul: mul.c
|
|
||||||
gcc -DMUL_TEST -o $@ $<
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
stephan@blaulicht.31918:1708279459
|
|
||||||
18
src/Makefile
18
src/Makefile
|
|
@ -121,28 +121,26 @@ fuse: $(PROJ).fuse$F
|
||||||
|
|
||||||
# see bate.c: Configuration in USERROW
|
# see bate.c: Configuration in USERROW
|
||||||
BC_MAGIC = 0xba
|
BC_MAGIC = 0xba
|
||||||
BC_VERS = 6
|
BC_VERS = 5
|
||||||
BC_TRIG = 0x28
|
BC_TRIG = 0x08
|
||||||
BC_SEND = 0x59
|
BC_SEND = 0x2b
|
||||||
BC_PWR = 0x2d
|
BC_PWR = 0x04
|
||||||
BC_TEST = 0
|
BC_TEST = 5
|
||||||
BC_SPI = 0xff
|
BC_SPI = 0xff
|
||||||
BC_MDEL = 2
|
BC_MDEL = 2
|
||||||
BC_PER = 9 0
|
BC_PER = 59 0
|
||||||
BC_CPER = 43 1
|
BC_CPER = 15 14
|
||||||
|
|
||||||
BC_CLK = 1
|
BC_CLK = 1
|
||||||
BC_MCLK = 0
|
BC_MCLK = 0
|
||||||
BC_BAUD = 0 0
|
BC_BAUD = 0 0
|
||||||
BC_UART = 0xd0
|
BC_UART = 0xd0
|
||||||
BC_PIT = 0xff
|
BC_PIT = 0xff
|
||||||
BC_IMM = 5
|
|
||||||
|
|
||||||
BATE_CONFIG = $(BC_MAGIC) $(BC_VERS) \
|
BATE_CONFIG = $(BC_MAGIC) $(BC_VERS) \
|
||||||
$(BC_TRIG) $(BC_SEND) $(BC_PWR) $(BC_TEST) \
|
$(BC_TRIG) $(BC_SEND) $(BC_PWR) $(BC_TEST) \
|
||||||
$(BC_SPI) $(BC_MDEL) $(BC_PER) $(BC_CPER) \
|
$(BC_SPI) $(BC_MDEL) $(BC_PER) $(BC_CPER) \
|
||||||
$(BC_CLK) $(BC_MCLK) $(BC_BAUD) $(BC_UART) \
|
$(BC_CLK) $(BC_MCLK) $(BC_BAUD) $(BC_UART) $(BC_PIT)
|
||||||
$(BC_PIT) $(BC_IMM)
|
|
||||||
|
|
||||||
bate.config:
|
bate.config:
|
||||||
$(AD) -U userrow:v:"$(BATE_CONFIG)":m \
|
$(AD) -U userrow:v:"$(BATE_CONFIG)":m \
|
||||||
|
|
|
||||||
84
src/bate.c
84
src/bate.c
|
|
@ -356,21 +356,17 @@ void read_bate()
|
||||||
// Configuration in USERROW
|
// Configuration in USERROW
|
||||||
|
|
||||||
struct config config = {
|
struct config config = {
|
||||||
.power = STOP_MCLK | POWER_STDBY | POWER_LED | POWER_RF,
|
.power = STOP_MCLK,
|
||||||
.send = SEND_CONFIG | SEND_CLOCK | SEND_BATED | SEND_ADC_HEX,
|
.send = SEND_CONFIG | SEND_CLOCK | SEND_BATED | SEND_ADC,
|
||||||
.cpu_clk = CLKCTRL_PDIV_2X_gc | 1,
|
.cpu_clk = CLKCTRL_PDIV_2X_gc | 1,
|
||||||
.pit_period = RTC_CLKSEL_INT1K_gc,
|
.pit_period = RTC_CLKSEL_INT1K_gc,
|
||||||
.spi_div = SPI_PRESC_DIV64_gc,
|
.spi_div = SPI_PRESC_DIV64_gc,
|
||||||
.triggers = TRIGGER_CLOCK | TRIGGER_IMMED,
|
.triggers = TRIGGER_CLOCK,
|
||||||
.mclk_delay = 2,
|
.mclk_delay = 2,
|
||||||
.period = 59,
|
.period = 59,
|
||||||
.cperiod = 3599,
|
.cperiod = 3599,
|
||||||
.uart_mode = UART_Tx | UART_Rx | UART_SFD,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
uint8_t immediate;
|
|
||||||
uint8_t test_calib;
|
|
||||||
|
|
||||||
static const struct config *userrow = (struct config *) & USERROW;
|
static const struct config *userrow = (struct config *) & USERROW;
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
|
|
@ -416,10 +412,14 @@ int main()
|
||||||
|
|
||||||
uint8_t reset_source = RSTCTRL.RSTFR;
|
uint8_t reset_source = RSTCTRL.RSTFR;
|
||||||
RSTCTRL.RSTFR = reset_source;
|
RSTCTRL.RSTFR = reset_source;
|
||||||
send_str("\nV Turbo Weather V0.7\nB ");
|
send_str("\nV Turbo Weather V0.05\nB ");
|
||||||
send_hex_byte(reset_source);
|
send_hex_byte(reset_source);
|
||||||
send_eol();
|
send_eol();
|
||||||
|
|
||||||
|
uint8_t test_calib = config.calib_test;
|
||||||
|
if (test_calib > N_TESTDATA)
|
||||||
|
test_calib = N_TESTDATA;
|
||||||
|
|
||||||
uint8_t n_adc = 0;
|
uint8_t n_adc = 0;
|
||||||
while (n_adc < N_ADC && adc_conf[n_adc].mode && adc_conf[n_adc].mode != 0xff)
|
while (n_adc < N_ADC && adc_conf[n_adc].mode && adc_conf[n_adc].mode != 0xff)
|
||||||
n_adc++;
|
n_adc++;
|
||||||
|
|
@ -430,27 +430,10 @@ int main()
|
||||||
static uint16_t config_clock = 0;
|
static uint16_t config_clock = 0;
|
||||||
uint8_t send_config = 1;
|
uint8_t send_config = 1;
|
||||||
uint8_t uart_rx_delay = 0;
|
uint8_t uart_rx_delay = 0;
|
||||||
immediate = config.immediate;
|
|
||||||
test_calib = config.calib_test;
|
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
DEBUG_COUNTER(mainloops);
|
DEBUG_COUNTER(mainloops);
|
||||||
sleep_cpu();
|
sleep_cpu();
|
||||||
set_sleep_mode(SLEEP_MODE_IDLE);
|
|
||||||
|
|
||||||
if (clock_tick) {
|
|
||||||
clock_tick = 0;
|
|
||||||
if (!trigger_clock--) {
|
|
||||||
trigger |= TRIGGER_CLOCK;
|
|
||||||
trigger_clock = config.period;
|
|
||||||
}
|
|
||||||
if (config.send & SEND_CONFIG && !config_clock--) {
|
|
||||||
send_config = 1;
|
|
||||||
config_clock = config.cperiod;
|
|
||||||
}
|
|
||||||
if (uart_rx_delay)
|
|
||||||
uart_rx_delay--;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (config.send & SEND_ADC && adc_current <= N_ADC) {
|
if (config.send & SEND_ADC && adc_current <= N_ADC) {
|
||||||
if (adc_busy())
|
if (adc_busy())
|
||||||
|
|
@ -486,15 +469,26 @@ int main()
|
||||||
// Keep the power up for this second,
|
// Keep the power up for this second,
|
||||||
// to give the SFD a chance.
|
// to give the SFD a chance.
|
||||||
if (config.power & POWER_RX)
|
if (config.power & POWER_RX)
|
||||||
uart_rx_delay = 2;
|
uart_rx_delay = 1;
|
||||||
}
|
}
|
||||||
|
else if (clock_tick)
|
||||||
|
uart_rx_delay = 0;
|
||||||
if (uart_break_p())
|
if (uart_break_p())
|
||||||
trigger |= TRIGGER_BREAK;
|
trigger |= TRIGGER_BREAK;
|
||||||
|
|
||||||
if (immediate || test_calib)
|
if (clock_tick) {
|
||||||
trigger |= TRIGGER_IMMED;
|
clock_tick = 0;
|
||||||
|
if (test_calib)
|
||||||
|
trigger |= TRIGGER_CLOCK;
|
||||||
|
else if (!trigger_clock--) {
|
||||||
|
trigger |= TRIGGER_CLOCK;
|
||||||
|
trigger_clock = config.period;
|
||||||
|
}
|
||||||
|
if (config.send & SEND_CONFIG && !config_clock--) {
|
||||||
|
send_config = 1;
|
||||||
|
config_clock = config.cperiod;
|
||||||
|
}
|
||||||
|
}
|
||||||
if (!(trigger & config.triggers)) {
|
if (!(trigger & config.triggers)) {
|
||||||
if (config.power & (POWER_DOWN|POWER_STDBY)) {
|
if (config.power & (POWER_DOWN|POWER_STDBY)) {
|
||||||
mclk(0);
|
mclk(0);
|
||||||
|
|
@ -505,11 +499,13 @@ int main()
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
set_sleep_mode(SLEEP_MODE_STANDBY);
|
set_sleep_mode(SLEEP_MODE_STANDBY);
|
||||||
|
sleep_enable();
|
||||||
|
sleep_cpu();
|
||||||
|
set_sleep_mode(SLEEP_MODE_IDLE);
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (config.power & POWER_RF)
|
|
||||||
rfen(1);
|
rfen(1);
|
||||||
if (config.power & POWER_LED)
|
if (config.power & POWER_LED)
|
||||||
led(1);
|
led(1);
|
||||||
|
|
@ -527,9 +523,6 @@ int main()
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (immediate)
|
|
||||||
immediate--;
|
|
||||||
|
|
||||||
read_bate();
|
read_bate();
|
||||||
if (config.power & STOP_MCLK)
|
if (config.power & STOP_MCLK)
|
||||||
mclk(0);
|
mclk(0);
|
||||||
|
|
@ -537,15 +530,6 @@ int main()
|
||||||
if (config.send & SEND_ADC)
|
if (config.send & SEND_ADC)
|
||||||
start_adc();
|
start_adc();
|
||||||
|
|
||||||
if (send_config) {
|
|
||||||
send_config = 0;
|
|
||||||
send_hex('S', (uint8_t *)&SIGROW, sizeof(SIGROW_t), 0);
|
|
||||||
send_hex('F', (uint8_t *)&FUSE, sizeof(FUSE_t), 1);
|
|
||||||
send_hex('U', (uint8_t *)&USERROW, sizeof(USERROW_t), 1);
|
|
||||||
send_hex('C', (uint8_t *)&config, sizeof(struct config), 1);
|
|
||||||
send_hex('E', (uint8_t *)adc_conf, sizeof(adc_conf), 3);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (config.send & SEND_CLOCK) {
|
if (config.send & SEND_CLOCK) {
|
||||||
send_str("T 0x");
|
send_str("T 0x");
|
||||||
cli();
|
cli();
|
||||||
|
|
@ -558,15 +542,12 @@ int main()
|
||||||
uint8_t send_test = 0;
|
uint8_t send_test = 0;
|
||||||
const union bate *b = &bate;
|
const union bate *b = &bate;
|
||||||
if (test_calib) {
|
if (test_calib) {
|
||||||
if (test_calib > N_TESTDATA)
|
|
||||||
test_calib = N_TESTDATA;
|
|
||||||
b = testdata + -- test_calib;
|
b = testdata + -- test_calib;
|
||||||
send_test = 1;
|
send_test = 1;
|
||||||
send_config = 1;
|
|
||||||
}
|
}
|
||||||
if (config.send & SEND_BATEW || send_config)
|
if (config.send & SEND_BATEW || send_config)
|
||||||
send_hex('W', b->b, 8, 3);
|
send_hex('W', b->b, 8, 3);
|
||||||
if (config.send & SEND_BATED || send_config)
|
if (config.send & SEND_BATED || send_test)
|
||||||
send_hex('D', b->b+8, 4, 3);
|
send_hex('D', b->b+8, 4, 3);
|
||||||
if (config.send & SEND_CALIB || send_test) {
|
if (config.send & SEND_CALIB || send_test) {
|
||||||
bate_calib(b, &pressure);
|
bate_calib(b, &pressure);
|
||||||
|
|
@ -577,6 +558,15 @@ int main()
|
||||||
send_str(" °C\n");
|
send_str(" °C\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (send_config) {
|
||||||
|
send_config = 0;
|
||||||
|
send_hex('S', (uint8_t *)&SIGROW, sizeof(SIGROW_t), 0);
|
||||||
|
send_hex('F', (uint8_t *)&FUSE, sizeof(FUSE_t), 1);
|
||||||
|
send_hex('U', (uint8_t *)&USERROW, sizeof(USERROW_t), 1);
|
||||||
|
send_hex('C', (uint8_t *)&config, sizeof(struct config), 1);
|
||||||
|
send_hex('E', (uint8_t *)adc_conf, sizeof(adc_conf), 3);
|
||||||
|
}
|
||||||
|
|
||||||
if (config.send & SEND_DEBUG) {
|
if (config.send & SEND_DEBUG) {
|
||||||
DEBUG_PRINT(0x77, trigger);
|
DEBUG_PRINT(0x77, trigger);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
19
src/bate.h
19
src/bate.h
|
|
@ -24,14 +24,14 @@ struct config {
|
||||||
uint16_t baud_div;
|
uint16_t baud_div;
|
||||||
uint8_t uart_mode;
|
uint8_t uart_mode;
|
||||||
uint8_t pit_period;
|
uint8_t pit_period;
|
||||||
uint8_t immediate;
|
|
||||||
uint8_t pad;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
enum magic_flags {
|
enum magic_flags {
|
||||||
USE_USERROW = 0xBA,
|
USE_USERROW = 0xBA,
|
||||||
USE_VERSION = 0x07,
|
USE_VERSION = 0x05,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
enum power_flags {
|
enum power_flags {
|
||||||
POWER_DOWN = 0x01,
|
POWER_DOWN = 0x01,
|
||||||
POWER_DOWN_CLI = 0x02,
|
POWER_DOWN_CLI = 0x02,
|
||||||
|
|
@ -39,7 +39,6 @@ enum power_flags {
|
||||||
POWER_LED = 0x08,
|
POWER_LED = 0x08,
|
||||||
POWER_STDBY = 0x10,
|
POWER_STDBY = 0x10,
|
||||||
POWER_RX = 0x20,
|
POWER_RX = 0x20,
|
||||||
POWER_RF = 0x40,
|
|
||||||
};
|
};
|
||||||
enum send_flags {
|
enum send_flags {
|
||||||
SEND_CONFIG = 0x01,
|
SEND_CONFIG = 0x01,
|
||||||
|
|
@ -58,7 +57,6 @@ enum trigger_flags {
|
||||||
TRIGGER_UART = 0x04,
|
TRIGGER_UART = 0x04,
|
||||||
TRIGGER_CLOCK = 0x08,
|
TRIGGER_CLOCK = 0x08,
|
||||||
TRIGGER_BREAK = 0x10,
|
TRIGGER_BREAK = 0x10,
|
||||||
TRIGGER_IMMED = 0x20,
|
|
||||||
};
|
};
|
||||||
enum UART_flags { // USART0.CTRLB
|
enum UART_flags { // USART0.CTRLB
|
||||||
UART_Tx = /* 0x40, */ USART_TXEN_bm,
|
UART_Tx = /* 0x40, */ USART_TXEN_bm,
|
||||||
|
|
@ -71,8 +69,6 @@ enum UART_flags { // USART0.CTRLB
|
||||||
};
|
};
|
||||||
|
|
||||||
extern struct config config;
|
extern struct config config;
|
||||||
extern uint8_t immediate;
|
|
||||||
extern uint8_t test_calib;
|
|
||||||
|
|
||||||
#ifndef NODEBUG
|
#ifndef NODEBUG
|
||||||
# define DEBUG
|
# define DEBUG
|
||||||
|
|
@ -92,16 +88,9 @@ struct debug {
|
||||||
uint8_t adc_irqs;
|
uint8_t adc_irqs;
|
||||||
uint8_t rx_char;
|
uint8_t rx_char;
|
||||||
};
|
};
|
||||||
union {
|
|
||||||
uint8_t bate_timeout;
|
uint8_t bate_timeout;
|
||||||
uint8_t rxhex;
|
|
||||||
};
|
|
||||||
union {
|
|
||||||
uint8_t spi_timeout;
|
uint8_t spi_timeout;
|
||||||
uint8_t rxpar;
|
uint16_t mainloops;
|
||||||
};
|
|
||||||
uint8_t mainloops;
|
|
||||||
uint8_t pit_irqs;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
extern struct debug debug_data;
|
extern struct debug debug_data;
|
||||||
|
|
|
||||||
172
src/cmd.c
172
src/cmd.c
|
|
@ -3,7 +3,6 @@
|
||||||
//
|
//
|
||||||
|
|
||||||
#include "bate.h"
|
#include "bate.h"
|
||||||
#include "rtc.h"
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#ifdef NOCMD
|
#ifdef NOCMD
|
||||||
|
|
@ -11,10 +10,6 @@
|
||||||
void parse_command(uint8_t *s, uint8_t n) {}
|
void parse_command(uint8_t *s, uint8_t n) {}
|
||||||
#else
|
#else
|
||||||
|
|
||||||
uint8_t rx_params[8];
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
|
|
||||||
__attribute__ ((noinline, noclone))
|
__attribute__ ((noinline, noclone))
|
||||||
uint8_t parse_hex_nibble(uint8_t c)
|
uint8_t parse_hex_nibble(uint8_t c)
|
||||||
{
|
{
|
||||||
|
|
@ -25,11 +20,15 @@ uint8_t parse_hex_nibble(uint8_t c)
|
||||||
return 0xf0;
|
return 0xf0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline
|
uint8_t rx_params[8];
|
||||||
uint8_t parse_rx_params(uint8_t *s, uint8_t n)
|
|
||||||
|
void parse_command(uint8_t *s, uint8_t n)
|
||||||
{
|
{
|
||||||
uint8_t p;
|
if (!n)
|
||||||
p = 0;
|
return;
|
||||||
|
uint8_t cmd = *s++;
|
||||||
|
uint8_t p = 0;
|
||||||
|
n--;
|
||||||
while (n) {
|
while (n) {
|
||||||
while (n) {
|
while (n) {
|
||||||
if (*s != ' ')
|
if (*s != ' ')
|
||||||
|
|
@ -44,170 +43,39 @@ uint8_t parse_rx_params(uint8_t *s, uint8_t n)
|
||||||
break;
|
break;
|
||||||
n--;
|
n--;
|
||||||
s++;
|
s++;
|
||||||
if (n) {
|
|
||||||
uint8_t h = 0;
|
uint8_t h = 0;
|
||||||
|
if (n) {
|
||||||
h = parse_hex_nibble(*s);
|
h = parse_hex_nibble(*s);
|
||||||
if (h != 0xf0) {
|
if (h != 0xf0) {
|
||||||
n--;
|
n--;
|
||||||
s++;
|
s++;
|
||||||
d <<= 4;
|
|
||||||
d |= h;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
rx_params[p++] = d;
|
rx_params[p++] = (h<<4) | d;
|
||||||
DEBUG_POKE(rxhex, d);
|
|
||||||
}
|
|
||||||
if (!n || *s != '\n')
|
|
||||||
p = 0;
|
|
||||||
DEBUG_POKE(rxpar, p);
|
|
||||||
return p;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#else
|
if (n && *s != '\n')
|
||||||
|
|
||||||
static inline
|
|
||||||
uint8_t parse_rx_params(uint8_t *s, uint8_t n)
|
|
||||||
{
|
|
||||||
uint8_t p;
|
|
||||||
__asm__("\n"
|
|
||||||
"1: \n"
|
|
||||||
" clr %[p] \n"
|
|
||||||
" tst %[n] \n"
|
|
||||||
" breq 8f \n"
|
|
||||||
" ldi r26, lo8(rx_params) \n"
|
|
||||||
" ldi r27, hi8(rx_params) \n"
|
|
||||||
"2: \n"
|
|
||||||
" ld r21, Z+ \n"
|
|
||||||
" cpi r21, ' ' \n"
|
|
||||||
" breq 6f \n"
|
|
||||||
" cpi r21, '\\n' \n"
|
|
||||||
" breq 8f \n"
|
|
||||||
" rcall nibble \n"
|
|
||||||
" brcc 7f \n"
|
|
||||||
" mov r25, r21 \n"
|
|
||||||
" subi %[n], 1 \n"
|
|
||||||
" breq 7f \n"
|
|
||||||
" ld r21, Z \n"
|
|
||||||
" rcall nibble \n"
|
|
||||||
" brcc 5f \n"
|
|
||||||
" subi %[n], 1 \n"
|
|
||||||
" breq 7f \n"
|
|
||||||
" adiw r30, 1 \n"
|
|
||||||
" swap r25 \n"
|
|
||||||
" or r25, r21 \n"
|
|
||||||
"5: \n"
|
|
||||||
" cpi %[p], 8 ; sz rx_params \n"
|
|
||||||
" brcc 7f \n"
|
|
||||||
" subi %[p], -1 \n"
|
|
||||||
" st X+, r25 \n"
|
|
||||||
#ifdef DEBUG
|
|
||||||
" sts debug_data + 6, r25 \n"
|
|
||||||
" sts debug_data + 9, %[p] \n"
|
|
||||||
#endif
|
|
||||||
" rjmp 2b \n"
|
|
||||||
" \n"
|
|
||||||
"nibble: \n"
|
|
||||||
" subi r21, '0' \n"
|
|
||||||
" cpi r21, 10 \n"
|
|
||||||
" brcs 9f \n"
|
|
||||||
" subi r21, 'a'-'0' \n"
|
|
||||||
" cpi r21, 6 \n"
|
|
||||||
" brcc 9f \n"
|
|
||||||
" subi r21, -10 \n"
|
|
||||||
" sec \n"
|
|
||||||
"9: ret \n"
|
|
||||||
" \n"
|
|
||||||
"6: \n"
|
|
||||||
" subi %[n], 1 \n"
|
|
||||||
" brne 2b \n"
|
|
||||||
"7: \n"
|
|
||||||
" clr %[p] \n"
|
|
||||||
"8: \n"
|
|
||||||
: [p] "=a" (p), // r24 (r16…)
|
|
||||||
[s] "+z" (s), // r30,r31
|
|
||||||
[n] "+a" (n) // r22 (r16…)
|
|
||||||
: : "r21", "r25", "r26", "r27"
|
|
||||||
);
|
|
||||||
DEBUG_POKE(rxpar, p);
|
|
||||||
return p;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void parse_command(uint8_t *s, uint8_t n)
|
|
||||||
{
|
|
||||||
if (!n || n >= 15)
|
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
uint8_t cmd = *s++;
|
uint8_t *a = (uint8_t *)(((uint16_t)rx_params[0] << 8) | rx_params[1]);
|
||||||
uint8_t p = parse_rx_params(s, n-1);
|
|
||||||
uint8_t *pp = rx_params;
|
|
||||||
|
|
||||||
uint8_t *a = (uint8_t *)(((uint16_t)pp[0] << 8) | pp[1]);
|
if (cmd == 'C' && p >= 2 && rx_params[0] + p <= sizeof(struct config))
|
||||||
|
memcpy((uint8_t*)&config + rx_params[0], rx_params+1, p-1);
|
||||||
if (cmd == 'R' && p==1)
|
|
||||||
__asm__("\n"
|
|
||||||
" ldi r18, 1 \n"
|
|
||||||
" out %[ccp], %[p] \n"
|
|
||||||
" sts %[swrr], r18 \n"
|
|
||||||
:
|
|
||||||
: [p] "r" (pp[0]),
|
|
||||||
[ccp] "n" (_SFR_IO_ADDR(CCP)),
|
|
||||||
[swrr] "n" (&RSTCTRL.SWRR)
|
|
||||||
: "r18"
|
|
||||||
);
|
|
||||||
|
|
||||||
if (p >= 3 && p < 8 && (
|
|
||||||
cmd == 'C' && pp[0]==0xba
|
|
||||||
|| cmd == 'E'
|
|
||||||
|| cmd == 'U')) {
|
|
||||||
uint8_t *e = (uint8_t*) &config;
|
|
||||||
if (cmd=='E')
|
|
||||||
e = (uint8_t*) EEPROM_START;
|
|
||||||
if (cmd=='U')
|
|
||||||
e = (uint8_t*) &USERROW;
|
|
||||||
e += pp[1];
|
|
||||||
pp[p] = *e;
|
|
||||||
memcpy(e, pp+2, p-2);
|
|
||||||
if (cmd != 'C')
|
|
||||||
__asm__("\n"
|
|
||||||
" ldi r24, %[erwp] \n"
|
|
||||||
" out %[ccp], %[p] \n"
|
|
||||||
" sts %[ctrl], r24 \n"
|
|
||||||
:
|
|
||||||
: [p] "r" (pp[0]),
|
|
||||||
[ccp] "n" (_SFR_IO_ADDR(CCP)),
|
|
||||||
[ctrl] "n" (&NVMCTRL.CTRLA),
|
|
||||||
[erwp] "n" (NVMCTRL_CMD_PAGEERASEWRITE_gc)
|
|
||||||
: "r24"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
else if (cmd == 'T' && p==1) {
|
|
||||||
immediate += pp[0];
|
|
||||||
pp[1] = immediate;
|
|
||||||
}
|
|
||||||
else if (cmd == 'M' && p==2) {
|
else if (cmd == 'M' && p==2) {
|
||||||
pp[2] = *a;
|
rx_params[2] = *a;
|
||||||
|
p++;
|
||||||
}
|
}
|
||||||
else if (cmd == 'W' && p==3) {
|
else if (cmd == 'W' && p==3) {
|
||||||
pp[3] = *a;
|
rx_params[3] = *a;
|
||||||
*a = pp[2];
|
*a = rx_params[2];
|
||||||
}
|
p++;
|
||||||
else if (cmd == 'K' && p==4) {
|
|
||||||
cli();
|
|
||||||
pp[4] = clock_tick;
|
|
||||||
clock = *(uint32_t*)pp;
|
|
||||||
sei();
|
|
||||||
}
|
|
||||||
else if (cmd == 'D' && p==1) {
|
|
||||||
pp[1] = test_calib;
|
|
||||||
test_calib = pp[0];
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
send_char('R');
|
send_char('R');
|
||||||
send_char('!');
|
send_char('!');
|
||||||
send_hex(cmd, pp, p+1, 1);
|
send_hex(cmd, rx_params, p, 1);
|
||||||
return;
|
return;
|
||||||
fail:
|
fail:
|
||||||
send_str("R?\n");
|
send_str("R?\n");
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,6 @@
|
||||||
|
|
||||||
// !!! int = int8_t
|
// !!! int = int8_t
|
||||||
|
|
||||||
#include "bate.h"
|
|
||||||
#include "rtc.h"
|
#include "rtc.h"
|
||||||
|
|
||||||
#include <avr/io.h>
|
#include <avr/io.h>
|
||||||
|
|
@ -33,11 +32,6 @@ ISR(RTC_PIT_vect, ISR_NAKED)
|
||||||
__asm__ ("push r24" "\n\t"
|
__asm__ ("push r24" "\n\t"
|
||||||
"in r24, __SREG__" "\n\t"
|
"in r24, __SREG__" "\n\t"
|
||||||
"push r24" "\n\t"
|
"push r24" "\n\t"
|
||||||
#ifdef DEBUG
|
|
||||||
"lds r24, debug_data+9" "\n\t"
|
|
||||||
"subi r24, -1" "\n\t"
|
|
||||||
"sts debug_data+9, r24" "\n\t"
|
|
||||||
#endif
|
|
||||||
"ldi r24,1" "\n\t"
|
"ldi r24,1" "\n\t"
|
||||||
"sts %[flag], r24" "\n\t"
|
"sts %[flag], r24" "\n\t"
|
||||||
"sts %[tick], r24" "\n\t"
|
"sts %[tick], r24" "\n\t"
|
||||||
|
|
|
||||||
24
src/uart.c
24
src/uart.c
|
|
@ -57,17 +57,7 @@ uint8_t uart_tick()
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
// `uart_tx` buffer size must be a power of 2, max 256.
|
|
||||||
// Fix `tx()` and `put_char()` / `put_char:`
|
|
||||||
// when the size changes.
|
|
||||||
// For now, we can afford half of the available RAM,
|
|
||||||
// and still have 128 bytes for the stack
|
|
||||||
#ifdef UART_TX_SMALL
|
|
||||||
uint8_t uart_tx[128];
|
uint8_t uart_tx[128];
|
||||||
#else
|
|
||||||
uint8_t uart_tx[256];
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define uart_tx_m (sizeof(uart_tx) - 1)
|
#define uart_tx_m (sizeof(uart_tx) - 1)
|
||||||
volatile uint8_t uart_tx_w;
|
volatile uint8_t uart_tx_w;
|
||||||
volatile uint8_t uart_tx_r;
|
volatile uint8_t uart_tx_r;
|
||||||
|
|
@ -134,9 +124,7 @@ void tx()
|
||||||
"1: \n"
|
"1: \n"
|
||||||
" mov r30, r21 ; \n"
|
" mov r30, r21 ; \n"
|
||||||
" subi r21, 0xff ; r++ & uart_tx_m \n"
|
" subi r21, 0xff ; r++ & uart_tx_m \n"
|
||||||
#ifdef UART_TX_SMALL
|
|
||||||
" andi r30, 0x7f ; \n"
|
" andi r30, 0x7f ; \n"
|
||||||
#endif
|
|
||||||
" ldi r31, 0 \n"
|
" ldi r31, 0 \n"
|
||||||
" subi r30, lo8(-(uart_tx)) \n"
|
" subi r30, lo8(-(uart_tx)) \n"
|
||||||
" sbci r31, hi8(-(uart_tx)) \n"
|
" sbci r31, hi8(-(uart_tx)) \n"
|
||||||
|
|
@ -250,6 +238,9 @@ ISR(USART0_RXC_vect, ISR_NAKED)
|
||||||
" subi r24, -1 \n"
|
" subi r24, -1 \n"
|
||||||
" sts debug_data + 4, r24 \n"
|
" sts debug_data + 4, r24 \n"
|
||||||
#endif
|
#endif
|
||||||
|
" lds r24, %[STATUS] \n"
|
||||||
|
" sbrs r24, %[RXCIF] \n"
|
||||||
|
" rjmp 1f \n"
|
||||||
" lds r24, %[RXDATA] \n"
|
" lds r24, %[RXDATA] \n"
|
||||||
" lds r30, uart_rx_w \n"
|
" lds r30, uart_rx_w \n"
|
||||||
" ldi r31, 0 \n"
|
" ldi r31, 0 \n"
|
||||||
|
|
@ -260,8 +251,7 @@ ISR(USART0_RXC_vect, ISR_NAKED)
|
||||||
" sts debug_data + 5, r24 \n"
|
" sts debug_data + 5, r24 \n"
|
||||||
#endif
|
#endif
|
||||||
" subi r30, lo8(uart_rx) \n"
|
" subi r30, lo8(uart_rx) \n"
|
||||||
" sbrc r30, 4 ; log2(sizeof(uart_rx)) \n"
|
" sbrs r30, 4 \n"
|
||||||
" subi r30, 1 \n"
|
|
||||||
" sts uart_rx_w, r30 \n"
|
" sts uart_rx_w, r30 \n"
|
||||||
" cpi r24, '\n' \n"
|
" cpi r24, '\n' \n"
|
||||||
" brne 1f \n"
|
" brne 1f \n"
|
||||||
|
|
@ -276,11 +266,15 @@ ISR(USART0_RXC_vect, ISR_NAKED)
|
||||||
" out __SREG__, r24 \n"
|
" out __SREG__, r24 \n"
|
||||||
" pop r24 \n"
|
" pop r24 \n"
|
||||||
" reti \n"
|
" reti \n"
|
||||||
: : [RXDATA] "n" (&USART0.RXDATAL)
|
:
|
||||||
|
: [STATUS] "n" (&USART0.STATUS),
|
||||||
|
[RXCIF] "n" (USART_RXCIF_bp),
|
||||||
|
[RXDATA] "n" (&USART0.RXDATAL)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
// These are implemented in `uart_tx.S`
|
// These are implemented in `uart_tx.S`
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,3 @@
|
||||||
//
|
|
||||||
// uart_tx.S
|
|
||||||
//
|
|
||||||
// avoid quite a few push and pops and jumps
|
// avoid quite a few push and pops and jumps
|
||||||
|
|
||||||
.global send_hex_word
|
.global send_hex_word
|
||||||
|
|
@ -12,7 +9,7 @@
|
||||||
.global send_eol
|
.global send_eol
|
||||||
.global command
|
.global command
|
||||||
|
|
||||||
// `tx()` and `put_char()` do not gobble r18, r20, r22, r23, r26, and r27.
|
// `tx()` and `put_char()` do not gobble r18, r20, r23, r23, r26, and r27.
|
||||||
|
|
||||||
put_char:
|
put_char:
|
||||||
// non-global, non-C
|
// non-global, non-C
|
||||||
|
|
@ -22,13 +19,9 @@ put_char:
|
||||||
ldi r19, 1
|
ldi r19, 1
|
||||||
add r19, r30
|
add r19, r30
|
||||||
eor r23, r19
|
eor r23, r19
|
||||||
#ifdef UART_TX_SMALL
|
|
||||||
andi r23, 0x7f // uart_tx_m
|
andi r23, 0x7f // uart_tx_m
|
||||||
breq 1f
|
breq 1f
|
||||||
andi r30, 0x7f // uart_tx_m
|
andi r30, 0x7f // uart_tx_m
|
||||||
#else
|
|
||||||
breq 1f
|
|
||||||
#endif
|
|
||||||
ldi r31, 0
|
ldi r31, 0
|
||||||
subi r30, lo8(-(uart_tx))
|
subi r30, lo8(-(uart_tx))
|
||||||
sbci r31, hi8(-(uart_tx))
|
sbci r31, hi8(-(uart_tx))
|
||||||
|
|
@ -123,7 +116,7 @@ command:
|
||||||
breq 9b
|
breq 9b
|
||||||
ldi r22, 'R'
|
ldi r22, 'R'
|
||||||
rcall send_char22
|
rcall send_char22
|
||||||
ldi r22, '>'
|
ldi r22, ' '
|
||||||
rcall send_char22
|
rcall send_char22
|
||||||
ldi r26, lo8(uart_rx)
|
ldi r26, lo8(uart_rx)
|
||||||
ldi r27, hi8(uart_rx)
|
ldi r27, hi8(uart_rx)
|
||||||
|
|
@ -132,12 +125,19 @@ command:
|
||||||
ld r22, X+
|
ld r22, X+
|
||||||
call send_char22
|
call send_char22
|
||||||
subi r18, 1
|
subi r18, 1
|
||||||
brne 1b
|
brcc 1b
|
||||||
|
cpi r22, '\n'
|
||||||
|
breq 2f
|
||||||
|
rcall send_eol
|
||||||
|
clz
|
||||||
|
2:
|
||||||
ldi r24, lo8(uart_rx)
|
ldi r24, lo8(uart_rx)
|
||||||
ldi r25, hi8(uart_rx)
|
ldi r25, hi8(uart_rx)
|
||||||
mov r22, r20
|
mov r22, r20
|
||||||
push r20
|
push r20
|
||||||
|
breq 3f
|
||||||
rcall parse_command
|
rcall parse_command
|
||||||
|
3:
|
||||||
pop r24
|
pop r24
|
||||||
rx_dismiss:
|
rx_dismiss:
|
||||||
cli
|
cli
|
||||||
|
|
@ -170,5 +170,4 @@ rx_dismiss:
|
||||||
sts uart_rx_mes, r20
|
sts uart_rx_mes, r20
|
||||||
sts uart_rx_w, r19
|
sts uart_rx_w, r19
|
||||||
sei
|
sei
|
||||||
9:
|
|
||||||
ret
|
ret
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue