AVR: More work on address assignment procedure.

This commit is contained in:
Martin Preuss
2023-02-06 21:09:38 +01:00
parent 012e33aea1
commit df70342ff3
3 changed files with 118 additions and 40 deletions

View File

@@ -132,14 +132,8 @@ Com_Init:
ldi r17, (comDataEnd-comDataBegin) ldi r17, (comDataEnd-comDataBegin)
rcall Utils_FillSram rcall Utils_FillSram
; read address from EEPROM ; set address to 0 (will be updated later)
ldi xl, LOW(EEPROM_OFFS_COMADDR)
ldi xh, HIGH(EEPROM_OFFS_COMADDR)
rcall Utils_ReadEeprom ; (R16)
cpi r16, 0xff
brne Com_Init_l1
clr r16 clr r16
Com_Init_l1:
sts comAddress, r16 sts comAddress, r16
; setup pins and interrupts ; setup pins and interrupts

View File

@@ -42,7 +42,9 @@
.equ CPRO_PACKET_DENYADDR_OFFS_ADDRESS = 8 .equ CPRO_PACKET_DENYADDR_OFFS_ADDRESS = 8
.equ CPRO_WAITTIME_GETADDR = 130 .equ CPRO_WAITTIME_GETADDR = 130
.equ CPRO_WAITTIME_CLAIMADDR = 30 .equ CPRO_WAITTIME_CLAIMADDR = 17
.equ CPRO_WAITTIME_RECLAIMADDR = 10
; current mode of operation ; current mode of operation
.equ CPRO_MODE_NORMAL = 0 ; normal operation .equ CPRO_MODE_NORMAL = 0 ; normal operation
@@ -51,6 +53,7 @@
.equ CPRO_MODE_CLAIMING_ADDR2 = 21 ; CLAIM_ADDRESS sent, 2nd try .equ CPRO_MODE_CLAIMING_ADDR2 = 21 ; CLAIM_ADDRESS sent, 2nd try
.equ CPRO_MODE_CLAIMING_ADDR3 = 22 ; CLAIM_ADDRESS sent, 3rd try .equ CPRO_MODE_CLAIMING_ADDR3 = 22 ; CLAIM_ADDRESS sent, 3rd try
.equ CPRO_MODE_SENDING_HAVE_ADDRESS = 30 ; waiting for our turn to send HAVE_ADDRESS packet .equ CPRO_MODE_SENDING_HAVE_ADDRESS = 30 ; waiting for our turn to send HAVE_ADDRESS packet
.equ CPRO_MODE_RECLAIMING_ADDR = 40 ; CLAIM_ADDRESS with the previously used address sent after bootup
@@ -111,8 +114,12 @@ CPRO_OnEverySecond_l4:
rjmp cproHandle1sClaimingAddr12 rjmp cproHandle1sClaimingAddr12
CPRO_OnEverySecond_l5: CPRO_OnEverySecond_l5:
cpi r17, CPRO_MODE_CLAIMING_ADDR3 cpi r17, CPRO_MODE_CLAIMING_ADDR3
brne CPRO_OnEverySecond_done brne CPRO_OnEverySecond_l6
rjmp cproHandle1sClaimingAddr3 rjmp cproHandle1sClaimingAddr3
CPRO_OnEverySecond_l6:
cpi r17, CPRO_MODE_RECLAIMING_ADDR
brne CPRO_OnEverySecond_done
rjmp cproHandle1sReclaimingAddr
CPRO_OnEverySecond_done: CPRO_OnEverySecond_done:
ret ret
@@ -388,6 +395,7 @@ CPRO_EnqueueValue:
push xh push xh
push xl push xl
mov r16, r6
ldi r17, CPRO_PAYLOAD_FLAGS_SECONDS | (6<<CPRO_PAYLOAD_FLAGS_SHIFT_NUM) ldi r17, CPRO_PAYLOAD_FLAGS_SECONDS | (6<<CPRO_PAYLOAD_FLAGS_SHIFT_NUM)
ldi r18, CPRO_CMD_VALUE ldi r18, CPRO_CMD_VALUE
rcall cproBeginMsgWithVariablePayload ; (R3, R4, R16, R17, R18, R19, R20, R21, X) rcall cproBeginMsgWithVariablePayload ; (R3, R4, R16, R17, R18, R19, R20, R21, X)

View File

