mirror of
https://codeberg.org/SiB64/turbo_weather.git
synced 2026-05-01 15:14:22 +02:00
Compare commits
2 commits
b73d564c61
...
df8cdf897c
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
df8cdf897c | ||
|
|
c7510b3d8c |
1 changed files with 178 additions and 3 deletions
181
src/README.md
181
src/README.md
|
|
@ -1,11 +1,186 @@
|
|||
## Turbo Weather
|
||||
# Turbo Weather
|
||||
|
||||
The ATtiny424 µC requires an up to date toolchain
|
||||
## ATtiny424SS resources
|
||||
|
||||
- `TCA0-WO0-PB0`: generate the 32768kHz clock for the MS5534C
|
||||
- `SPI0-PA1…3`: communication with the MS5534C
|
||||
- `USART0-RxD/TxD-PB2…3`: transmission of data, receive commands
|
||||
- `PORTB-PB1`: enable the RF power regulator
|
||||
- `PORTA-PA5`: light up the LED
|
||||
- `ADC0-PA4,6…7: read Batterie, NTC, and RF power voltage, and internal sources.
|
||||
- `PIT`: generate clock tick, to wake the µC once per second from deep sleep.
|
||||
- `USERROW`: store persistent configuration
|
||||
- `EEPROM`: store `ADC` readings configuration, store sensor test data records.
|
||||
- `RAM`: 256 byte TX buffer, 16 bytes RX buffer, ~128 bytes stack.
|
||||
- `FLASH`: pretty full. With lots of assembly, -O2 fits with -DDEBUG.
|
||||
|
||||
## Source files
|
||||
|
||||
- `bate.c`: main program, interface to the MS5534C
|
||||
- `calib.c`: calculate the calibrated the pressure sensor readings.
|
||||
- `adc.c`: configure and run the ADC, calculate calibrated results
|
||||
- `mul.c`: handcraft 16-bit multiplication and decimal printing.
|
||||
- `rtc.c`: configure the _periodic interrupt timer_ `PIT`.
|
||||
- `spi.c`: configure the `SPI0` and run a 16-bit frame.
|
||||
- `uart.c`: configure the USART0, provide Tx and Rx buffers for IO.
|
||||
- `cmd.c`: parse and run simple commands received from the UART.
|
||||
|
||||
## Output records
|
||||
|
||||
The programm issues several types of output lines. Each type is
|
||||
prefixed with a unique capital letter.
|
||||
|
||||
- `V`: sent at boot, a greeting and version.
|
||||
- `B`: sent at boot, a single byte `RSTCTRL.RSTFR`, the reset reason.
|
||||
- `S`: config record (`SEND_CONFIG`): hex dump of the `SIGROW`.
|
||||
- `F`: config record (`SEND_CONFIG`): hex dump of the `FUSES`.
|
||||
- `U`: config record (`SEND_CONFIG`): hex dump of the `USERROW`.
|
||||
- `C`: config record (`SEND_CONFIG`): hex dump of the `config` structure in `RAM`.
|
||||
- `E`: config record (`SEND_CONFIG`): hex dump of the ADC configuration in `EEPROM`.
|
||||
- `W`: calibration record (`SEND_BATEW`): sensor calibration data (hex) read from the sensor.
|
||||
- `D`: sensor record (`SEND_BATED`): sensor reading data (hex) acquired from the sensor.
|
||||
- `P`: pressure record (`SEND_CALIB`): sensor readings in natural units.
|
||||
- `A`: ADC readings (`SEND_ADC_HEX`): hex words, 16-bit range.
|
||||
- `V`: ADC readings (`SEND_ADC_VOLT`): calibrated, natural units.
|
||||
- `X`: Debug (`SEND_DEBUG`): hex dump of the `debug_data` structure.
|
||||
- `R`: command reception.
|
||||
|
||||
Config records are sent at boot, with test data, and when enabled via
|
||||
`SEND_CONFIG` with a subset of sensor readings. The config byte `confp`
|
||||
is the number of readings sent in between without sending config records.
|
||||
|
||||
Debug data is only available when not disabled during compilation. Do
|
||||
`make DEBUG=-DNODEBUG` to disable all debugging code and data.
|
||||
|
||||
The `SEND` flags are stored in byte[3] of the `config` structure with
|
||||
the bit positions
|
||||
|
||||
- `SEND_CONFIG = 0x01`
|
||||
- `SEND_BATED = 0x02`
|
||||
- `SEND_BATEW = 0x04`
|
||||
- `SEND_CLOCK = 0x08`
|
||||
- `SEND_CALIB = 0x10`
|
||||
- `SEND_ADC_HEX = 0x20`
|
||||
- `SEND_ADC_VOLT = 0x40`
|
||||
- `SEND_DEBUG = 0x80`
|
||||
|
||||
## Configuration
|
||||
|
||||
At boot, the configuration is copied from the `USERROW` to the
|
||||
`config` structure in `RAM`, iff the first byte in the `USERROW` is
|
||||
the magic `0xba`, and the second byte matches the version of the
|
||||
`config` structure, currently `0x08`. Else, the defaults are used.
|
||||
|
||||
The config structure is
|
||||
- `[0]`: `magic = 0xba`.
|
||||
- `[1]`: `version = 0x08`.
|
||||
- `[2]`: `triggers`: trigger enables.
|
||||
- `[3]`: `send`: output data configuration.
|
||||
- `[4]`: `power`: power management.
|
||||
- `[5]`: `calib_test`: number of test records to send after a reset.
|
||||
- `[6]`: `spi_div`: `SPI0.CTRLA.SPI_PRESC` \[÷64\]
|
||||
- `[7]`: `mclk_delay`: number of `MCLK` ticks to wait before a reading.
|
||||
- `[8]`: `period`: number of seconds-1 between readings.
|
||||
- `[9]`: `confp`: number of readings without config records.
|
||||
- `[10]`: `cpu_clk`: `CLKCTRL.MCLKCTRLB` \[÷2\]
|
||||
- `[11]`: `mclk_period`: `TCA0.SINGLE.CMP0` \[÷76\]
|
||||
- `[12]`: `baud_div`: two bytes little endian \[÷16667\]
|
||||
- `[14]`: `uart_mode`: `USART0.CTRLB`
|
||||
- `[15]`: `pit_period`: `RTC.CLKSEL` \[%1024\]
|
||||
- `[16]`: `immediate`: number of immediate readings at boot.
|
||||
|
||||
### Triggers
|
||||
|
||||
The `triggers` byte\[2\] enables various reasons to do a sensor reading.
|
||||
|
||||
- `TRIGGER_ONCE = 0x01`: one reading at boot.
|
||||
- `TRIGGER_CONT = 0x02`: continuously read the sensor.
|
||||
- `TRIGGER_UART = 0x04`: read the sensor when the UART Rx input toggles.
|
||||
- `TRIGGER_CLOCK = 0x08`: read periodically, every `period`+1 _seconds_.
|
||||
- `TRIGGER_BREAK = 0x10`: read continuously while the UART Rx input is low.
|
||||
- `TRIGGER_IMMED = 0x20`: do any requested immediate readings.
|
||||
|
||||
_Seconds_ are define by the `PIT`. Those can be up to 8 real seconds
|
||||
long, or much shorter. _Immediate_ readings can be requested at boot
|
||||
or via the command `T`.
|
||||
|
||||
### Power
|
||||
|
||||
The bits in the power byte\[4\] are
|
||||
|
||||
- `POWER_DOWN = 0x01`: Enter `POWER_DOWN` sleep between readings.
|
||||
- `POWER_DOWN_CLI = 0x02`: Disable interrupts before `POWER_DOWN`.
|
||||
- `STOP_MCLK = 0x04`: Stop the `MCLK` after the reading.
|
||||
- `POWER_LED = 0x08`: Turn on the LED during a reading.
|
||||
- `POWER_STDBY = 0x10`: Enter `STANDBY` sleep between readings.
|
||||
- `POWER_RX = 0x20`: Do not `POWER_DOWN` when the `UART` Rx is active
|
||||
- `POWER_RF = 0x40`: Turn on the RF transmitter power.
|
||||
|
||||
`POWER_STDBY` is sufficient to reduce the power to a minimum.
|
||||
`POWER_RX` does not seem to work. From `POWER_DOWN_CLI` we shall
|
||||
never wake up, unless the `WDT` is enabled in the fuses. When the
|
||||
`MCLK` is stopped after a reading, it will be truned on and
|
||||
`mclk_delay` ticks must pass before communication with the sensor
|
||||
resumes. That delay is probably not necessary. `POWER_RF` is
|
||||
necessary to bias the NTC measured by ADC readings.
|
||||
|
||||
## Commands
|
||||
|
||||
Commandlines received via the UART must be in the format
|
||||
- `«C» {[«space»] «hex»}+ [«space»]+ «linefeed»`
|
||||
|
||||
A command letter, uppercase, and up to seven (optionally space
|
||||
separated) hex bytes, optionally followed by more space characters and
|
||||
a linefeed. A hex character is one or two hex digits, letters `a`…`f`
|
||||
_must_ be lowercase. Obviously, a single hex digit must be separated
|
||||
with space characters from any following byte. No spaces are required
|
||||
at all when all bytes are written with two digits. The Rx buffer can
|
||||
accomodate commandlines up to 15 bytes long, including the newline
|
||||
char.
|
||||
|
||||
The parser echos the received line, preceeded with the string `R>`.
|
||||
When the command is valid, the answer bytes are sent prefixed with
|
||||
`R!`. Invalid commands are answered with `R?`.
|
||||
|
||||
Most commands require a specific number of hex bytes as arguments. As
|
||||
currently implemented, all commands echo all their arguments and one
|
||||
additional byte.
|
||||
|
||||
### List of commands:
|
||||
|
||||
- `R «ccp»`: Reboot the µC. The argument byte must be `d8` the
|
||||
`CCP[IOREG]` key, to validate the reset.
|
||||
|
||||
- `C «key» «bytes»…`: write to the `config` structure in `RAM`
|
||||
- `U «key» «bytes»…`: write to persistent config in the `USERROW`
|
||||
- `E «key» «bytes»…`: write to `EEPROM`
|
||||
|
||||
Up to six «bytes» are written. The «key» must be `9d`, the `CCP[SPM]``
|
||||
key, for the persistent stores, and `ba` for the `RAM`. Prints
|
||||
the old value of the first bytes written to.
|
||||
|
||||
- `T «n»`: trigger «n» more immediate sensor readings.
|
||||
|
||||
- `M «aaaa»`: reads any memory address «aaaa» (two bytes) and prints the
|
||||
byte.
|
||||
|
||||
- `W «aaaa» «bb»`: write a byte «bb» into any address «aaaa», return
|
||||
the old value of that memory location.
|
||||
|
||||
- `K «bb» «bb» «bb» «bb»`: set the clock. The 32-bit time value must
|
||||
be sent little endian.
|
||||
|
||||
- `D «n»`: process and send calibrated readings for «n» test data
|
||||
records. The `EEPROM` has space for up to five records.
|
||||
|
||||
## Toolchain
|
||||
|
||||
The ATtiny424 µC requires an up-to-date toolchain
|
||||
- binutits: `./configure --target=avr --program-prefix=avr-`
|
||||
- gcc: `../gcc/configure --program-prefix=avr- --with-avrlibc --target=avr --enable-languages=c --disable-nls`
|
||||
- avr-libc: `./configure --host=avr`
|
||||
|
||||
TODO: (all done)
|
||||
## TODO (all done)
|
||||
- √ Use the SPI hardware to talk to the sensor.
|
||||
- √ Send results via UART hardware.
|
||||
- × Setup the watchdog. √ Use PIT instead
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue