avr: split code in multiple files and routines.

This commit is contained in:
Martin Preuss
2023-04-22 11:54:09 +02:00
parent 3e6501c834
commit 3b44fb9c5b
12 changed files with 656 additions and 498 deletions

View File

@@ -74,11 +74,11 @@ com2ReceivePacketRaw_error:
; - x : ptr to buffer to send
; OUT:
; - CFLAGS: set if okay, cleared otherwise (errorcode in R16)
; REGS: R15, R16, R22 (R17, R21, X)
; REGS: R16, R22 (R17, R21, X)
COM2_SendPacketWithAttn:
in r15, SREG
push r15
in r15, SREG
cli
Utils_WaitNanoSecs COM_BIT_LENGTH, 0, r22 ; wait for one bit duration
; check for ATTN line: busy?
@@ -103,8 +103,8 @@ COM2_SendPacketWithAttn:
cbi COM_DDR_ATTN, COM_PINNUM_ATTN ; release ATTN line (by setting direction to IN)
brcc COM2_SendPacketWithAttn_ioError
; packet successfully sent
out SREG, r15
pop r15
out SREG, r15
sec
ret

23
avr/modules/flash/README Normal file
View File

@@ -0,0 +1,23 @@
This implements the boot loader. It can be used to flash new firmware to node.
How it works
============
Whenever the MCU reboots the bootloader is started. The first thing it does is to send a FLASH_READY message to the bus
containing its UID (if any) as well as type and version of the currently installed firmware.
If no FLASH_START message is received for the UID of the device then the bootloader tries to start the main firmware.
If a FLASH_START message is received from manager software (e.g. on a Linux machine) the MCU responds with a positive FLASH_RESPONSE
message.
After that the manager software sends FLASH_DATA messages to which the MCU responds with positive or negative FLASH_RESPONSE messages.
The last flash page is followed by a FLASH_END message.
Then the MCU tries to start the freshly installed firmware.
If at any point in the flashing process an unrecoverable error occurrs the bootloader is restarted, waiting again for a FLASH_START
message.

View File

@@ -0,0 +1,67 @@
; ***************************************************************************
; copyright : (C) 2023 by Martin Preuss
; email : martin@libchipcard.de
;
; ***************************************************************************
; * This file is part of the project "AqHome". *
; * Please see toplevel file COPYING of that project for license details. *
; ***************************************************************************
; ***************************************************************************
; code
.cseg
; ---------------------------------------------------------------------------
; Write a FLASH_READY packet.
;
; IN:
; - X : buffer to write to
; OUT:
; - nothing
; MODIFIED REGS: R16, Z (R17, R18, R19, R20)
flashWriteFlashReady:
ldi r16, 0xff
st X+, r16 ; dest address (unused)
ldi r16, 12 ; msg code+src address+ten payload bytes
st X+, r16 ; msg len
ldi r16, CPRO_CMD_FLASH_READY
st X+, r16 ; msg code
ldi r16, COM2_MAINTENANCE_ADDR
st X+, r16 ; src address (not used)
; payload
lds r16, flashUid
st X+, r16
lds r16, flashUid+1
st X+, r16
lds r16, flashUid+2
st X+, r16
lds r16, flashUid+3
st X+, r16
ldi zl, low(firmwareType*2)
ldi zh, HIGH(firmwareType*2)
lpm r16, Z+
st X+, r16 ; firmwareType (low)
lpm r16, Z+
st X+, r16 ; firmwareType (high)
lpm r16, Z+
st X+, r16 ; firmwareVersion (low)
lpm r16, Z+
st X+, r16 ; firmwareVersion (high)
ldi r16, LOW(PAGESIZE*2)
st X+, r16
ldi r16, HIGH(PAGESIZE*2)
st X, r16
sbiw xh:xl, 13
rcall com2CalcAndAddChecksumByte ; (R16, R17, R18, R19, R20, X)
sbiw xh:xl, 14
ret

View File

