avr: bootloader partially works now but stops after 3 messages...

This commit is contained in:
Martin Preuss
2025-01-20 23:47:13 +01:00
parent 0d7aca0060
commit 0a10d136d5
23 changed files with 398 additions and 1260 deletions

View File

@@ -3,16 +3,13 @@
<gwbuild>
<extradist>
bootloader.asm
defs.asm
flash.asm
flash_ready.asm
flash_rsp.asm
hdl_flash_data.asm
hdl_flash_end.asm
hdl_flash_start.asm
recv.asm
send.asm
flashprocess.asm
io.asm
io_attn.asm
io_bitbang.asm
io_uart1.asm
wait.asm
</extradist>

View File

@@ -1,5 +1,5 @@
This implements the boot loader. It can be used to flash new firmware to node.
This implements the boot loader. It can be used to flash new firmware to nodes.
How it works

View File

@@ -1,218 +0,0 @@
; ***************************************************************************
; 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. *
; ***************************************************************************
.equ FLASH_ERROR_NONE = 0
.equ FLASH_ERROR_MSGERROR = 1
.equ FLASH_RECVBUFFER_MAXLEN = 128
.equ FLASH_CMD_FLASH_RSP = 74
.equ FLASH_MSG_OFFS_DESTADDR = 0
.equ FLASH_MSG_OFFS_MSGLEN = 1
.equ FLASH_MSG_OFFS_MSGDATA = 2
.equ FLASH_MSG_OFFS_CMD = 2 ; first at COM2_MSG_OFFS_MSGDATA
.equ FLASH_MSG_OFFS_SRCADDR = 3
.equ FLASH_MSG_OFFS_PAYLOAD = 4 ; payload for the cmd follows here
.equ FLASH_PACKET_DATA_OFFS_ADDR = FLASH_MSG_OFFS_PAYLOAD+0 ; 4 bytes
.equ FLASH_PACKET_DATA_OFFS_DATA = FLASH_MSG_OFFS_PAYLOAD+4 ; n bytes
.equ FLASH_PACKET_START_OFFS_UID = FLASH_MSG_OFFS_PAYLOAD+0 ; 4 bytes
; ***************************************************************************
; data
.dseg
flashDataBegin:
flashUid: .byte 4
flashSendBuffer: .byte 32
flashRecvBuffer: .byte FLASH_RECVBUFFER_MAXLEN
flashDataEnd:
; ***************************************************************************
; code
.cseg
FLASH_PROTO_BEGIN:
bootLoader:
cli ; disable interrupts throughout the whole process
; setup stack
.ifdef SPH ; if SPH is defined
ldi r16, High(RAMEND)
out SPH, r16 ; init MSB stack pointer
.endif
ldi r16, Low(RAMEND)
out SPL, r16 ; init LSB stack pointer
; start by setting all ports as inputs and enable internal pull-up resistors
ldi r16, 0xff
clr r17
.ifdef PORTA
out DDRA, r17 ; all input
out PORTA, r16 ; enable pull-up on all
.endif
.ifdef PORTB
out DDRB, r17 ; all input
out PORTB, r16 ; enable pull-up on all
.endif
.ifdef PORTC
out DDRC, r17 ; all input
out PORTC, r16 ; enable pull-up on all
.endif
; rcall watchdogOff ; turn off watchdog timer (sometimes it stays on after reboot)
; setup pins and interrupts
cbi COM_DATA_DDR, COM_DATA_PIN ; set TXD port as input
cbi COM_DATA_OUTPUT, COM_DATA_PIN ; disable internal pullup for TXD
cbi COM_ATTN_DDR, COM_ATTN_PIN ; set ATTN port as input
cbi COM_ATTN_OUTPUT, COM_ATTN_PIN ; disable internal pullup for ATTN
sbi LED_DDR, LED_PINNUM ; out
cbi LED_PORT, LED_PINNUM ; on
rcall flashReadUid
ldi xh, HIGH(flashUid)
ldi xl, LOW(flashUid)
st X+, r18
st X+, r19
st X+, r20
st X+, r21
; wait for 3 secs before doing anything else
ldi r16, 30
rcall flashWaitForMulti100ms
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
bootLoader_startFirmware:
cbi LED_PORT, LED_PINNUM ; on
ldi r16, 10
rcall flashWaitForMulti100ms
sbi LED_PORT, LED_PINNUM ; off
ldi r16, 3
rcall flashWaitForMulti100ms
cbi LED_PORT, LED_PINNUM ; on
ldi r16, 10
rcall flashWaitForMulti100ms
sbi LED_PORT, LED_PINNUM ; off
rjmp firmwareStart
bootLoader_waitAndRestartBootLoader:
sbi LED_PORT, LED_PINNUM ; off
ldi r16, 20
rcall flashWaitForMulti100ms
rjmp bootLoader
; ---------------------------------------------------------------------------
; 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, Y, (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, Y, 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:
bootLoaderFlash_loop1:
; wait up to 10s for incoming FLASH_DATA message
ldi r16, CPRO_CMD_FLASH_DATA
ldi r17, 100 ; 100*100ms=10s
rcall flashWaitForSpecificMessageWithLed
brcc bootRet
; either FLASH_DATA or FLASH_END received
cpi r16, CPRO_CMD_FLASH_DATA ; not FLASH_DATA, flashing ended/aborted
brne bootSecRet ; FLASH_END received, done
; flash data
rcall flashHandleFlashData
rjmp bootLoaderFlash_loop1
bootLoaderFlash_endReceived:
rjmp flashHandleFlashEnd
bootClcRet:
clc
bootRet:
ret
bootSecRet:
sec
ret
FLASH_PROTO_END:
.equ MODULE_SIZE_FLASH_PROTO = FLASH_PROTO_END-FLASH_PROTO_BEGIN

View File

@@ -1,81 +0,0 @@
; ***************************************************************************
; copyright : (C) 2025 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. *
; ***************************************************************************
; ***************************************************************************
; data
.dseg
flashDataBegin:
flashUid: .byte 4
flashSendBuffer: .byte 32
flashRecvBuffer: .byte FLASH_RECVBUFFER_MAXLEN
flashDataEnd:
; ***************************************************************************
; code
.cseg
FLASH_PROTO_BEGIN:
bootLoader:
; rcall watchdogOff ; turn off watchdog timer (sometimes it stays on after reboot)
sbi LED_DDR, LED_PINNUM ; out
cbi LED_PORT, LED_PINNUM ; on
ldi r16, 30
rcall flashWaitForMulti100ms
rcall flashReadUidIntoSdram ; R16, X, Y
rcall checkFlash ; (r16, r17, r18, r19, r20, r22, x, y, z)
brcc bootLoader_startFirmware ; no flash process, try to start installed firmware
rcall flashProcess ; received a FLASH START msg, handle flashing
brcc bootLoader_waitAndRestartBootLoader
; try to start firmware
bootLoader_startFirmware:
cbi LED_PORT, LED_PINNUM ; on
rjmp firmwareStart
bootLoader_waitAndRestartBootLoader:
sbi LED_PORT, LED_PINNUM ; off
ldi r16, 20
rcall flashWaitForMulti100ms
rjmp bootLoader
bootClcRet:
clc
bootRet:
ret
bootSecRet:
sec
ret
FLASH_PROTO_END:
.equ MODULE_SIZE_FLASH_PROTO = FLASH_PROTO_END-FLASH_PROTO_BEGIN

View File

@@ -1,61 +0,0 @@
; ***************************************************************************
; 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, R18, Y, Z (R17, R19, R20)
flashWriteFlashReady:
ldi r16, 0xff
st X+, r16 ; dest address (unused)
ldi r16, 20 ; msg code+src address+18 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
; payload
ldi yh, HIGH(flashUid) ; 4 bytes
ldi yl, LOW(flashUid)
ldi r18, 4
rcall Utils_Copy_SDRAM ; (R17, R18, X, Y)
ldi zl, LOW(devInfoBlock*2) ; 12 bytes
ldi zh, HIGH(devInfoBlock*2)
ldi r18, 12
rcall Utils_CopyFromFlash ; (R16, R18, X, Z)
ldi r16, LOW(PAGESIZE*2) ; 2 bytes
st X+, r16
ldi r16, HIGH(PAGESIZE*2)
st X+, r16
sbiw xh:xl, 22 ; go back to beginning of message
rcall com2CalcAndAddChecksumByte ; (R16, R17, R18, R19, R20, X)
sbiw xh:xl, 23 ; go back to beginning of message
ret

View File

@@ -1,66 +0,0 @@
; ***************************************************************************
; 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
#if 0
; ---------------------------------------------------------------------------
; 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)
rcall flashWriteFlashRsp ; (R16, R17, R18, R19, R20)
rjmp flashSendPacketUntilSuccess ; (R15, R16, R17, R21, R22, X)
#endif
; ---------------------------------------------------------------------------
; 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, 5
rcall com2CalcAndAddChecksumByte ; (R16, R17, R18, R19, R20, X)
sbiw xh:xl, 6
ret