@@ -4,12 +4,16 @@
; need to assign addresses to themselves with help from the community of existing ; need to assign addresses to themselves with help from the community of existing
; nodes. ; nodes.
; ;
; The protocol is as follows: ; Protocol A: Full Address Assignment Protocol
; --------------------------------------------
; This protocol is used when a node has no currently or previously assigned address.
; In this case we need to find a free address which no other node uses.
;
; 1) a node needs an address. It sends the packet "NEED_ADDRESS" ; 1) a node needs an address. It sends the packet "NEED_ADDRESS"
; 2) every node which already has an address sees this message and answers with ; 2) every node which already has an address sees this message and answers with
; a "HAVE_ADDRESS" packet. The nodes must not answer all at once to avoid ; a "HAVE_ADDRESS" packet. The nodes must not answer all at once to avoid
; congestions. Instead, the time it takes for a node to respond depends on ; congestions. Instead, the time it takes for a node to respond depends on
; its own address (e.g. a node with address 10 will wait for 10s before answering) ; its own address (e.g. a node with address 10 will wait for 10+3s before answering)
; 3) the initial node collects all "HAVE_ADDRESS" packets and puts the addresses ; 3) the initial node collects all "HAVE_ADDRESS" packets and puts the addresses
; received this way into a bitfield in which for every address received a bit is ; received this way into a bitfield in which for every address received a bit is
; set ; set
@@ -24,6 +28,18 @@
; 6) after no node denied the to-be-claimed address the initial node finally takes the ; 6) after no node denied the to-be-claimed address the initial node finally takes the
; address and sends a "HAVE_ADDRESS" packet. ; address and sends a "HAVE_ADDRESS" packet.
; 7) this concludes the address assignemt protocol ; 7) this concludes the address assignemt protocol
;
; Protocol B: Shortened Address Assignment Protocol
; -------------------------------------------------
; This protocol is used upon boot when a node previously got an address assigned to it.
; In this case the address is probably not used by an other node so we can shorten the
; procedure.
;
; 1) a node sends the packet CLAIM_ADDRESS with the previously assigned address
; 2) is any other node objects to this node using that address (e.g. because the other
; node now uses that address) that node will send a DENY_ADDRESS packet.
; 3) if no DENY_ADDRESS has been received within 10s the address can be used.
; 4) Otherwise the node changes into protocol A (see above).
@@ -35,6 +51,59 @@
CPRO_StartReclaimAddrProcedure:
ldi xl, LOW(EEPROM_OFFS_COMADDR)
ldi xh, HIGH(EEPROM_OFFS_COMADDR)
in r15, SREG
cli
rcall Utils_ReadEeprom ; (R16)
tst r16
breq CPRO_StartReclaimAddrProcedure_l1
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
sts cproMode, r16
sec
ret
CPRO_StartReclaimAddrProcedure_l1:
rcall CPRO_StartGetAddrProcedure
ret
CPRO_StartGetAddrProcedure:
; reset bitfield of used addresses
ldi xh, HIGH(cproUsedAddresses)
ldi xl, LOW(cproUsedAddresses)
clr r16
ldi r17, 16
rcall Utils_FillSram
; preset range
ldi r16, 1
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
sts cproMode, r16
sec
ret
CPRO_StartGetAddrProcedure_error:
clc
ret
; *************************************************************************** ; ***************************************************************************
; onEverySecond handlers ; onEverySecond handlers
@@ -99,7 +168,7 @@ cproHandle1sClaimingAddr3:
sts comAddress, r16 ; write address into eeprom sts comAddress, r16 ; write address into eeprom
ldi xl, LOW(EEPROM_OFFS_COMADDR) ldi xl, LOW(EEPROM_OFFS_COMADDR)
ldi xh, HIGH(EEPROM_OFFS_COMADDR) ldi xh, HIGH(EEPROM_OFFS_COMADDR)
; TODO rcall Utils_WriteEeprom rcall Utils_WriteEeprom ; write address to EEPROM
ldi r16, CPRO_MODE_NORMAL ; set mode to "normal" ldi r16, CPRO_MODE_NORMAL ; set mode to "normal"
sts cproMode, r16 sts cproMode, r16
rcall CPRO_EnqueueHaveAddress rcall CPRO_EnqueueHaveAddress
@@ -108,6 +177,23 @@ cproHandle1sClaimingAddr3_done:
ret 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
@@ -167,15 +253,31 @@ cproHandlePckClaimAddr_done:
cproHandleDenyAddr: cproHandleDenyAddr:
; first check address
ldd r16, y+(COM_BUFFER_OFFS_DATA+CPRO_PACKET_DENYADDR_OFFS_ADDRESS) ldd r16, y+(COM_BUFFER_OFFS_DATA+CPRO_PACKET_DENYADDR_OFFS_ADDRESS)
lds r17, cproAddrRangeBegin lds r17, cproAddrRangeBegin
cp r16, r17 cp r16, r17
brne cproHandleDenyAddr_done ; not our currently claimed address, ignore 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 rcall cproClaimNextFreeAddr ; claim next free address
brcs cproHandleDenyAddr_done brcs cproHandleDenyAddr_done
; no free address, abort TODO: send an error message to bus ("bus full") ; no free address, abort TODO: send an error message to bus ("bus full")
ldi r16, CPRO_MODE_NORMAL ldi r16, CPRO_MODE_NORMAL
sts cproMode, r16 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: cproHandleDenyAddr_done:
sec sec
ret ret
@@ -235,6 +337,8 @@ cproHandleAddrRange: ; not handled for now
cproEnterSendingHaveAddressMode: cproEnterSendingHaveAddressMode:
ldi r17, 3
add r16, r17
sts cproAddressWaitCounter, r16 ; set counter to own address sts cproAddressWaitCounter, r16 ; set counter to own address
ldi r16, CPRO_MODE_SENDING_HAVE_ADDRESS ldi r16, CPRO_MODE_SENDING_HAVE_ADDRESS
sts cproMode, r16 sts cproMode, r16
@@ -242,34 +346,6 @@ cproEnterSendingHaveAddressMode:
CPRO_StartGetAddrProcedure:
; reset bitfield of used addresses
ldi xh, HIGH(cproUsedAddresses)
ldi xl, LOW(cproUsedAddresses)
clr r16
ldi r17, 16
rcall Utils_FillSram
; preset range
ldi r16, 1
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
sts cproMode, r16
sec
ret
CPRO_StartGetAddrProcedure_error:
clc
ret
; --------------------------------------------------------------------------- ; ---------------------------------------------------------------------------
; cproFindFreeAddr ; cproFindFreeAddr
; ;