@@ -0,0 +1,65 @@
; ***************************************************************************
; copyright : (C) 2023 by Martin Preuss
; email : martin@libchipcard.de
;
; ***************************************************************************
; * This file is part of the project "AqHome". *
; * Please see toplevel file COPYING of that project for license details. *
; ***************************************************************************
; ***************************************************************************
; code
.cseg
; ---------------------------------------------------------------------------
; Create and send a FLASH RESPONSE packet
;
; IN:
; - R16: response code to send
; OUT:
; - nothing
; REGS: r16, X (R15, R17, R18, R19, R20, R21, R22)
flashSendFlashResponse:
; send flash ready message
ldi xl, LOW(flashSendBuffer)
ldi xh, HIGH(flashSendBuffer)
clr r16
rcall flashWriteFlashRsp ; (R16, R17, R18, R19, R20)
rjmp flashSendPacketUntilSuccess ; (R15, R16, R17, R21, R22, X)
; ---------------------------------------------------------------------------
; Write a FLASH_RESPONSE packet.
;
; IN:
; - R16: response code (0 if ok, error code otherwise)
; - X : buffer to write to
; OUT:
; - nothing
; MODIFIED REGS: R16, R17 (R18, R19, R20)
flashWriteFlashRsp:
clr r18
st X+, r18 ; dest address (unused)
ldi r18, 3 ; msg code+src address+one payload byte
st X+, r18 ; msg len
ldi r17, CPRO_CMD_FLASH_RSP
st X+, r17 ; msg code
clr r17
st X+, r17 ; src address (not used)
st X, r16 ; payload byte
sbiw xh:xl, 4
rcall com2CalcAndAddChecksumByte ; (R16, R17, R18, R19, R20, X)
sbiw xh:xl, 5
ret

View File