View File

@@ -9,6 +9,22 @@
; ***************************************************************************
; data
.dseg
flashDataBegin:
flashUid: .byte 4
flashSendBuffer: .byte 32
flashRecvBuffer: .byte FLASH_RECVBUFFER_MAXLEN
flashDataEnd:
; ***************************************************************************
; code
.cseg
@@ -23,15 +39,16 @@
; @clobbers r16, r20, X, (r17, r18, r19, r22, y, z)
checkFlash:
rcall flashInitIo ; (R16, R17)
rcall flashReadUidIntoSdram ; R16, X, Y
rcall ioRawInit ; (R16, R17)
ldi xl, LOW(flashSendBuffer)
ldi xh, HIGH(flashSendBuffer)
rcall flashProcessWriteFlashReady ; (R16, R17, R18, R19, R20, Y, Z)
rcall flashRawSendMsg ; (r16, r17, X)
rcall ioRawSendMsg ; (r16, r17, X)
ldi r16, CPRO_CMD_FLASH_START
ldi r20, 10 ; wait for up to 10s
rcall flashWaitForGivenMsg ; (r16, r17, r18, r19, r20, r22, X)
rcall ioWaitForGivenMsg ; (r16, r17, r18, r19, r20, r22, X)
brcc checkFlash_end
cpi r16, CPRO_CMD_FLASH_START
@@ -66,8 +83,8 @@ flashProcess:
flashProcess_loop1:
; wait up to 10s for incoming FLASH_DATA message
ldi r16, CPRO_CMD_FLASH_DATA
ldi r20, 5 ; wait for 5s
rcall flashWaitForGivenMsg ; (r16, r17, r18, r19, r20, r22, X)
ldi r20, 5 ; wait for 5s (not used!)
rcall ioWaitForGivenMsg ; (r16, r17, r18, r19, r20, r22, X)
brcc flashProcess_end ; no FLASH_DATA or FLASH_END msg
; either FLASH_DATA or FLASH_END received
ldi xl, LOW(flashRecvBuffer)
@@ -156,17 +173,17 @@ flashProcessHandleFlashData:
ld zh, X+ ; address (high)
adiw xh:xl, 2 ; ignore high bytes, points to first data byte now
push zl
push zh
flashProcessHandleFlashData_loop:
ld r0, X+
ld r1, X+
rcall Flash_WriteIntoPage ; (R15, R16, Z+)
subi r18, 2
brne flashProcessHandleFlashData_loop
pop zh
pop zl
rcall Flash_FinishPage ; (R15, R16, R20)
; push zl
; push zh
;flashProcessHandleFlashData_loop:
; ld r0, X+
; ld r1, X+
; rcall Flash_WriteIntoPage ; (R15, R16, Z+)
; subi r18, 2
; brne flashProcessHandleFlashData_loop
; pop zh
; pop zl
; rcall Flash_FinishPage ; (R15, R16, R20)
clr r16
rjmp flashProcessHandleFlashData_sendResponse
flashProcessHandleFlashData_badData:
@@ -210,7 +227,7 @@ flashProcessSendFlashResponse:
ldi xl, LOW(flashSendBuffer)
ldi xh, HIGH(flashSendBuffer)
rcall flashProcessWriteFlashRsp ; (R16, R17, R18, R19, R20, X)
rjmp flashRawSendMsg ; (R16, R17, X)
rjmp ioRawSendMsg ; (R16, R17, X)
; @end

