avr: improved protocol timing for COM2.
- increased waiting time after lowering ATTN line - lengthten stop bit for cleaner frames (now recognized by PulseView) - count "NOTFORME" conditions - introduce definition COM_HALFBIT_LENGTH (I dont' trust value calculations in avrasm)
This commit is contained in:
@@ -47,7 +47,8 @@
|
|||||||
; ---------------------------------------------------------------------------
|
; ---------------------------------------------------------------------------
|
||||||
; COM module
|
; COM module
|
||||||
|
|
||||||
.equ COM_BIT_LENGTH = 52000 ; 104000=9600, 52000=19200, 26000=38400
|
.equ COM_BIT_LENGTH = 52000 ; 104000ns=9600, 52000ns=19200, 26000ns=38400
|
||||||
|
.equ COM_HALFBIT_LENGTH = 26000 ; see https://de.wikipedia.org/wiki/Universal_Asynchronous_Receiver_Transmitter
|
||||||
|
|
||||||
.equ COM_DDR_DATA = DDRA
|
.equ COM_DDR_DATA = DDRA
|
||||||
.equ COM_PORT_DATA = PORTA
|
.equ COM_PORT_DATA = PORTA
|
||||||
|
|||||||
@@ -47,7 +47,8 @@
|
|||||||
; ---------------------------------------------------------------------------
|
; ---------------------------------------------------------------------------
|
||||||
; COM module
|
; COM module
|
||||||
|
|
||||||
.equ COM_BIT_LENGTH = 52000 ; 104000=9600, 52000=19200, 26000=38400
|
.equ COM_BIT_LENGTH = 52000 ; 104000ns=9600, 52000ns=19200, 26000ns=38400
|
||||||
|
.equ COM_HALFBIT_LENGTH = 26000 ; see https://de.wikipedia.org/wiki/Universal_Asynchronous_Receiver_Transmitter
|
||||||
|
|
||||||
.equ COM_DDR_DATA = DDRA
|
.equ COM_DDR_DATA = DDRA
|
||||||
.equ COM_PORT_DATA = PORTA
|
.equ COM_PORT_DATA = PORTA
|
||||||
@@ -60,7 +61,7 @@
|
|||||||
.equ COM_PINNUM_ATTN = PORTA7
|
.equ COM_PINNUM_ATTN = PORTA7
|
||||||
|
|
||||||
.equ COM_IRQ_ADDR_ATTN = PCMSK0
|
.equ COM_IRQ_ADDR_ATTN = PCMSK0
|
||||||
.equ COM_IRQ_BIT_ATTN = 7 ; bit 7 in PCMSK0
|
.equ COM_IRQ_BIT_ATTN = PCINT7 ; bit 7 in PCMSK0
|
||||||
.equ COM_IRQ_GIFR_ATTN = PCIF0
|
.equ COM_IRQ_GIFR_ATTN = PCIF0
|
||||||
.equ COM_IRQ_GIMSK_ATTN = PCIE0
|
.equ COM_IRQ_GIMSK_ATTN = PCIE0
|
||||||
|
|
||||||
|
|||||||
@@ -47,7 +47,7 @@
|
|||||||
; COM module
|
; COM module
|
||||||
|
|
||||||
.equ COM_BIT_LENGTH = 52000 ; 104000ns=9600, 52000ns=19200, 26000ns=38400
|
.equ COM_BIT_LENGTH = 52000 ; 104000ns=9600, 52000ns=19200, 26000ns=38400
|
||||||
; see https://de.wikipedia.org/wiki/Universal_Asynchronous_Receiver_Transmitter
|
.equ COM_HALFBIT_LENGTH = 26000 ; see https://de.wikipedia.org/wiki/Universal_Asynchronous_Receiver_Transmitter
|
||||||
.equ COM_DDR_DATA = DDRA
|
.equ COM_DDR_DATA = DDRA
|
||||||
.equ COM_PORT_DATA = PORTA
|
.equ COM_PORT_DATA = PORTA
|
||||||
.equ COM_PIN_DATA = PINA
|
.equ COM_PIN_DATA = PINA
|
||||||
@@ -59,7 +59,7 @@
|
|||||||
.equ COM_PINNUM_ATTN = PORTA7
|
.equ COM_PINNUM_ATTN = PORTA7
|
||||||
|
|
||||||
.equ COM_IRQ_ADDR_ATTN = PCMSK0
|
.equ COM_IRQ_ADDR_ATTN = PCMSK0
|
||||||
.equ COM_IRQ_BIT_ATTN = 7 ; bit 7 in PCMSK0
|
.equ COM_IRQ_BIT_ATTN = PCINT7 ; bit 7 in PCMSK0
|
||||||
.equ COM_IRQ_GIFR_ATTN = PCIF0
|
.equ COM_IRQ_GIFR_ATTN = PCIF0
|
||||||
.equ COM_IRQ_GIMSK_ATTN = PCIE0
|
.equ COM_IRQ_GIMSK_ATTN = PCIE0
|
||||||
|
|
||||||
|
|||||||
@@ -161,6 +161,10 @@ firmwareStart: rjmp main
|
|||||||
.include "modules/comproto/msg_device.asm"
|
.include "modules/comproto/msg_device.asm"
|
||||||
.include "modules/comproto/msg_reboot.asm"
|
.include "modules/comproto/msg_reboot.asm"
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef MODULES_LCD
|
||||||
|
.include "modules/com2/screen.asm"
|
||||||
|
.include "modules/comproto/screen.asm"
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
#ifdef MODULES_TWI_MASTER
|
#ifdef MODULES_TWI_MASTER
|
||||||
.include "modules/twimaster/main.asm"
|
.include "modules/twimaster/main.asm"
|
||||||
@@ -194,9 +198,18 @@ firmwareStart: rjmp main
|
|||||||
|
|
||||||
.dseg
|
.dseg
|
||||||
|
|
||||||
|
programRamBegin:
|
||||||
|
#ifdef MODULES_LCD
|
||||||
|
screenCounter: .byte 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
programRamEnd:
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef MODULES_LCD
|
#ifdef MODULES_LCD
|
||||||
sramTimerWriteStats: .byte 2
|
sramTimerWriteStats: .byte 2
|
||||||
|
sramTimerScreen: .byte 2
|
||||||
#endif
|
#endif
|
||||||
sramTimerEnqueueValues: .byte 2
|
sramTimerEnqueueValues: .byte 2
|
||||||
#ifdef MODULES_SI7021
|
#ifdef MODULES_SI7021
|
||||||
@@ -221,12 +234,6 @@ sramTimerEnqueueValues: .byte 2
|
|||||||
|
|
||||||
.cseg
|
.cseg
|
||||||
|
|
||||||
#ifdef MODULES_LED
|
|
||||||
ledA3Flash: .db DDRA+0x20, PORTA+0x20, PINA+0x20, (1<<PORTA3)
|
|
||||||
blinkPattern: .db 2, 50, 0xff, 0xff ; 1 short blink, 5s pause, restart
|
|
||||||
;blinkPattern2: .db 2, 2, 0xff, 0xff ; 1 short blink, short pause, restart
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
; ---------------------------------------------------------------------------
|
; ---------------------------------------------------------------------------
|
||||||
@@ -242,8 +249,9 @@ timerList:
|
|||||||
.dw statsSendTimer, Stats_Timer, TIMER_FLAGS_IF_ADDR, 3000 ; every 5m
|
.dw statsSendTimer, Stats_Timer, TIMER_FLAGS_IF_ADDR, 3000 ; every 5m
|
||||||
#endif
|
#endif
|
||||||
#ifdef MODULES_LCD
|
#ifdef MODULES_LCD
|
||||||
; .dw sramPeriodicalLcdMark, periodicalLcdMark, 0, 20 ; every 2s
|
; .dw sramPeriodicalLcdMark, periodicalLcdMark, 0, 20 ; every 2s
|
||||||
.dw sramTimerWriteStats, writeStats, 0, 100
|
; .dw sramTimerWriteStats, writeStats, 0, 100
|
||||||
|
.dw sramTimerScreen, printScreen, TIMER_FLAGS_IF_ADDR, 50 ; every 5s
|
||||||
#endif
|
#endif
|
||||||
#ifdef MODULES_SI7021
|
#ifdef MODULES_SI7021
|
||||||
.dw sramTimerSI7021Measure, SI7021_OnTimer, 0, 300 ; every 30s
|
.dw sramTimerSI7021Measure, SI7021_OnTimer, 0, 300 ; every 30s
|
||||||
@@ -292,18 +300,55 @@ systemSetBootSpeed:
|
|||||||
; Called on first time run, i.e. on system start. No arguments, no results.
|
; Called on first time run, i.e. on system start. No arguments, no results.
|
||||||
|
|
||||||
onSystemStart:
|
onSystemStart:
|
||||||
|
ldi xh, HIGH(programRamBegin)
|
||||||
|
ldi xl, LOW(programRamBegin)
|
||||||
|
clr r16
|
||||||
|
ldi r17, (programRamEnd-programRamBegin)
|
||||||
|
rcall Utils_FillSram
|
||||||
ret
|
ret
|
||||||
|
|
||||||
|
|
||||||
#ifdef MODULES_LCD
|
#ifdef MODULES_LCD
|
||||||
periodicalLcdMark:
|
|
||||||
rcall printTimerMark
|
printScreen:
|
||||||
|
lds r16, screenCounter
|
||||||
|
tst r16
|
||||||
|
brne printScreen_l1
|
||||||
|
rcall CPRO_Screen
|
||||||
|
rjmp printScreen_counter
|
||||||
|
printScreen_l1:
|
||||||
|
cpi r16, 1
|
||||||
|
brne printScreen_l2
|
||||||
|
rcall COM2_Screen_RecvStats
|
||||||
|
rjmp printScreen_counter
|
||||||
|
printScreen_l2:
|
||||||
|
; cpi r16, 2
|
||||||
|
; brne printScreen_l3
|
||||||
|
; rcall COM2_Screen_SendStats
|
||||||
|
; rjmp printScreen_counter
|
||||||
|
printScreen_l3:
|
||||||
|
; add more screens here
|
||||||
|
|
||||||
|
printScreen_counter:
|
||||||
|
lds r16, screenCounter
|
||||||
|
inc r16
|
||||||
|
cpi r16, 2 ; number of screens
|
||||||
|
brcs printScreen_store
|
||||||
|
clr r16
|
||||||
|
printScreen_store:
|
||||||
|
sts screenCounter, r16
|
||||||
|
printScreen_end:
|
||||||
ret
|
ret
|
||||||
|
|
||||||
|
|
||||||
writeStats:
|
;periodicalLcdMark:
|
||||||
rcall printSendStats
|
; rcall printTimerMark
|
||||||
ret
|
; ret
|
||||||
|
|
||||||
|
|
||||||
|
;writeStats:
|
||||||
|
; rcall printSendStats
|
||||||
|
; ret
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -45,7 +45,8 @@
|
|||||||
; ---------------------------------------------------------------------------
|
; ---------------------------------------------------------------------------
|
||||||
; COM module
|
; COM module
|
||||||
|
|
||||||
.equ COM_BIT_LENGTH = 52000 ; 104000=9600, 52000=19200, 26000=38400
|
.equ COM_BIT_LENGTH = 52000 ; 104000ns=9600, 52000ns=19200, 26000ns=38400
|
||||||
|
.equ COM_HALFBIT_LENGTH = 26000 ; see https://de.wikipedia.org/wiki/Universal_Asynchronous_Receiver_Transmitter
|
||||||
|
|
||||||
.equ COM_DDR_DATA = DDRA
|
.equ COM_DDR_DATA = DDRA
|
||||||
.equ COM_PORT_DATA = PORTA
|
.equ COM_PORT_DATA = PORTA
|
||||||
|
|||||||
@@ -42,7 +42,8 @@
|
|||||||
; ---------------------------------------------------------------------------
|
; ---------------------------------------------------------------------------
|
||||||
; COM module
|
; COM module
|
||||||
|
|
||||||
.equ COM_BIT_LENGTH = 52000 ; 104000=9600, 52000=19200, 26000=38400
|
.equ COM_BIT_LENGTH = 52000 ; 104000ns=9600, 52000ns=19200, 26000ns=38400
|
||||||
|
.equ COM_HALFBIT_LENGTH = 26000 ; see https://de.wikipedia.org/wiki/Universal_Asynchronous_Receiver_Transmitter
|
||||||
|
|
||||||
.equ COM_DDR_DATA = DDRB
|
.equ COM_DDR_DATA = DDRB
|
||||||
.equ COM_PORT_DATA = PORTB
|
.equ COM_PORT_DATA = PORTB
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ com2SendByte:
|
|||||||
; send startbit
|
; send startbit
|
||||||
cbi COM_PORT_DATA, COM_PINNUM_DATA ; +2 set DATA low
|
cbi COM_PORT_DATA, COM_PINNUM_DATA ; +2 set DATA low
|
||||||
sbi COM_DDR_DATA, COM_PINNUM_DATA ; +2 set DATA as output
|
sbi COM_DDR_DATA, COM_PINNUM_DATA ; +2 set DATA as output
|
||||||
Utils_WaitNanoSecs COM_BIT_LENGTH, 5, r22 ; wait for one bit duration
|
Utils_WaitNanoSecs COM_BIT_LENGTH, 1, r22 ; wait for one bit duration
|
||||||
; send data bits
|
; send data bits
|
||||||
com2SendByte_loop: ; 9 for low bit
|
com2SendByte_loop: ; 9 for low bit
|
||||||
lsr r16 ; 1+ bit to send -> CARRY
|
lsr r16 ; 1+ bit to send -> CARRY
|
||||||
@@ -43,16 +43,16 @@ com2SendByte_setLow:
|
|||||||
com2SendByte_setHigh:
|
com2SendByte_setHigh:
|
||||||
cbi COM_DDR_DATA, COM_PINNUM_DATA ; +2 set DATA as input, pullup R makes it ONE
|
cbi COM_DDR_DATA, COM_PINNUM_DATA ; +2 set DATA as input, pullup R makes it ONE
|
||||||
nop ; +1 (to make pin change available)
|
nop ; +1 (to make pin change available)
|
||||||
Utils_WaitNanoSecs COM_BIT_LENGTH/2, 11, r22 ; wait for half a bit length for line to safely settle
|
Utils_WaitNanoSecs COM_HALFBIT_LENGTH, 0, r22 ; wait for half a bit length for line to safely settle
|
||||||
sbis COM_PIN_DATA, COM_PINNUM_DATA ; +1 if no skip, +2 if skipped
|
sbis COM_PIN_DATA, COM_PINNUM_DATA ; +1 if no skip, +2 if skipped
|
||||||
rjmp com2SendByte_error ; +2 if error (collision: we wanted line to be high but it is low)
|
rjmp com2SendByte_error ; +2 if error (collision: we wanted line to be high but it is low)
|
||||||
Utils_WaitNanoSecs COM_BIT_LENGTH/2, 0, r22
|
Utils_WaitNanoSecs COM_HALFBIT_LENGTH, 11, r22
|
||||||
com2SendByte_loopEnd:
|
com2SendByte_loopEnd:
|
||||||
dec r21 ; +1
|
dec r21 ; +1
|
||||||
brne com2SendByte_loop ; +2, sum per loop: 10 cycles
|
brne com2SendByte_loop ; +2, sum per loop: 10 cycles
|
||||||
; send stopbit
|
; send stopbit
|
||||||
cbi COM_DDR_DATA, COM_PINNUM_DATA ; +2 set DATA as input, pullup R makes it ONE
|
cbi COM_DDR_DATA, COM_PINNUM_DATA ; +2 set DATA as input, pullup R makes it ONE
|
||||||
Utils_WaitNanoSecs COM_BIT_LENGTH, 4, r22 ; wait for one bit length
|
Utils_WaitNanoSecs COM_BIT_LENGTH, 0, r22 ; wait for one bit length
|
||||||
rjmp com2LowLevelSecRet
|
rjmp com2LowLevelSecRet
|
||||||
|
|
||||||
com2SendByte_error:
|
com2SendByte_error:
|
||||||
@@ -81,7 +81,7 @@ com2ReceiveByte:
|
|||||||
; wait for startbit
|
; wait for startbit
|
||||||
rcall com2WaitForDataLow ; (R16, R17, R22)
|
rcall com2WaitForDataLow ; (R16, R17, R22)
|
||||||
brcc com2ReceiveByte_error
|
brcc com2ReceiveByte_error
|
||||||
Utils_WaitNanoSecs COM_BIT_LENGTH/2, 5, r22 ; goto middle of startbit to maximize sync stability
|
Utils_WaitNanoSecs COM_HALFBIT_LENGTH, 10, r22 ; goto middle of startbit to maximize sync stability
|
||||||
com2ReceiveByte_loop:
|
com2ReceiveByte_loop:
|
||||||
Utils_WaitNanoSecs COM_BIT_LENGTH, 8, r22 ; 8 cycles used in the complete loop between waits
|
Utils_WaitNanoSecs COM_BIT_LENGTH, 8, r22 ; 8 cycles used in the complete loop between waits
|
||||||
sec ; +1
|
sec ; +1
|
||||||
@@ -149,7 +149,7 @@ com2WaitForAttnHigh:
|
|||||||
; ---------------------------------------------------------------------------
|
; ---------------------------------------------------------------------------
|
||||||
; com2WaitForDataState1ms
|
; com2WaitForDataState1ms
|
||||||
;
|
;
|
||||||
; Waits up to 1ms for high DATA line
|
; Waits up to 500us for high DATA line
|
||||||
; IN:
|
; IN:
|
||||||
; - R16: state to wait for (00 for low, 0xff for high)
|
; - R16: state to wait for (00 for low, 0xff for high)
|
||||||
; OUT:
|
; OUT:
|
||||||
@@ -163,12 +163,14 @@ com2WaitForDataState1ms_loop:
|
|||||||
eor r22, r16
|
eor r22, r16
|
||||||
andi r22, (1<<COM_PINNUM_DATA)
|
andi r22, (1<<COM_PINNUM_DATA)
|
||||||
breq com2WaitForDataState1ms_stateReached
|
breq com2WaitForDataState1ms_stateReached
|
||||||
rcall Utils_WaitFor10MicroSecs ; wait for 10us (R22)
|
; rcall Utils_WaitFor10MicroSecs ; wait for 10us (R22)
|
||||||
|
Utils_WaitNanoSecs 5000, 0, r22
|
||||||
dec r17
|
dec r17
|
||||||
brne com2WaitForDataState1ms_loop
|
brne com2WaitForDataState1ms_loop
|
||||||
rjmp com2LowLevelClcRet
|
rjmp com2LowLevelClcRet
|
||||||
com2WaitForDataState1ms_stateReached:
|
com2WaitForDataState1ms_stateReached:
|
||||||
rjmp com2LowLevelSecRet
|
sec
|
||||||
|
ret
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ com2RecvStatsBegin: ; 12 bytes
|
|||||||
com2StatsIoError: .byte 2
|
com2StatsIoError: .byte 2
|
||||||
com2StatsNoBufferError: .byte 2
|
com2StatsNoBufferError: .byte 2
|
||||||
com2StatsHandled: .byte 2
|
com2StatsHandled: .byte 2
|
||||||
|
com2StatsNotForMe: .byte 2
|
||||||
com2StatsMissed: .byte 2 ; currently not used
|
com2StatsMissed: .byte 2 ; currently not used
|
||||||
com2RecvStatsEnd:
|
com2RecvStatsEnd:
|
||||||
|
|
||||||
@@ -331,6 +332,8 @@ com2ReceivePacket_error:
|
|||||||
breq com2ReceivePacket_ioError
|
breq com2ReceivePacket_ioError
|
||||||
cpi r16, COM2_ERROR_DATAERROR
|
cpi r16, COM2_ERROR_DATAERROR
|
||||||
breq com2ReceivePacket_dataError
|
breq com2ReceivePacket_dataError
|
||||||
|
cpi r16, COM2_ERROR_NOTFORME
|
||||||
|
breq com2ReceivePacket_notForMe
|
||||||
rjmp com2ReceivePacket_retnc
|
rjmp com2ReceivePacket_retnc
|
||||||
com2ReceivePacket_ioError:
|
com2ReceivePacket_ioError:
|
||||||
ldi xl, LOW(com2StatsIoError)
|
ldi xl, LOW(com2StatsIoError)
|
||||||
@@ -340,6 +343,10 @@ com2ReceivePacket_dataError:
|
|||||||
ldi xl, LOW(com2StatsContentError)
|
ldi xl, LOW(com2StatsContentError)
|
||||||
ldi xh, HIGH(com2StatsContentError)
|
ldi xh, HIGH(com2StatsContentError)
|
||||||
rjmp com2ReceivePacket_incCounterDeallocNc
|
rjmp com2ReceivePacket_incCounterDeallocNc
|
||||||
|
com2ReceivePacket_notForMe:
|
||||||
|
ldi xl, LOW(com2StatsNotForMe)
|
||||||
|
ldi xh, HIGH(com2StatsNotForMe)
|
||||||
|
rjmp com2ReceivePacket_incCounterDeallocNc
|
||||||
com2ReceivePacket_incCounterDeallocNc:
|
com2ReceivePacket_incCounterDeallocNc:
|
||||||
rcall Utils_IncrementCounter16 ; (r18, r19, 22)
|
rcall Utils_IncrementCounter16 ; (r18, r19, 22)
|
||||||
com2ReceivePacket_deallocRetnc:
|
com2ReceivePacket_deallocRetnc:
|
||||||
|
|||||||
@@ -77,7 +77,6 @@ COM2_SendPacketWithAttn:
|
|||||||
push r15
|
push r15
|
||||||
in r15, SREG
|
in r15, SREG
|
||||||
cli
|
cli
|
||||||
; rcall com2WaitForOneBitLength ; wait for one bit duration (R22)
|
|
||||||
; check for ATTN line: busy?
|
; check for ATTN line: busy?
|
||||||
cbi COM_PORT_ATTN, COM_PINNUM_ATTN ; disable pullup on ATTN
|
cbi COM_PORT_ATTN, COM_PINNUM_ATTN ; disable pullup on ATTN
|
||||||
cbi COM_DDR_ATTN, COM_PINNUM_ATTN ; set ATTN as input
|
cbi COM_DDR_ATTN, COM_PINNUM_ATTN ; set ATTN as input
|
||||||
@@ -87,7 +86,8 @@ COM2_SendPacketWithAttn:
|
|||||||
|
|
||||||
cbi COM_PORT_ATTN, COM_PINNUM_ATTN ; set ATTN low
|
cbi COM_PORT_ATTN, COM_PINNUM_ATTN ; set ATTN low
|
||||||
sbi COM_DDR_ATTN, COM_PINNUM_ATTN ; set ATTN as output
|
sbi COM_DDR_ATTN, COM_PINNUM_ATTN ; set ATTN as output
|
||||||
rcall com2WaitForOneBitLength ; wait for one bit duration (R22)
|
rcall com2WaitForOneBitLength ; wait for one bit duration (R22)
|
||||||
|
rcall com2WaitForOneBitLength ; wait for another bit duration (R22)
|
||||||
|
|
||||||
adiw xh:xl, COM2_MSG_OFFS_MSGLEN
|
adiw xh:xl, COM2_MSG_OFFS_MSGLEN
|
||||||
ld r16, X
|
ld r16, X
|
||||||
|
|||||||
Reference in New Issue
Block a user