Compare commits

...

12 commits

Author SHA1 Message Date
Stephan I. Böttcher
ee05542813 cmd: K set clock, D test data test 2024-04-14 23:28:45 +02:00
Stephan I. Böttcher
4ccae7f99f bate v0.7, config 2024-04-14 23:27:58 +02:00
Stephan I. Böttcher
a3377dc97e cmd: require a sig for C as well 2024-04-14 22:36:18 +02:00
Stephan I. Böttcher
e6197c43ad cmd: E and U for writing EEPROM and USERROW 2024-04-14 22:14:11 +02:00
Stephan I. Böttcher
9030ed194e uart: tx buffer 128 bytes → 256 bytes, stack size 128 bytes 2024-04-14 21:31:19 +02:00
Stephan I. Böttcher
9aa0daa6ab trigger: fix immediate 2024-04-14 20:32:57 +02:00
Stephan I. Böttcher
e16bac4cbc more to .gitignore 2024-04-14 20:24:22 +02:00
Stephan I. Böttcher
fd575d8f17 cmd T, fix period trigger 2024-04-14 20:23:47 +02:00
Stephan I. Böttcher
f7484a5d7e rtc: add debug counter 2024-04-14 20:21:46 +02:00
Stephan I. Böttcher
ec0609759b cmd: work now, add some assembler 2024-04-14 19:40:04 +02:00
Stephan I. Böttcher
e69a74ce46 rtc: add debug counter 2024-04-14 19:38:27 +02:00
Stephan I. Böttcher
9122a63f77 rtc: add debug counter 2024-04-14 19:35:54 +02:00
10 changed files with 427 additions and 92 deletions

3
.gitignore vendored
View file