View File

@@ -1,62 +0,0 @@
; ***************************************************************************
; 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

@@ -1,38 +0,0 @@
; ***************************************************************************
; 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 END 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)
flashHandleFlashEnd:
rcall flashWaitFor100ms
clr r16
rcall flashSendFlashResponse ; (R15, R16, R17, R18, R19, R20, R21, R22, X)
sec
ret

View File

@@ -1,73 +0,0 @@
; ***************************************************************************
; 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
; ---------------------------------------------------------------------------
; @routine flashHandleFlashStart
; Handle FLASH START packet.
;
; @return CFLAG set if message is for us, cleared otherwise
; @param X buffer containing the message
; @clobbers r16, (R15, R17, R18, R19, R20, R21, R22, X)
flashHandleFlashStart:
rcall flashCheckFlashStart
brcc flashHandleFlashStart_notMe
; okay, flash start message is for us
rcall flashWaitFor100ms
clr r16
rcall flashSendFlashResponse ; (R15, R16, R17, R18, R19, R20, R21, R22, X)
sec
ret
flashHandleFlashStart_notMe:
ret
; @end
; ---------------------------------------------------------------------------
; @routine flashCheckFlashStart
;
; Check whether the UID in the given msg matches our UID.
;
; @return CFLAG set if message is for us, cleared otherwise
; @param X buffer containing the message
; @clobbers r16, r17, r18, X, Y
flashCheckFlashStart:
ldi yh, HIGH(flashUid)
ldi yl, LOW(flashUid)
adiw xh:xl, FLASH_PACKET_START_OFFS_UID
ldi r18, 4
flashCheckFlashStart_loop:
ld r16, X+
ld r17, Y+
cp r16, r17
brne flashCheckFlashStart_notMe
dec r18
brne flashCheckFlashStart_loop
sec
ret
flashCheckFlashStart_notMe:
clc
ret
; @end