@@ -0,0 +1,62 @@
; ***************************************************************************
; copyright : (C) 2023 by Martin Preuss
; email : martin@libchipcard.de
;
; ***************************************************************************
; * This file is part of the project "AqHome". *
; * Please see toplevel file COPYING of that project for license details. *
; ***************************************************************************
; ***************************************************************************
; code
.cseg
; ---------------------------------------------------------------------------
; Handle FLASH DATA packet.
;
; IN:
; - X : buffer containing the message
; OUT:
; - CFLAG: set if message is for us, cleared otherwise
; REGS: R0, R1, R15, R16, R17, R18, R19, R20, R21, R24, R25, X, Z
flashHandleFlashData:
adiw xh:xl, FLASH_MSG_OFFS_MSGLEN
ld r18, X ; length (subtract 6
cpi r18, 6 ; cmd(1), src(1), addr(4)
brcs flashHandleFlashData_badData
subi r18, 6 ; remaining length
adiw xh:xl, FLASH_PACKET_DATA_OFFS_ADDR-FLASH_MSG_OFFS_MSGLEN
ld zl, X+ ; address (low)
ld zh, X+ ; address (high)
adiw xh:xl, 2 ; ignore high bytes, points to first data byte now
; rcall Flash_StartPage ; (R0, R1, R16, R20, R24, R25)
push zl
push zh
flashHandleFlashData_loop:
ld r0, X+
ld r1, X+
rcall Flash_WriteIntoPage ; (R15, R16, Z+)
subi r18, 2
brne flashHandleFlashData_loop
pop zh
pop zl
rcall Flash_FinishPage ; (R15, R16, R20)
clr r16
rjmp flashHandleFlashData_sendResponse
flashHandleFlashData_badData:
ldi r16, FLASH_ERROR_MSGERROR
flashHandleFlashData_sendResponse:
rcall flashSendFlashResponse ; (R15, R16, R17, R18, R19, R20, R21, R22, X)
sec
ret

View File

@@ -0,0 +1,58 @@
; ***************************************************************************
; copyright : (C) 2023 by Martin Preuss
; email : martin@libchipcard.de
;
; ***************************************************************************
; * This file is part of the project "AqHome". *
; * Please see toplevel file COPYING of that project for license details. *
; ***************************************************************************
; ***************************************************************************
; code
.cseg
; ---------------------------------------------------------------------------
; Handle FLASH START packet.
;
; IN:
; - X : buffer containing the message
; OUT:
; - CFLAG: set if message is for us, cleared otherwise
; REGS: r16, r18. r19. r20, r21, X (R15, R17, R22)
flashHandleFlashStart:
lds r18, flashUid
lds r19, flashUid+1
lds r20, flashUid+2
lds r21, flashUid+3
adiw xh:xl, FLASH_PACKET_START_OFFS_UID
ld r16, X+
cp r16, r18
brne flashHandleFlashStart_notMe
ld r16, X+
cp r16, r19
brne flashHandleFlashStart_notMe
ld r16, X+
cp r16, r20
brne flashHandleFlashStart_notMe
ld r16, X
cp r16, r21
brne flashHandleFlashStart_notMe
; okay, flash start message is for us
rcall flashWaitFor100ms
rcall flashSendFlashResponse ; (R15, R16, R17, R18, R19, R20, R21, R22, X)
sec
ret
flashHandleFlashStart_notMe:
clc
ret

View File

@@ -81,8 +81,8 @@ bootLoader:
sbi DDRA, PORTA3 ; out
cbi PORTA, PORTA3 ; on
sbi DDRA, PORTA2 ; out (debug)
sbi PORTA, PORTA2 ; off (debug)
cbi DDRA, PORTA2 ; in (debug led)
sbi PORTA, PORTA2 ; pullup on (debug led)
rcall flashReadUid
sts flashUid, r18
@@ -90,34 +90,13 @@ bootLoader:
sts flashUid+2, r20
sts flashUid+3, r21
; wait for 3 secs before sending message
; wait for 3 secs before doing anything else
ldi r16, 30
rcall flashWaitForMulti100ms
; send flash ready message
ldi xl, LOW(flashSendBuffer)
ldi xh, HIGH(flashSendBuffer)
rcall flashWriteFlashReady
rcall flashSendPacketUntilSuccess
sbi PORTA, PORTA3 ; LED off
bootLoader_loop1:
; wait up to 10s for incoming FLASH_START message
ldi r16, CPRO_CMD_FLASH_START
ldi r17, 100 ; 100*100ms=10s
rcall flashWaitForSpecificMessageWithLed
brcc bootLoader_startFirmware
; either FLASH_START or FLASH_END received
cpi r16, CPRO_CMD_FLASH_START ; not FLASH_START, no flashing requested
brne bootLoader_startFirmware
; receive and flash new firmware
rcall flashHandleFlashStart
brcc bootLoader_loop1
; received a FLASH START msg, handle flashing
rcall bootLoaderFlash
rcall bootCheckFlash
brcc bootLoader_startFirmware ; no flash process, try start installed firmware
rcall bootLoaderFlash ; received a FLASH START msg, handle flashing
brcc bootLoader_waitAndRestartBootLoader
; try to start firmware
@@ -136,6 +115,44 @@ bootLoader_waitAndRestartBootLoader:
; ---------------------------------------------------------------------------
; check for incoming flash request
;
; send a FLASH_READY message and wait for about 10s for incoming FLASH_START which is then handled.
;
; IN:
; - R16: message type to receive
; - R17: wait time in 100ms (1=100ms, 2=200ms etc.)
; OUT:
; - CFLAG: set if incoming flash request received, cleared otherwise
; - R16: message type received (if CFLAG set)
; REGS: R16, R17, X (R1, R2, R18, R19, R20, R21, R22, R24, R25)
bootCheckFlash:
; send flash ready message
ldi xl, LOW(flashSendBuffer)
ldi xh, HIGH(flashSendBuffer)
rcall flashWriteFlashReady ; (R16, R17, R18, R19, R20, Z)
rcall flashSendPacketUntilSuccess ; (R16, R17, R18, R21, R22, R24, R25, X)
bootCheckFlash_loop:
; wait up to 10s for incoming FLASH_START message
ldi r16, CPRO_CMD_FLASH_START
ldi r17, 100 ; 100*100ms=10s
rcall flashWaitForSpecificMessageWithLed ; R2, R16, R17 (R1, R24, R25, X)
brcc bootRet
; either FLASH_START or FLASH_END received
cpi r16, CPRO_CMD_FLASH_START ; not FLASH_START, no flashing requested
brne bootClcRet
; received FLASH_START
rcall flashHandleFlashStart
brcc bootCheckFlash_loop
ret ; ret with CARRY flag set
bootLoaderFlash:
@@ -144,456 +161,31 @@ bootLoaderFlash_loop1:
ldi r16, CPRO_CMD_FLASH_DATA
ldi r17, 100 ; 100*100ms=10s
rcall flashWaitForSpecificMessageWithLed
brcc bootLoaderFlash_error
brcc bootRet
; either FLASH_DATA or FLASH_END received
cpi r16, CPRO_CMD_FLASH_DATA ; not FLASH_DATA, flashing ended/aborted
brne bootLoaderFlash_end
brne bootSecRet ; FLASH_END received, done
; flash data
rcall flashHandleFlashData
rjmp bootLoaderFlash_loop1
bootLoaderFlash_end:
sec
ret
bootLoaderFlash_error:
bootClcRet:
clc
bootRet:
ret
; ---------------------------------------------------------------------------
; wait for a specific message to arrive within given time, flashing LED
;
; IN:
; - R16: message type to receive
; - R17: wait time in 100ms (1=100ms, 2=200ms etc.)
; OUT:
; - CFLAG: set if msg received (either expected msg or FLASH_END), cleared otherwise
; - R16: message type received (if CFLAG set)
; REGS: R2, R16, R17 (R1, R24, R25, X)
flashWaitForSpecificMessageWithLed:
mov r2, r16
sbi PORTA, PORTA3 ; LED off
flashWaitForSpecificMessageWithLed_loop:
sbi PINA, PORTA3 ; toggle LED
mov r16, r2
push r17
ldi r17, 100 ; wait up to 100ms
rcall flashWaitForSpecificMessage ; (R1, R16, R17, R24, R25, X)
pop r17
brcs flashWaitForSpecificMessageWithLed_received
dec r17
brne flashWaitForSpecificMessageWithLed_loop
sbi PORTA, PORTA3 ; off
clc
ret
flashWaitForSpecificMessageWithLed_received:
sbi PORTA, PORTA3 ; off
bootSecRet:
sec
ret
; ---------------------------------------------------------------------------
; wait for a specific message to arrive within given time.
;
; IN:
; - R16: msg command to wait for
; - R17: time to wait for packet (in milliseconds)
; OUT:
; - CFLAG: set if msg received, cleared on timeout
; - R16 : message type received
; REGS: R1, R16, R17, X (R24, R25)
flashWaitForSpecificMessage:
mov r1, r16 ; expected message type
flashWaitForSpecificMessage_loop0:
; wait for ATTN to go low
flashWaitForSpecificMessage_loop1:
ldi r16, 0 ; wait for low
rcall flashWaitForAttnState1ms ; (R22, R24)
brcs flashWaitForSpecificMessage_isLow
dec r17
brne flashWaitForSpecificMessage_loop1
rjmp flashWaitForSpecificMessage_timeout
; receive message
flashWaitForSpecificMessage_isLow: ; is low, receive message, check for msg type
push r17
ldi r16, COM2_MAINTENANCE_ADDR
ldi r17, FLASH_RECVBUFFER_MAXLEN-3
ldi xl, LOW(flashRecvBuffer)
ldi xh, HIGH(flashRecvBuffer)
rcall com2ReceivePacketRaw
pop r17
brcc flashWaitForSpecificMessage_waitAttnHigh
ldi xl, LOW(flashRecvBuffer)
ldi xh, HIGH(flashRecvBuffer)
adiw xh:xl, COM2_MSG_OFFS_CMD
ld r16, X
sbiw xh:xl, COM2_MSG_OFFS_CMD
cp r16, r1
breq flashWaitForSpecificMessage_received
cpi r16, CPRO_CMD_FLASH_END
breq flashWaitForSpecificMessage_received
flashWaitForSpecificMessage_waitAttnHigh:
dec r17
breq flashWaitForSpecificMessage_timeout
; wait for ATTN to go high
flashWaitForSpecificMessage_loop2:
ldi r16, 0xff ; wait for high
rcall flashWaitForAttnState1ms ; (R22, R24)
brcs flashWaitForSpecificMessage_isHigh
dec r17
brne flashWaitForSpecificMessage_loop2
rjmp flashWaitForSpecificMessage_timeout
flashWaitForSpecificMessage_isHigh:
rjmp flashWaitForSpecificMessage_loop0
flashWaitForSpecificMessage_received: ; R16 contains message type
sec
ret
flashWaitForSpecificMessage_timeout:
clc
ret
; ---------------------------------------------------------------------------
; Wait for up to 1ms for ATTN line to reach the given state
;
; IN:
; - R16: expected state (0xff for high, 0 for low)
; OUT:
; - CFLAG: set if state reached, cleared otherwise
; REGS: R24 (R22)
flashWaitForAttnState1ms:
ldi r24, 100
flashWaitForAttnState1ms_loop:
push r17
in r17, COM_PIN_ATTN
eor r17, r16
andi r17, (1<<COM_PINNUM_ATTN)
pop r17
breq flashWaitForAttnState1ms_stateReached
Utils_WaitNanoSecs 10000, 0, r22 ; wait for 10us
dec r24
brne flashWaitForAttnState1ms_loop
clc
ret
flashWaitForAttnState1ms_stateReached:
sec
ret
; ---------------------------------------------------------------------------
; wait indefinately until ATTN line is high, send packet over wire, retry until successfull
;
; IN:
; - x : ptr to buffer to send
; OUT:
; - nothing
; REGS: R15, R16, R22 (R17, R21, X)
flashSendPacketUntilSuccess:
push xl
push xh
rcall COM2_SendPacketWithAttn
pop xh
pop xl
brcc flashSendPacket_error
ret
flashSendPacket_error:
rcall flashWaitForAttnHigh
rjmp flashSendPacketUntilSuccess
; ---------------------------------------------------------------------------
; wait indefinately for free ATTN line
;
; IN:
; - nothing
; OUT:
; - nothing
; REGS: R15, R16, R22 (R17, R21, X)
flashWaitForAttnHigh:
rcall com2WaitForAttnHigh ; waits for up to 100us
brcc flashWaitForAttnHigh_stillLow
ret
flashWaitForAttnHigh_stillLow:
rcall flashWaitDependingOnUid ; (R16, R18, R22, R24, R25)
rjmp flashWaitForAttnHigh
; ---------------------------------------------------------------------------
; wait depending on lowest byte of uid.
;
; Wait interval is between 100ms and 25s (i.e. 255*100ms). This is used to avoid
; all nodes on the network trying to send messages at the exact same time (e.g. after
; power outage which would affect all nodes at the same time).
;
; IN:
; - nothing
; OUT:
; - nothing
; REGS: R16 (R18, R22, R24, R25)
flashWaitDependingOnUid:
lds r16, flashUid
tst r16
brne flashWaitDependingOnUid_l1
ldi r16, 17
flashWaitDependingOnUid_l1:
rjmp flashWaitForMulti100ms
; ---------------------------------------------------------------------------
; wait for multiples of 100ms.
;
; IN:
; - R16: number of 100ms loops
; OUT:
; - nothing
; REGS: R16 (R18, R22, R24, R25)
flashWaitForMulti100ms:
flashWaitForMulti100ms_loop:
rcall flashWaitFor100ms ; (R18, R22, R24, R25)
dec r16
brne flashWaitForMulti100ms_loop
ret
; ---------------------------------------------------------------------------
; wait for 100 milliseconds.
;
; IN:
; - nothing
; OUT:
; - nothing
; REGS: R18 (R22, R24, R25)
flashWaitFor100ms:
ldi r18, 100
flashWaitFor100ms_loop:
rcall flashWaitFor1ms ; (R22, R24, R25)
dec r18
brne flashWaitFor100ms_loop
ret
; ---------------------------------------------------------------------------
; wait for 1 millisecond.
;
; IN:
; - nothing
; OUT:
; - nothing
; REGS: R24 (R22)
flashWaitFor1ms:
ldi r24, 10
flashWaitFor1ms_loop:
Utils_WaitNanoSecs 100000, 0, r22 ; wait for 100us
dec r24
brne flashWaitFor1ms_loop
ret
; ---------------------------------------------------------------------------
; Write a FLASH_RESPONSE packet.
;
; IN:
; - R16: response code (0 if ok, error code otherwise)
; - X : buffer to write to
; OUT:
; - nothing
; MODIFIED REGS: R16, R17 (R18, R19, R20)
flashWriteFlashRsp:
clr r18
st X+, r18 ; dest address (unused)
ldi r18, 3 ; msg code+src address+one payload byte
st X+, r18 ; msg len
ldi r17, CPRO_CMD_FLASH_RSP
st X+, r17 ; msg code
clr r17
st X+, r17 ; src address (not used)
st X, r16 ; payload byte
sbiw xh:xl, 4
rcall com2CalcAndAddChecksumByte ; (R16, R17, R18, R19, R20, X)
sbiw xh:xl, 5
ret
; ---------------------------------------------------------------------------
; Write a FLASH_READY packet.
;
; IN:
; - X : buffer to write to
; OUT:
; - nothing
; MODIFIED REGS: R16, Z (R17, R18, R19, R20)
flashWriteFlashReady:
ldi r16, 0xff
st X+, r16 ; dest address (unused)
ldi r16, 12 ; msg code+src address+ten payload bytes
st X+, r16 ; msg len
ldi r16, CPRO_CMD_FLASH_READY
st X+, r16 ; msg code
ldi r16, COM2_MAINTENANCE_ADDR
st X+, r16 ; src address (not used)
; payload
lds r16, flashUid
st X+, r16
lds r16, flashUid+1
st X+, r16
lds r16, flashUid+2
st X+, r16
lds r16, flashUid+3
st X+, r16
ldi zl, low(firmwareType*2)
ldi zh, HIGH(firmwareType*2)
lpm r16, Z+
st X+, r16 ; firmwareType (low)
lpm r16, Z+
st X+, r16 ; firmwareType (high)
lpm r16, Z+
st X+, r16 ; firmwareVersion (low)
lpm r16, Z+
st X+, r16 ; firmwareVersion (high)
ldi r16, LOW(PAGESIZE*2)
st X+, r16
ldi r16, HIGH(PAGESIZE*2)
st X, r16
sbiw xh:xl, 13
rcall com2CalcAndAddChecksumByte ; (R16, R17, R18, R19, R20, X)
sbiw xh:xl, 14
ret
; ---------------------------------------------------------------------------
; Handle FLASH START packet.
;
; IN:
; - X : buffer containing the message
; OUT:
; - CFLAG: set if message is for us, cleared otherwise
; REGS: r16, r18. r19. r20, r21, X (R15, R17, R22)
flashHandleFlashStart:
lds r18, flashUid
lds r19, flashUid+1
lds r20, flashUid+2
lds r21, flashUid+3
adiw xh:xl, FLASH_PACKET_START_OFFS_UID
ld r16, X+
cp r16, r18
brne flashHandleFlashStart_notMe
ld r16, X+
cp r16, r19
brne flashHandleFlashStart_notMe
ld r16, X+
cp r16, r20
brne flashHandleFlashStart_notMe
ld r16, X
cp r16, r21
brne flashHandleFlashStart_notMe
; okay, flash start message is for us
rcall flashWaitFor100ms
rcall flashSendFlashResponse ; (R15, R16, R17, R18, R19, R20, R21, R22, X)
sec
ret
flashHandleFlashStart_notMe:
clc
ret
; ---------------------------------------------------------------------------
; Handle FLASH DATA packet.
;
; IN:
; - X : buffer containing the message
; OUT:
; - CFLAG: set if message is for us, cleared otherwise
; REGS: R0, R1, R15, R16, R17, R18, R19, R20, R21, R24, R25, X, Z
flashHandleFlashData:
adiw xh:xl, FLASH_MSG_OFFS_MSGLEN
ld r18, X ; length (subtract 6
cpi r18, 6 ; cmd(1), src(1), addr(4)
brcs flashHandleFlashData_badData
subi r18, 6 ; remaining length
adiw xh:xl, FLASH_PACKET_DATA_OFFS_ADDR-FLASH_MSG_OFFS_MSGLEN
ld zl, X+ ; address (low)
ld zh, X+ ; address (high)
adiw xh:xl, 2 ; ignore high bytes, points to first data byte now
; rcall Flash_StartPage ; (R0, R1, R16, R20, R24, R25)
push zl
push zh
flashHandleFlashData_loop:
ld r0, X+
ld r1, X+
rcall Flash_WriteIntoPage ; (R15, R16, Z+)
subi r18, 2
brne flashHandleFlashData_loop
pop zh
pop zl
rcall Flash_FinishPage ; (R15, R16, R20)
clr r16
rjmp flashHandleFlashData_sendResponse
flashHandleFlashData_badData:
ldi r16, FLASH_ERROR_MSGERROR
flashHandleFlashData_sendResponse:
rcall flashSendFlashResponse ; (R15, R16, R17, R18, R19, R20, R21, R22, X)
sec
ret
; ---------------------------------------------------------------------------
; Create and send a FLASH RESPONSE packet
;
; IN:
; - R16: response code to send
; OUT:
; - nothing
; REGS: r16, X (R15, R17, R18, R19, R20, R21, R22)
flashSendFlashResponse:
; send flash ready message
ldi xl, LOW(flashSendBuffer)
ldi xh, HIGH(flashSendBuffer)
clr r16
rcall flashWriteFlashRsp ; (R16, R17, R18, R19, R20)
rjmp flashSendPacketUntilSuccess ; (R15, R16, R17, R21, R22, X)
FLASH_PROTO_END:
.equ MODULE_SIZE_FLASH_PROTO = FLASH_PROTO_END-FLASH_PROTO_BEGIN

150
avr/modules/flash/recv.asm Normal file
View File

@@ -0,0 +1,150 @@
; ***************************************************************************
; copyright : (C) 2023 by Martin Preuss
; email : martin@libchipcard.de
;
; ***************************************************************************
; * This file is part of the project "AqHome". *
; * Please see toplevel file COPYING of that project for license details. *
; ***************************************************************************
; ***************************************************************************
; code
.cseg
; ---------------------------------------------------------------------------
; wait for a specific message to arrive within given time, flashing LED
;
; IN:
; - R16: message type to receive
; - R17: wait time in 100ms (1=100ms, 2=200ms etc.)
; OUT:
; - CFLAG: set if msg received (either expected msg or FLASH_END), cleared otherwise
; - R16: message type received (if CFLAG set)
; REGS: R2, R16, R17 (R1, R24, R25, X)
flashWaitForSpecificMessageWithLed:
mov r2, r16
sbi PORTA, PORTA3 ; LED off
flashWaitForSpecificMessageWithLed_loop:
sbi PINA, PORTA3 ; toggle LED
mov r16, r2
push r17
ldi r17, 100 ; wait up to 100ms
rcall flashWaitForSpecificMessage ; (R1, R16, R17, R24, R25, X)
pop r17
brcs flashWaitForSpecificMessageWithLed_received
dec r17
brne flashWaitForSpecificMessageWithLed_loop
sbi PORTA, PORTA3 ; off
rjmp flash_recv_clc_ret ; timeout
flashWaitForSpecificMessageWithLed_received:
sbi PORTA, PORTA3 ; off
sec
ret
; ---------------------------------------------------------------------------
; wait for a specific message to arrive within given time.
;
; IN:
; - R16: msg command to wait for
; - R17: time to wait for packet (in milliseconds)
; OUT:
; - CFLAG: set if msg received, cleared on timeout
; - R16 : message type received
; REGS: R1, R16, R17, X (R24, R25)
flashWaitForSpecificMessage:
mov r1, r16 ; expected message type
flashWaitForSpecificMessage_loop0:
; wait for ATTN to go low
flashWaitForSpecificMessage_loop1:
ldi r16, 0 ; wait for low
rcall flashWaitForAttnState1ms ; (R22, R24)
brcs flashWaitForSpecificMessage_isLow
dec r17
brne flashWaitForSpecificMessage_loop1
rjmp flash_recv_clc_ret ; timeout
; receive message
flashWaitForSpecificMessage_isLow: ; is low, receive message, check for msg type
push r17
ldi r16, COM2_MAINTENANCE_ADDR
ldi r17, FLASH_RECVBUFFER_MAXLEN-3
ldi xl, LOW(flashRecvBuffer)
ldi xh, HIGH(flashRecvBuffer)
rcall com2ReceivePacketRaw
pop r17
brcc flashWaitForSpecificMessage_waitAttnHigh
ldi xl, LOW(flashRecvBuffer)
ldi xh, HIGH(flashRecvBuffer)
adiw xh:xl, COM2_MSG_OFFS_CMD
ld r16, X
sbiw xh:xl, COM2_MSG_OFFS_CMD
cp r16, r1
breq flashWaitForSpecificMessage_received
cpi r16, CPRO_CMD_FLASH_END
breq flashWaitForSpecificMessage_received
flashWaitForSpecificMessage_waitAttnHigh:
dec r17
breq flash_recv_clc_ret
; wait for ATTN to go high
flashWaitForSpecificMessage_loop2:
ldi r16, 0xff ; wait for high
rcall flashWaitForAttnState1ms ; (R22, R24)
brcs flashWaitForSpecificMessage_isHigh
dec r17
brne flashWaitForSpecificMessage_loop2
rjmp flash_recv_clc_ret ; timeout
flashWaitForSpecificMessage_isHigh:
rjmp flashWaitForSpecificMessage_loop0
flashWaitForSpecificMessage_received: ; R16 contains message type
sec
ret
; ---------------------------------------------------------------------------
; Wait for up to 1ms for ATTN line to reach the given state
;
; IN:
; - R16: expected state (0xff for high, 0 for low)
; OUT:
; - CFLAG: set if state reached, cleared otherwise
; REGS: R24 (R22)
flashWaitForAttnState1ms:
ldi r24, 100
flashWaitForAttnState1ms_loop:
push r17
in r17, COM_PIN_ATTN
eor r17, r16
andi r17, (1<<COM_PINNUM_ATTN)
pop r17
breq flashWaitForAttnState1ms_stateReached
Utils_WaitNanoSecs 10000, 0, r22 ; wait for 10us
dec r24
brne flashWaitForAttnState1ms_loop
rjmp flash_recv_clc_ret
flashWaitForAttnState1ms_stateReached:
sec
ret
flash_recv_clc_ret:
clc
flash_recv_ret:
ret

View File

@@ -0,0 +1,62 @@
; ***************************************************************************
; copyright : (C) 2023 by Martin Preuss
; email : martin@libchipcard.de
;
; ***************************************************************************
; * This file is part of the project "AqHome". *
; * Please see toplevel file COPYING of that project for license details. *
; ***************************************************************************
; ***************************************************************************
; code
.cseg
; ---------------------------------------------------------------------------
; wait indefinately until ATTN line is high, send packet over wire, retry until successfull
;
; IN:
; - x : ptr to buffer to send
; OUT:
; - nothing
; REGS: (R16, R17, R18, R21, R22, R24, R25, X)
flashSendPacketUntilSuccess:
push xl
push xh
rcall COM2_SendPacketWithAttn ; (R16, R17, R21, R22, X)
pop xh
pop xl
brcc flashSendPacket_error
ret
flashSendPacket_error:
rcall flashWaitForAttnHigh ; (R16, R17, R18, R22, R24, R25, X)
rjmp flashSendPacketUntilSuccess
; ---------------------------------------------------------------------------
; wait indefinately for free ATTN line
;
; IN:
; - nothing
; OUT:
; - nothing
; REGS: (R16, R17, R18, R22, R24, R25, X)
flashWaitForAttnHigh:
rcall com2WaitForAttnHigh ; (r17, r22, X)
brcc flashWaitForAttnHigh_stillLow
ret
flashWaitForAttnHigh_stillLow:
rcall flashWaitDependingOnUid ; (R16, R18, R22, R24, R25)
rjmp flashWaitForAttnHigh

100
avr/modules/flash/wait.asm Normal file
View File

@@ -0,0 +1,100 @@
; ***************************************************************************
; copyright : (C) 2023 by Martin Preuss
; email : martin@libchipcard.de
;
; ***************************************************************************
; * This file is part of the project "AqHome". *
; * Please see toplevel file COPYING of that project for license details. *
; ***************************************************************************
; ***************************************************************************
; code
.cseg
; ---------------------------------------------------------------------------
; wait depending on lowest byte of uid.
;
; Wait interval is between 100ms and 25s (i.e. 255*100ms). This is used to avoid
; all nodes on the network trying to send messages at the exact same time (e.g. after
; power outage which would affect all nodes at the same time).
;
; IN:
; - nothing
; OUT:
; - nothing
; REGS: R16 (R18, R22, R24, R25)
flashWaitDependingOnUid:
lds r16, flashUid
tst r16
brne flashWaitDependingOnUid_l1
ldi r16, 17
flashWaitDependingOnUid_l1:
rjmp flashWaitForMulti100ms
; ---------------------------------------------------------------------------
; wait for multiples of 100ms.
;
; IN:
; - R16: number of 100ms loops
; OUT:
; - nothing
; REGS: R16 (R18, R22, R24, R25)
flashWaitForMulti100ms:
flashWaitForMulti100ms_loop:
rcall flashWaitFor100ms ; (R18, R22, R24, R25)
dec r16
brne flashWaitForMulti100ms_loop
ret
; ---------------------------------------------------------------------------
; wait for 100 milliseconds.
;
; IN:
; - nothing
; OUT:
; - nothing
; REGS: R18 (R22, R24, R25)
flashWaitFor100ms:
ldi r18, 100
flashWaitFor100ms_loop:
rcall flashWaitFor1ms ; (R22, R24, R25)
dec r18
brne flashWaitFor100ms_loop
ret
; ---------------------------------------------------------------------------
; wait for 1 millisecond.
;
; IN:
; - nothing
; OUT:
; - nothing
; REGS: R24 (R22)
flashWaitFor1ms:
ldi r24, 10
flashWaitFor1ms_loop:
Utils_WaitNanoSecs 100000, 0, r22 ; wait for 100us
dec r24
brne flashWaitFor1ms_loop
ret