@ -18,3 +18,6 @@ gerber/*.pdf
*.EI
src/calib
src/mul
*.bin
*.eeprom
*.elf

163
src/#Makefile# Normal file
View file

@ -0,0 +1,163 @@
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
src/.#Makefile Symbolic link
View file

@ -0,0 +1 @@
stephan@blaulicht.31918:1708279459

View file

@ -121,26 +121,28 @@ fuse: $(PROJ).fuse$F
# see bate.c: Configuration in USERROW
BC_MAGIC = 0xba
BC_VERS = 5
BC_TRIG = 0x08
BC_SEND = 0x2b
BC_PWR = 0x04
BC_TEST = 5
BC_VERS = 6
BC_TRIG = 0x28
BC_SEND = 0x59
BC_PWR = 0x2d
BC_TEST = 0
BC_SPI = 0xff
BC_MDEL = 2
BC_PER = 59 0
BC_CPER = 15 14
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_CLK) $(BC_MCLK) $(BC_BAUD) $(BC_UART) \
$(BC_PIT) $(BC_IMM)
bate.config:
$(AD) -U userrow:v:"$(BATE_CONFIG)":m \

View file

@ -356,17 +356,21 @@ void read_bate()
// Configuration in USERROW
struct config config = {
.power = STOP_MCLK,
.send = SEND_CONFIG | SEND_CLOCK | SEND_BATED | SEND_ADC,
.power = STOP_MCLK | POWER_STDBY | POWER_LED | POWER_RF,
.send = SEND_CONFIG | SEND_CLOCK | SEND_BATED | SEND_ADC_HEX,
.cpu_clk = CLKCTRL_PDIV_2X_gc | 1,
.pit_period = RTC_CLKSEL_INT1K_gc,
.spi_div = SPI_PRESC_DIV64_gc,
.triggers = TRIGGER_CLOCK,
.triggers = TRIGGER_CLOCK | TRIGGER_IMMED,
.mclk_delay = 2,
.period = 59,
.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;
#ifdef DEBUG
@ -412,14 +416,10 @@ int main()
uint8_t reset_source = RSTCTRL.RSTFR;
RSTCTRL.RSTFR = reset_source;
send_str("\nV Turbo Weather V0.05\nB ");
send_str("\nV Turbo Weather V0.7\nB ");
send_hex_byte(reset_source);
send_eol();
uint8_t test_calib = config.calib_test;
if (test_calib > N_TESTDATA)
test_calib = N_TESTDATA;
uint8_t n_adc = 0;
while (n_adc < N_ADC && adc_conf[n_adc].mode && adc_conf[n_adc].mode != 0xff)
n_adc++;
@ -430,10 +430,27 @@ int main()
static uint16_t config_clock = 0;
uint8_t send_config = 1;
uint8_t uart_rx_delay = 0;
immediate = config.immediate;
test_calib = config.calib_test;
while (1) {
DEBUG_COUNTER(mainloops);
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 (adc_busy())
@ -469,26 +486,15 @@ int main()
// Keep the power up for this second,
// to give the SFD a chance.
if (config.power & POWER_RX)
uart_rx_delay = 1;
uart_rx_delay = 2;
}
else if (clock_tick)
uart_rx_delay = 0;
if (uart_break_p())
trigger |= TRIGGER_BREAK;
if (clock_tick) {
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 (immediate || test_calib)
trigger |= TRIGGER_IMMED;
if (!(trigger & config.triggers)) {
if (config.power & (POWER_DOWN|POWER_STDBY)) {
mclk(0);
@ -499,14 +505,12 @@ int main()
}
else
set_sleep_mode(SLEEP_MODE_STANDBY);
sleep_enable();
sleep_cpu();
set_sleep_mode(SLEEP_MODE_IDLE);
}
continue;
}
rfen(1);
if (config.power & POWER_RF)
rfen(1);
if (config.power & POWER_LED)
led(1);
@ -523,6 +527,9 @@ int main()
continue;
}
if (immediate)
immediate--;
read_bate();
if (config.power & STOP_MCLK)
mclk(0);
@ -530,6 +537,15 @@ int main()
if (config.send & SEND_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) {
send_str("T 0x");
cli();
@ -542,12 +558,15 @@ int main()
uint8_t send_test = 0;
const union bate *b = &bate;
if (test_calib) {
if (test_calib > N_TESTDATA)
test_calib = N_TESTDATA;
b = testdata + -- test_calib;
send_test = 1;
send_config = 1;
}
if (config.send & SEND_BATEW || send_config)
send_hex('W', b->b, 8, 3);
if (config.send & SEND_BATED || send_test)
if (config.send & SEND_BATED || send_config)
send_hex('D', b->b+8, 4, 3);
if (config.send & SEND_CALIB || send_test) {
bate_calib(b, &pressure);
@ -558,15 +577,6 @@ int main()
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) {
DEBUG_PRINT(0x77, trigger);
}

View file

@ -24,14 +24,14 @@ struct config {
uint16_t baud_div;
uint8_t uart_mode;
uint8_t pit_period;
uint8_t immediate;
uint8_t pad;
};
enum magic_flags {
USE_USERROW = 0xBA,
USE_VERSION = 0x05,
USE_VERSION = 0x07,
};
enum power_flags {
POWER_DOWN = 0x01,
POWER_DOWN_CLI = 0x02,
@ -39,6 +39,7 @@ enum power_flags {
POWER_LED = 0x08,
POWER_STDBY = 0x10,
POWER_RX = 0x20,
POWER_RF = 0x40,
};
enum send_flags {
SEND_CONFIG = 0x01,
@ -57,6 +58,7 @@ enum trigger_flags {
TRIGGER_UART = 0x04,
TRIGGER_CLOCK = 0x08,
TRIGGER_BREAK = 0x10,
TRIGGER_IMMED = 0x20,
};
enum UART_flags { // USART0.CTRLB
UART_Tx = /* 0x40, */ USART_TXEN_bm,
@ -69,6 +71,8 @@ enum UART_flags { // USART0.CTRLB
};
extern struct config config;
extern uint8_t immediate;
extern uint8_t test_calib;
#ifndef NODEBUG
# define DEBUG
@ -88,9 +92,16 @@ struct debug {
uint8_t adc_irqs;
uint8_t rx_char;
};
uint8_t bate_timeout;
uint8_t spi_timeout;
uint16_t mainloops;
union {
uint8_t bate_timeout;
uint8_t rxhex;
};
union {
uint8_t spi_timeout;
uint8_t rxpar;
};
uint8_t mainloops;
uint8_t pit_irqs;
};
extern struct debug debug_data;

174
src/cmd.c
View file

