Compare commits

..

No commits in common. "e62e03f5506e8adbf988c82f9f861c5f9fbc0980" and "da3a5dd8243383fa6d9ef249390686dcb106d3bf" have entirely different histories.

8 changed files with 102 additions and 234 deletions

View file

@ -8,7 +8,7 @@ all: $(PROJ).hex
SN_bate = 1
MCU_bate = attiny424
C_FILES_bate = uart.c rtc.c calib.c mul.c adc.c spi.c
C_FILES_bate = uart.c rtc.c calib.c mul.c adc.c
BATE_PERIOD=76
bate_CFLAGS = -DPERIOD=$(BATE_PERIOD)
@ -133,13 +133,10 @@ BC_PIT = 0xff
BC_BAUD = 0 0
BC_TEST = 0
BC_PERIOD= 9
BC_SPI = 0xff
BATE_CONFIG = $(BC_MAGIC) $(BC_VERS) $(BC_CLK) \
$(BC_PWR) $(BC_SEND) $(BC_TRIG) \
$(BC_MCLK) $(BC_MDEL) $(BC_PIT) $(BC_BAUD) \
$(BC_TEST) $(BC_PERIOD) $(BC_SPI)
$(BC_MCLK) $(BC_MDEL) $(BC_PIT) $(BC_BAUD) $(BC_TEST) $(BC_PERIOD)
bate.config:
$(AD) -U userrow:v:"$(BATE_CONFIG)":m \
|| $(AD) -U userrow:w:"$(BATE_CONFIG)":m

View file

