current state of TODO file.

This commit is contained in:
Martin Preuss
2023-04-11 21:19:51 +02:00
parent d14649df0e
commit da6b7da501

502
TODO
View File

@@ -419,12 +419,14 @@ Infrastructure, what's next
- RSP: set value (response to set value request)
- request value info
- make the node send the current value of a given module
- time (date, time, day/night flag)
Bauteile fuer Platine:
- Widerstaende:
- 1K fuer LEDs
- 10K fuer Pull-up (UART lines)
- 1K fuer Pull-up (UART lines)
- 100 Ohm serial inline (UART lines)
- 4K7/10K fuer Pull-up (I2C lines)
- Kondensatoren:
- 10 microF (fuer Spannungsregler)
@@ -432,31 +434,21 @@ Bauteile fuer Platine:
- Chips:
- HT7333 (3V3 Spannungsregler
- 74LS21: Dual 4-Port AND Gate (OpenCollector Outputs)
- 74LS03, 74LS04: Interface for usbserial (OpenCollector Outputs)
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
- 0x0020-0x04ff: base system (1248 words, starting with irq table)
- 0x0500-end : main system starting with IRQ table (2816 words)
Interrupt-Vektoren:
- bei aktivem maintenance system:
- rjmp PC+0x050
- bei aktivem working system:
- rjmp PC+0xa00
Next:
- read/write FLASH
- bei aktivem base system:
- rjmp PC+0x020 (0xc01f)
- bei aktivem main system:
- rjmp PC+0x500 (0xc4ff)
@@ -520,25 +512,473 @@ Next:
; generic node 5
; AtTiny84
; --------
; VCC 1 14 GND
; PB0 2 13 PA0
; DOOR-ADC1 PB1 3 12 PA1 COM-DATA
; /RESET PB3 4 11 PA2
; PB2 5 10 PA3 LED
; COM_ATTN PA7 6 9 PA4 TWI-SCL
; TWI-SDA PA6 7 8 PA5 DOOR-ADC0 (CNY70 Collector)
; --------
; AtTiny85
; --------
; /RESET PB5 1 8 VCC
; COM-ATTN PB3 2 7 PB2 TWI-SCL
; COM-DATA PB4 3 6 PB1 LED
; GND 4 5 PB0 TWI-SDA
; --------
; HT7333
; ------
; Vin +-------+
; = C (10 uF)
; Gnd +-------+
; = C (10 uF)
; Vout +-------+
; ------
Timer_Run TODO:
- disable interrupts
- first handle internal counters and sample into internal flags
- enable interrupts
- call handlers (every10s etc) according to flags
format of an intel hex file:
:02 0000 02 0000 FC
| | | | |
| | | | checksum = -(len + addrlow+addrHigh+every_data_byte)
| addr | data
length record type (02=extended segment address record)
:10 0000 00 34 C8 18 95 7E C1 18 95 18 95 18 95 18 95 18 95 A7
:10 0100 00 02 E0 09 BF 08 95 08 95 FF B6 F8 94 00 27 10 91 02
see https://developer.arm.com/documentation/ka003292/latest
record types:
00 data record;
01 End of file record. Usually, it is 00000001FF
02 Extended Segment address record. This indicates segment base address when 16 bits is not enough for addressing memory;
[ 03 Start segment address record. Indicates initial segment base address.]
04 Extended Linear Address Record allows 32 bit addressing.
05 Start Linear Address Record.
for record type 2:
- should be 0 for attiny
- real address is segment address from record type 2 left-shifted by 4 bits + address in data segments, e.g.:
adress from data record: 2462
type 2 address: 1200 <- shift left by 4
resulting address: 00014462
for type 4 (start address of appication):
- data part contains full 32-bit address
int writehex( FILE *fp, ulong adr, uchar *data, int len )
{
if( len ){
int pruef;
fprintf( fp, ":%02X%04lX00", len, adr );
pruef = len + (adr & 0xFF) + (adr >> 8);
for(; len--; data++){
fprintf( fp, "%02X", *data );
pruef += *data;
}
fprintf( fp, "%02X\r\n", -pruef & 0xFF );
return 1;
}
fputs( ":00000001FF\r\n", fp );
return 1;
}
Das Attiny-Projekt O Der Bootloader 4
ldi temp, LOW(RAMEND) ; Stackpointer auf RAMEND setzen
out SPL, temp
GuckObStarten:
sbis pinD, DTR ; DTR = 0 bzw. Taster Ta1 geschlossen -> BOOTLOADER,
; sonst Anwender-Programm
rjmp Start
rjmp $079F ; Sprung zum Anwender-Programm
Start:
sbi ddrd, LED ; f<>r Anzeige LED
sbi portD, LED ; Anzeige: LED an D.5 an, wenn Bootloading
sbis pinD, DTR ; warten bis DTR = 1 bzw. Ta1 offen
rjmp Start
; UART initialisieren:
sbi UCSRB, 4 ; UCR=UCSRB=0x0B RXEN=Bit4 RX aktivieren
sbi UCSRB, 3 ; UCR=UCSRB=0x0B UDRE=Bit3 TX aktiv
ldi uartparam, 4000000/(9600*16)-1 ;Baudrate 9600 einstellen
out UBRRL, uartparam
rcall rdcom ; warten auf Startbyte
cbi portd, LED ; LED an D.5 aus, wenn Startbyte erhalten
ldi param, 105 ; ACK senden
rcall wrcom
MainSchlaufe:
rcall rdcom
mov command, param
B201: ; Block (Page) schreiben
cpi command, 201
brne B203
rcall Schreib_Block
ldi param, 1 ; ACK Block_Schreiben
rcall wrcom
B203: ; Anwender-Programm starten
cpi command, 203
brne zurueck ; Wenn keine Zahl zutrifft zum Anfang
ldi param, 11 ; ACK Ende des Uploads
rcall wrcom
rcall warte1ms ; 1 ms warten
cbi UCSRB, 4 ; RX deaktivieren
cbi UCSRB, 3 ; TX deaktivieren
rjmp $03AF
zurueck:
rjmp MainSchlaufe
Schreib_Block:
ldi r23, PageSize4313
rcall rdcom ; Block-Adresse vom Master
mov ZH, r16
rcall rdcom
mov ZL, r16
Loeschen: ; Block loeschen
ldi r22, 3
out spmcsr, r22
spm
Puffer_Schreib_Schleife: ; alle Woerter des Blocks einzeln in den Puffer
; r1:r0 uebertragen
rcall rdcom
mov r0, r16
rcall rdcom
mov r1, r16
ldi r22, 1 ; Puffer schreiben
out spmcsr, r22
spm
adiw ZL, 2 ; Flash-Adresse um 1 Word erhoehen
mov r16, r0 ; ACK fuer die Uebernahme erhoehen
rcall wrcom
mov r16, r1
rcall wrcom
dec r23
brne Puffer_Schreib_Schleife ; Ende der Puffer_Schreib_Schleife
subi ZL, PageSize4313 ; Startwert fuer Page in Z-Register restaurieren, um...
subi ZL, PageSize4313
ldi r22, 5 ; ... gesamten Puffer in FLASH schreiben
out spmcsr, r22
spm
ret
; temp1, temp2, looplo, loophi, spmcrval
; in: Z=address in FLASH (byte address like for LPM!)
; Y=address in RAM
.equ PAGESIZEB = PAGESIZE*2 ; PAGESIZEB is page size in BYTES, not words
write_page:
; page erase
ldi r20, (1<<PGERS) + (1<<SPMEN)
call do_spm
;transfer data from RAM to Flash page buffer
ldi r18, low(PAGESIZEB) ;init loop variable
ldi r19, high(PAGESIZEB) ;not required for PAGESIZEB<=256
wrloop: ld r0, Y+
ld r1, Y+
ldi r20, (1<<SPMEN)
call do_spm
adiw ZH:ZL, 2
sbiw r19:r18, 2 ;use subi for PAGESIZEB<=256
brne wrloop
;execute page write
subi ZL, low(PAGESIZEB) ;restore pointer
sbci ZH, high(PAGESIZEB) ;not required for PAGESIZEB<=256
ldi r20, (1<<PGWRT) + (1<<SPMEN)
call do_spm
;read back and check, optional
ldi r18, low(PAGESIZEB) ; init loop variable
ldi r19, high(PAGESIZEB) ; not required for PAGESIZEB<=256
subi YL, low(PAGESIZEB) ;restore pointer
sbci YH, high(PAGESIZEB)
rdloop:
lpm r0, Z+
ld r1, Y+
cpse r0, r1
jmp error ; skipped if equal
sbiw r19:r18, 2 ;use subi for PAGESIZEB<=256
brne rdloop
;return
ret
do_spm:
; input: r20 determines SPM action
; disable interrupts if enabled, store status
in r17, SREG
cli
;check for previous SPM complete
wait:
in r16, SPMCR
sbrc r16, SPMEN
rjmp wait
; SPM timed sequence
out SPMCR, r20
spm
; restore SREG (to enable interrupts if originally enabled)
out SREG, r17
ret
TODO:
- Pseudo random:
- add some dynamics (otherwise nodes with the exact same firmware will have the same sequence of random numbers)
- read/write FLASH
- Timer_Run TODO:
- disable interrupts
- first handle internal counters and sample into internal flags
- enable interrupts
- call handlers (every10s etc) according to flags
- Serial TODO:
- work out how to check for ATTN line before sending data
- add onEveryHour
- add onEveryDay
- choose between systems:
- write correct command into every vector of the low irq table
- for calling maintenance system: "C:aaaaaa c04f" (low: 4f, high: c0)
- never flash into the initial irq table (starting at 0!!)
- that table will be set according to currently active system
- writeWord:
- current address pointer: start of page?
- yes:
startPage
- Flash_ReadPageIntoPageBuffer
- Flash_WriteIntoPage (increments Z)
- current address pointer: start of page (meaning: next page)
- yes:
finishPage
- z=z-(PAGESIZE*2)
- Flash_ErasePage (previous page!)
- Flash_WritePage (previous page!)
- z=z+(PAGESIZE*2)
- store address (Z)
- setAddress:
- new address inside current page?
- yes: only set new address
- no:
- finish current page
- start new page
- set new address
FlashMsg:
- start flash
- set address
- msg num (2 bytes)
- address (2 bytes)
- write bytes
- msg num (2 bytes)
- bytes (up to 8)
- end flash
msg size in buffer:
COM_BUFFER_SIZE-3-COM_BUFFER_OFFS_DATA)
16 -3-1 ; 12 bytes max
- 4 bytes header (destaddr, msglen, cmd, srcaddr)
- 1 byte XOR
- 1 byte flags in buffer
->6 bytes overhead
-> 10 usable bytes left
flash data msg:
- 2 bytes msg num
- remaining data bytes: 8
Part list N03:
- Resistors
- R1: 100 Ohm
- R2: 100 Ohm
- R3: 10K Ohm
- R4: 1K Ohm
- R5: 10K Ohm
- R6: 10K Ohm
- R7: 120 Ohm (restrict current to 27mA at 3.3V)
- R8: 220K Ohm
- Capacitors
- C1: 10 uF
- C2: 10 uF
- C3: 100 nF
Part list N04, N05, N06:
- Resistors
- R1: 100 Ohm serial COM_ATTN
- R2: 100 Ohm serial COM_DATA
- R3: 10K Ohm pullup reset
- R4: 1K Ohm serial LED
- R5: 10K Ohm pullup SDA
- R6: 10K Ohm pullup SCL
- R7: 120 Ohm (restrict CNY70 LED current to 27mA at 3.3V)
- R8: 220K Ohm pullup CNY70 photo transistor
- Capacitors
- C1: 10 uF
- C2: 10 uF
- C3: 100 nF
Node header:
- baseFirmwareVersion (2 bytes)
- mainFirmwareVersion (2 bytes)
- modules mask: (2 bytes)
Registered firmware modules:
- 0x01: LED
- 0x02: SI7021
- 0x03: CNY70
- etc.
Next:
- aqhome:
- add IPC client
- add IPC command to set accepted msg groups
- add IPC command to query nodeinfo database
- add IPC command for sending value change
- node (UID, addr?)
- value id
- value type
- new value
- avr:
- add firmware header
- add msg which sends that header
- value msg: send uid instead of timestamp
- maybe use fletcher16? (https://en.wikipedia.org/wiki/Fletcher%27s_checksum)
- or crc8 (https://stackoverflow.com/questions/51752284/how-to-calculate-crc8-in-c)? [use this!]
3 4 2 1
1 2 3 4 1: GND x
x x x 2: ATTN
x 3: DATA x
4: 5V
Gehaeuse:
- Abstandshalter in Gehaeuse?
- Platine verkehrt herum einbauen, einschrauben (Abstandshuelsen?)
- oder: LED und Schalter auf der Rueckseite einbauen, Platine mit Abstandshuelsen einschrauben
- Deckel an der Wand befestigen
- Kabel innerhalb der Dose verlegen (sauberere Anschluesse)
Kabel:
- ROT : 5V
- SCHWARZ: GND
- GRUEN : DATA
- BLAU : ATTN
Tasmota-Steckdosen melden alle 300s:
tele/tasmota/plug01/STATE
{
"Time":"1970-01-01T09:01:09",
"Uptime":"0T09:00:41",
"UptimeSec":32441,
"Heap":29,
"SleepMode":"Dynamic",
"Sleep":50,
"LoadAvg":19,
"MqttCount":1,
"POWER":"ON",
"Wifi":{
"AP":1,
"SSId":"CAMELOT_IOT",
"BSSId":"74:DA:38:EF:8B:DC",
"Channel":4,
"Mode":"11n",
"RSSI":98,
"Signal":-51,
"LinkCount":1,
"Downtime":"0T00:00:06"
}
}
tele/tasmota/plug01/SENSOR
{
"Time":"1970-01-01T09:01:09",
"ENERGY": {
"TotalStartTime":"1970-01-01T00:00:00",
"Total":0.131,
"Yesterday":0.000,
"Today":0.131,
"Period": 4,
"Power":49,
"ApparentPower":55,
"ReactivePower":25,
"Factor":0.89,
"Voltage":232,
"Current":0.235
}
}
node 2: no messages received again???
rewrite COM:
- send message:
- alloc buffer
- message vorbereiten lassen
- send message
- dealloc buffer
- wenn fehler (z.B. line busy): spaeter alles wiederholen (dann aber durch das anfordernde modul, nicht das COM modul)
- kein fire and forget mehr!
- evtl. einen buffer fuer notfall-meldungen
- reihenfolge aendern bei comInterrupt (counter hinterher erhoehen)