View File

@@ -16,7 +16,7 @@
; ---------------------------------------------------------------------------
; @routine flashWaitForGivenMsg
; @routine ioWaitForGivenMsg
; Wait for incoming msg with given command
;
; @return CFLAG set if okay (packet received), cleared on error
@@ -25,28 +25,28 @@
; @param r20 time in seconds to wait for a message
; @clobbers: r16, r17, r20, X (r18, r19, r22)
flashWaitForGivenMsg:
flashWaitForGivenMsg_loop:
ioWaitForGivenMsg:
ioWaitForGivenMsg_loop:
push r16
rcall flashRawWaitForValidMsg ; (r16, r17, r18, r19, r22, X)
rcall ioRawWaitForValidMsg ; (r16, r17, r18, r19, r22, X)
pop r16
brcc flashWaitForGivenMsg_end
brcc ioWaitForGivenMsg_end
ldi xl, LOW(flashRecvBuffer)
ldi xh, HIGH(flashRecvBuffer)
adiw xh:xl, COM2_MSG_OFFS_CMD
ld r17, X
sbiw xh:xl, COM2_MSG_OFFS_CMD
cp r16, r17
breq flashWaitForGivenMsg_gotIt
breq ioWaitForGivenMsg_gotIt
cpi r16, CPRO_CMD_FLASH_END
breq flashWaitForGivenMsg_gotIt
breq ioWaitForGivenMsg_gotIt
dec r20
brne flashWaitForGivenMsg_loop
brne ioWaitForGivenMsg_loop
clc
rjmp flashWaitForGivenMsg_end
flashWaitForGivenMsg_gotIt:
rjmp ioWaitForGivenMsg_end
ioWaitForGivenMsg_gotIt:
sec
flashWaitForGivenMsg_end:
ioWaitForGivenMsg_end:
ret
; @end

View File

@@ -16,28 +16,52 @@
; ---------------------------------------------------------------------------
; @routine flashWaitForAttnState
; @routine ioWaitForAttnState100ms
;
; @param r16 expected state (0x00 or 0xff)
; @param r17 time to wait for expected state (in milliseconds)
; @clobbers
; @param r17 time to wait for expected state (in 100 ms units)
; @clobbers R17 (R22, R24)
flashWaitForAttnState:
flashWaitForAttnState_loop:
rcall flashWaitForAttnState1ms ; (R22, R24)
brcs flashWaitForAttnState_stateReached
ioWaitForAttnState100ms:
ioWaitForAttnState100ms_loop:
push r17
ldi r17, 100
rcall ioWaitForAttnStateMilliSeconds ; (R22, R24)
pop r17
brcs ioWaitForAttnState100ms_stateReached
dec r17
brne flashWaitForAttnState_loop
brne ioWaitForAttnState100ms_loop
clc
ret
flashWaitForAttnState_stateReached:
ioWaitForAttnState100ms_stateReached:
ret
; @end
; ---------------------------------------------------------------------------
; @routine flashWaitForAttnState1ms
; @routine ioWaitForAttnStateMilliSeconds
;
; @param r16 expected state (0x00 or 0xff)
; @param r17 time to wait for expected state (in milliseconds)
; @clobbers R17 (R22, R24)
ioWaitForAttnStateMilliSeconds:
ioWaitForAttnStateMilliSeconds_loop:
rcall ioWaitForAttnState1ms ; (R22, R24)
brcs ioWaitForAttnStateMilliSeconds_stateReached
dec r17
brne ioWaitForAttnStateMilliSeconds_loop
clc
ret
ioWaitForAttnStateMilliSeconds_stateReached:
ret
; @end
; ---------------------------------------------------------------------------
; @routine ioWaitForAttnState1ms
;
; Wait for up to 1ms for ATTN line to reach the given state
;
@@ -45,22 +69,23 @@ flashWaitForAttnState_stateReached:
; @param R16 expected state (0xff for high, 0 for low)
; @clobbers R24 (R22)
flashWaitForAttnState1ms:
ioWaitForAttnState1ms:
cbi COM_ATTN_DDR, COM_ATTN_PIN ; set ATTN port as input
cbi COM_ATTN_OUTPUT, COM_ATTN_PIN ; disable internal pullup for ATTN
ldi r24, 100
flashWaitForAttnState1ms_loop:
ioWaitForAttnState1ms_loop:
push r17
in r17, COM_ATTN_INPUT
eor r17, r16
andi r17, (1<<COM_ATTN_PIN)
pop r17
breq flashWaitForAttnState1ms_stateReached
breq ioWaitForAttnState1ms_stateReached
rcall Utils_WaitFor10MicroSecs ; wait for 10us (R22)
dec r24
brne flashWaitForAttnState1ms_loop
rjmp flash_recv_clc_ret
flashWaitForAttnState1ms_stateReached:
brne ioWaitForAttnState1ms_loop
clc
ret
ioWaitForAttnState1ms_stateReached:
sec
ret
; @end

View File

@@ -0,0 +1,87 @@
; ***************************************************************************
; copyright : (C) 2025 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
; ---------------------------------------------------------------------------
; @routine ioRawInit
; Init raw message subsystem.
;
; @clobbers none
ioRawInit:
; setup pins and interrupts
cbi COM_DATA_DDR, COM_DATA_PIN ; set DATA port as input
cbi COM_DATA_OUTPUT, COM_DATA_PIN ; disable internal pullup for TXD
cbi COM_ATTN_DDR, COM_ATTN_PIN ; set ATTN port as input
cbi COM_ATTN_OUTPUT, COM_ATTN_PIN ; disable internal pullup for ATTN
ret
;@end
; ---------------------------------------------------------------------------
; @routine ioRawSendMsg
; Send a message
;
; @clobbers X (R16, R17, R21, R22)
ioRawSendMsg:
ioRawSendMsg_loop:
ldi r16, 0xff ; expect ATTN high
ldi r17, 3
rcall ioWaitForAttnState100ms ; wait for up to 300ms
brcs ioRawSendMsg_attnHigh
ret
ioRawSendMsg_attnHigh:
ldi xl, LOW(flashSendBuffer)
ldi xh, HIGH(flashSendBuffer)
rcall uartBitbang_SendPacket ; R16, R22 (R17, R21, X)
brcc ioRawSendMsg_loop
ret
; @end
; ---------------------------------------------------------------------------
; @routine ioRawWaitForValidMsg
; Wait for valid incoming msg
;
; @return CFLAG set if okay (packet received), cleared on error
; @clobbers:
ioRawWaitForValidMsg:
ldi r16, 0 ; expect ATTN low
ldi r17, 100
rcall ioWaitForAttnState100ms ; wait for up to 10s
brcs ioRawWaitForValidMsg_attnLow
ret
ioRawWaitForValidMsg_attnLow:
ldi xl, LOW(flashRecvBuffer)
ldi xh, HIGH(flashRecvBuffer)
ldi r16, COM2_MAINTENANCE_ADDR
ldi r17, FLASH_RECVBUFFER_MAXLEN-3
rcall uartBitbang_ReceivePacketIntoBuffer
brcs ioRawWaitForValidMsg_packetReceived
ret
ioRawWaitForValidMsg_packetReceived:
ldi r16, 0xff ; expect ATTN high
ldi r17, 100
rjmp ioWaitForAttnState100ms ; wait for up to 10s
; @end

View File

@@ -17,24 +17,24 @@
; ---------------------------------------------------------------------------
; @routine flashInitIo
; @routine ioRawInit
; Send a message
;
; @clobbers r16, r17
flashInitIo:
ioRawInit:
rjmp UART_HW_Uart1_RawInit ; (R16, R17)
;@end
; ---------------------------------------------------------------------------
; @routine flashRawSendMsg
; @routine ioRawSendMsg
; Send a message
;
; @clobbers r16, r17, X
flashRawSendMsg:
ioRawSendMsg:
ldi xl, LOW(flashSendBuffer)
ldi xh, HIGH(flashSendBuffer)
rjmp UART_HW_Uart1_RawSendPacket ; (r16, r17, X)
@@ -43,28 +43,30 @@ flashRawSendMsg:
; ---------------------------------------------------------------------------
; @routine flashRawWaitForValidMsg
; @routine ioRawWaitForValidMsg
; Wait for valid incoming msg
;
; @return CFLAG set if okay (packet received), cleared on error
; @clobbers: r16, r17, r18 (r19, r22, X)
flashRawWaitForValidMsg:
ioRawWaitForValidMsg:
rcall UART_HW_Uart1_EnableRawRecv ; (R16)
flashRawWaitForValidMsg_loop:
ioRawWaitForValidMsg_loop:
ldi xl, LOW(flashRecvBuffer)
ldi xh, HIGH(flashRecvBuffer)
ldi r16, COM2_MAINTENANCE_ADDR
ldi r17, FLASH_RECVBUFFER_MAXLEN-3
ldi r18, 10 ; 10s
rcall UART_HW_Uart1_RawRecvPacket ; (r16, r17, r18, r19, r22, X)
brcc flashRawWaitForValidMsg_error
brcc ioRawWaitForValidMsg_error
ldi xl, LOW(flashRecvBuffer)
ldi xh, HIGH(flashRecvBuffer)
rcall com2CheckMessageInBuffer ; (R16, R17, R18, R19, R20, X)
brcc flashRawWaitForValidMsg_loop ; invalid msg, try next
brcc ioRawWaitForValidMsg_loop ; invalid msg, try next
rcall UART_HW_Uart1_DisableRawRecv ; (R16)
sec
ret
flashRawWaitForValidMsg_error:
ioRawWaitForValidMsg_error:
rcall UART_HW_Uart1_DisableRawRecv ; (R16)
clc
ret

View File

@@ -1,123 +0,0 @@
; ***************************************************************************
; 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 LED_PORT, LED_PINNUM ; off
flashWaitForSpecificMessageWithLed_loop:
sbi LED_PIN, LED_PINNUM ; toggle
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 LED_PORT, LED_PINNUM ; off
rjmp flash_recv_clc_ret ; timeout
flashWaitForSpecificMessageWithLed_received:
sbi LED_PORT, LED_PINNUM ; off
rjmp flash_recv_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 uartBitbang_ReceivePacketIntoBuffer
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
rjmp flash_recv_sec_ret
flash_recv_clc_ret:
clc
ret
flash_recv_sec_ret:
sec
ret

View File

@@ -1,65 +0,0 @@
; ***************************************************************************
; 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 uartBitbang_SendPacket ; (R16, R17, R21, R22, X)
pop xh
pop xl
brcc flashSendPacket_error
ret
flashSendPacket_error:
ldi r16, 3
rcall flashWaitForMulti100ms
rcall flashWaitForAttnHigh ; (R16, R17, R18, R22, R24, R25)
rjmp flashSendPacketUntilSuccess
; ---------------------------------------------------------------------------
; wait indefinately for free ATTN line
;
; IN:
; - nothing
; OUT:
; - nothing
; REGS: (R16, R17, R18, R22, R24, R25)
flashWaitForAttnHigh:
rcall uartBitbang_WaitForAttnHigh ; (r17, r22)
brcc flashWaitForAttnHigh_stillLow
ret
flashWaitForAttnHigh_stillLow:
rcall flashWaitDependingOnUid ; (R16, R18, R22, R24, R25)
rjmp flashWaitForAttnHigh