@ -17,7 +17,6 @@
#include "calib.h"
#include "mul.h"
#include "adc.h"
#include "spi.h"
#define Bit(x) (1<<(x))
@ -101,53 +100,6 @@ void init_mclk(uint8_t p)
MCLK.CTRLB = TCA_SINGLE_CMP0EN_bm | TCA_SINGLE_WGMODE_FRQ_gc;
BATE_PORT.DIR |= Bit(DIN_PORT);
BATE_PORT.DIR |= Bit(SCK_PORT);
PORTA.PIN2CTRL = PORT_PULLUPEN_bm;
}
ISR(PORTA_PORT_vect, ISR_NAKED)
{
__asm__ ("push r24" "\n\t"
"lds r24,%[stat]" "\n\t"
"sts %[stat], r24" "\n\t"
"pop r24" "\n\t"
"reti" "\n"
: : [stat] "n" (&VPORTA.INTFLAGS)
);
}
volatile uint8_t tick;
ISR(TCA0_CMP0_vect, ISR_NAKED)
{
__asm__ ("push r24" "\n\t"
"ldi r24, 0x10" "\n\t"
"sts %[flag], r24" "\n\t"
"sts tick, r24" "\n\t"
"pop r24" "\n\t"
"reti" "\n"
:
: [flag] "n" (&MCLK.INTFLAGS)
);
}
__attribute__ ((noinline, noclone))
static
void bate_wait()
{
uint16_t timeout = 3277; // 50ms
tick = 0;
while (BATE_PORT.IN & Bit(DOUT_PORT)) {
PORTA.PIN2CTRL = PORT_PULLUPEN_bm | PORT_ISC_FALLING_gc;
sleep_cpu();
if (tick) {
tick = 0;
if (!--timeout) {
DEBUG_COUNTER(bate_timeout);
break;
}
}
}
PORTA.PIN2CTRL = PORT_PULLUPEN_bm | PORT_ISC_INTDISABLE_gc;
}
static inline
@ -165,10 +117,24 @@ uint8_t mclk_status()
return MCLK.CTRLA & TCA_SINGLE_ENABLE_bm;
}
volatile uint8_t tick;
ISR(TCA0_CMP0_vect, ISR_NAKED)
{
__asm__ ("push r24" "\n\t"
"ldi r24, 0x10" "\n\t"
"sts %[flag], r24" "\n\t"
"sts tick, r24" "\n\t"
"pop r24" "\n\t"
"reti" "\n"
:
: [flag] "n" (&MCLK.INTFLAGS)
);
}
union bate bate;
struct pressure pressure;
#ifdef BIT_BANG_BATE
// Spec:
// _____ _____ _____
@ -258,6 +224,8 @@ uint8_t bate_bit(uint8_t r, uint8_t c, uint8_t ii)
return r;
}
__attribute__ ((noinline, noclone))
static
uint16_t bate_frame(uint16_t d, uint8_t n)
@ -295,67 +263,101 @@ uint16_t bate_frame(uint16_t d, uint8_t n)
return (uint16_t)r1<<8 | r0;
}
__attribute__ ((noinline, noclone))
static
void bate_wait()
{
uint16_t timeout = 3277; // 50ms
sei();
while (BATE_PORT.IN & Bit(DOUT_PORT)) {
if (tick) {
tick = 0;
if (!timeout)
break;
timeout--;
}
}
cli();
}
static inline
void read_bate()
{
cli();
bate.H1 = 0x0001;
bate_frame(0xaaaa, 16);
bate_frame(0, 8);
bate_frame(0x3aa0, 16);
bate_frame(0, 5);
bate_frame(0x3aa0, 14);
bate.W1 = bate_frame(0, 16);
bate_frame(0x3ac0, 16);
bate_frame(0x3ac0, 14);
bate.W2 = bate_frame(0, 16);
bate_frame(0x3b20, 16);
bate_frame(0x3b20, 14);
bate.W3 = bate_frame(0, 16);
bate_frame(0x3b40, 16);
bate_frame(0x3b40, 14);
bate.W4 = bate_frame(0, 16);
bate_frame(0x0f40, 16);
sei();
bate_frame(0x0f40, 12);
bate.H1 = 0x0002;
bate_wait();
cli();
bate_frame(0,1);
bate.D1 = bate_frame(0, 16);
bate_frame(0x0f20, 16);
sei();
bate_frame(0x0f20, 12);
bate.H1 = 0x0003;
bate_wait();
cli();
bate_frame(0,1);
bate.D2 = bate_frame(0, 16);
bate.H1 = 0xba7e;
bate.H2 += 1;
sei();
}
#else // !BIT_BANG_BATE
static inline
void read_bate()
{
init_spi(config.spi_div);
spi_frame(0b0000000010101010);
spi_frame(0b1010101000000000);
spi_frame(0b0001110101010000);
bate.W1 = spi_frame(0);
spi_frame(0b0001110101100000);
bate.W2 = spi_frame(0);
spi_frame(0b0001110110010000);
bate.W3 = spi_frame(0);
spi_frame(0b0001110110100000);
bate.W4 = spi_frame(0);
spi_frame(0b0000111101000000);
bate_wait();
bate.D1 = spi_frame(0);
spi_frame(0b0000111100100000);
bate_wait();
bate.D2 = spi_frame(0);
spi_off();
}
#endif // !BIT_BANG_BATE
////////////////////////////////////////////////////////////////////////////////
//
// Configuration in USERROW
struct config config = {
struct config {
uint8_t magic;
uint8_t version;
uint8_t cpu_clk;
uint8_t power;
uint8_t send;
uint8_t triggers;
uint8_t mclk_period;
uint8_t mclk_delay;
uint8_t pit_period;
uint16_t baud_div;
uint8_t calib_test;
uint8_t period;
};
enum magic_flags {
USE_USERROW = 0xBA,
USE_VERSION = 0x03,
};
enum power_flags {
POWER_DOWN = 0x01,
POWER_DOWN_CLI = 0x02,
STOP_MCLK = 0x04,
};
enum send_flags {
SEND_BOOT_MESSAGE = 0x01,
SEND_CLOCK = 0x02,
SEND_HEX = 0x04,
SEND_CALIB = 0x08,
SEND_ADC = 0x10,
SEND_DEBUG = 0x80,
};
enum trigger_flags {
TRIGGER_ONCE = 0x01,
TRIGGER_CONT = 0x02,
TRIGGER_UART = 0x04,
TRIGGER_CLOCK = 0x08,
TRIGGER_BREAK = 0x10,
};
static struct config config = {
.power = STOP_MCLK,
.send = SEND_BOOT_MESSAGE | SEND_CLOCK | SEND_HEX | SEND_ADC,
.cpu_clk = CLKCTRL_PDIV_2X_gc | 1,
@ -363,9 +365,7 @@ struct config config = {
.mclk_delay = 2,
.pit_period = RTC_CLKSEL_INT1K_gc,
.period = 9,
.spi_div = SPI_PRESC_DIV64_gc,
};
static const struct config *userrow = (struct config *) & USERROW;
#ifdef DEBUG
@ -409,13 +409,14 @@ int main()
sleep_enable();
sei();
send_str("\nV Turbo Weather V0.03\n");
send_str("Hallo\n");
if (config.send & SEND_BOOT_MESSAGE) {
send_str("V Turbo Weather V0.01\n");
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), 1);
}
uint8_t test_calib = config.calib_test;

View file

@ -4,55 +4,6 @@
#include "uart.h"
////////////////////////////////////////////////////////////////////////////////
//
// Configuration
struct config {
uint8_t magic;
uint8_t version;
uint8_t cpu_clk;
uint8_t power;
uint8_t send;
uint8_t triggers;
uint8_t mclk_period;
uint8_t mclk_delay;
uint8_t pit_period;
uint16_t baud_div;
uint8_t calib_test;
uint8_t period;
uint8_t spi_div;
};
enum magic_flags {
USE_USERROW = 0xBA,
USE_VERSION = 0x03,
};
enum power_flags {
POWER_DOWN = 0x01,
POWER_DOWN_CLI = 0x02,
STOP_MCLK = 0x04,
};
enum send_flags {
SEND_BOOT_MESSAGE = 0x01,
SEND_CLOCK = 0x02,
SEND_HEX = 0x04,
SEND_CALIB = 0x08,
SEND_ADC = 0x10,
SEND_DEBUG = 0x80,
};
enum trigger_flags {
TRIGGER_ONCE = 0x01,
TRIGGER_CONT = 0x02,
TRIGGER_UART = 0x04,
TRIGGER_CLOCK = 0x08,
TRIGGER_BREAK = 0x10,
};
extern struct config config;
#ifndef NODEBUG
# define DEBUG
#endif
@ -64,12 +15,10 @@ extern struct config config;
struct debug {
uint8_t value;
uint8_t magic;
uint8_t tx_sleep;
uint8_t tx_irqs;
uint8_t rx_irqs;
uint8_t adc_irqs;
uint8_t bate_timeout;
uint8_t spi_timeout;
uint16_t adc_irqs;
uint16_t tx_irqs;
uint16_t rx_irqs;
uint16_t tx_sleep;
uint16_t mainloops;
};

