Compare commits

..

2 commits

Author SHA1 Message Date
Stephan I. Böttcher
4920c5b8e1 src/README, THHOR version 2026-04-08 23:21:26 +02:00
Stephan I. Böttcher
9723c5b3d6 TxE_PIN fix 2026-04-08 23:17:49 +02:00
2 changed files with 109 additions and 174 deletions

View file

@ -1,194 +1,129 @@
# Turbo Weather # THHOR Cosmic Ray Sensor
## ATtiny424SS resources ## ATtiny3224 resources
- `TCA0-WO0-PB0`: generate the 32768kHz clock for the MS5534C - `TCA0`: ADC trigger clock
- `SPI0-PA1…3`: communication with the MS5534C - `SPI0-PA1…3, 7`: communication with flash and FPGA
- `USART0-RxD/TxD-PB2…3`: transmission of data, receive commands - `USART0-RxD/TxD-PB0,2…3`: transmission of data, receive commands
- `PORTB-PB1`: enable the RF power regulator - `PORTB-PB1`: enable the RF power regulator
- `PORTA-PA5`: light up the LED - `ADC`: internal sources.
- `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. - `PIT`: generate clock tick, to wake the µC once per second from deep sleep.
- `RTC`: clock
- `USERROW`: store persistent configuration - `USERROW`: store persistent configuration
- `EEPROM`: store `ADC` readings configuration, store sensor test data records. - `EEPROM`: io configuration, `ADC` readings configuration
- `RAM`: 256 byte TX buffer, 16 bytes RX buffer, ~128 bytes stack. - `RAM`: 64 byte TX buffer, 16 bytes RX buffer, ~128 bytes stack.
- `FLASH`: pretty full. With lots of assembly, -O2 fits with -DDEBUG.
## Source files ## Source files
- `bate.c`: main program, interface to the MS5534C - `thhor.c`: main program, interface to the MS5534C.
- `calib.c`: calculate the calibrated the pressure sensor readings. - `config.c`: io configuration, userrow config.
- `adc.c`: configure and run the ADC, calculate calibrated results - `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`. - `rtc.c`: configure the _periodic interrupt timer_ `PIT`.
- `spi.c`: configure the `SPI0` and run a 16-bit frame. - `spi.c`: configure the `SPI0` and run a 16-bit frame.
- `uart.c`: configure the USART0, provide Tx and Rx buffers for IO. - `uart.c`: configure the USART0, provide Tx and Rx buffers for IO.
- `uart_tx.S`: assembly implemention for uart.
- `base85.c`: Base85 encode/decode 16-bytes `cmd_buffer` on UART.
- `base85a.S` assembly implemention for bch4369.
- `cmd.c`: parse and run simple commands received from the UART. - `cmd.c`: parse and run simple commands received from the UART.
- `flash.c`: talk to the external flash via SPI
- `bch4369.c`: EDAC on flash pages
- `flga.c`: talk to the FPGA via SPI
- `pipe.c`: move data streams
## Output records ## UART protocol
The programm issues several types of output lines. Each type is The host sends commands consisting of
prefixed with a unique capital letter. - a capital letter,
- flags
- optionally one space and 16 base85 encoded `data` bytes
- a newline
- `V`: sent at boot, a greeting and version. When the first flags is a digit `0``4`, it selects a section of the
- `B`: sent at boot, a single byte `RSTCTRL.RSTFR`, the reset reason. block buffer. When no section is selected, the command operates on
- `S`: config record (`SEND_CONFIG`): hex dump of the `SIGROW`. the `data` buffer directly, where applicable.
- `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 When the last flag is a haf-mesh `=` and there is no `data`, and the
`SEND_CONFIG` with a subset of sensor readings. The config byte `confp` previous command was the same letter, then the `data` of the previous
is the number of readings sent in between without sending config records. command is used again, possibly modified by the previous command
execution.
Debug data is only available when not disabled during compilation. Do The µC answers with
`make DEBUG=-DNODEBUG` to disable all debugging code and data. - a mesh `#`,
- the command letter and used flags,
- optionally one space and 16 base85 encoded `data` bytes,
- a newline.
The `SEND` flags are stored in byte[3] of the `config` structure to In case of any error the answer is terminated with a what `?` and a newline,
enable the respective output records, with the bit positions without encoded data bytes.
- `SEND_CONFIG = 0x01` ### Commands
- `SEND_BATED = 0x02`
- `SEND_BATEW = 0x04`
- `SEND_CLOCK = 0x08`
- `SEND_CALIB = 0x10`
- `SEND_ADC_HEX = 0x20`
- `SEND_ADC_VOLT = 0x40`
- `SEND_DEBUG = 0x80`
## Configuration - `A`: ADC
All variants return number of completed channels.
There are two configued channels, T and Vcc.
* `A`: return status
* `A!`: start conversions
* `A<`: return ADC readings
At boot, the configuration is copied from the `USERROW` to the - `B`: Block buffer ops, return valid sections.
`config` structure in `RAM`, if the first byte in the `USERROW` is The block buffer is 80 bytes, in five sections.
the magic `0xba`, and the second byte matches the version of the One flash page is 8 blocks of 64 bytes, plus one section 4 for EDAC in the last block.
`config` structure, currently `0x08`. Else, the defaults are used. When no section is selected, the `data` is used in the cmd buffer.
* `B0``B4`: select section.
* `B@`: mark all sections invalid.
* `B0 data`: fill the invalid selected section with the data and mark is valid..
* `B0! data`: fill the selected section with the data even is it is valid.
* `B…%@`: reset the BCH4369 parity.
* `B…%`: add the selected section/data to the parity.
* `B…%!`: Complete the parity and copy to section 4 in the block buffer.
* `B…<`: Return valid data from the selected section and mark it invalid.
* `B…<!`: Return data from the selected section, evcen when invalid, and do not mark is invalid.
The config structure is The operations _write_, _parity_, and _read_ can be combined in
- `[0]`: `magic = 0xba`. that order, as indicated by `…`.
- `[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 - 'C': FPGA command
* `C@`: reset the FPGA to unconfigured state.
* `C data`: send a command to the FPGA, up to 14 bytes that came back.
The command format is defined by `struct fpga_cmd`
The `triggers` byte\[2\] enables various reasons to do a sensor reading. - `D`: Find the first free page in the flash telemetry area.
- `TRIGGER_ONCE = 0x01`: one reading at boot. - `F`: Command to the flash chip via SPI.
- `TRIGGER_CONT = 0x02`: continuously read the sensor. * `F': return SPI status.
- `TRIGGER_UART = 0x04`: read the sensor when the UART Rx input toggles. * `F data`: submit command
- `TRIGGER_CLOCK = 0x08`: read periodically, every `period`+1 _seconds_. * `F!`: Poll SPI.
- `TRIGGER_BREAK = 0x10`: read continuously while the UART Rx input is low. * `F<`: Return the answer.
- `TRIGGER_IMMED = 0x20`: do any requested immediate readings.
_Seconds_ are define by the `PIT`. Those can be up to 8 real seconds - `M` peek/poke.
long, or much shorter. _Immediate_ readings can be requested at boot * `M data`: execute a peek of poke.
or via the command `T`. * `M=`: continue the just emitted peak/poke.
### Power `data` is a `struct peek_poke`. Up to 12 bytes can be transfered by each call.
Writing to EEPROM requires a key for the CCP.
The bits in the power byte\[4\] are - `O`: Power/configure the FPGA, return FPGA status.
* `O0`: Turn power off.
* `O1`: Turn power on.
* `O2`: Configure from flash, if powered and unconfigured.
* `O3`: Power off if unconfigured.
* `O4`: Configure from flash, unconditionally.
- `POWER_DOWN = 0x01`: Enter `POWER_DOWN` sleep between readings. - `P`: Pipe stream ops.
- `POWER_DOWN_CLI = 0x02`: Disable interrupts before `POWER_DOWN`. * `P@`: Stop current stream (clear all destinations).
- `STOP_MCLK = 0x04`: Stop the `MCLK` after the reading. * `P data`: confiure ans start a stream.
- `POWER_LED = 0x08`: Turn on the LED during a reading. * `P.`: Poll the flash stream.
- `POWER_STDBY = 0x10`: Enter `STANDBY` sleep between readings. * `P,`: Poll the flashj stream with ACK.
- `POWER_RX = 0x20`: Do not `POWER_DOWN` when the `UART` Rx is active * `P!`: Poll the pipe.
- `POWER_RF = 0x40`: Turn on the RF transmitter power.
- `POWER_LINE = 0x80`: Send a preamble after rfen()
`POWER_STDBY` is sufficient to reduce the power to a minimum. The poll options are usefull for debugging, when mainloop polling is on hold.
`POWER_RX` does not seem to work. From `POWER_DOWN_CLI` we shall Do `poke("magic+2", 0x01, s=1)` to set the pipe polling on hold.
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. The `POWER_LINE`
preamble charges the AC-coupled output of the RF receiver to
properly receive subsequent characters.
## 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`.
These commands return the old value of the first byte that was
written.
- `T «n»`: trigger «n» more immediate sensor readings.
- `M «aaaa»`: reads any memory address «aaaa» (two bytes, big endian)
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 data records.
## Toolchain ## Toolchain
The ATtiny424 µC requires an up-to-date toolchain The ATtiny3224 µC requires an up-to-date toolchain
- binutits: `./configure --target=avr --program-prefix=avr-` - binutits: `./configure --target=avr --program-prefix=avr-`
- gcc: `../gcc/configure --program-prefix=avr- --with-avrlibc --target=avr --enable-languages=c --disable-nls` - gcc: `../gcc/configure --program-prefix=avr- --with-avrlibc --target=avr --enable-languages=c --disable-nls`
- avr-libc: `./configure --host=avr` - avr-libc: `./configure --host=avr`
## TODO (all done)
- √ Use the SPI hardware to talk to the sensor.
- √ Send results via UART hardware.
- × Setup the watchdog. √ Use PIT instead
- √ Control power to the RF transmitter
- √ Light the LED.
- √ Readout the ADCs, thermistors.
- √ Readout the internal temperature sensor.

View file

@ -70,7 +70,7 @@ extern struct io_config ee9_start[], ee9_end[];
#define UART_VPORT VPORTB #define UART_VPORT VPORTB
#define UART_PORT PORTB #define UART_PORT PORTB
#define TxE_PIN 1 #define TxE_PIN 0
#define TxD_PIN 2 #define TxD_PIN 2
#define RxD_PIN 3 #define RxD_PIN 3
#define RxD_PINCTRL UART_PORT.PIN3CTRL #define RxD_PINCTRL UART_PORT.PIN3CTRL