flashing older nodes across t03 now works!
older nodes need the new bootloader which doesn't depend on pagesize because those older nodes used quite large message sizes which are not supported across t03 nodes (we would need to much RAM on t03 for this).
This commit is contained in:
@@ -28,9 +28,11 @@ ioWaitForGivenMsg:
|
||||
ldi r20, 10 ; number of tries
|
||||
ioWaitForGivenMsg_loop:
|
||||
push r16
|
||||
rcall ioRawWaitForValidMsg ; (r16, r17, r18, r19, r22, X)
|
||||
pop r17 ; pop into r17 (from r16)
|
||||
brcc ioWaitForGivenMsg_end
|
||||
push r20
|
||||
rcall ioRawWaitForValidMsg ; (r16, r17, r18, r19, r20, r21, r22, X)
|
||||
pop r20
|
||||
pop r17 ; pop expected code to r17!
|
||||
brcc ioWaitForGivenMsg_loopEnd
|
||||
ldi xl, LOW(flashRecvBuffer)
|
||||
ldi xh, HIGH(flashRecvBuffer)
|
||||
adiw xh:xl, COM2_MSG_OFFS_CMD
|
||||
@@ -40,7 +42,8 @@ ioWaitForGivenMsg_loop:
|
||||
breq ioWaitForGivenMsg_gotIt
|
||||
cpi r16, CPRO_CMD_FLASH_END
|
||||
breq ioWaitForGivenMsg_gotIt
|
||||
mov r16, r17 ; put expected msg code back into r16 for next loop
|
||||
ioWaitForGivenMsg_loopEnd:
|
||||
mov r17, r16 ; move expected code back to r16
|
||||
dec r20
|
||||
brne ioWaitForGivenMsg_loop
|
||||
clc
|
||||
@@ -52,6 +55,3 @@ ioWaitForGivenMsg_end:
|
||||
; @end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -23,6 +23,8 @@
|
||||
; @clobbers R17 (R22, R24)
|
||||
|
||||
ioWaitForAttnState100ms:
|
||||
cbi COM_ATTN_DDR, COM_ATTN_PIN ; set ATTN port as input
|
||||
cbi COM_ATTN_OUTPUT, COM_ATTN_PIN ; disable internal pullup for ATTN
|
||||
ioWaitForAttnState100ms_loop:
|
||||
push r17
|
||||
ldi r17, 100
|
||||
@@ -32,7 +34,6 @@ ioWaitForAttnState100ms_loop:
|
||||
dec r17
|
||||
brne ioWaitForAttnState100ms_loop
|
||||
clc
|
||||
ret
|
||||
ioWaitForAttnState100ms_stateReached:
|
||||
ret
|
||||
; @end
|
||||
@@ -53,7 +54,6 @@ ioWaitForAttnStateMilliSeconds_loop:
|
||||
dec r17
|
||||
brne ioWaitForAttnStateMilliSeconds_loop
|
||||
clc
|
||||
ret
|
||||
ioWaitForAttnStateMilliSeconds_stateReached:
|
||||
ret
|
||||
; @end
|
||||
@@ -70,8 +70,6 @@ ioWaitForAttnStateMilliSeconds_stateReached:
|
||||
; @clobbers R24 (R22)
|
||||
|
||||
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
|
||||
ioWaitForAttnState1ms_loop:
|
||||
push r17
|
||||
|
||||
@@ -8,6 +8,65 @@
|
||||
; ***************************************************************************
|
||||
|
||||
|
||||
; ***************************************************************************
|
||||
; macros
|
||||
|
||||
; ---------------------------------------------------------------------------
|
||||
; @macro UART_BB_M_WAIT_FOR_PIN_LOW IN_REG_DATA, IN_PINNUM
|
||||
; 0 1
|
||||
; Wait for a pin to become low
|
||||
; @param %0 DATA register for input pin (e.g. PINB)
|
||||
; @param %1 pin number for input (e.g. PORTB1)
|
||||
; @return CFLAG set if okay, clear otherwise
|
||||
; @clobbers R17, R22
|
||||
|
||||
.macro UART_BB_M_WAIT_FOR_PIN_LOW
|
||||
ldi r17, 200
|
||||
l_loop:
|
||||
sbis @0, @1
|
||||
rjmp l_reached
|
||||
Utils_WaitNanoSecs 5000, 0, r22 ; wait for 5us
|
||||
dec r17
|
||||
brne l_loop
|
||||
clc
|
||||
rjmp l_end
|
||||
l_reached:
|
||||
sec
|
||||
l_end:
|
||||
.endmacro
|
||||
; @end
|
||||
|
||||
|
||||
|
||||
; ---------------------------------------------------------------------------
|
||||
; @macro UART_BB_M_WAIT_FOR_PIN_HIGH IN_REG_DATA, IN_PINNUM
|
||||
; 0 1
|
||||
; Wait for a pin to become high (up to 1ms)
|
||||
; @param %0 DATA register for input pin (e.g. PINB)
|
||||
; @param %1 pin number for input (e.g. PORTB1)
|
||||
; @return CFLAG set if okay, clear otherwise
|
||||
; @clobbers R17, R22
|
||||
|
||||
.macro UART_BB_M_WAIT_FOR_PIN_HIGH
|
||||
ldi r17, 200
|
||||
l_loop:
|
||||
sbic @0, @1
|
||||
rjmp l_reached
|
||||
Utils_WaitNanoSecs 5000, 0, r22 ; wait for 5us
|
||||
dec r17
|
||||
brne l_loop
|
||||
clc
|
||||
rjmp l_end
|
||||
l_reached:
|
||||
sec
|
||||
l_end:
|
||||
.endmacro
|
||||
; @end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
; ***************************************************************************
|
||||
; code
|
||||
|
||||
@@ -49,7 +108,7 @@ ioRawSendMsg_loop:
|
||||
ioRawSendMsg_attnHigh:
|
||||
ldi xl, LOW(flashSendBuffer)
|
||||
ldi xh, HIGH(flashSendBuffer)
|
||||
rcall uartBitbang_SendPacket ; R16, R22 (R17, R21, X)
|
||||
rcall ioRawSendPacket ; R16, R22 (R17, R21, X)
|
||||
brcc ioRawSendMsg_loop
|
||||
ret
|
||||
; @end
|
||||
@@ -61,7 +120,7 @@ ioRawSendMsg_attnHigh:
|
||||
; Wait for valid incoming msg
|
||||
;
|
||||
; @return CFLAG set if okay (packet received), cleared on error
|
||||
; @clobbers:
|
||||
; @clobbers: r16, r17 (r18, r19, r20, r21, r22, X)
|
||||
|
||||
ioRawWaitForValidMsg:
|
||||
ldi r16, 0 ; expect ATTN low
|
||||
@@ -74,14 +133,301 @@ ioRawWaitForValidMsg_attnLow:
|
||||
ldi xh, HIGH(flashRecvBuffer)
|
||||
ldi r16, COM2_MAINTENANCE_ADDR
|
||||
ldi r17, FLASH_RECVBUFFER_MAXLEN-3
|
||||
rcall uartBitbang_ReceivePacketIntoBuffer
|
||||
rcall ioRawReceivePacketIntoBuffer
|
||||
brcs ioRawWaitForValidMsg_packetReceived
|
||||
ret
|
||||
ioRawWaitForValidMsg_packetReceived:
|
||||
ldi r16, 0xff ; expect ATTN high
|
||||
ldi r17, 100
|
||||
rjmp ioWaitForAttnState100ms ; wait for up to 10s
|
||||
rcall ioWaitForAttnState100ms ; wait for up to 10s
|
||||
brcc ioRawWaitForValidMsg_end
|
||||
ldi xl, LOW(flashRecvBuffer)
|
||||
ldi xh, HIGH(flashRecvBuffer)
|
||||
rcall com2CheckMessageInBuffer ; (R16, R17, R18, R19, R20, X)
|
||||
ioRawWaitForValidMsg_end:
|
||||
ret
|
||||
; @end
|
||||
|
||||
|
||||
|
||||
; ---------------------------------------------------------------------------
|
||||
; @routine ioRawReceivePacketIntoBuffer
|
||||
;
|
||||
; Receive a packet into buffer pointed to by X.
|
||||
; Expects interrupts to be disabled.
|
||||
;
|
||||
; @param R16 COM address to listen to
|
||||
; @param R17 maximum value for accepted msg data (i.e. buffersize minus 3)
|
||||
; @param X buffer to receive to
|
||||
; @return CFLAG set if okay (packet received), cleared on error
|
||||
; @return R16 error code if CFLAG is cleared (COM2_ERROR_NOTFORME, COM2_ERROR_IOERROR, COM2_ERROR_DATAERROR)
|
||||
; @clobbers: r16, r17, r18, X (r19, r20, r21, r22)
|
||||
|
||||
ioRawReceivePacketIntoBuffer:
|
||||
mov r18, r17
|
||||
push r16
|
||||
; read destination address
|
||||
rcall ioRawReceiveByte ; read byte (R16, R17, R20, R21, R22)
|
||||
pop r17 ; pop from R16 to R17
|
||||
brcc ioRawReceivePacketIntoBuffer_ioError
|
||||
#ifndef COM_ACCEPT_ALL_DEST ; accept every destination address
|
||||
; compare destination address (accept "FF" and own address)
|
||||
cp r16, r17
|
||||
breq ioRawReceivePacketIntoBuffer_acceptAddr
|
||||
cpi r16, 0xff
|
||||
breq ioRawReceivePacketIntoBuffer_acceptAddr
|
||||
ldi r16, COM2_ERROR_NOTFORME
|
||||
rjmp ioRawReceivePacketIntoBuffer_error ; clc/ret
|
||||
#endif
|
||||
ioRawReceivePacketIntoBuffer_acceptAddr:
|
||||
st X+, r16 ; store dest address, lock buffer
|
||||
; read msg length
|
||||
rcall ioRawReceiveByte ; read packet length (R16, R17, R20, R21, R22)
|
||||
brcc ioRawReceivePacketIntoBuffer_ioError
|
||||
st X+, r16
|
||||
cp r16, r18 ; (COM2_BUFFER_SIZE-3)
|
||||
brcc ioRawReceivePacketIntoBuffer_contentError ; packet too long
|
||||
inc r16 ; account for checksum byte
|
||||
mov r17, r16
|
||||
ioRawReceivePacketIntoBuffer_loop:
|
||||
push r17
|
||||
rcall ioRawReceiveByte ; read byte (R16, R17, R20, R21, R22)
|
||||
pop r17
|
||||
brcc ioRawReceivePacketIntoBuffer_ioError
|
||||
st X+, r16
|
||||
dec r17
|
||||
brne ioRawReceivePacketIntoBuffer_loop
|
||||
sec
|
||||
ret
|
||||
ioRawReceivePacketIntoBuffer_ioError:
|
||||
ldi r16, COM2_ERROR_IOERROR
|
||||
rjmp ioRawReceivePacketIntoBuffer_error
|
||||
ioRawReceivePacketIntoBuffer_contentError:
|
||||
ldi r16, COM2_ERROR_DATAERROR
|
||||
ioRawReceivePacketIntoBuffer_error:
|
||||
clc
|
||||
ret
|
||||
; @end
|
||||
|
||||
|
||||
|
||||
; ---------------------------------------------------------------------------
|
||||
; @routine ioRawReceiveByte
|
||||
;
|
||||
; Read a byte.
|
||||
; Expects interrupts to be disabled.
|
||||
;
|
||||
; @return CFLAG set if okay, clear otherwise
|
||||
; @return R16 byte received
|
||||
; @clobbers R16, R20, R21, R22 (R17)
|
||||
|
||||
ioRawReceiveByte:
|
||||
cbi COM_DATA_DDR, COM_DATA_PIN ; set DATA port as input
|
||||
cbi COM_DATA_OUTPUT, COM_DATA_PIN ; disable internal pullup for RXD
|
||||
ldi r21, 8 ; bits left
|
||||
clr r20 ; byte currently receiving
|
||||
; wait for startbit
|
||||
rcall ioRawWaitForDataLow ; (R17, R22)
|
||||
brcc ioRawReceiveByte_error
|
||||
Utils_WaitNanoSecs COM_HALFBIT_LENGTH, 10, r22 ; goto middle of startbit to maximize sync stability
|
||||
ioRawReceiveByte_loop:
|
||||
Utils_WaitNanoSecs COM_BIT_LENGTH, 8, r22 ; 8 cycles used in the complete loop between waits
|
||||
sec ; +1
|
||||
sbic COM_DATA_INPUT, COM_DATA_PIN ; LOW: +2, HIGH: +1
|
||||
rjmp ioRawReceiveByte_shiftIn ; HIGH: +2, rjmp, use set CFLAG
|
||||
clc ; LOW: +1
|
||||
ioRawReceiveByte_shiftIn:
|
||||
ror r20 ; +1
|
||||
dec r21 ; +1
|
||||
brne ioRawReceiveByte_loop ; +2, sum per loop: 8 cycles
|
||||
rcall ioRawWaitForDataHigh ; wait for start of stopbit
|
||||
brcc ioRawReceiveByte_error
|
||||
mov r16, r20
|
||||
sec
|
||||
ret
|
||||
ioRawReceiveByte_error:
|
||||
clc
|
||||
ret
|
||||
; @end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
; ---------------------------------------------------------------------------
|
||||
; @routine ioRawSendPacket
|
||||
;
|
||||
; Send packet over wire, handle ATTN line.
|
||||
;
|
||||
; @param X ptr to buffer to send
|
||||
; @return CFLAGS set if okay, cleared otherwise (errorcode in R16)
|
||||
; @clobbers R16, R22 (R17, R21, X)
|
||||
|
||||
ioRawSendPacket:
|
||||
rcall ioRawAcquireBus
|
||||
brcc ioRawSendPacket_lineBusyError
|
||||
|
||||
rcall ioRawWaitForOneBitLength ; wait for one bit duration (R22)
|
||||
rcall ioRawWaitForOneBitLength ; wait for one bit duration (R22)
|
||||
|
||||
adiw xh:xl, COM2_MSG_OFFS_MSGLEN
|
||||
ld r17, X
|
||||
sbiw xh:xl, COM2_MSG_OFFS_MSGLEN
|
||||
inc r17 ; account for dest addr
|
||||
inc r17 ; account for msglen byte
|
||||
inc r17 ; account for crc byte
|
||||
|
||||
ioRawSendPacket_loop:
|
||||
ld r16, X+
|
||||
rcall ioRawSendByte ; send byte (R16, R21, R22)
|
||||
brcc ioRawSendPacket_releaseBusRet
|
||||
dec r17
|
||||
brne ioRawSendPacket_loop
|
||||
sec
|
||||
ioRawSendPacket_releaseBusRet:
|
||||
cbi COM_ATTN_DDR, COM_ATTN_PIN ; release ATTN line (by setting direction to IN)
|
||||
brcc ioRawSendPacket_ioError
|
||||
; packet successfully sent
|
||||
ret
|
||||
ioRawSendPacket_ioError:
|
||||
ldi r16,COM2_ERROR_COLLISION
|
||||
ret
|
||||
ioRawSendPacket_lineBusyError:
|
||||
ldi r16,COM2_ERROR_BUSY
|
||||
ret
|
||||
; @end
|
||||
|
||||
|
||||
|
||||
; ---------------------------------------------------------------------------
|
||||
; @routine ioRawAcquireBus
|
||||
;
|
||||
; Reserve bus if free (otherwise return error)
|
||||
; Expects interrupts to be disabled.
|
||||
;
|
||||
; @return CFLAG set if okay (bus acquired), cleared on error
|
||||
; @clobbers: none
|
||||
|
||||
ioRawAcquireBus:
|
||||
; check for ATTN line: busy?
|
||||
cbi COM_ATTN_DDR, COM_ATTN_PIN ; set ATTN as input
|
||||
cbi COM_ATTN_OUTPUT, COM_ATTN_PIN ; disable pullup on ATTN
|
||||
nop ; needed to sample current input
|
||||
sbis COM_ATTN_INPUT, COM_ATTN_PIN ; ATTN low?
|
||||
rjmp ioRawAcquireBus_busy ; jump if it is
|
||||
sbi COM_ATTN_DDR, COM_ATTN_PIN ; set ATTN as output
|
||||
cbi COM_ATTN_OUTPUT, COM_ATTN_PIN ; set ATTN low
|
||||
sec
|
||||
ret
|
||||
ioRawAcquireBus_busy:
|
||||
clc
|
||||
ret
|
||||
; @end
|
||||
|
||||
|
||||
|
||||
; ---------------------------------------------------------------------------
|
||||
; @routine ioRawWaitForOneBitLength
|
||||
;
|
||||
; wait for one bit length (minus cycles for call and ret).
|
||||
;
|
||||
; @clobbers r22
|
||||
|
||||
ioRawWaitForOneBitLength:
|
||||
Utils_WaitNanoSecs COM_BIT_LENGTH, 7, r22 ; wait for one bit duration (minus RCALL/RET)
|
||||
ret
|
||||
; @end
|
||||
|
||||
|
||||
|
||||
; ---------------------------------------------------------------------------
|
||||
; @routine ioRawSendByte
|
||||
;
|
||||
; Send a byte.
|
||||
; We only set the data pin to low at the beginning for the startbit. After that
|
||||
; we only change the pin direction (e.g. input vs output):
|
||||
; - for 0 bit: set DDR to output, forcing the data line low
|
||||
; - for 1 bit: set DDR to input, letting the external pullup R pull the data line to HIGH
|
||||
; since the output pin is still set to 0 the internal pullup is disabled
|
||||
; Expects interrupts to be disabled.
|
||||
;
|
||||
; @param R16 byte to send
|
||||
; @return CFLAG set if okay, clear otherwise
|
||||
; @clobbers R16, R21, R22
|
||||
|
||||
ioRawSendByte:
|
||||
cbi COM_DATA_DDR, COM_DATA_PIN ; set DATA port as input
|
||||
cbi COM_DATA_OUTPUT, COM_DATA_PIN ; disable internal pullup for DATA
|
||||
ldi r21, 8 ; +1 bits left
|
||||
; send startbit
|
||||
sbi COM_DATA_DDR, COM_DATA_PIN ; +2 set DATA as output
|
||||
cbi COM_DATA_OUTPUT, COM_DATA_PIN ; +2 set DATA low
|
||||
Utils_WaitNanoSecs COM_BIT_LENGTH, 1, r22 ; wait for one bit duration
|
||||
; send data bits
|
||||
ioRawSendByte_loop: ; 9 for low bit
|
||||
lsr r16 ; 1+ bit to send -> CARRY
|
||||
brcs ioRawSendByte_setHigh ; HI: +2, LO: +1
|
||||
ioRawSendByte_setLow:
|
||||
sbi COM_DATA_DDR, COM_DATA_PIN ; +2 set DATA as output
|
||||
cbi COM_DATA_OUTPUT, COM_DATA_PIN ; +2 set DATA low
|
||||
Utils_WaitNanoSecs COM_BIT_LENGTH, 11, r22
|
||||
rjmp ioRawSendByte_loopEnd ; +2
|
||||
ioRawSendByte_setHigh:
|
||||
cbi COM_DATA_DDR, COM_DATA_PIN ; +2 set DATA as input, pullup R makes it ONE
|
||||
nop ; +1 (to make pin change available)
|
||||
Utils_WaitNanoSecs COM_HALFBIT_LENGTH, 0, r22 ; wait for half a bit length for line to safely settle
|
||||
sbis COM_DATA_INPUT, COM_DATA_PIN ; +1 if no skip, +2 if skipped
|
||||
rjmp ioRawSendByte_error ; +2 if error (collision: we wanted line to be high but it is low)
|
||||
Utils_WaitNanoSecs COM_HALFBIT_LENGTH, 11, r22
|
||||
ioRawSendByte_loopEnd:
|
||||
dec r21 ; +1
|
||||
brne ioRawSendByte_loop ; +2, sum per loop: 10 cycles
|
||||
; send stopbit
|
||||
cbi COM_DATA_DDR, COM_DATA_PIN ; +2 set DATA as input, pullup R makes it ONE
|
||||
Utils_WaitNanoSecs COM_BIT_LENGTH, 0, r22 ; wait for one bit length
|
||||
sec
|
||||
ret
|
||||
|
||||
ioRawSendByte_error:
|
||||
clc
|
||||
ret
|
||||
; @end
|
||||
|
||||
|
||||
|
||||
; ---------------------------------------------------------------------------
|
||||
; @routine ioRawWaitForDataLow
|
||||
;
|
||||
; Wait up to 1ms for data pin to become low
|
||||
; @return CFLAG set if okay, clear otherwise
|
||||
; @clobbers R17, R22
|
||||
|
||||
ioRawWaitForDataLow:
|
||||
cbi COM_DATA_DDR, COM_DATA_PIN ; set DATA port as input
|
||||
cbi COM_DATA_OUTPUT, COM_DATA_PIN ; disable internal pullup for TXD
|
||||
UART_BB_M_WAIT_FOR_PIN_LOW COM_DATA_INPUT, COM_DATA_PIN
|
||||
ret
|
||||
; @end
|
||||
|
||||
|
||||
|
||||
; ---------------------------------------------------------------------------
|
||||
; @routine ioRawWaitForDataHigh
|
||||
;
|
||||
; Wait up to 1ms for data pin to become high
|
||||
; @return CFLAG set if okay, clear otherwise
|
||||
; @clobbers R17, R22
|
||||
|
||||
ioRawWaitForDataHigh:
|
||||
cbi COM_DATA_DDR, COM_DATA_PIN ; set DATA port as input
|
||||
cbi COM_DATA_OUTPUT, COM_DATA_PIN ; disable internal pullup for TXD
|
||||
UART_BB_M_WAIT_FOR_PIN_HIGH COM_DATA_INPUT, COM_DATA_PIN
|
||||
ret
|
||||
; @end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user