View file

@ -75,7 +75,7 @@ void bate_calib(const union bate *bate, struct pressure *pt)
}
static const union bate testdata[] = {
{ .w = { 0xA691, 0x0A97, 0x989F, 0xAF28, 0x4896, 0x71F4 }, },
{ .w = { 0x7EBA, 0xA41A, 0xA691, 0x0A93, 0x989F, 0x28AF, 0x4896, 0x71F4 }, },
{ .W = { 0xabaf, 0x3c99, 0xa31a, 0xb589}, .D = { 0x470c, 0x773f }, }, // 21.2 °C, 1021.7 mbar
{ .W = { 0xabaf, 0x3c99, 0xa31a, 0xb589}, .D = { 0x1a51, 0x6fed }, }, // 7.5 °C, 5.4 mbar
{ .W = { 0xaa3d, 0x35d9, 0xcbe5, 0xb736}, .D = { 0x4bb7, 0x7487 }, }, // 17.7 °C, 1023.0 mbar

View file

@ -3,13 +3,16 @@
// !!! int = int8_t
union bate {
uint8_t b[12];
uint16_t w[6];
uint8_t b[16];
uint16_t w[8];
struct {
uint16_t H[2];
uint16_t W[4];
uint16_t D[2];
};
struct {
uint16_t H1;
uint16_t H2;
uint16_t W1;
uint16_t W2;
uint16_t W3;

View file

@ -1,68 +0,0 @@
//
// spi.c
//
// !!! int = int8_t
#include "spi.h"
#include "bate.h"
#include <avr/interrupt.h>
#include <avr/sleep.h>
volatile uint8_t spi_tick;
// The Pressure sensor samples on the rising edge, MODE = 0
static const uint8_t SPI_Mode_Write = SPI_SSD_bm | SPI_BUFEN_bm;
// The Pressure sensor delivers on the rising edge, MODE = 1
static const uint8_t SPI_Mode_Read = SPI_SSD_bm | SPI_BUFEN_bm | SPI_MODE_0_bm;
void init_spi(uint8_t div)
{
if (div & ~SPI_PRESC_gm)
div = SPI_PRESC_DIV64_gc;
SPI.CTRLB = SPI_Mode_Write;
SPI.CTRLA = SPI_MASTER_bm | SPI_ENABLE_bm | div;
SPI.DATA;
SPI.DATA;
SPI.INTFLAGS = 0xff;
SPI.INTCTRL = SPI_TXCIE_bm;
}
uint16_t spi_frame(uint16_t d)
{
if (d)
SPI.CTRLB = SPI_Mode_Write;
else
SPI.CTRLB = SPI_Mode_Read;
SPI.DATA;
SPI.DATA;
SPI.INTFLAGS = 0xff;
spi_tick = 0;
SPI.DATA = d >> 8;
SPI.DATA = d;
uint8_t timeout = 20; // 20×15µs = 300µs
sei();
while (!spi_tick) {
sleep_cpu();
if (!--timeout) {
DEBUG_COUNTER(spi_timeout);
break;
}
}
uint16_t b = SPI.DATA;
return (b<<8) | SPI.DATA;
}
ISR(SPI0_INT_vect, ISR_NAKED)
{
__asm__ ("push r24" "\n\t"
"lds r24, %[flag]" "\n\t"
"sts %[flag], r24" "\n\t"
"sts spi_tick, r24" "\n\t"
"pop r24" "\n\t"
"reti" "\n"
: : [flag] "n" (&SPI.INTFLAGS)
);
}

View file

@ -1,13 +0,0 @@
//
// spi.h
//
#include <stdint.h>
#include <avr/io.h>
#define SPI SPI0
extern volatile uint8_t spi_tick;
uint16_t spi_frame(uint16_t d);
void init_spi(uint8_t div);
static inline void spi_off() { SPI.INTCTRL = SPI.CTRLA = 0; }

View file

@ -22,10 +22,9 @@ void init_uart(uint16_t div)
div = UART_DIV;
USART0.BAUD = div;
PORTB.DIRSET = Bit(2);
PORTB.PIN3CTRL = PORT_PULLUPEN_bm | PORT_ISC_LEVEL_gc;
USART0.CTRLB = USART_RXEN_bm | USART_TXEN_bm;
USART0.CTRLA = USART_RXCIE_bm;
// `BOTHEDGES` should wake from power down sleep()
PORTB.PIN3CTRL = PORT_PULLUPEN_bm | PORT_ISC_BOTHEDGES_gc;
}
uint8_t rx_tick;