455 lines
11 KiB
Plaintext
455 lines
11 KiB
Plaintext
|
|
|
|
|
|
MODULE_INFO
|
|
- descr:
|
|
- one MODULE_INFO for every module
|
|
- can share code (e.g. use multiple MODULE_INFOs for different pins in PinOut module)
|
|
- def:
|
|
- name[16]
|
|
- id
|
|
- handlerFunctionAddr()
|
|
- code:
|
|
.equ MODULE_INFO_HANDLER_LO = 0
|
|
.equ MODULE_INFO_HANDLER_HI = 1
|
|
.equ MODULE_INFO_ID = 2
|
|
.equ MODULE_INFO_NAME = 4
|
|
.equ MODULE_INFO_SIZE = 12
|
|
|
|
|
|
SIGNAL_TABLE:
|
|
- descr:
|
|
- one table for every signal a module can emit
|
|
- def:
|
|
- array of SLOT objects (end of array: 0x0000)
|
|
|
|
|
|
SLOT:
|
|
- descr:
|
|
- one SLOT for every module which is waiting for this signal
|
|
- def:
|
|
- MODULE_INFO *modInfoPtr (16 bit)
|
|
- signalIdForCaller (8 bit)
|
|
- signalIdForCallee (8 bit)
|
|
|
|
|
|
|
|
|
|
Initial module:
|
|
- OS
|
|
- sent signals:
|
|
- init
|
|
- fini
|
|
- receivable signals:
|
|
- sleep
|
|
- hardReset
|
|
- softReset
|
|
|
|
|
|
Other modules:
|
|
- Timer
|
|
- sent signals:
|
|
- 1Hz
|
|
- 10Hz
|
|
- 100Hz
|
|
|
|
- PinOut
|
|
- receivable signals:
|
|
- setValue
|
|
- setOnDuration
|
|
- setOffDuration
|
|
- sent signals:
|
|
- none
|
|
|
|
|
|
|
|
|
|
Module_EmitSignal:
|
|
- params:
|
|
- senderId (8 bit) R16
|
|
- signalIdForSender (8 bit, unique in the realm of the sender) R17
|
|
- slotIdForRecipient (8 bit, unique in the realm of the recipient) R18
|
|
- paramLo (8 bit) R26 (YL)
|
|
- paramHi (8 bit) R27 (YH)
|
|
- recipientModule R30 (ZL), R31 (ZH) (16 bit)
|
|
|
|
|
|
Notes:
|
|
- R24 und R25: 16 register (supports ADIW and SBIW)
|
|
- for RAM access: R26-R31 (X, Y, Z)
|
|
- for flash memory access: R0 and Z (R30/31)
|
|
- in INT: use R15 for flags
|
|
- for everything else: R1-R14
|
|
- LDI only for upper 16 regs
|
|
|
|
|
|
Generic signals from OS module:
|
|
- init
|
|
- fini
|
|
- request (REQUEST flag for a module can be set by an interrupt handler to request that the corresponding
|
|
module be called as soon as the event handler loop is reached)
|
|
|
|
|
|
<moduledef name="os" ramSizeNeeded="2"> <!-- 16 bit request mask, maximum 16 modules for now -->
|
|
<signals>
|
|
<signal name="1Hz" />
|
|
</signals>
|
|
|
|
<interrupts>
|
|
<irq id="EXT_INT0" handler="AQOS_Timer_Int0" />
|
|
</interrupts>
|
|
|
|
</moduledef>
|
|
|
|
|
|
|
|
|
|
<moduledef name="timer">
|
|
<signals>
|
|
<signal name="100Hz" />
|
|
<signal name="10Hz" />
|
|
<signal name="1Hz" />
|
|
</signals>
|
|
|
|
<interrupts>
|
|
<irq id="EXT_INT0" handler="AQOS_Timer_Int0" />
|
|
</interrupts>
|
|
|
|
</moduledef>
|
|
|
|
|
|
<moduledef name="togglePort" ramSizeNeeded="2" >
|
|
<depModules>
|
|
<depModule name="timer" />
|
|
</depModules>
|
|
|
|
|
|
<signals>
|
|
<signal name="100Hz" />
|
|
<signal name="10Hz" />
|
|
<signal name="1Hz" />
|
|
</signals>
|
|
|
|
<slots>
|
|
<slot name="timer10Hz" />
|
|
<slot name="setValue" />
|
|
<slot name="setOnDuration" />
|
|
<slot name="setOffDuration" />
|
|
</slots>
|
|
|
|
<connections>
|
|
<connect module="timer" signalId=10Hz" slotId="timer10Hz" />
|
|
</connections>
|
|
|
|
</moduledef>
|
|
|
|
|
|
<moduledef name="inputPinChange" ramSizeNeeded="8"> <!-- current state of ports a..d and change masks -->
|
|
<signals>
|
|
<signal name="aPortChanged" />
|
|
<signal name="bPortChanged" />
|
|
<signal name="cPortChanged" />
|
|
<signal name="dPortChanged" />
|
|
</signals>
|
|
|
|
<interrupts>
|
|
<irq id="PCI0" handler="AQOS_InputPinChange_PCI0" />
|
|
<irq id="PCI1" handler="AQOS_InputPinChange_PCI1" />
|
|
</interrupts>
|
|
|
|
<slots>
|
|
<slot name="request" />
|
|
</slots>
|
|
|
|
|
|
irq handler:
|
|
- for every port:
|
|
- is port change mask 0? -> SET new mask, otherwise OR new mask with old mask
|
|
-> gracefully handling overrun (e.g. a new PIN change before the previous one was handled)
|
|
|
|
req handler:
|
|
- for every port:
|
|
- is port change mask 0? -> emit aPortChanged(currentPortValue, portChangeMask), clear mask
|
|
|
|
</moduledef>
|
|
|
|
|
|
|
|
|
|
File format:
|
|
|
|
IRQ-Table
|
|
|
|
.include "os/rqhandlers.inc"
|
|
.include "timer/irqhandlers.inc"
|
|
.include "toggleport/irqhandlers.inc"
|
|
|
|
|
|
.equ MODULE_ID_OS = 0
|
|
.equ MODULE_ID_TIMER = 1
|
|
.equ MODULE_ID_TOGGLEPORT = 2
|
|
|
|
|
|
.equ TIMER_USE_100Hz = 1
|
|
.equ TIMER_USE_10Hz = 1
|
|
.equ TIMER_USE_10z = 1
|
|
|
|
; in file timer/modinfo.inc
|
|
|
|
; timer module
|
|
modInfoTimer:
|
|
.db "TIMER ", 0 ; name
|
|
.db MODULE_ID_TIMER, 0 ; id, reserved byte (0)
|
|
.dw timerSignalHandler ; handler
|
|
|
|
.equ TIMER_SIG_1HZ = 1
|
|
|
|
.equ TIMER_SLOT_INIT = 0
|
|
.equ TIMER_SLOT_FINI = 1
|
|
|
|
|
|
|
|
; in file toggleport/module.inc
|
|
|
|
; toggleport module
|
|
.equ TOGGLEPORT_SLOT_OS_INIT = 0
|
|
.equ TOGGLEPORT_SLOT_OS_FINI = 1
|
|
.equ TOGGLEPORT_SLOT_TIMER_1HZ = 2
|
|
|
|
|
|
|
|
|
|
; in main source file
|
|
|
|
; signal table for timer
|
|
timerSignalTable:
|
|
.db TIMER_SIG_1HZ, TOGGLEPORT_SLOT_TIMER_1HZ, LOW(modInfoTogglePort), HIGH(modInfoTogglePort)
|
|
.db 0, 0, 0, 0 ; last entry
|
|
|
|
|
|
|
|
|
|
|
|
Assembler:
|
|
- generate automatic list of modified registers
|
|
|
|
|
|
.object test1 {
|
|
.sram {
|
|
Testdata:
|
|
.bytes 16
|
|
}
|
|
|
|
.eprom {
|
|
}
|
|
|
|
.code {
|
|
}
|
|
}
|
|
|
|
|
|
|
|
function test1 {
|
|
ld r16, 10
|
|
l1:
|
|
dec r16
|
|
brne l1
|
|
ret
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
Hardware:
|
|
|
|
AtTiny 84
|
|
=========
|
|
----------
|
|
VCC + 1 14 + GND
|
|
(PCINT8, XTAL1, CLKI) PB0 + 2 13 + PA0 (ADC0, AREF, PCINT0) IN/OUT
|
|
(PCINT9, XTAL2) PB1 + 3 12 + PA1 (ADC1, AIN0, PCINT1) WAN-DATA
|
|
(PCINT11, RESET, dW) PB3 + 4 11 + PA2 (ADC2, AIN1, PCINT2) IN/OUT [LED (red)]
|
|
KEY->IRQ_PCI1 (PCINT10, INT0, OC0A, CKOUT) PB2 + 5 10 + PA3 (ADC3, T0, PCINT3) LED (green)
|
|
WAN-ATTN(PCI0)(PCINT7, ICP1, OC0B, ADC7) PA7 + 6 9 + PA4 (ADC4, USCK, SCL, T1, PCINT4) I2C, SPI
|
|
I2C, SPI (PCINT6, OC1A, SDA, MOSI, DI, ADC6) PA6 + 7 8 + PA5 (ADC5, DO, MISO, OC1B, PCINT5) SPI
|
|
----------
|
|
|
|
|
|
AtTiny 85
|
|
=========
|
|
----------
|
|
(PCINT5, /RESET, ADC0, dW) PB5 + 1 8 + VCC
|
|
WAN-ATTN (PCINT3, XTAL1, CLKI, /OC1B, ADC3) PB3 + 2 7 + PB2 (SCK, USCK, SCL, ADC1, T0, INT0, PCINT2)
|
|
WAN-DATA (PCINT4, XTAL2, CLKO, OC1B, ADC2) PB4 + 3 6 + PB1 (MISO, DO, AIN1, OC0B, OC1A, PCINT1)
|
|
GND + 4 5 + PB0 (MOSI, DI, SDA, AIN0, OC0A, /OC1A, AREF, PCINT0)
|
|
----------
|
|
|
|
|
|
|
|
ADC = ADC Input Channel
|
|
AREF = External Analog Reference
|
|
PCINT = Pin Change Interrupt
|
|
AIN = Analog Comparator Input (0=positive, 1=negative input)
|
|
T0 = Timer/Counter0 Clock Source
|
|
T1 = Timer/Counter1 Clock Source
|
|
USCK = USI Clock (Three Wire Mode)
|
|
SCL = USI Clock (I2C Mode=
|
|
DO = USI Data Output (Three Wire Mode)
|
|
MISO = SPI Master Data Input / Slave Data Output (Three Wire Mode)
|
|
OC0A = Timer/Counter0 Compare Match A Output
|
|
OC0B = Timer/Counter0 Compare Match B Output
|
|
OC1A = Timer/Counter1 Compare Match A Output
|
|
OC1B = Timer/Counter1 Compare Match B Output
|
|
SDA = USI Data Input (I2C Mode)
|
|
MOSI = SPI Data Master Output/Slave Data Input (Three Wire Mode)
|
|
ICP1 = Timer/Counter1 Input Capture Pin
|
|
|
|
|
|
|
|
WAN-ATTN -> irq PCI0
|
|
KEY -> irq PCI1
|
|
PA0 -> in/out1
|
|
PA2 -> in/out2
|
|
PA3 -> LED
|
|
PA4-6: I2C, SPI
|
|
|
|
|
|
|
|
WAN-Communication:
|
|
|
|
WAN-Protocol (UART 9600bps 8N1)
|
|
|
|
|
|
104us pro bit bei 9600bps, about 1040us per byte, about 8.3ms per 8 bytes
|
|
|
|
52us 104us 104us 104us 104us 104us 104us 104us 104us 104us 104us
|
|
INACTIVE START 0 1 2 3 4 5 6 7 STOP INACTIVE
|
|
- DATA ~11111111 00000000 00000000 00000000 11111111 00000000 11111111 00000000 11111111 00000000 11111111 11111111 11~
|
|
- /ACTIVE ~11100000000000000000000000000000000000000000000000000000000000000000000000000000000000000 00000000 11111111 11~
|
|
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX (repeat for every byte)
|
|
|
|
|
|
|
|
Sensors:
|
|
- Erd-Feuchtigkeitssensor:
|
|
https://www.mouser.de/ProductDetail/M5Stack/U019?qs=sGAEpiMZZMu2rInN%2FZRmFkkq%2FqtywxsmOLlgBBfclSVLB6YzCank4Q%3D%3D
|
|
|
|
|
|
- rename WAN -> inc (inter-node-communication)
|
|
- INC messages:
|
|
- 1 byte : dest address [not saved]
|
|
- 1 byte : msg length (not including dest address, msg length and xor byte) [not saved]
|
|
- n bytes: data
|
|
- 1 byte : XOR checksum [not saved]
|
|
|
|
Packet in buffer:
|
|
- 1 byte: buffer length
|
|
- 1 byte: flags
|
|
- 1 byte: dest address
|
|
- 1 byte: msg data
|
|
|
|
|
|
- receivePacket:
|
|
- recv dest address
|
|
- matches?
|
|
- no: finished
|
|
- recv msg size
|
|
- too big?
|
|
- yes: ABORT
|
|
- alloc buffer (msg size +1)
|
|
- error?
|
|
- yes: ABORT
|
|
- write to buffer: size+0x80 (0x80: READ)
|
|
- for every msg size byte: receive byte
|
|
- receive XOR byte
|
|
- check XOR checksum
|
|
- 0?
|
|
- no: ABORT, DeallocBufferBack
|
|
|
|
|
|
|
|
|
|
Infrastructure, what's next
|
|
===========================
|
|
|
|
- build PC module to read and write control messages
|
|
- make WAN code in AVR stable
|
|
- implement command to write debug messages to PC via WAN
|
|
|
|
- node
|
|
- unit (e.g. environment, presence, door, power) [defines per unit type, use uint8_t values]
|
|
- value (e.g. temp, humidity, pressure, light)
|
|
|
|
- addresses:
|
|
- 8-bits total, but:
|
|
- bit 7=0: bit 0-6 contains a node address (i.e. max 127 node devices)
|
|
- bit 7=1, bit 6=0: bits 0-5 contain id of a group:
|
|
- nodes with window/door status
|
|
- nodes with alarm output (e.g. horn, bell or or sms)
|
|
- nodes with environmental readouts (temp, humidity etc.)
|
|
- 240+: special ids
|
|
- 252: timekeeper node
|
|
- 253: id of database node
|
|
- 254: id of a router node to upper layers (e.g. room -> appartement -> floor -> house)
|
|
- 255: broadcast (every node)
|
|
- 0: only unassigned nodes (used when assigning an address)
|
|
|
|
- nodes:
|
|
- database node
|
|
- contains a list of known nodes and their modules and addresses on a bus
|
|
- router node
|
|
- forwards upwards in the hierarchy (e.g. from room to appartement level)
|
|
|
|
- commands:
|
|
- ping
|
|
- announce device
|
|
- used to assign a 8-bit device id on a bus
|
|
- needs a 8-byte serial number for the device
|
|
- assign device id
|
|
- response from a database node to "announce device"
|
|
- announce module
|
|
- make information about a module on a node available to a central node (or other interested nodes)
|
|
- announce value
|
|
- make info about data available
|
|
- value data
|
|
- announce changes in a given module
|
|
- RQ: set value
|
|
- allow to change a value
|
|
- RSP: set value (response to set value request)
|
|
- request value info
|
|
- make the node send the current value of a given module
|
|
|
|
|
|
Bauteile fuer Platine:
|
|
- Widerstaende:
|
|
- 1K fuer LEDs
|
|
- 10K fuer Pull-up (UART lines)
|
|
- Kondensatoren:
|
|
- 10 microF (fuer Spannungsregler)
|
|
- 100nF (Abblockkondensatoren fuer Chips)
|
|
|
|
|
|
Memory Layout:
|
|
- 0x0000-0x003f: Reset and IRQ vectors
|
|
- 0x0040 : 8 bytes node id (never overwritten)
|
|
- 0x0048 : 2 bytes maintenance system version
|
|
- 0x004a-0x004f: reserved
|
|
- 0x0050-0x09ff: maintenance system (2479 bytes)
|
|
- 0x0a00-0x0a3f: working system; reset and IRQ vectors
|
|
- 0x0a40-0x0a4f: reserved (later: pointer to version etc)
|
|
- 0x0a50-end : rest of working system
|
|
|
|
|
|
Interrupt-Vektoren:
|
|
- bei aktivem maintenance system:
|
|
- rjmp PC+0x050
|
|
- bei aktivem working system:
|
|
- rjmp PC+0xa00
|
|
|
|
|
|
|
|
Next:
|
|
- read/write FLASH
|
|
|