@ -3,6 +3,7 @@
//
#include "bate.h"
#include "rtc.h"
#include <string.h>
#ifdef NOCMD
@ -10,6 +11,10 @@
void parse_command(uint8_t *s, uint8_t n) {}
#else
uint8_t rx_params[8];
#if 0
__attribute__ ((noinline, noclone))
uint8_t parse_hex_nibble(uint8_t c)
{
@ -20,15 +25,11 @@ uint8_t parse_hex_nibble(uint8_t c)
return 0xf0;
}
uint8_t rx_params[8];
void parse_command(uint8_t *s, uint8_t n)
static inline
uint8_t parse_rx_params(uint8_t *s, uint8_t n)
{
if (!n)
return;
uint8_t cmd = *s++;
uint8_t p = 0;
n--;
uint8_t p;
p = 0;
while (n) {
while (n) {
if (*s != ' ')
@ -43,39 +44,170 @@ void parse_command(uint8_t *s, uint8_t n)
break;
n--;
s++;
uint8_t h = 0;
if (n) {
uint8_t h = 0;
h = parse_hex_nibble(*s);
if (h != 0xf0) {
n--;
s++;
d <<= 4;
d |= h;
}
}
rx_params[p++] = (h<<4) | d;
rx_params[p++] = d;
DEBUG_POKE(rxhex, d);
}
if (!n || *s != '\n')
p = 0;
DEBUG_POKE(rxpar, p);
return p;
}
if (n && *s != '\n')
#else
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;
uint8_t *a = (uint8_t *)(((uint16_t)rx_params[0] << 8) | rx_params[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);
uint8_t cmd = *s++;
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 == '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) {
rx_params[2] = *a;
p++;
pp[2] = *a;
}
else if (cmd == 'W' && p==3) {
rx_params[3] = *a;
*a = rx_params[2];
p++;
pp[3] = *a;
*a = pp[2];
}
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
goto fail;
send_char('R');
send_char('!');
send_hex(cmd, rx_params, p, 1);
send_hex(cmd, pp, p+1, 1);
return;
fail:
send_str("R?\n");

View file

@ -4,6 +4,7 @@
// !!! int = int8_t
#include "bate.h"
#include "rtc.h"
#include <avr/io.h>
@ -32,6 +33,11 @@ ISR(RTC_PIT_vect, ISR_NAKED)
__asm__ ("push r24" "\n\t"
"in r24, __SREG__" "\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"
"sts %[flag], r24" "\n\t"
"sts %[tick], r24" "\n\t"

View file

@ -57,7 +57,17 @@ uint8_t uart_tick()
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];
#else
uint8_t uart_tx[256];
#endif
#define uart_tx_m (sizeof(uart_tx) - 1)
volatile uint8_t uart_tx_w;
volatile uint8_t uart_tx_r;
@ -124,7 +134,9 @@ void tx()
"1: \n"
" mov r30, r21 ; \n"
" subi r21, 0xff ; r++ & uart_tx_m \n"
#ifdef UART_TX_SMALL
" andi r30, 0x7f ; \n"
#endif
" ldi r31, 0 \n"
" subi r30, lo8(-(uart_tx)) \n"
" sbci r31, hi8(-(uart_tx)) \n"
@ -238,9 +250,6 @@ ISR(USART0_RXC_vect, ISR_NAKED)
" subi r24, -1 \n"
" sts debug_data + 4, r24 \n"
#endif
" lds r24, %[STATUS] \n"
" sbrs r24, %[RXCIF] \n"
" rjmp 1f \n"
" lds r24, %[RXDATA] \n"
" lds r30, uart_rx_w \n"
" ldi r31, 0 \n"
@ -251,7 +260,8 @@ ISR(USART0_RXC_vect, ISR_NAKED)
" sts debug_data + 5, r24 \n"
#endif
" subi r30, lo8(uart_rx) \n"
" sbrs r30, 4 \n"
" sbrc r30, 4 ; log2(sizeof(uart_rx)) \n"
" subi r30, 1 \n"
" sts uart_rx_w, r30 \n"
" cpi r24, '\n' \n"
" brne 1f \n"
@ -266,15 +276,11 @@ ISR(USART0_RXC_vect, ISR_NAKED)
" out __SREG__, r24 \n"
" pop r24 \n"
" reti \n"
:
: [STATUS] "n" (&USART0.STATUS),
[RXCIF] "n" (USART_RXCIF_bp),
[RXDATA] "n" (&USART0.RXDATAL)
: : [RXDATA] "n" (&USART0.RXDATAL)
);
}
#endif
#if 0
// These are implemented in `uart_tx.S`

View file

@ -1,3 +1,6 @@
//
// uart_tx.S
//
// avoid quite a few push and pops and jumps
.global send_hex_word
@ -9,7 +12,7 @@
.global send_eol
.global command
// `tx()` and `put_char()` do not gobble r18, r20, r23, r23, r26, and r27.
// `tx()` and `put_char()` do not gobble r18, r20, r22, r23, r26, and r27.
put_char:
// non-global, non-C
@ -19,9 +22,13 @@ put_char:
ldi r19, 1
add r19, r30
eor r23, r19
#ifdef UART_TX_SMALL
andi r23, 0x7f // uart_tx_m
breq 1f
andi r30, 0x7f // uart_tx_m
#else
breq 1f
#endif
ldi r31, 0
subi r30, lo8(-(uart_tx))
sbci r31, hi8(-(uart_tx))
@ -116,7 +123,7 @@ command:
breq 9b
ldi r22, 'R'
rcall send_char22
ldi r22, ' '
ldi r22, '>'
rcall send_char22
ldi r26, lo8(uart_rx)
ldi r27, hi8(uart_rx)
@ -125,19 +132,12 @@ command:
ld r22, X+
call send_char22
subi r18, 1
brcc 1b
cpi r22, '\n'
breq 2f
rcall send_eol
clz
2:
brne 1b
ldi r24, lo8(uart_rx)
ldi r25, hi8(uart_rx)
mov r22, r20
push r20
breq 3f
rcall parse_command
3:
pop r24
rx_dismiss:
cli
@ -170,4 +170,5 @@ rx_dismiss:
sts uart_rx_mes, r20
sts uart_rx_w, r19
sei
9:
ret