mirror of
https://codeberg.org/SiB64/turbo_weather.git
synced 2026-05-01 15:14:22 +02:00
Compare commits
8 commits
da3a5dd824
...
e62e03f550
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e62e03f550 | ||
|
|
59fe3a7949 | ||
|
|
a341b2c454 | ||
|
|
affd866a7c | ||
|
|
2287dbc7b9 | ||
|
|
9af59b100f | ||
|
|
423016de10 | ||
|
|
fc180c1881 |
8 changed files with 234 additions and 102 deletions
|
|
@ -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
|
||||
C_FILES_bate = uart.c rtc.c calib.c mul.c adc.c spi.c
|
||||
|
||||
BATE_PERIOD=76
|
||||
bate_CFLAGS = -DPERIOD=$(BATE_PERIOD)
|
||||
|
|
@ -133,10 +133,13 @@ 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_MCLK) $(BC_MDEL) $(BC_PIT) $(BC_BAUD) \
|
||||
$(BC_TEST) $(BC_PERIOD) $(BC_SPI)
|
||||
|
||||
bate.config:
|
||||
$(AD) -U userrow:v:"$(BATE_CONFIG)":m \
|
||||
|| $(AD) -U userrow:w:"$(BATE_CONFIG)":m
|
||||
|
|
|
|||
177
src/bate.c
177
src/bate.c
|
|
@ -17,6 +17,7 @@
|
|||
#include "calib.h"
|
||||
#include "mul.h"
|
||||
#include "adc.h"
|
||||
#include "spi.h"
|
||||
|
||||
#define Bit(x) (1<<(x))
|
||||
|
||||
|
|
@ -100,21 +101,18 @@ 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;
|
||||
}
|
||||
|
||||
static inline
|
||||
void mclk(uint8_t on)
|
||||
ISR(PORTA_PORT_vect, ISR_NAKED)
|
||||
{
|
||||
if (on)
|
||||
MCLK.CTRLA |= TCA_SINGLE_ENABLE_bm;
|
||||
else
|
||||
MCLK.CTRLA &=~ TCA_SINGLE_ENABLE_bm;
|
||||
}
|
||||
|
||||
static inline
|
||||
uint8_t mclk_status()
|
||||
{
|
||||
return MCLK.CTRLA & TCA_SINGLE_ENABLE_bm;
|
||||
__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;
|
||||
|
|
@ -132,9 +130,45 @@ ISR(TCA0_CMP0_vect, ISR_NAKED)
|
|||
);
|
||||
}
|
||||
|
||||
__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
|
||||
void mclk(uint8_t on)
|
||||
{
|
||||
if (on)
|
||||
MCLK.CTRLA |= TCA_SINGLE_ENABLE_bm;
|
||||
else
|
||||
MCLK.CTRLA &=~ TCA_SINGLE_ENABLE_bm;
|
||||
}
|
||||
|
||||
static inline
|
||||
uint8_t mclk_status()
|
||||
{
|
||||
return MCLK.CTRLA & TCA_SINGLE_ENABLE_bm;
|
||||
}
|
||||
|
||||
union bate bate;
|
||||
struct pressure pressure;
|
||||
|
||||
#ifdef BIT_BANG_BATE
|
||||
|
||||
// Spec:
|
||||
// _____ _____ _____
|
||||
|
|
@ -224,8 +258,6 @@ 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)
|
||||
|
|
@ -263,101 +295,67 @@ 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, 5);
|
||||
bate_frame(0x3aa0, 14);
|
||||
bate_frame(0, 8);
|
||||
bate_frame(0x3aa0, 16);
|
||||
bate.W1 = bate_frame(0, 16);
|
||||
bate_frame(0x3ac0, 14);
|
||||
bate_frame(0x3ac0, 16);
|
||||
bate.W2 = bate_frame(0, 16);
|
||||
bate_frame(0x3b20, 14);
|
||||
bate_frame(0x3b20, 16);
|
||||
bate.W3 = bate_frame(0, 16);
|
||||
bate_frame(0x3b40, 14);
|
||||
bate_frame(0x3b40, 16);
|
||||
bate.W4 = bate_frame(0, 16);
|
||||
bate_frame(0x0f40, 12);
|
||||
bate.H1 = 0x0002;
|
||||
bate_frame(0x0f40, 16);
|
||||
sei();
|
||||
bate_wait();
|
||||
cli();
|
||||
bate_frame(0,1);
|
||||
bate.D1 = bate_frame(0, 16);
|
||||
bate_frame(0x0f20, 12);
|
||||
bate.H1 = 0x0003;
|
||||
bate_frame(0x0f20, 16);
|
||||
sei();
|
||||
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 {
|
||||
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 = {
|
||||
struct config config = {
|
||||
.power = STOP_MCLK,
|
||||
.send = SEND_BOOT_MESSAGE | SEND_CLOCK | SEND_HEX | SEND_ADC,
|
||||
.cpu_clk = CLKCTRL_PDIV_2X_gc | 1,
|
||||
|
|
@ -365,7 +363,9 @@ static 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,14 +409,13 @@ int main()
|
|||
sleep_enable();
|
||||
sei();
|
||||
|
||||
send_str("Hallo\n");
|
||||
|
||||
send_str("\nV Turbo Weather V0.03\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;
|
||||
|
|
|
|||
59
src/bate.h
59
src/bate.h
|
|
@ -4,6 +4,55 @@
|
|||
|
||||
#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
|
||||
|
|
@ -15,10 +64,12 @@
|
|||
struct debug {
|
||||
uint8_t value;
|
||||
uint8_t magic;
|
||||
uint16_t adc_irqs;
|
||||
uint16_t tx_irqs;
|
||||
uint16_t rx_irqs;
|
||||
uint16_t tx_sleep;
|
||||
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 mainloops;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -75,7 +75,7 @@ void bate_calib(const union bate *bate, struct pressure *pt)
|
|||
}
|
||||
|
||||
static const union bate testdata[] = {
|
||||
{ .w = { 0x7EBA, 0xA41A, 0xA691, 0x0A93, 0x989F, 0x28AF, 0x4896, 0x71F4 }, },
|
||||
{ .w = { 0xA691, 0x0A97, 0x989F, 0xAF28, 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
|
||||
|
|
|
|||
|
|
@ -3,16 +3,13 @@
|
|||
// !!! int = int8_t
|
||||
|
||||
union bate {
|
||||
uint8_t b[16];
|
||||
uint16_t w[8];
|
||||
uint8_t b[12];
|
||||
uint16_t w[6];
|
||||
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;
|
||||
|
|
|
|||
68
src/spi.c
Normal file
68
src/spi.c
Normal file
|
|
@ -0,0 +1,68 @@
|
|||
//
|
||||
// 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)
|
||||
);
|
||||
}
|
||||
|
||||
13
src/spi.h
Normal file
13
src/spi.h
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
//
|
||||
// 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; }
|
||||
|
|
@ -22,9 +22,10 @@ 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;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue