avr: started reworking COM module.

- sending and receiving now basically works again, but too often the
  read buffer is in use when trying to receive a message.
This commit is contained in:
Martin Preuss
2023-04-12 15:30:38 +02:00
parent 0feceeb96e
commit 024d40fc95
21 changed files with 1816 additions and 1926 deletions

View File

@@ -53,6 +53,32 @@
; 4) Otherwise the node changes into protocol A (see above).
#ifdef MODULES_COM_WITH_ADDR_PROTO
; ***************************************************************************
; defs
; ***************************************************************************
; data
.dseg
cproAddressDataBegin:
cproAddressFlags: .byte 1
cproAddresModeTimer: .byte 2
cproAddrRangeBegin: .byte 1
cproAddrRangeEnd: .byte 1
cproAddressWaitCounter: .byte 1 ; counter for seconds to wait for all nodes to respond
cproUsedAddresses: .byte 16 ; one bit per address known to b in use
cproAddressDataEnd:
; ***************************************************************************
@@ -62,6 +88,23 @@
CPRO_Address_Init:
ldi xh, HIGH(cproAddressDataBegin)
ldi xl, LOW(cproAddressDataBegin)
clr r16
ldi r17, (cproAddressDataEnd-cproAddressDataBegin)
rcall Utils_FillSram
; setup timer for address setup (after 10s)
ldi r16, CPRO_MODE_NOADDRESS
sts cproMode, r16
ldi r18, 10
ldi r19, 0
rcall cproAddressSetTimer
ret
CPRO_StartReclaimAddrProcedure:
ldi xl, LOW(EEPROM_OFFS_COMADDR)
ldi xh, HIGH(EEPROM_OFFS_COMADDR)
@@ -73,12 +116,9 @@ CPRO_StartReclaimAddrProcedure:
cpi r16, 0xff
breq CPRO_StartReclaimAddrProcedure_l1
sts cproAddrRangeBegin, r16 ; currently claimed address
mov r19, r16
rcall CPRO_EnqueueClaimAddress
ldi r16, CPRO_WAITTIME_RECLAIMADDR
sts cproAddressWaitCounter, r16
ldi r16, CPRO_MODE_RECLAIMING_ADDR
ldi r16, CPRO_MODE_SEND_RECLAIM_ADDR
sts cproMode, r16
rcall cproAddressSetTimer1s ; use singleshot timer, send after 1s
sec
ret
CPRO_StartReclaimAddrProcedure_l1:
@@ -99,197 +139,10 @@ CPRO_StartGetAddrProcedure:
sts cproAddrRangeBegin, r16
ldi r16, 126
sts cproAddrRangeEnd, r16
; send "NEED_ADDRESS" packet
rcall CPRO_EnqueueNeedAddress
brcc CPRO_StartGetAddrProcedure_error
; set waittimer for sampling of "HAVE_ADDRESS" packets
ldi r16, CPRO_WAITTIME_GETADDR
sts cproAddressWaitCounter, r16
ldi r16, CPRO_MODE_GETADDRSTARTED
; setup singleshot timer to later send "NEED_ADDRESS" packet
ldi r16, CPRO_MODE_SEND_NEED_ADDR
sts cproMode, r16
sec
ret
CPRO_StartGetAddrProcedure_error:
clc
ret
; ***************************************************************************
; onEverySecond handlers
cproHandle1sSendingHaveAddress:
; waiting for counter to reach zero to send a HAVE_ADDRESS packet
lds r16, cproAddressWaitCounter
dec r16
sts cproAddressWaitCounter, r16
brne cproHandle1sSendingHaveAddress_done ; counter not 0, done for now
rcall CPRO_EnqueueHaveAddress ; counter is 0, send HAVE_ADDRESS
ldi r16, CPRO_MODE_NORMAL
sts cproMode, r16
cproHandle1sSendingHaveAddress_done:
ret
cproHandle1sGetAddrStarted:
lds r16, cproAddressWaitCounter
dec r16
sts cproAddressWaitCounter, r16
brne cproHandle1sGetAddrStarted_done ; counter not 0, done for now
rcall cproClaimFirstFreeAddr ; counter 0, find first free address and claim it
brcs cproHandle1sGetAddrStarted_done
; no free address, abort TODO: send an error message to bus ("bus full")
ldi r16, CPRO_MODE_NORMAL
sts cproMode, r16
cproHandle1sGetAddrStarted_done:
ret
cproHandle1sClaimingAddr12:
lds r16, cproAddressWaitCounter
dec r16
sts cproAddressWaitCounter, r16
brne cproHandle1sClaimingAddr12_done ; counter not 0, done for now
push r17
lds r19, cproAddrRangeBegin ; currently claimed address
rcall CPRO_EnqueueClaimAddress
pop r17
ldi r16, CPRO_WAITTIME_CLAIMADDR
sts cproAddressWaitCounter, r16
inc r17 ; next mode (CPRO_MODE_CLAIMING_ADDR1 and 2)
sts cproMode, r17
cproHandle1sClaimingAddr12_done:
ret
cproHandle1sClaimingAddr3:
lds r16, cproAddressWaitCounter
dec r16
sts cproAddressWaitCounter, r16
brne cproHandle1sClaimingAddr3_done ; counter not 0, done for now
; claimed given address 3rd time, set address and enter "normal" mode
lds r16, cproAddrRangeBegin ; currently sent address is in cproAddrRangeBegin
in r15, SREG
cli
sts comAddress, r16 ; write address into eeprom
ldi xl, LOW(EEPROM_OFFS_COMADDR)
ldi xh, HIGH(EEPROM_OFFS_COMADDR)
rcall Utils_WriteEepromIncr ; write address to EEPROM
ldi r16, CPRO_MODE_NORMAL ; set mode to "normal"
sts cproMode, r16
rcall CPRO_EnqueueHaveAddress
out SREG, r15
cproHandle1sClaimingAddr3_done:
ret
cproHandle1sReclaimingAddr:
lds r16, cproAddressWaitCounter
dec r16
sts cproAddressWaitCounter, r16
brne cproHandle1sReclaimingAddr_done ; counter not 0, done for now
; successfully claimed given address, set address and enter "normal" mode
lds r16, cproAddrRangeBegin ; currently sent address is in cproAddrRangeBegin
sts comAddress, r16 ; write address into eeprom
ldi r16, CPRO_MODE_NORMAL ; set mode to "normal"
sts cproMode, r16
rcall CPRO_EnqueueHaveAddress
cproHandle1sReclaimingAddr_done:
ret
; ***************************************************************************
; onPacketReceived handlers
cproHandlePckNeedAddr:
lds r17, cproMode
cpi r17, CPRO_MODE_NORMAL
brne cproHandlePckNeedAddr_done
; enter CPRO_MODE_SENDING_HAVE_ADDRESS mode
lds r16, comAddress
tst r16
breq cproHandlePckNeedAddr_done ; we have no address, don't handle
rcall cproEnterSendingHaveAddressMode
cproHandlePckNeedAddr_done:
sec
ret
cproHandlePckHaveAddr:
lds r17, cproMode
cpi r17, CPRO_MODE_GETADDRSTARTED
brne cproHandlePckHaveAddr_done
; validate address
ldd r16, y+(COM_BUFFER_OFFS_DATA+CPRO_PACKET_HAVEADDR_OFFS_ADDRESS)
tst r16
breq cproHandlePckHaveAddr_done ; invalid address, ignore
cpi r16, 127
brcc cproHandlePckHaveAddr_done ; invalid address, ignore
; set bit corresponding to given address in bitfield of used addresses
dec r16
rcall cproSetBitInBitfield
cproHandlePckHaveAddr_done:
sec
ret
cproHandlePckClaimAddr:
ldd r16, y+(COM_BUFFER_OFFS_DATA+CPRO_PACKET_CLAIMADDR_OFFS_ADDRESS)
tst r16
breq cproHandlePckClaimAddr_done
cpi r16, 0xff
breq cproHandlePckClaimAddr_done
lds r17, comAddress
cp r16, r17
brne cproHandlePckClaimAddr_done
rcall CPRO_EnqueueDenyAddress
cproHandlePckClaimAddr_done:
sec
ret
cproHandleDenyAddr:
; first check address
ldd r16, y+(COM_BUFFER_OFFS_DATA+CPRO_PACKET_DENYADDR_OFFS_ADDRESS)
lds r17, cproAddrRangeBegin
cp r16, r17
brne cproHandleDenyAddr_done ; not our currently claimed address, ignore
; then check mode
lds r17, cproMode
cpi r17, CPRO_MODE_CLAIMING_ADDR1
brcs cproHandleDenyAddr_l1
cpi r17, CPRO_MODE_CLAIMING_ADDR3+1
brcc cproHandleDenyAddr_l1
; we are in one of the three CLAIM_ADDRESS modes
rcall cproClaimNextFreeAddr ; claim next free address
brcs cproHandleDenyAddr_done
; no free address, abort TODO: send an error message to bus ("bus full")
ldi r16, CPRO_MODE_NORMAL
sts cproMode, r16
rjmp cproHandleDenyAddr_done
cproHandleDenyAddr_l1:
lds r17, cproMode
cpi r17, CPRO_MODE_RECLAIMING_ADDR
brne cproHandleDenyAddr_done
; reclaiming went wrong, go through full address assignment protocol
rcall CPRO_StartGetAddrProcedure
rjmp cproHandleDenyAddr_done
cproHandleDenyAddr_done:
rcall cproAddressSetTimer1s
sec
ret
@@ -297,40 +150,57 @@ cproHandleDenyAddr_done:
; REGS: r18, r19
;
cproAddressSetTimer1s:
ldi r18, 1
ldi r19, 0
rjmp cproAddressSetTimer
cproClaimFirstFreeAddr:
rjmp cproFindAndClaimFreeAddr
cproClaimNextFreeAddr:
lds r16, cproAddrRangeBegin
inc r16
sts cproAddrRangeBegin, r16
rjmp cproFindAndClaimFreeAddr
; IN:
; - R16: address to claim
; - r18: timer value (low)
; - r19: timer value (high)
; REGS: none
cproFindAndClaimFreeAddr:
cproAddressSetTimer:
push r15
in r15, SREG
cli
sts cproAddresModeTimer, r18
sts cproAddresModeTimer+1, r19
out SREG, r15
pop r15
ret
cproGetFirstFreeAddr:
rjmp cproGetFreeAddr
cproGetNextFreeAddr:
lds r16, cproAddrRangeBegin
inc r16
sts cproAddrRangeBegin, r16
rjmp cproGetFreeAddr
cproGetFreeAddr:
lds r16, cproAddrRangeBegin
lds r17, cproAddrRangeEnd
cp r16, r17
brge cproFindAndClaimFreeAddr_error
brge cproGetFreeAddr_error
rcall cproFindFreeAddr
brcc cproFindAndClaimFreeAddr_error
lds r19, cproAddrRangeBegin ; currently claimed address
rcall CPRO_EnqueueClaimAddress
ldi r16, CPRO_WAITTIME_CLAIMADDR
sts cproAddressWaitCounter, r16
ldi r16, CPRO_MODE_CLAIMING_ADDR1
sts cproMode, r16
brcc cproGetFreeAddr_error
sec
ret
cproFindAndClaimFreeAddr_error:
cproGetFreeAddr_error:
clc
ret
@@ -347,16 +217,6 @@ cproHandleAddrRange: ; not handled for now
cproEnterSendingHaveAddressMode:
ldi r17, 3
add r16, r17
sts cproAddressWaitCounter, r16 ; set counter to own address
ldi r16, CPRO_MODE_SENDING_HAVE_ADDRESS
sts cproMode, r16
ret
; ---------------------------------------------------------------------------
; cproFindFreeAddr
;
@@ -374,7 +234,7 @@ cproFindFreeAddr:
ldi xh, HIGH(cproUsedAddresses)
lds r16, cproAddrRangeBegin
dec r16
rcall CPRO_GetPosAndMaskInBitField ; r1=bit pos, r2=mask (r1, r2, r17, Z)
rcall cproGetPosAndMaskInBitField ; r1=bit pos, r2=mask (r1, r2, r17, Z)
clr r17
add xl, r1
adc xh, r17 ; X: pointer to byte
@@ -427,7 +287,7 @@ cproFindFreeAddr_allFull:
cproSetBitInBitfield:
; set bit corresponding to given address in bitfield of used addresses
rcall CPRO_GetPosAndMaskInBitField ; get offset into R1, mask into R2 (r1, r2, r17, Z)
rcall cproGetPosAndMaskInBitField ; get offset into R1, mask into R2 (r1, r2, r17, Z)
ldi xl, LOW(cproUsedAddresses)
ldi xh, HIGH(cproUsedAddresses)
clr r17
@@ -440,105 +300,6 @@ cproSetBitInBitfield:
; ---------------------------------------------------------------------------
; Enqueue a NEEDADDRESS packet.
;
; IN:
; - nothing
; OUT:
; - CFLAG: set if okay, clear otherwise
; MODIFIED REGS: R18 (R3, R4, R15, R16, R17, R20, R21, X, Y (R18, R19)
CPRO_EnqueueNeedAddress:
ldi r18, CPRO_CMD_NEED_ADDRESS
rjmp cproEnqueueAddressPacket
; ---------------------------------------------------------------------------
; Enqueue a HAVE_ADDRESS packet.
;
; IN:
; - nothing
; OUT:
; - CFLAG: set if okay, clear otherwise
; MODIFIED REGS: R18 (R3, R4, R15, R16, R17, R18, R19, R20, R21, X, Y)
CPRO_EnqueueHaveAddress:
ldi r18, CPRO_CMD_HAVE_ADDRESS
lds r19, comAddress
rjmp cproEnqueueAddressPacket
; ---------------------------------------------------------------------------
; Enqueue a CLAIM_ADDRESS packet.
;
; IN:
; - R19: claimed address
; OUT:
; - CFLAG: set if okay, clear otherwise
; MODIFIED REGS: R18 (R3, R4, R15, R16, R17, R18, R19, R20, R21, X, Y)
CPRO_EnqueueClaimAddress:
ldi r18, CPRO_CMD_CLAIM_ADDRESS
rjmp cproEnqueueAddressPacket
; ---------------------------------------------------------------------------
; Enqueue a DENY_ADDRESS packet.
;
; IN:
; - nothing
; OUT:
; - CFLAG: set if okay, clear otherwise
; MODIFIED REGS: R18, R19 (R3, R4, R15, R16, R17, R20, R21, X, Y)
CPRO_EnqueueDenyAddress:
ldi r18, CPRO_CMD_DENY_ADDRESS
lds r19, comAddress
rjmp cproEnqueueAddressPacket
; ---------------------------------------------------------------------------
; cproEnqueueAddressPacket
; Enqueue a NEED/HAVE/CLAIM ADDRESS packet.
;
; IN:
; - R18: command (either CPRO_CMD_NEED_ADDRESS, CPRO_CMD_HAVE_ADDRESS or CPRO_CMD_CLAIM_ADDRESS)
; - R19: address to send (claim, have)
; OUT:
; - CFLAG: set if okay, clear otherwise
; MODIFIED REGS: R16, R17, R20, R21, X, Y (R3, R4, R15, R16, R17, R18, R19, R21, X)
cproEnqueueAddressPacket:
mov r6, r19
rcall COM_AllocBufferAndGetXY ; (r16, r17, r21)
brcc cproEnqueueAddressPacket_error
ldi r16, 0xff
ldi r17, CPRO_PAYLOAD_FLAGS_UID | (1<<CPRO_PAYLOAD_FLAGS_SHIFT_NUM)
push xh
push xl
rcall cproBeginMsgWithVariablePayload ; (R3, R4, R16, R17, R18, R19, R20, R21, X)
st X+, r6 ; 5: value id
pop xl
pop xh
rcall comCalcAndAddChecksumByte ; (R16, R17, R18, R19, X)
; mark buffer as enqueued with PRIO "important" (higher retry count)
ldi r20, COM_BUFFER_PRIO_IMPORTANT
rcall COM_EnqueuePacket ; (R15, R16)
brcc cproEnqueueAddressPacket_error
sec
ret
cproEnqueueAddressPacket_error:
clc
ret
; ---------------------------------------------------------------------------
; Get offset and mask for a given bit in a bitfield
; IN:
@@ -548,7 +309,7 @@ cproEnqueueAddressPacket_error:
; - R2: mask for given id (apply to r1)
; USED REGISTERS: r1, r2, r17, Z
CPRO_GetPosAndMaskInBitField:
cproGetPosAndMaskInBitField:
mov r1, r16 ; divide by 8 to get the offset to the byte containing the given module id
lsr r1
lsr r1
@@ -559,9 +320,9 @@ CPRO_GetPosAndMaskInBitField:
ldi zh, HIGH(cproModuleBitNumToMaskMap*2)
ldi zl, LOW(cproModuleBitNumToMaskMap*2)
add zl, r2
brcc CPRO_GetPosAndMaskInBitField_noOverflow
brcc cproGetPosAndMaskInBitField_noOverflow
inc zh
CPRO_GetPosAndMaskInBitField_noOverflow:
cproGetPosAndMaskInBitField_noOverflow:
lpm r2, z ; r2=mask for bit in byte from bitfield
ret
@@ -570,3 +331,100 @@ cproModuleBitNumToMaskMap:
.db 1, 2, 4, 8, 16, 32, 64, 128
; ---------------------------------------------------------------------------
; Send a NEEDADDRESS packet.
;
; IN:
; - nothing
; OUT:
; - CFLAG: set if okay, clear otherwise
; MODIFIED REGS: R18 (R3, R4, R15, R16, R17, R20, R21, X, Y (R18, R19)
CPRO_SendNeedAddress:
ldi r18, CPRO_CMD_NEED_ADDRESS
rjmp cproSendAddressPacket
; ---------------------------------------------------------------------------
; Send a HAVE_ADDRESS packet.
;
; IN:
; - nothing
; OUT:
; - CFLAG: set if okay, clear otherwise
; MODIFIED REGS: R18 (R3, R4, R15, R16, R17, R18, R19, R20, R21, X, Y)
CPRO_SendHaveAddress:
ldi r18, CPRO_CMD_HAVE_ADDRESS
lds r19, com2Address
rjmp cproSendAddressPacket
; ---------------------------------------------------------------------------
; Send a CLAIM_ADDRESS packet.
;
; IN:
; - R19: claimed address
; OUT:
; - CFLAG: set if okay, clear otherwise
; MODIFIED REGS: R18 (R3, R4, R15, R16, R17, R18, R19, R20, R21, X, Y)
CPRO_SendClaimAddress:
ldi r18, CPRO_CMD_CLAIM_ADDRESS
rjmp cproSendAddressPacket
; ---------------------------------------------------------------------------
; Send a DENY_ADDRESS packet.
;
; IN:
; - nothing
; OUT:
; - CFLAG: set if okay, clear otherwise
; MODIFIED REGS: R18, R19 (R3, R4, R15, R16, R17, R20, R21, X, Y)
CPRO_SendDenyAddress:
ldi r18, CPRO_CMD_DENY_ADDRESS
lds r19, com2Address
rjmp cproSendAddressPacket
; ---------------------------------------------------------------------------
; cproSendAddressPacket
; Send a NEED/HAVE/CLAIM ADDRESS packet.
;
; IN:
; - R18: command (either CPRO_CMD_NEED_ADDRESS, CPRO_CMD_HAVE_ADDRESS or CPRO_CMD_CLAIM_ADDRESS)
; - R19: address to send (claim, have)
; OUT:
; - CFLAG: set if okay, clear otherwise
; MODIFIED REGS: R16, R17, R20, R21, X, Y (R3, R4, R15, R16, R17, R18, R19, R21, X)
cproSendAddressPacket:
ldi xl, LOW(com2SendBuffer)
ldi xh, HIGH(com2SendBuffer)
mov r6, r19
ldi r16, 0xff
ldi r17, COM2_PAYLOAD_FLAGS_UID | (1<<COM2_PAYLOAD_FLAGS_SHIFT_NUM)
rcall COM2_BeginMsgWithVariablePayload ; (R3, R4, R16, R17, R18, R19, R20, R21, X)
st X+, r6 ; address
ldi xl, LOW(com2SendBuffer)
ldi xh, HIGH(com2SendBuffer)
rcall com2CalcAndAddChecksumByte ; (R16, R17, R18, R19, X)
rjmp COM2_SendPacket
.include "comproto_addr1.asm"
.include "comproto_addr2.asm"
#endif ; MODULES_COM_WITH_ADDR_PROTO