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:
@@ -197,8 +197,7 @@ Offset Length Meaning
|
||||
4 4 UID of the sending node
|
||||
8 2 packets out
|
||||
10 2 collisions
|
||||
12 2 aborted
|
||||
14 2 no buffer errors
|
||||
12 2 line busy errors
|
||||
|
||||
|
||||
|
||||
@@ -214,11 +213,9 @@ Offset Length Meaning
|
||||
---------------------------------------------------------
|
||||
4 4 UID of the sending node
|
||||
8 2 packets in
|
||||
10 2 crc errors
|
||||
10 2 content errors (invalid msg length, CRC errors)
|
||||
12 2 io errors
|
||||
14 2 no buffer errors
|
||||
16 2 handled packets
|
||||
18 2 missed
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -61,9 +61,10 @@
|
||||
|
||||
#define MODULES_TIMER
|
||||
#define MODULES_COM
|
||||
;#define MODULES_COM_WITH_ADDR_PROTO
|
||||
#define MODULES_LED
|
||||
#define MODULES_TWI_MASTER
|
||||
;#define MODULES_LCD
|
||||
#define MODULES_LCD
|
||||
#define MODULES_SI7021
|
||||
|
||||
|
||||
@@ -199,7 +200,7 @@
|
||||
|
||||
rjmp main ; Reset vector
|
||||
reti ; EXT_INT0
|
||||
rjmp comIsrPcint0 ; PCI0
|
||||
rjmp com2IsrPcint0 ; PCI0
|
||||
reti ; PCI1
|
||||
reti ; WATCHDOG
|
||||
reti ; ICP1
|
||||
@@ -222,18 +223,14 @@
|
||||
.include "utils.asm"
|
||||
.include "timer.asm"
|
||||
.include "led.asm"
|
||||
.include "com.asm"
|
||||
.include "com2.asm"
|
||||
.include "comproto.asm"
|
||||
.include "comproto_addr.asm"
|
||||
.include "comproto_stats.asm"
|
||||
.include "comproto_device.asm"
|
||||
.include "comproto_memstats.asm"
|
||||
.include "comproto_sysstats.asm"
|
||||
.include "comproto_values.asm"
|
||||
;.include "comproto_debug.asm"
|
||||
;.include "comproto_twi.asm"
|
||||
.include "comproto_recvstats.asm"
|
||||
.include "comproto_pong.asm"
|
||||
;.include "comproto_values.asm"
|
||||
.include "twimaster.asm"
|
||||
;.include "lcd.asm"
|
||||
.include "lcd.asm"
|
||||
.include "si7021.asm"
|
||||
|
||||
|
||||
@@ -250,7 +247,7 @@ sramTimerEnqueueMemStats: .byte 2
|
||||
sramTimerEnqueueSysStats: .byte 2
|
||||
sramTimerEnqueueValues: .byte 2
|
||||
sramTimerSI7021Measure: .byte 2
|
||||
|
||||
sramPeriodicalLcdMark: .byte 2
|
||||
|
||||
|
||||
; ***************************************************************************
|
||||
@@ -271,12 +268,13 @@ blinkPattern: .db 2, 50, 0xff, 0xff ; 1 short blink, 2s pause, restart
|
||||
|
||||
timerList:
|
||||
; SRAM variable/counter routine flags secs (0=don't start or restart)
|
||||
.dw sramTimerProtocolEverySec, CPRO_OnEverySecond, 0, 1 ; every 1s
|
||||
.dw sramTimerEnqueueComStats, enqueueComStats, TIMER_FLAGS_IF_ADDR, 300 ; every 5m
|
||||
.dw sramTimerEnqueueMemStats, enqueueMemStats, TIMER_FLAGS_IF_ADDR, 300 ; every 5m
|
||||
.dw sramTimerEnqueueSysStats, enqueueSysStats, TIMER_FLAGS_IF_ADDR, 60 ; every 60s
|
||||
.dw sramTimerSI7021Measure, SI7021_PeriodicMeasurement, 0, 30 ; every 30s
|
||||
.dw sramTimerEnqueueValues, Main_SendValueMsg, TIMER_FLAGS_IF_ADDR, 60 ; every 1m
|
||||
#ifdef MODULES_COM_WITH_ADDR_PROTO
|
||||
; .dw cproAddresModeTimer, CPRO_Address_OnTimer, 0, 0 ; (no restart)
|
||||
#endif
|
||||
.dw sramTimerEnqueueComStats, enqueueComStats, TIMER_FLAGS_IF_ADDR, 10 ; every 30s
|
||||
.dw sramPeriodicalLcdMark, periodicalLcdMark, 0, 1 ; every sec
|
||||
; .dw sramTimerSI7021Measure, SI7021_PeriodicMeasurement, 0, 30 ; every 30s
|
||||
; .dw sramTimerEnqueueValues, Main_SendValueMsg, TIMER_FLAGS_IF_ADDR, 60 ; every 1m
|
||||
.dw 0 ; end of list
|
||||
|
||||
|
||||
@@ -290,33 +288,51 @@ timerList:
|
||||
; Called on first time run, i.e. on system start. No arguments, no results.
|
||||
|
||||
onSystemStart:
|
||||
; todo: setup once timer to start reclaiming address
|
||||
rcall CPRO_StartReclaimAddrProcedure
|
||||
ldi r16, 2 ; DEBUG: set static address
|
||||
sts com2Address, r16
|
||||
|
||||
; rcall printStartSendPackage
|
||||
|
||||
; ldi r16, 0xff ; send to everybody
|
||||
; ldi xl, LOW(com2SendBuffer)
|
||||
; ldi xh, HIGH(com2SendBuffer)
|
||||
; rcall CPRO_WriteComRecvStats
|
||||
|
||||
; rcall printStartSendPackage
|
||||
; rcall COM2_SendPacket
|
||||
; rcall printEndSendPackage
|
||||
|
||||
; rcall printSendStats
|
||||
ret
|
||||
|
||||
|
||||
|
||||
periodicalLcdMark:
|
||||
rcall printTimerMark
|
||||
ret
|
||||
|
||||
|
||||
enqueueComStats:
|
||||
rcall printSendStats
|
||||
ldi r16, 0xff ; send to everybody
|
||||
rcall CPRO_EnqueueComSendStats
|
||||
|
||||
ldi r16, 0xff ; send to everybody
|
||||
rjmp CPRO_EnqueueComRecvStats
|
||||
ldi xl, LOW(com2SendBuffer)
|
||||
ldi xh, HIGH(com2SendBuffer)
|
||||
rcall CPRO_WriteComRecvStats
|
||||
rjmp COM2_SendPacket
|
||||
ret
|
||||
|
||||
|
||||
;enqueueMemStats:
|
||||
; ldi r16, 0xff ; send to everybody
|
||||
; rcall CPRO_EnqueueMemStats
|
||||
|
||||
enqueueMemStats:
|
||||
ldi r16, 0xff ; send to everybody
|
||||
rcall CPRO_EnqueueMemStats
|
||||
|
||||
ldi r16, 0xff ; send to everybody
|
||||
rjmp CPRO_EnqueueDevice
|
||||
; ldi r16, 0xff ; send to everybody
|
||||
; rjmp CPRO_EnqueueDevice
|
||||
|
||||
|
||||
enqueueSysStats:
|
||||
ldi r16, 0xff ; send to everybody
|
||||
rjmp CPRO_EnqueueSysStats
|
||||
;enqueueSysStats:
|
||||
; ldi r16, 0xff ; send to everybody
|
||||
; rjmp CPRO_EnqueueSysStats
|
||||
|
||||
|
||||
|
||||
@@ -344,15 +360,17 @@ onEvery100ms:
|
||||
;
|
||||
; Called after a packet was received via COM module. Add your routine calls here.
|
||||
;
|
||||
; The packet will be removed from buffer in any case after return from this call.
|
||||
; The packet will be released in any case after return from this call.
|
||||
; IN:
|
||||
; - Y : pointer to received buffer
|
||||
; - X : pointer to received buffer
|
||||
; OUT:
|
||||
; - CFLAG: set if handled, cleared otherwise
|
||||
; USED: depending on called routines
|
||||
|
||||
onPacketReceived:
|
||||
rcall CPRO_OnPacketReceived
|
||||
; rcall CPRO_OnPacketReceived
|
||||
sbi PINA, PORTA2 ; debug (toggle)
|
||||
|
||||
ret
|
||||
|
||||
|
||||
|
||||
313
avr/com.asm
313
avr/com.asm
@@ -1,313 +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. *
|
||||
; ***************************************************************************
|
||||
|
||||
|
||||
|
||||
; ***************************************************************************
|
||||
; defines
|
||||
|
||||
.equ COM_MAXWAIT_US = 100 ; maximum wait time in microseconds when waiting for rising/falling clock
|
||||
|
||||
.equ COM_MAINTENANCE_ADDR = 0xf1
|
||||
|
||||
.equ COM_BUFFER_FLAGS_DONE = 0x80
|
||||
.equ COM_BUFFER_FLAGS_RECEIVED = 0x40
|
||||
.equ COM_BUFFER_FLAGS_TOSEND = 0x20
|
||||
.equ COM_BUFFER_FLAGS_RELEASED = 0x10
|
||||
.equ COM_BUFFER_FLAGS_PRIO1 = 0x08
|
||||
.equ COM_BUFFER_FLAGS_PRIO0 = 0x04
|
||||
.equ COM_BUFFER_FLAGS_IFACE1 = 0x02
|
||||
.equ COM_BUFFER_FLAGS_IFACE0 = 0x01
|
||||
|
||||
.equ COM_BUFFER_PRIO_INFO = 0
|
||||
.equ COM_BUFFER_PRIO_NORMAL = COM_BUFFER_FLAGS_PRIO0
|
||||
.equ COM_BUFFER_PRIO_IMPORTANT = COM_BUFFER_FLAGS_PRIO1
|
||||
.equ COM_BUFFER_PRIO_VITAL = (COM_BUFFER_FLAGS_PRIO0 | COM_BUFFER_FLAGS_PRIO1)
|
||||
|
||||
.equ COM_REPEAT_INFO = 3
|
||||
.equ COM_REPEAT_NORMAL = 32
|
||||
.equ COM_REPEAT_IMPORTANT = 64
|
||||
.equ COM_REPEAT_VITAL = 255
|
||||
|
||||
.equ COM_BUFFER_NUM = 6
|
||||
.equ COM_BUFFER_SIZE = 24 ; CAVE: Need to change routine COM_BufferPosToY when changing this value!!
|
||||
|
||||
|
||||
.equ COM_BUFFER_OFFS_FLAGS = 0 ; first byte in buffer is flags byte
|
||||
.equ COM_BUFFER_OFFS_DATA = 1
|
||||
|
||||
.equ COM_MSG_OFFS_DESTADDR = 0
|
||||
.equ COM_MSG_OFFS_MSGLEN = 1
|
||||
.equ COM_MSG_OFFS_MSGDATA = 2
|
||||
.equ COM_MSG_OFFS_CMD = 2 ; first at COM_MSG_OFFS_MSGDATA
|
||||
.equ COM_MSG_OFFS_SRCADDR = 3
|
||||
.equ COM_MSG_OFFS_PAYLOAD = 4 ; payload for the cmd follows here
|
||||
|
||||
.equ COM_ERR_NOTFORME = 1
|
||||
.equ COM_ERR_CHECKSUM = 2
|
||||
.equ COM_ERR_IO = 3
|
||||
|
||||
|
||||
; ***************************************************************************
|
||||
; data
|
||||
|
||||
.dseg
|
||||
|
||||
|
||||
comDataBegin:
|
||||
comFlags: .byte 1
|
||||
comAddress: .byte 1
|
||||
comRepeatCount: .byte 1
|
||||
comReserved1: .byte 1
|
||||
|
||||
comInterrupts: .byte 2
|
||||
|
||||
comStatsPacketsIn: .byte 2
|
||||
comStatsPacketsOut: .byte 2
|
||||
|
||||
comStatsRecvErrs: .byte 2
|
||||
comStatsRecvCrcErrs: .byte 2
|
||||
comStatsMissed: .byte 2
|
||||
comStatsIgnored: .byte 2
|
||||
comStatsHandled: .byte 2
|
||||
|
||||
comStatsCollisions: .byte 2
|
||||
comStatsAborted: .byte 2
|
||||
|
||||
comStatsSendNoBuffer: .byte 2
|
||||
comStatsRecvNoBuffer: .byte 2
|
||||
|
||||
comRecvBuffersReadPos: .byte 1
|
||||
comRecvBuffersWritePos: .byte 1
|
||||
comRecvBuffersUsed: .byte 1
|
||||
comMaxBuffersUsed: .byte 1
|
||||
comRecvBuffers: .byte (COM_BUFFER_SIZE*COM_BUFFER_NUM)
|
||||
comDataEnd:
|
||||
|
||||
|
||||
|
||||
; ***************************************************************************
|
||||
; code
|
||||
|
||||
.cseg
|
||||
|
||||
COM_BEGIN:
|
||||
|
||||
|
||||
comIsrPcint0:
|
||||
push r15
|
||||
in r15, SREG
|
||||
sbic COM_PIN_ATTN, COM_PINNUM_ATTN
|
||||
rjmp comIsrPcint0_end
|
||||
; low, read packet
|
||||
push r1
|
||||
push r16
|
||||
push r17
|
||||
push r18
|
||||
push r19
|
||||
push r20
|
||||
push r21
|
||||
push r22
|
||||
push xh
|
||||
push xl
|
||||
push yh
|
||||
push yl
|
||||
rcall comReceivePacketHandleBuffer ; (R1, R16, R17, R18, R19, R20, R21, R22, X, Y
|
||||
lds xl, comInterrupts
|
||||
lds xh, comInterrupts+1
|
||||
adiw xh:xl, 1
|
||||
sts comInterrupts, xl
|
||||
sts comInterrupts+1, xh
|
||||
pop yl
|
||||
pop yh
|
||||
pop xl
|
||||
pop xh
|
||||
pop r22
|
||||
pop r21
|
||||
pop r20
|
||||
pop r19
|
||||
pop r18
|
||||
pop r17
|
||||
pop r16
|
||||
pop r1
|
||||
|
||||
comIsrPcint0_end:
|
||||
pop r15
|
||||
reti
|
||||
|
||||
|
||||
|
||||
; ---------------------------------------------------------------------------
|
||||
; Com_Init
|
||||
;
|
||||
; IN:
|
||||
; OUT:
|
||||
; - CFLAG: set if okay, clear on error
|
||||
; USED: R16, R17, X, Y
|
||||
|
||||
Com_Init:
|
||||
; preset SRAM data area
|
||||
ldi xh, HIGH(comDataBegin)
|
||||
ldi xl, LOW(comDataBegin)
|
||||
clr r16
|
||||
ldi r17, (comDataEnd-comDataBegin)
|
||||
rcall Utils_FillSram
|
||||
|
||||
; set address to 0 (will be updated later)
|
||||
clr r16
|
||||
sts comAddress, r16
|
||||
|
||||
; setup pins and interrupts
|
||||
cbi COM_PORT_DATA, COM_PINNUM_DATA ; disable internal pullup for DATA
|
||||
cbi COM_DDR_DATA, COM_PINNUM_DATA ; set DATA port as input
|
||||
|
||||
cbi COM_PORT_ATTN, COM_PINNUM_ATTN ; disable internal pullup for ATTN
|
||||
cbi COM_DDR_ATTN, COM_PINNUM_ATTN ; set ATTN port as input
|
||||
|
||||
sbi COM_IRQ_ADDR_ATTN, COM_IRQ_BIT_ATTN ; enable pin change irq for ATTN line
|
||||
in r16, GIMSK ; enable pin change irq PCIE0 or PCIE1
|
||||
ori r16, (1<<COM_IRQ_GIMSK_ATTN)
|
||||
out GIMSK, R16
|
||||
|
||||
ldi r16, (1<<COM_IRQ_GIFR_ATTN) ; clear pending irq by writing 1 to ATTN bit
|
||||
out GIFR, r16
|
||||
|
||||
sec
|
||||
ret
|
||||
|
||||
|
||||
|
||||
; ---------------------------------------------------------------------------
|
||||
; Com_Run
|
||||
;
|
||||
; IN:
|
||||
; - nothing
|
||||
; OUT:
|
||||
; - CFLAG: set if something done, can be called again immediately (otherwise: wait for timer interrupt and retry)
|
||||
; REGS: (R1, R3, R16, R17, R18, R19, R22, X)
|
||||
|
||||
Com_Run:
|
||||
rcall comHandleNextPacketInQueue ; nothing more than handling packages in ringbuffer
|
||||
; clc
|
||||
ret
|
||||
|
||||
|
||||
|
||||
; ---------------------------------------------------------------------------
|
||||
; Mark a packet as enqueued.
|
||||
;
|
||||
; IN:
|
||||
; - Y: pointer to buffer containing the enqueued packet
|
||||
; - R20: priority
|
||||
; OUT:
|
||||
; - CFLAG: set if okay, clear otherwise
|
||||
; MODIFIED REGS: R15, R16
|
||||
|
||||
COM_EnqueuePacket:
|
||||
in r15, SREG
|
||||
cli
|
||||
ldd r16, y+COM_BUFFER_OFFS_FLAGS
|
||||
andi r16, (~(COM_BUFFER_FLAGS_PRIO1 | COM_BUFFER_FLAGS_PRIO0 | COM_BUFFER_FLAGS_RECEIVED | COM_BUFFER_FLAGS_DONE)) & 0xff
|
||||
or r16, r20 ; add priority
|
||||
ori r16, COM_BUFFER_FLAGS_TOSEND
|
||||
std y+COM_BUFFER_OFFS_FLAGS, r16
|
||||
out SREG, r15 ; restore IRQ flag
|
||||
sec
|
||||
ret
|
||||
|
||||
|
||||
|
||||
; ---------------------------------------------------------------------------
|
||||
; comHandleNextPacketInQueue
|
||||
;
|
||||
; IN:
|
||||
; - nothing
|
||||
; OUT:
|
||||
; - CFLAG: set if something done, can be called again immediately (otherwise: wait for timer interrupt and retry)
|
||||
; MODIFIED REGS: R16, R17, Y (R15, R18, R21, R22, X)
|
||||
|
||||
|
||||
comHandleNextPacketInQueue:
|
||||
lds r16, comRecvBuffersUsed
|
||||
tst r16
|
||||
breq comHandleNextPacketInQueue_retNc ; no buffers in use
|
||||
|
||||
lds r16, comRecvBuffersReadPos
|
||||
rcall COM_BufferPosToY ; get current read buffer to Y (R16, R17)
|
||||
ldd r16, y+COM_BUFFER_OFFS_FLAGS ; get flags
|
||||
; check for released buffer (dealloc)
|
||||
mov r17, r16
|
||||
andi r17, COM_BUFFER_FLAGS_RELEASED ; check for buffer released
|
||||
brne comHandleNextPacketInQueue_releaseBuffer
|
||||
; check for received packet
|
||||
mov r17, r16
|
||||
andi r17, COM_BUFFER_FLAGS_RECEIVED
|
||||
brne comHandleNextPacketInQueue_receivedPacket
|
||||
; check for buffer to send
|
||||
mov r17, r16
|
||||
andi r17, COM_BUFFER_FLAGS_TOSEND ; check for message to send
|
||||
brne comHandleNextPacketInQueue_sendPacket
|
||||
; nothing to do (e.g. buffer not ready to be sent)
|
||||
rjmp comHandleNextPacketInQueue_retNc
|
||||
comHandleNextPacketInQueue_sendPacket:
|
||||
rcall comSendPacketHandleRepeat ; (R15, R16, R17, R18, R21, R22, X)
|
||||
ret ; use CFLAG from subroutine
|
||||
comHandleNextPacketInQueue_receivedPacket:
|
||||
clr r17
|
||||
sts comRepeatCount, r17 ; set comRepeatCount to zero
|
||||
rcall comHandleReceivedPacket ; (r16, r17, r21, X)
|
||||
sec ; always return with set CFLAG
|
||||
ret
|
||||
comHandleNextPacketInQueue_releaseBuffer:
|
||||
rcall COM_BufferDeallocFront
|
||||
sec ; always return with set CFLAG
|
||||
ret
|
||||
comHandleNextPacketInQueue_retNc:
|
||||
clc
|
||||
ret
|
||||
|
||||
|
||||
|
||||
; ---------------------------------------------------------------------------
|
||||
; comHandleReceivedPacket
|
||||
;
|
||||
; IN:
|
||||
; - Y: pointer to current buffer (pointed to by comRecvBuffersReadPos)
|
||||
; OUT:
|
||||
; - nothing
|
||||
; MODIFIED REGS: X (r16, r17, r21)
|
||||
|
||||
|
||||
comHandleReceivedPacket:
|
||||
rcall onPacketReceived
|
||||
brcs comHandleReceivedPacket_l1
|
||||
ldi xl, LOW(comStatsIgnored)
|
||||
ldi xh, HIGH(comStatsIgnored)
|
||||
rjmp comHandleReceivedPacket_l2
|
||||
comHandleReceivedPacket_l1:
|
||||
ldi xl, LOW(comStatsHandled)
|
||||
ldi xh, HIGH(comStatsHandled)
|
||||
comHandleReceivedPacket_l2:
|
||||
rcall comDeallocReadBufAndIncrCounter ; (r16, r17, r21)
|
||||
ret
|
||||
|
||||
|
||||
|
||||
|
||||
.include "com_lowlevel.asm"
|
||||
.include "com_buffer.asm"
|
||||
.include "com_crc.asm"
|
||||
.include "com_send.asm"
|
||||
.include "com_recv.asm"
|
||||
|
||||
|
||||
|
||||
COM_END:
|
||||
.equ MODULE_SIZE_COM = COM_END-COM_BEGIN
|
||||
|
||||
804
avr/com2.asm
Normal file
804
avr/com2.asm
Normal file
@@ -0,0 +1,804 @@
|
||||
; ***************************************************************************
|
||||
; 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. *
|
||||
; ***************************************************************************
|
||||
|
||||
|
||||
|
||||
; ***************************************************************************
|
||||
; defines
|
||||
|
||||
.equ COM2_BUFFER_SIZE = 24
|
||||
|
||||
.equ COM2_MAXWAIT_US = 100 ; maximum wait time in microseconds when waiting for rising/falling clock
|
||||
.equ COM2_MAINTENANCE_ADDR = 0xc1
|
||||
.equ COM2_CRC_POLYNOMIAL = 0x97
|
||||
|
||||
|
||||
; flags for variable payload enqueue function
|
||||
.equ COM2_PAYLOAD_FLAGS_SECONDS = 0x01
|
||||
.equ COM2_PAYLOAD_FLAGS_UID = 0x02
|
||||
.equ COM2_PAYLOAD_FLAGS_RESERVED1 = 0x04
|
||||
.equ COM2_PAYLOAD_FLAGS_NUM0 = 0x08
|
||||
.equ COM2_PAYLOAD_FLAGS_NUM1 = 0x10
|
||||
.equ COM2_PAYLOAD_FLAGS_NUM2 = 0x20
|
||||
.equ COM2_PAYLOAD_FLAGS_NUM3 = 0x40
|
||||
.equ COM2_PAYLOAD_FLAGS_NUM4 = 0x80
|
||||
.equ COM2_PAYLOAD_FLAGS_SHIFT_NUM = 3
|
||||
|
||||
|
||||
|
||||
.equ COM2_MSG_OFFS_DESTADDR = 0
|
||||
.equ COM2_MSG_OFFS_MSGLEN = 1
|
||||
.equ COM2_MSG_OFFS_MSGDATA = 2
|
||||
.equ COM2_MSG_OFFS_CMD = 2 ; first at COM2_MSG_OFFS_MSGDATA
|
||||
.equ COM2_MSG_OFFS_SRCADDR = 3
|
||||
.equ COM2_MSG_OFFS_PAYLOAD = 4 ; payload for the cmd follows here
|
||||
|
||||
|
||||
|
||||
; ***************************************************************************
|
||||
; data
|
||||
|
||||
.dseg
|
||||
|
||||
|
||||
com2DataBegin:
|
||||
com2Address: .byte 1
|
||||
|
||||
com2Interrupts: .byte 2
|
||||
|
||||
com2StatsPacketsIn: .byte 2
|
||||
com2StatsPacketsOut: .byte 2
|
||||
|
||||
com2StatsIoError: .byte 2
|
||||
com2StatsContentError: .byte 2
|
||||
com2StatsNoBufferError: .byte 2
|
||||
|
||||
com2StatsBusyError: .byte 2
|
||||
com2StatsCollisions: .byte 2
|
||||
|
||||
com2RecvBuffer: .byte COM2_BUFFER_SIZE
|
||||
com2SendBuffer: .byte COM2_BUFFER_SIZE
|
||||
com2DataEnd:
|
||||
|
||||
|
||||
|
||||
; ***************************************************************************
|
||||
; code
|
||||
|
||||
.cseg
|
||||
|
||||
COM2_BEGIN:
|
||||
|
||||
|
||||
|
||||
|
||||
; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
; Module interface
|
||||
; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
|
||||
|
||||
|
||||
; ---------------------------------------------------------------------------
|
||||
; Com2_Init
|
||||
;
|
||||
; IN:
|
||||
; OUT:
|
||||
; - CFLAG: set if okay, clear on error
|
||||
; USED: R16, R17, X, Y
|
||||
|
||||
Com2_Init:
|
||||
; preset SRAM data area
|
||||
ldi xh, HIGH(com2DataBegin)
|
||||
ldi xl, LOW(com2DataBegin)
|
||||
clr r16
|
||||
ldi r17, (com2DataEnd-com2DataBegin)
|
||||
rcall Utils_FillSram
|
||||
|
||||
; set address to 0 (will be updated later)
|
||||
clr r16
|
||||
sts com2Address, r16
|
||||
|
||||
; setup pins and interrupts
|
||||
cbi COM_PORT_DATA, COM_PINNUM_DATA ; disable internal pullup for DATA
|
||||
cbi COM_DDR_DATA, COM_PINNUM_DATA ; set DATA port as input
|
||||
|
||||
cbi COM_PORT_ATTN, COM_PINNUM_ATTN ; disable internal pullup for ATTN
|
||||
cbi COM_DDR_ATTN, COM_PINNUM_ATTN ; set ATTN port as input
|
||||
|
||||
sbi COM_IRQ_ADDR_ATTN, COM_IRQ_BIT_ATTN ; enable pin change irq for ATTN line
|
||||
in r16, GIMSK ; enable pin change irq PCIE0 or PCIE1
|
||||
ori r16, (1<<COM_IRQ_GIMSK_ATTN)
|
||||
out GIMSK, R16
|
||||
|
||||
ldi r16, (1<<COM_IRQ_GIFR_ATTN) ; clear pending irq by writing 1 to ATTN bit
|
||||
out GIFR, r16
|
||||
|
||||
sec
|
||||
ret
|
||||
|
||||
|
||||
|
||||
; ---------------------------------------------------------------------------
|
||||
; Com_Run
|
||||
;
|
||||
; IN:
|
||||
; - nothing
|
||||
; OUT:
|
||||
; - CFLAG: set if something done, can be called again immediately (otherwise: wait for timer interrupt and retry)
|
||||
; REGS: (R1, R3, R16, R17, R18, R19, R22, X)
|
||||
|
||||
COM2_Run:
|
||||
lds r16, com2RecvBuffer
|
||||
tst r16
|
||||
brne COM2_Run_packetReceived
|
||||
clc
|
||||
ret
|
||||
|
||||
COM2_Run_packetReceived:
|
||||
ldi xl, LOW(com2RecvBuffer)
|
||||
ldi xh, HIGH(com2RecvBuffer)
|
||||
rcall onPacketReceived
|
||||
clr r16
|
||||
sts com2RecvBuffer, r16 ; unlock buffer
|
||||
sec
|
||||
ret
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
; Preparing messages
|
||||
; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
|
||||
|
||||
|
||||
; ---------------------------------------------------------------------------
|
||||
; Write a simple packet into the given buffer with payload being only CMD and source address.
|
||||
;
|
||||
; IN:
|
||||
; - R16: destination address
|
||||
; - R18: command (e.g. CPRO_CMD_PING or CPRO_CMD_PONG)
|
||||
; - X : pointer to buffer to write to
|
||||
; OUT:
|
||||
; - CFLAG: set if okay, clear otherwise
|
||||
; MODIFIED REGS: R16, R17, X, Y (R3, R4, R15, R16, R17, R18, R19, R20, R21)
|
||||
|
||||
COM2_WriteMsgWithCmdAndSrcAddr:
|
||||
ldi r17, COM2_PAYLOAD_FLAGS_SECONDS
|
||||
push xh
|
||||
push xl
|
||||
rcall COM2_BeginMsgWithVariablePayload ; (R3, R4, R16, R17, R18, R19, R20, R21, X)
|
||||
pop xl
|
||||
pop xh
|
||||
rcall com2CalcAndAddChecksumByte ; (R16, R17, R18, R19, X)
|
||||
sec
|
||||
ret
|
||||
COM2_WriteMsgWithCmdAndSrcAddr_error:
|
||||
clc
|
||||
ret
|
||||
|
||||
|
||||
|
||||
; ---------------------------------------------------------------------------
|
||||
; begin packet with variable payload.
|
||||
;
|
||||
; IN:
|
||||
; - R16: destination address
|
||||
; - R17: flags
|
||||
; - R18: command (e.g. CPRO_CMD_PING)
|
||||
; - X : pointer to packet buffer
|
||||
; OUT:
|
||||
; - X : points to end of packet as it was written so far
|
||||
; MODIFIED REGS: R3, R16, R17, R18, R19, R20, R21, X (R4)
|
||||
|
||||
COM2_BeginMsgWithVariablePayload:
|
||||
; write header (dest address, msg length)
|
||||
st X+, r16 ; destination address
|
||||
mov r16, r17 ; calculate payload size
|
||||
mov r3, r17
|
||||
rcall com2CalcPayloadSize ; (R4, R16, R17)
|
||||
inc r16 ; add CMD byte
|
||||
inc r16 ; add source address byte
|
||||
st X+, r16
|
||||
; write payload
|
||||
st X+, r18 ; 0: CMD
|
||||
lds r16, com2Address ; 1: source address
|
||||
st X+, r16
|
||||
lsr r3 ; shift out COM2_PAYLOAD_FLAGS_SECONDS
|
||||
brcc COM2_BeginMsgWithVariablePayload_l1
|
||||
; write seconds
|
||||
lds r16, timerModuleCounterSecs ; adding of current seconds counter requested
|
||||
st X+, r16
|
||||
lds r16, timerModuleCounterSecs+1
|
||||
st X+, r16
|
||||
lds r16, timerModuleCounterSecs+2
|
||||
st X+, r16
|
||||
lds r16, timerModuleCounterSecs+3
|
||||
st X+, r16
|
||||
COM2_BeginMsgWithVariablePayload_l1:
|
||||
lsr r3 ; shift out shift out COM2_PAYLOAD_FLAGS_UID
|
||||
brcc COM2_BeginMsgWithVariablePayload_l2
|
||||
; write uid
|
||||
push xh
|
||||
push xl
|
||||
rcall Utils_ReadUid ; (R16, X)
|
||||
pop xl
|
||||
pop xh
|
||||
st X+, r18
|
||||
st X+, r19
|
||||
st X+, r20
|
||||
st X+, r21
|
||||
COM2_BeginMsgWithVariablePayload_l2:
|
||||
ret
|
||||
|
||||
|
||||
|
||||
; ---------------------------------------------------------------------------
|
||||
; com2CalcPayloadSize
|
||||
;
|
||||
; Calculate payload size from given flags
|
||||
;
|
||||
; IN:
|
||||
; - R16: flags
|
||||
; OUT:
|
||||
; - R16: payload size
|
||||
; MODIFIED REGS: R4, R16, R17
|
||||
|
||||
com2CalcPayloadSize:
|
||||
clr r4
|
||||
ldi r17, 4
|
||||
lsr r16 ; shift out COM2_PAYLOAD_FLAGS_SECONDS
|
||||
brcc com2CalcPayloadSize_l1
|
||||
add r4, r17 ; add 4 bytes
|
||||
com2CalcPayloadSize_l1:
|
||||
lsr r16 ; shift out COM2_PAYLOAD_FLAGS_UID
|
||||
brcc com2CalcPayloadSize_l2
|
||||
add r4, r17 ; add 4 bytes
|
||||
com2CalcPayloadSize_l2:
|
||||
lsr r16 ; shift out reserved1, after this R16 contains COM2_PAYLOAD_FLAGS_NUM0-4
|
||||
add r16, r4 ; add previous bytes to R16
|
||||
ret
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
; Sending and receiving messages
|
||||
; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
|
||||
|
||||
; ---------------------------------------------------------------------------
|
||||
; receive packet.
|
||||
;
|
||||
; OUT:
|
||||
; - CFLAG: set if okay (packet received), cleared on error
|
||||
; REGS: r16, r17, x (r18, r19, r20, r21, r22)
|
||||
|
||||
com2ReceivePacket:
|
||||
ldi xl, LOW(com2RecvBuffer)
|
||||
ldi xh, HIGH(com2RecvBuffer)
|
||||
|
||||
ld r16, X ; check: buffer in use?
|
||||
tst r16
|
||||
breq com2ReceivePacket_bufferAvailable
|
||||
|
||||
ldi xl, LOW(com2StatsNoBufferError) ; buffer in use, don't release
|
||||
ldi xh, HIGH(com2StatsNoBufferError) ; just increment error counter
|
||||
rcall Utils_IncrementCounter16 ; (r18, r19, 22)
|
||||
clc
|
||||
ret
|
||||
|
||||
com2ReceivePacket_bufferAvailable:
|
||||
; read destination address
|
||||
rcall com2ReceiveByte ; read byte (R16, R17, R20, R21, R22)
|
||||
brcc com2ReceivePacket_ioError
|
||||
; compare destination address (accept "FF" and own address)
|
||||
cpi r16, 0xff
|
||||
breq com2ReceivePacket_acceptAddr
|
||||
lds r17, com2Address
|
||||
cp r16, r17
|
||||
breq com2ReceivePacket_acceptAddr
|
||||
clc ; not for me
|
||||
ret
|
||||
|
||||
com2ReceivePacket_acceptAddr:
|
||||
st X+, r16 ; store dest address, lock buffer
|
||||
; read msg length
|
||||
rcall com2ReceiveByte ; read packet length (R16, R17, R20, R21, R22)
|
||||
brcc com2ReceivePacket_ioError
|
||||
st X+, r16
|
||||
cpi r16, (COM2_BUFFER_SIZE-3)
|
||||
brcc com2ReceivePacket_contentError ; packet too long
|
||||
inc r16 ; account for checksum byte
|
||||
mov r17, r16
|
||||
com2ReceivePacket_loop:
|
||||
push r17
|
||||
rcall com2ReceiveByte ; read byte (R16, R17, R20, R21, R22)
|
||||
pop r17
|
||||
brcc com2ReceivePacket_ioError
|
||||
st X+, r16
|
||||
dec r17
|
||||
brne com2ReceivePacket_loop
|
||||
|
||||
ldi xl, LOW(com2RecvBuffer)
|
||||
ldi xh, HIGH(com2RecvBuffer)
|
||||
rcall com2CheckMessageInBuffer ; (R16, R17, R18, R19, R20, X)
|
||||
brcc com2ReceivePacket_contentError
|
||||
; done, increment packet counter, set flags
|
||||
ldi xl, LOW(com2StatsPacketsIn)
|
||||
ldi xh, HIGH(com2StatsPacketsIn)
|
||||
rcall Utils_IncrementCounter16 ; (r18, r19, 22)
|
||||
sec
|
||||
ret
|
||||
|
||||
com2ReceivePacket_ioError:
|
||||
ldi xl, LOW(com2StatsIoError)
|
||||
ldi xh, HIGH(com2StatsIoError)
|
||||
rjmp com2ReceivePacket_incCounter
|
||||
|
||||
com2ReceivePacket_contentError:
|
||||
ldi xl, LOW(com2StatsContentError)
|
||||
ldi xh, HIGH(com2StatsContentError)
|
||||
rjmp com2ReceivePacket_incCounter
|
||||
|
||||
com2ReceivePacket_incCounter:
|
||||
rcall Utils_IncrementCounter16 ; (r18, r19, 22)
|
||||
clr r16
|
||||
sts com2RecvBuffer, r16 ; unlock buffer
|
||||
clc
|
||||
ret
|
||||
|
||||
|
||||
|
||||
; ---------------------------------------------------------------------------
|
||||
; send packet from sendBuffer, if line free.
|
||||
;
|
||||
; IN:
|
||||
; - nothing
|
||||
; OUT:
|
||||
; - CFLAG: set if okay (packet sent), cleared on error
|
||||
; REGS: r22, x (r18, r19, r22)
|
||||
|
||||
COM2_SendPacket:
|
||||
ldi xl, LOW(com2SendBuffer)
|
||||
ldi xh, HIGH(com2SendBuffer)
|
||||
|
||||
COM2_SendPacketAtX:
|
||||
in r15, SREG
|
||||
push r15
|
||||
cli
|
||||
; check for ATTN line: busy?
|
||||
cbi COM_PORT_ATTN, COM_PINNUM_ATTN ; disable pullup on ATTN
|
||||
cbi COM_DDR_ATTN, COM_PINNUM_ATTN ; set ATTN as input
|
||||
nop ; needed to sample current input
|
||||
sbis COM_PIN_ATTN, COM_PINNUM_ATTN ; ATTN low?
|
||||
rjmp COM2_SendPacket_lineBusyError ; jump if it is
|
||||
|
||||
cbi COM_PORT_ATTN, COM_PINNUM_ATTN ; set ATTN low
|
||||
sbi COM_DDR_ATTN, COM_PINNUM_ATTN ; set ATTN as output
|
||||
Utils_WaitNanoSecs COM_BIT_LENGTH, 0, r22 ; wait for one bit duration
|
||||
|
||||
adiw xh:xl, COM2_MSG_OFFS_MSGLEN
|
||||
ld r16, X
|
||||
sbiw xh:xl, COM2_MSG_OFFS_MSGLEN
|
||||
inc r16 ; account for dest addr
|
||||
inc r16 ; account for msglen byte
|
||||
inc r16 ; account for crc byte
|
||||
rcall com2SendPacketRaw
|
||||
|
||||
cbi COM_DDR_ATTN, COM_PINNUM_ATTN ; release ATTN line (by setting direction to IN)
|
||||
brcc COM2_SendPacket_ioError
|
||||
; packet successfully sent
|
||||
ldi xl, LOW(com2StatsPacketsOut)
|
||||
ldi xh, HIGH(com2StatsPacketsOut)
|
||||
rcall Utils_IncrementCounter16 ; (r18, r19, r22)
|
||||
pop r15
|
||||
out SREG, r15
|
||||
sec
|
||||
ret
|
||||
|
||||
COM2_SendPacket_ioError:
|
||||
ldi xl, LOW(com2StatsCollisions)
|
||||
ldi xh, HIGH(com2StatsCollisions)
|
||||
rjmp COM2_SendPacket_incCounter
|
||||
|
||||
COM2_SendPacket_lineBusyError:
|
||||
ldi xl, LOW(com2StatsBusyError)
|
||||
ldi xh, HIGH(com2StatsBusyError)
|
||||
rjmp COM2_SendPacket_incCounter
|
||||
|
||||
COM2_SendPacket_incCounter:
|
||||
rcall Utils_IncrementCounter16 ; (r18, r19, r22)
|
||||
pop r15
|
||||
out SREG, r15
|
||||
clc
|
||||
ret
|
||||
|
||||
|
||||
|
||||
; ---------------------------------------------------------------------------
|
||||
; send packet over wire, expects ATTN to be low.
|
||||
;
|
||||
; IN:
|
||||
; - r16: number of bytes to send
|
||||
; - x : ptr to buffer to send
|
||||
; OUT:
|
||||
; - nothing
|
||||
; REGS: r16, r17, x (r21, r22)
|
||||
|
||||
com2SendPacketRaw:
|
||||
mov r17, r16
|
||||
com2SendPacket_loop:
|
||||
ld r16, X+
|
||||
rcall com2SendByte ; send byte (R16, R21, R22)
|
||||
brcc com2SendPacket_ioError
|
||||
dec r17
|
||||
brne com2SendPacket_loop
|
||||
sec
|
||||
ret
|
||||
com2SendPacket_ioError:
|
||||
clc
|
||||
ret
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
; ISR
|
||||
; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
|
||||
|
||||
|
||||
com2IsrPcint0:
|
||||
push r15
|
||||
in r15, SREG
|
||||
sbic COM_PIN_ATTN, COM_PINNUM_ATTN
|
||||
rjmp com2IsrPcint0_end
|
||||
; low, read packet
|
||||
push r1
|
||||
push r16
|
||||
push r17
|
||||
push r18
|
||||
push r19
|
||||
push r20
|
||||
push r21
|
||||
push r22
|
||||
push xh
|
||||
push xl
|
||||
rcall com2ReceivePacket ; (r16, r17, r18, r19, r20, r21, r22, x)
|
||||
lds xl, com2Interrupts
|
||||
lds xh, com2Interrupts+1
|
||||
adiw xh:xl, 1
|
||||
sts com2Interrupts, xl
|
||||
sts com2Interrupts+1, xh
|
||||
pop xl
|
||||
pop xh
|
||||
pop r22
|
||||
pop r21
|
||||
pop r20
|
||||
pop r19
|
||||
pop r18
|
||||
pop r17
|
||||
pop r16
|
||||
pop r1
|
||||
|
||||
com2IsrPcint0_end:
|
||||
pop r15
|
||||
reti
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
; Lowlevel IO
|
||||
; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
|
||||
|
||||
|
||||
; ---------------------------------------------------------------------------
|
||||
; com2SendByte
|
||||
;
|
||||
; 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
|
||||
; IN:
|
||||
; - R16: byte to send
|
||||
; OUT:
|
||||
; - CFLAG: set if okay, clear otherwise
|
||||
; MODIFIED REGS: R16, R21, R22
|
||||
|
||||
com2SendByte:
|
||||
ldi r21, 8 ; +1 bits left
|
||||
; send startbit
|
||||
cbi COM_PORT_DATA, COM_PINNUM_DATA ; +2 set DATA low
|
||||
sbi COM_DDR_DATA, COM_PINNUM_DATA ; +2 set DATA as output
|
||||
Utils_WaitNanoSecs COM_BIT_LENGTH, 5, r22 ; wait for one bit duration
|
||||
; send data bits
|
||||
com2SendByte_loop: ; 9 for low bit
|
||||
lsr r16 ; 1+ bit to send -> CARRY
|
||||
brcs com2SendByte_setHigh ; HI: +2, LO: +1
|
||||
com2SendByte_setLow:
|
||||
sbi COM_DDR_DATA, COM_PINNUM_DATA ; +2 set DATA as output
|
||||
Utils_WaitNanoSecs COM_BIT_LENGTH, 9, r22
|
||||
rjmp com2SendByte_loopEnd ; +2
|
||||
com2SendByte_setHigh:
|
||||
cbi COM_DDR_DATA, COM_PINNUM_DATA ; +2 set DATA as input, pullup R makes it ONE
|
||||
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
|
||||
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)
|
||||
Utils_WaitNanoSecs COM_BIT_LENGTH/2, 0, r22
|
||||
com2SendByte_loopEnd:
|
||||
dec r21 ; +1
|
||||
brne com2SendByte_loop ; +2, sum per loop: 10 cycles
|
||||
; send stopbit
|
||||
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
|
||||
sec
|
||||
ret
|
||||
|
||||
com2SendByte_error:
|
||||
clc
|
||||
ret
|
||||
|
||||
|
||||
|
||||
; ---------------------------------------------------------------------------
|
||||
; com2ReceiveByte
|
||||
;
|
||||
; Receive a byte.
|
||||
;
|
||||
; IN:
|
||||
; - nothing
|
||||
; OUT:
|
||||
; - CFLAG: set if okay, clear otherwise
|
||||
; - R16: byte read (if CFLAG set)
|
||||
; MODIFIED REGS: R16, R20, R21, R22 (R17)
|
||||
|
||||
com2ReceiveByte:
|
||||
cbi COM_DDR_DATA, COM_PINNUM_DATA ; set DATA port as input
|
||||
cbi COM_PORT_DATA, COM_PINNUM_DATA ; disable internal pullup for DATA
|
||||
|
||||
ldi r21, 8 ; bits left
|
||||
clr r20 ; byte currently receiving
|
||||
; wait for startbit
|
||||
rcall com2WaitForDataLow ; (R17)
|
||||
brcc com2ReceiveByte_error
|
||||
Utils_WaitNanoSecs COM_BIT_LENGTH/2, 5, r22 ; goto middle of startbit to maximize sync stability
|
||||
com2ReceiveByte_loop:
|
||||
Utils_WaitNanoSecs COM_BIT_LENGTH, 8, r22 ; 8 cycles used in the complete loop between waits
|
||||
sec ; +1
|
||||
sbic COM_PIN_DATA, COM_PINNUM_DATA ; LOW: +2, HIGH: +1
|
||||
rjmp com2ReceiveByte_shiftIn ; HIGH: +2, rjmp, use set CFLAG
|
||||
clc ; LOW: +1
|
||||
com2ReceiveByte_shiftIn:
|
||||
ror r20 ; +1
|
||||
dec r21 ; +1
|
||||
brne com2ReceiveByte_loop ; +2, sum per loop: 8 cycles
|
||||
rcall com2WaitForDataHigh ; wait for start of stopbit
|
||||
brcc com2ReceiveByte_error
|
||||
mov r16, r20
|
||||
sec
|
||||
ret
|
||||
com2ReceiveByte_error:
|
||||
clc
|
||||
ret
|
||||
|
||||
|
||||
|
||||
; ---------------------------------------------------------------------------
|
||||
; com2WaitForDataLow
|
||||
;
|
||||
; Waits up to COM2_MAXWAIT_US loops for low data line
|
||||
; IN:
|
||||
; OUT:
|
||||
; - CFLAG: set if okay, clear otherwise
|
||||
; MODIFIED REGISTERS: r17, r22
|
||||
|
||||
com2WaitForDataLow:
|
||||
ldi r17, COM2_MAXWAIT_US
|
||||
|
||||
com2WaitForDataLow_loop:
|
||||
sbis COM_PIN_DATA, COM_PINNUM_DATA
|
||||
rjmp com2WaitForDataLow_done
|
||||
rcall com2WaitFor1000ns
|
||||
dec r17
|
||||
brne com2WaitForDataLow_loop
|
||||
clc ; timeout
|
||||
ret
|
||||
|
||||
com2WaitForDataLow_done:
|
||||
sec ; ok
|
||||
ret
|
||||
|
||||
|
||||
|
||||
; ---------------------------------------------------------------------------
|
||||
; com2WaitForDataHigh
|
||||
;
|
||||
; Waits up to COM2_MAXWAIT_US loops for high data line
|
||||
; IN:
|
||||
; OUT:
|
||||
; - CFLAG: set if okay, clear otherwise
|
||||
; MODIFIED REGISTERS: r17, r22, X
|
||||
|
||||
com2WaitForDataHigh:
|
||||
ldi r17, COM2_MAXWAIT_US
|
||||
|
||||
com2WaitForDataHigh_loop:
|
||||
sbic COM_PIN_DATA, COM_PINNUM_DATA
|
||||
rjmp com2WaitForDataHigh_done
|
||||
rcall com2WaitFor1000ns
|
||||
dec r17
|
||||
brne com2WaitForDataHigh_loop
|
||||
clc ; timeout
|
||||
ret
|
||||
|
||||
com2WaitForDataHigh_done:
|
||||
sec ; ok
|
||||
ret
|
||||
|
||||
|
||||
|
||||
; ---------------------------------------------------------------------------
|
||||
; com2WaitForAttnHigh
|
||||
;
|
||||
; Waits up to COM2_MAXWAIT_US loops for high ATTN line
|
||||
; IN:
|
||||
; OUT:
|
||||
; - CFLAG: set if okay, clear otherwise
|
||||
; MODIFIED REGISTERS: r17, r22, X
|
||||
|
||||
com2WaitForAttnHigh:
|
||||
ldi r17, COM2_MAXWAIT_US
|
||||
|
||||
com2WaitForAttnHigh_loop:
|
||||
sbic COM_PIN_ATTN, COM_PINNUM_ATTN
|
||||
rjmp com2WaitForAttnHigh_done
|
||||
rcall com2WaitFor1000ns
|
||||
dec r17
|
||||
brne com2WaitForAttnHigh_loop
|
||||
clc ; timeout
|
||||
ret
|
||||
|
||||
com2WaitForAttnHigh_done:
|
||||
sec ; ok
|
||||
ret
|
||||
|
||||
|
||||
|
||||
; ---------------------------------------------------------------------------
|
||||
; comWaitFor100ns
|
||||
;
|
||||
; Waits for 100 nanoseconds.
|
||||
; IN:
|
||||
; OUT:
|
||||
; - CFLAG: set if okay, clear otherwise
|
||||
; REGS: r17, r22
|
||||
|
||||
com2WaitFor1000ns:
|
||||
Utils_WaitNanoSecs 1000, 7, r22 ; wait for 100 nanosecs (minus 3 cycles for rcall, 4 for ret)
|
||||
ret
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
; CRC code
|
||||
; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
|
||||
|
||||
; ---------------------------------------------------------------------------
|
||||
; add checksum byte to buffer
|
||||
;
|
||||
; IN:
|
||||
; - X : pointer to packet buffer
|
||||
; OUT:
|
||||
; - CFLAG: set if okay, clear otherwise
|
||||
; MODIFIED REGS: R16, R17, R18, R19, X
|
||||
|
||||
com2CalcAndAddChecksumByte:
|
||||
adiw xh:xl, COM2_MSG_OFFS_MSGLEN
|
||||
ld r18, X ; read msg len
|
||||
sbiw xh:xl, COM2_MSG_OFFS_MSGLEN
|
||||
inc r18 ; account for dest address
|
||||
inc r18 ; account for msg len byte
|
||||
ldi r19, COM2_CRC_POLYNOMIAL
|
||||
rcall com2CalcCrc8 ; (R16, R17, R18, R20, X)
|
||||
st X, r16 ; add checksum byte
|
||||
sec
|
||||
ret
|
||||
|
||||
|
||||
|
||||
; ---------------------------------------------------------------------------
|
||||
; check message in buffer
|
||||
;
|
||||
; IN:
|
||||
; - X : pointer to packet buffer
|
||||
; OUT:
|
||||
; - CFLAG: set if okay, clear otherwise
|
||||
; MODIFIED REGS: R16, R17, R18, R19, R20, X
|
||||
|
||||
com2CheckMessageInBuffer:
|
||||
adiw xh:xl, COM2_MSG_OFFS_MSGLEN
|
||||
ld r18, X ; read msg len
|
||||
sbiw xh:xl, COM2_MSG_OFFS_MSGLEN
|
||||
inc r18 ; account for dest address
|
||||
inc r18 ; account for msg len byte
|
||||
ldi r19, COM2_CRC_POLYNOMIAL
|
||||
rcall com2CalcCrc8 ; (R16, R17, R18, R20, X)
|
||||
ld r17, X
|
||||
cp r16, r17 ; should be equal
|
||||
brne com2CheckMessageInBuffer_error
|
||||
sec
|
||||
ret
|
||||
com2CheckMessageInBuffer_error:
|
||||
clc
|
||||
ret
|
||||
|
||||
|
||||
|
||||
; ---------------------------------------------------------------------------
|
||||
; calc crc8 checksum using given polynomial
|
||||
;
|
||||
; IN:
|
||||
; - X : pointer to data to calc crc8 for
|
||||
; - r18: number of bytes to calc crc8 for
|
||||
; - r19: polynomial to use (e.g. 0x97: HD=4 up to 119 bytes, e.g. detects all 1 to 3 bit errors)
|
||||
; OUT:
|
||||
; - r16: crc8 checksum
|
||||
; - X : point directly behind the checked area
|
||||
; MODIFIED REGS: R16, R17, R18, R20, X
|
||||
|
||||
com2CalcCrc8:
|
||||
ldi r16, 0xff ; crc
|
||||
|
||||
com2CalcCrc8_loop1:
|
||||
ld r17, X+ ; running var
|
||||
eor r16, r17
|
||||
ldi r20, 8 ; counter for loop2
|
||||
com2CalcCrc8_loop2:
|
||||
lsl r16
|
||||
brcc com2CalcCrc8_l1
|
||||
eor r16, r19
|
||||
com2CalcCrc8_l1:
|
||||
dec r20
|
||||
brne com2CalcCrc8_loop2
|
||||
dec r18
|
||||
brne com2CalcCrc8_loop1
|
||||
ret
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
COM2_END:
|
||||
.equ MODULE_SIZE_COM2 = COM2_END-COM2_BEGIN
|
||||
|
||||
@@ -1,211 +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
|
||||
|
||||
COM_BUFFER_BEGIN:
|
||||
|
||||
|
||||
; ---------------------------------------------------------------------------
|
||||
; COM_AllocBufferAndGetXY
|
||||
;
|
||||
; IN:
|
||||
; - nothing
|
||||
; OUT:
|
||||
; - CFLAG: set if okay, clear otherwise
|
||||
; - Y: pointer to buffer
|
||||
; - X: pointer to data portion of the buffer
|
||||
; MODIFIED REGS: R16, R17 (R21)
|
||||
|
||||
COM_AllocBufferAndGetXY:
|
||||
rcall COM_BufferAlloc ; (r16, r17, r21)
|
||||
brcc COM_AllocBufferAndGetXY_error
|
||||
mov xl, yl
|
||||
mov xh, yh
|
||||
adiw xh:xl, COM_BUFFER_OFFS_DATA
|
||||
sec
|
||||
ret
|
||||
COM_AllocBufferAndGetXY_error:
|
||||
ldi xl, LOW(comStatsSendNoBuffer)
|
||||
ldi xh, HIGH(comStatsSendNoBuffer)
|
||||
clc
|
||||
ret
|
||||
|
||||
|
||||
|
||||
; ---------------------------------------------------------------------------
|
||||
; COM_BufferAlloc
|
||||
;
|
||||
; Allocate a transfer buffer.
|
||||
; IN:
|
||||
; - nothing
|
||||
; OUT:
|
||||
; - CFLAG: set if okay, clear otherwise
|
||||
; - Y: pointer to allocated buffer in SRAM
|
||||
; MODIFIED REGISTERS: r16, r17, r21
|
||||
|
||||
|
||||
COM_BufferAlloc:
|
||||
in r21, SREG ; save global interrupt enable bit from SREG
|
||||
cli
|
||||
lds r17, comRecvBuffersUsed
|
||||
cpi r17, COM_BUFFER_NUM
|
||||
brcc COM_AllocBuffer_error ; no buffer available
|
||||
inc r17 ; increment number of buffers used
|
||||
sts comRecvBuffersUsed, r17 ; store new value
|
||||
lds r16, comMaxBuffersUsed ; calc max buffers used
|
||||
cp r16, r17
|
||||
brcc COM_AllocBuffer_l0
|
||||
sts comMaxBuffersUsed, r17
|
||||
COM_AllocBuffer_l0:
|
||||
lds r16, comRecvBuffersWritePos ; get current write pos
|
||||
mov r17, r16 ; increment for next call
|
||||
inc r17
|
||||
cpi r17, COM_BUFFER_NUM ; CF set if COM_BUFFER_NUM > R17
|
||||
brcs COM_AllocBuffer_l1
|
||||
clr r17 ; wraparound
|
||||
COM_AllocBuffer_l1:
|
||||
sts comRecvBuffersWritePos, r17 ; store new writepos for next caller
|
||||
rcall COM_BufferPosToY ; (R16, R17)
|
||||
clr r17
|
||||
std y+COM_BUFFER_OFFS_FLAGS, r17 ; preset flags
|
||||
out SREG, r21 ; restore global interrupt enable bit in SREG
|
||||
sec
|
||||
ret
|
||||
COM_AllocBuffer_error:
|
||||
out SREG, r21
|
||||
clc
|
||||
ret
|
||||
|
||||
|
||||
|
||||
; ---------------------------------------------------------------------------
|
||||
; COM_BufferDeallocBack
|
||||
;
|
||||
; Release a transfer buffer at the end of the list by decreasing the write pos.
|
||||
; This releases the last allocated buffer!
|
||||
;
|
||||
; IN:
|
||||
; - nothing
|
||||
; OUT:
|
||||
; - CFLAG: set if okay, clear otherwise
|
||||
; MODIFIED REGISTERS: r16, r17, r21
|
||||
|
||||
COM_BufferDeallocBack:
|
||||
in r21, SREG ; save global interrupt enable bit from SREG
|
||||
cli
|
||||
lds r17, comRecvBuffersUsed
|
||||
tst r17
|
||||
breq COM_BufferDeallocBack_error ; no buffer allocated, nothing to release
|
||||
dec r17
|
||||
sts comRecvBuffersUsed, r17 ; store new value
|
||||
lds r17, comRecvBuffersWritePos
|
||||
tst r17 ; 0?
|
||||
brne COM_BufferDeallocBack_l1 ; nope go directly decrement r17
|
||||
ldi r17, COM_BUFFER_NUM ; wrap-around
|
||||
COM_BufferDeallocBack_l1:
|
||||
dec r17
|
||||
sts comRecvBuffersWritePos, r17
|
||||
out SREG, r21
|
||||
sec
|
||||
ret
|
||||
COM_BufferDeallocBack_error:
|
||||
out SREG, r21
|
||||
clc
|
||||
ret
|
||||
|
||||
|
||||
|
||||
; ---------------------------------------------------------------------------
|
||||
; COM_BufferDeallocFront
|
||||
;
|
||||
; Release a transfer buffer by increasing the read pos.
|
||||
;
|
||||
; IN:
|
||||
; - nothing
|
||||
; OUT:
|
||||
; - CFLAG: set if okay, clear otherwise
|
||||
; MODIFIED REGISTERS: r16, r17, r21
|
||||
|
||||
COM_BufferDeallocFront:
|
||||
in r21, SREG ; save global interrupt enable bit from SREG
|
||||
cli
|
||||
lds r17, comRecvBuffersUsed
|
||||
tst r17
|
||||
breq COM_BufferDeallocFront_error ; no buffer allocated, nothing to release
|
||||
dec r17
|
||||
sts comRecvBuffersUsed, r17 ; store new value
|
||||
lds r17, comRecvBuffersReadPos
|
||||
inc r17
|
||||
cpi r17, COM_BUFFER_NUM
|
||||
brcs COM_BufferDeallocFront_l1
|
||||
clr r17 ; wrap-around
|
||||
COM_BufferDeallocFront_l1:
|
||||
sts comRecvBuffersReadPos, r17
|
||||
out SREG, r21
|
||||
sec
|
||||
ret
|
||||
COM_BufferDeallocFront_error:
|
||||
out SREG, r21
|
||||
clc
|
||||
ret
|
||||
|
||||
|
||||
|
||||
; ---------------------------------------------------------------------------
|
||||
; COM_BufferPosToY
|
||||
;
|
||||
; Get a pointer to the SRAM position of the given buffer.
|
||||
; CAVE: Code must correspond to COM_BUFFER_SIZE!!
|
||||
; IN:
|
||||
; - R16: buffer number (starting with 0)
|
||||
; OUT:
|
||||
; - Y: pointer to buffer in SRAM
|
||||
; MODIFIED REGISTERS: R16, R17
|
||||
|
||||
COM_BufferPosToY:
|
||||
; calculate offset
|
||||
clr r17
|
||||
mov yl, r16
|
||||
clr yh
|
||||
|
||||
lsl yl
|
||||
rol yh ; *2
|
||||
|
||||
add yl, r16
|
||||
adc yh, r17 ; *3
|
||||
|
||||
lsl yl
|
||||
rol yh ; *6
|
||||
|
||||
lsl yl
|
||||
rol yh ; *12
|
||||
|
||||
lsl yl
|
||||
rol yh ; *24
|
||||
|
||||
; add base position of buffers
|
||||
ldi r16, LOW(comRecvBuffers)
|
||||
ldi r17, HIGH(comRecvBuffers)
|
||||
add yl, r16
|
||||
adc yh, r17
|
||||
ret
|
||||
|
||||
|
||||
COM_BUFFER_END:
|
||||
.equ MODULE_SIZE_COM_BUFFER = COM_BUFFER_END-COM_BUFFER_BEGIN
|
||||
|
||||
|
||||
|
||||
143
avr/com_crc.asm
143
avr/com_crc.asm
@@ -1,143 +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. *
|
||||
; ***************************************************************************
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#define COM_USE_CRC8 1
|
||||
#define COM_CRC_POLYNOMIAL 0x97
|
||||
|
||||
|
||||
|
||||
; ***************************************************************************
|
||||
; code
|
||||
|
||||
.cseg
|
||||
|
||||
|
||||
COM_CRC_BEGIN:
|
||||
|
||||
|
||||
|
||||
; ---------------------------------------------------------------------------
|
||||
; add checksum byte to buffer
|
||||
;
|
||||
; IN:
|
||||
; - X : pointer to packet buffer
|
||||
; OUT:
|
||||
; - CFLAG: set if okay, clear otherwise
|
||||
; MODIFIED REGS: R16, R17, R18, R19, X
|
||||
|
||||
comCalcAndAddChecksumByte:
|
||||
adiw xh:xl, COM_MSG_OFFS_MSGLEN
|
||||
ld r18, X ; read msg len
|
||||
inc r18 ; account for dest address
|
||||
inc r18 ; account for msg len byte
|
||||
sbiw xh:xl, COM_MSG_OFFS_MSGLEN
|
||||
#ifdef COM_USE_CRC8
|
||||
ldi r19, COM_CRC_POLYNOMIAL
|
||||
rcall cproCalcCrc8 ; (R16, R17, R18, R20, X)
|
||||
#else
|
||||
rcall cproCalcXor ; (R16, R17, R18, X)
|
||||
#endif
|
||||
st X, r16 ; add checksum byte
|
||||
sec
|
||||
ret
|
||||
|
||||
|
||||
|
||||
; ---------------------------------------------------------------------------
|
||||
; check message in buffer
|
||||
;
|
||||
; IN:
|
||||
; - X : pointer to packet buffer
|
||||
; OUT:
|
||||
; - CFLAG: set if okay, clear otherwise
|
||||
; MODIFIED REGS: R16, R17, R18, R19, R20, X
|
||||
|
||||
cproCheckMessageInBuffer:
|
||||
adiw xh:xl, COM_MSG_OFFS_MSGLEN
|
||||
ld r18, X ; read msg len
|
||||
inc r18 ; account for dest address
|
||||
inc r18 ; account for msg len byte
|
||||
sbiw xh:xl, COM_MSG_OFFS_MSGLEN
|
||||
#ifdef COM_USE_CRC8
|
||||
ldi r19, COM_CRC_POLYNOMIAL
|
||||
rcall cproCalcCrc8 ; (R16, R17, R18, R20, X)
|
||||
#else
|
||||
rcall cproCalcXor ; (R16, R17, R18, X)
|
||||
#endif
|
||||
ld r17, X
|
||||
cp r16,r17 ; should be equal
|
||||
brne cproCheckMessageInBuffer_error
|
||||
sec
|
||||
ret
|
||||
cproCheckMessageInBuffer_error:
|
||||
clc
|
||||
ret
|
||||
|
||||
|
||||
|
||||
; ---------------------------------------------------------------------------
|
||||
; calc xor checksum
|
||||
;
|
||||
; IN:
|
||||
; - X : pointer to data to calc crc8 for
|
||||
; - r18: number of bytes to calc crc8 for
|
||||
; OUT:
|
||||
; - r16: xor checksum
|
||||
; - X : point directly behind the checked area
|
||||
; MODIFIED REGS: R16, R17, R18, X
|
||||
cproCalcXor:
|
||||
clr r16
|
||||
cproCalcXor_loop1:
|
||||
ld r17, X+
|
||||
eor r16, r17
|
||||
dec r18
|
||||
brne cproCalcXor_loop1
|
||||
ret
|
||||
|
||||
|
||||
|
||||
; ---------------------------------------------------------------------------
|
||||
; calc crc8 checksum using given polynomial
|
||||
;
|
||||
; IN:
|
||||
; - X : pointer to data to calc crc8 for
|
||||
; - r18: number of bytes to calc crc8 for
|
||||
; - r19: polynomial to use (e.g. 0x97: HD=4 up to 119 bytes, e.g. detects all 1 to 3 bit errors)
|
||||
; OUT:
|
||||
; - r16: crc8 checksum
|
||||
; - X : point directly behind the checked area
|
||||
; MODIFIED REGS: R16, R17, R18, R20, X
|
||||
|
||||
cproCalcCrc8:
|
||||
ldi r16, 0xff ; crc
|
||||
|
||||
cproCalcCrc8_loop1:
|
||||
ld r17, X+ ; running var
|
||||
eor r16, r17
|
||||
ldi r20, 8 ; counter for loop2
|
||||
cproCalcCrc8_loop2:
|
||||
lsl r16
|
||||
brcc cproCalcCrc8_l1
|
||||
eor r16, r19
|
||||
cproCalcCrc8_l1:
|
||||
dec r20
|
||||
brne cproCalcCrc8_loop2
|
||||
dec r18
|
||||
brne cproCalcCrc8_loop1
|
||||
ret
|
||||
|
||||
|
||||
COM_CRC_END:
|
||||
.equ MODULE_SIZE_COM_CRC = COM_CRC_END-COM_CRC_BEGIN
|
||||
|
||||
|
||||
@@ -1,215 +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
|
||||
|
||||
|
||||
COM_LOWLEVEL_BEGIN:
|
||||
|
||||
|
||||
; ---------------------------------------------------------------------------
|
||||
; comSendByte
|
||||
;
|
||||
; 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
|
||||
; IN:
|
||||
; - R16: byte to send
|
||||
; OUT:
|
||||
; - CFLAG: set if okay, clear otherwise
|
||||
; MODIFIED REGS: R16, R21, R22
|
||||
|
||||
comSendByte:
|
||||
ldi r21, 8 ; +1 bits left
|
||||
; send startbit
|
||||
cbi COM_PORT_DATA, COM_PINNUM_DATA ; +2 set DATA low
|
||||
sbi COM_DDR_DATA, COM_PINNUM_DATA ; +2 set DATA as output
|
||||
Utils_WaitNanoSecs COM_BIT_LENGTH, 5, r22 ; wait for one bit duration
|
||||
; send data bits
|
||||
comSendByte_loop: ; 9 for low bit
|
||||
lsr r16 ; 1+ bit to send -> CARRY
|
||||
brcs comSendByte_setHigh ; HI: +2, LO: +1
|
||||
comSendByte_setLow:
|
||||
sbi COM_DDR_DATA, COM_PINNUM_DATA ; +2 set DATA as output
|
||||
Utils_WaitNanoSecs COM_BIT_LENGTH, 9, r22
|
||||
rjmp comSendByte_loopEnd ; +2
|
||||
comSendByte_setHigh:
|
||||
cbi COM_DDR_DATA, COM_PINNUM_DATA ; +2 set DATA as input, pullup R makes it ONE
|
||||
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
|
||||
sbis COM_PIN_DATA, COM_PINNUM_DATA ; +1 if no skip, +2 if skipped
|
||||
rjmp comSendByte_error ; +2 if error (collision: we wanted line to be high but it is low)
|
||||
Utils_WaitNanoSecs COM_BIT_LENGTH/2, 0, r22
|
||||
comSendByte_loopEnd:
|
||||
dec r21 ; +1
|
||||
brne comSendByte_loop ; +2, sum per loop: 10 cycles
|
||||
; send stopbit
|
||||
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
|
||||
sec
|
||||
ret
|
||||
|
||||
comSendByte_error:
|
||||
clc
|
||||
ret
|
||||
|
||||
|
||||
|
||||
; ---------------------------------------------------------------------------
|
||||
; comReceiveByte
|
||||
;
|
||||
; Receive a byte.
|
||||
;
|
||||
; IN:
|
||||
; - nothing
|
||||
; OUT:
|
||||
; - CFLAG: set if okay, clear otherwise
|
||||
; - R16: byte read (if CFLAG set)
|
||||
; MODIFIED REGS: R16, R20, R21, R22 (R17)
|
||||
|
||||
comReceiveByte:
|
||||
cbi COM_DDR_DATA, COM_PINNUM_DATA ; set DATA port as input
|
||||
cbi COM_PORT_DATA, COM_PINNUM_DATA ; disable internal pullup for DATA
|
||||
|
||||
ldi r21, 8 ; bits left
|
||||
clr r20 ; byte currently receiving
|
||||
; wait for startbit
|
||||
rcall comWaitForDataLow ; (R17)
|
||||
brcc comReceiveByte_error
|
||||
Utils_WaitNanoSecs COM_BIT_LENGTH/2, 5, r22 ; goto middle of startbit to maximize sync stability
|
||||
comReceiveByte_loop:
|
||||
Utils_WaitNanoSecs COM_BIT_LENGTH, 8, r22 ; 8 cycles used in the complete loop between waits
|
||||
sec ; +1
|
||||
sbic COM_PIN_DATA, COM_PINNUM_DATA ; LOW: +2, HIGH: +1
|
||||
rjmp comReceiveByte_shiftIn ; HIGH: +2, rjmp, use set CFLAG
|
||||
clc ; LOW: +1
|
||||
comReceiveByte_shiftIn:
|
||||
ror r20 ; +1
|
||||
dec r21 ; +1
|
||||
brne comReceiveByte_loop ; +2, sum per loop: 8 cycles
|
||||
rcall comWaitForDataHigh ; wait for start of stopbit
|
||||
brcc comReceiveByte_error
|
||||
mov r16, r20
|
||||
sec
|
||||
ret
|
||||
comReceiveByte_error:
|
||||
clc
|
||||
ret
|
||||
|
||||
|
||||
|
||||
; ---------------------------------------------------------------------------
|
||||
; comWaitForDataLow
|
||||
;
|
||||
; Waits up to COM_MAXWAIT_US loops for low data line
|
||||
; IN:
|
||||
; OUT:
|
||||
; - CFLAG: set if okay, clear otherwise
|
||||
; MODIFIED REGISTERS: r17, r22
|
||||
|
||||
comWaitForDataLow:
|
||||
ldi r17, COM_MAXWAIT_US
|
||||
|
||||
comWaitForDataLow_loop:
|
||||
sbis COM_PIN_DATA, COM_PINNUM_DATA
|
||||
rjmp comWaitForDataLow_done
|
||||
rcall comWaitFor1000ns
|
||||
dec r17
|
||||
brne comWaitForDataLow_loop
|
||||
clc ; timeout
|
||||
ret
|
||||
|
||||
comWaitForDataLow_done:
|
||||
sec ; ok
|
||||
ret
|
||||
|
||||
|
||||
|
||||
; ---------------------------------------------------------------------------
|
||||
; comWaitForDataHigh
|
||||
;
|
||||
; Waits up to COM_MAXWAIT_US loops for high data line
|
||||
; IN:
|
||||
; OUT:
|
||||
; - CFLAG: set if okay, clear otherwise
|
||||
; MODIFIED REGISTERS: r17, r22, X
|
||||
|
||||
comWaitForDataHigh:
|
||||
ldi r17, COM_MAXWAIT_US
|
||||
|
||||
comWaitForDataHigh_loop:
|
||||
sbic COM_PIN_DATA, COM_PINNUM_DATA
|
||||
rjmp comWaitForDataHigh_done
|
||||
rcall comWaitFor1000ns
|
||||
dec r17
|
||||
brne comWaitForDataHigh_loop
|
||||
clc ; timeout
|
||||
ret
|
||||
|
||||
comWaitForDataHigh_done:
|
||||
sec ; ok
|
||||
ret
|
||||
|
||||
|
||||
|
||||
; ---------------------------------------------------------------------------
|
||||
; comWaitForAttnHigh
|
||||
;
|
||||
; Waits up to COM_MAXWAIT_US loops for high ATTN line
|
||||
; IN:
|
||||
; OUT:
|
||||
; - CFLAG: set if okay, clear otherwise
|
||||
; MODIFIED REGISTERS: r17, r22, X
|
||||
|
||||
comWaitForAttnHigh:
|
||||
ldi r17, COM_MAXWAIT_US
|
||||
|
||||
comWaitForAttnHigh_loop:
|
||||
sbic COM_PIN_ATTN, COM_PINNUM_ATTN
|
||||
rjmp comWaitForAttnHigh_done
|
||||
rcall comWaitFor1000ns
|
||||
dec r17
|
||||
brne comWaitForAttnHigh_loop
|
||||
clc ; timeout
|
||||
ret
|
||||
|
||||
comWaitForAttnHigh_done:
|
||||
sec ; ok
|
||||
ret
|
||||
|
||||
|
||||
|
||||
; ---------------------------------------------------------------------------
|
||||
; comWaitFor100ns
|
||||
;
|
||||
; Waits for 100 nanoseconds.
|
||||
; IN:
|
||||
; OUT:
|
||||
; - CFLAG: set if okay, clear otherwise
|
||||
; MODIFIED REGISTERS: r17, r22, X
|
||||
|
||||
comWaitFor1000ns:
|
||||
Utils_WaitNanoSecs 1000, 7, r22 ; wait for 100 nanosecs (minus 3 cycles for rcall, 4 for ret)
|
||||
ret
|
||||
|
||||
|
||||
COM_LOWLEVEL_END:
|
||||
.equ MODULE_SIZE_COM_LOWLEVEL = COM_LOWLEVEL_END-COM_LOWLEVEL_BEGIN
|
||||
|
||||
|
||||
|
||||
161
avr/com_recv.asm
161
avr/com_recv.asm
@@ -1,161 +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
|
||||
|
||||
COM_RECV_BEGIN:
|
||||
|
||||
|
||||
; ---------------------------------------------------------------------------
|
||||
; comReceivePacketHandleBuffer
|
||||
;
|
||||
; Allocate a buffer and receive a packet into it.
|
||||
; On success the buffer flags will have COM_BUFFER_FLAGS_RECEIVED set.
|
||||
; On error the buffer will be deallocated.
|
||||
; IN:
|
||||
; - nothing
|
||||
; OUT:
|
||||
; - CFLAG: set if okay, cleared otherwise
|
||||
; MODIFIED REGISTERS: R16, R17, X, Y (R1, R18, R19, R20, R21, R22)
|
||||
|
||||
comReceivePacketHandleBuffer:
|
||||
rcall COM_BufferAlloc
|
||||
brcs comReceivePacketHandleBuffer_haveBuffer
|
||||
ldi xl, LOW(comStatsRecvNoBuffer)
|
||||
ldi xh, HIGH(comStatsRecvNoBuffer)
|
||||
rjmp comReceivePacketHandleBuffer_errorWithCounter
|
||||
|
||||
comReceivePacketHandleBuffer_haveBuffer:
|
||||
; get pos of data portion for the allocated buffer
|
||||
mov xl, yl
|
||||
mov xh, yh
|
||||
adiw xh:xl, COM_BUFFER_OFFS_DATA
|
||||
rcall comReceivePacketToXandCheck ; (r16, r17, r18, r20, r21, r22, X)
|
||||
brcs comReceivePacketHandleBuffer_haveMessage
|
||||
push r16
|
||||
rcall COM_BufferDeallocBack ; (r16, r17, r21)
|
||||
pop r16
|
||||
cpi r16, COM_ERR_NOTFORME ; packet just not for me?
|
||||
breq comReceivePacketHandleBuffer_notforme ; correct, don't count as error
|
||||
ldi xl, LOW(comStatsRecvCrcErrs)
|
||||
ldi xh, HIGH(comStatsRecvCrcErrs)
|
||||
cpi r16, COM_ERR_CHECKSUM
|
||||
breq comReceivePacketHandleBuffer_errorWithCounter
|
||||
ldi xl, LOW(comStatsRecvErrs) ; generic error
|
||||
ldi xh, HIGH(comStatsRecvErrs)
|
||||
rjmp comReceivePacketHandleBuffer_errorWithCounter
|
||||
|
||||
comReceivePacketHandleBuffer_haveMessage:
|
||||
; handle buffer flags
|
||||
ldi r16, COM_BUFFER_FLAGS_RECEIVED
|
||||
std y+COM_BUFFER_OFFS_FLAGS, r16
|
||||
ldi xl, LOW(comStatsPacketsIn)
|
||||
ldi xh, HIGH(comStatsPacketsIn)
|
||||
rcall Utils_IncrementCounter16 ; (r18, r19, 22)
|
||||
sec
|
||||
ret
|
||||
|
||||
comReceivePacketHandleBuffer_errorWithCounter:
|
||||
rcall Utils_IncrementCounter16 ; (r18, r19, 22)
|
||||
comReceivePacketHandleBuffer_notforme:
|
||||
clc
|
||||
ret
|
||||
|
||||
|
||||
|
||||
; ---------------------------------------------------------------------------
|
||||
; comReceivePacketToXandCheck
|
||||
;
|
||||
; Receive a packet to the given SRAM position.
|
||||
; IN:
|
||||
; - X: pointer to start of buffer to receive bytes
|
||||
; OUT:
|
||||
; - CFLAG: set if okay, clear otherwise
|
||||
; - R16: error code if CFLAG cleared
|
||||
; MODIFIED REGISTERS: r16, r17, r18, X (r19, r20, r21, r22)
|
||||
|
||||
comReceivePacketToXandCheck:
|
||||
push xh
|
||||
push xl
|
||||
rcall comReceivePacketToSram ; (r16, r17, R20, R21, R22, X)
|
||||
pop xl
|
||||
pop xh
|
||||
brcc comReceivePacketToXandCheck_error
|
||||
rcall cproCheckMessageInBuffer ; (R16, R17, R18, R19, R20, X)
|
||||
ldi r16, COM_ERR_CHECKSUM
|
||||
brcc comReceivePacketToXandCheck_error
|
||||
sec
|
||||
ret
|
||||
comReceivePacketToXandCheck_error:
|
||||
clc
|
||||
ret
|
||||
|
||||
|
||||
|
||||
; ---------------------------------------------------------------------------
|
||||
; comReceivePacketToSram
|
||||
;
|
||||
; Receive a packet to the given SRAM position.
|
||||
; IN:
|
||||
; - X: pointer to start of buffer to receive bytes
|
||||
; OUT:
|
||||
; - CFLAG: set if okay, clear otherwise
|
||||
; MODIFIED REGISTERS: r16, r17, X (R20, R21, R22)
|
||||
|
||||
comReceivePacketToSram:
|
||||
; read destination address
|
||||
rcall comReceiveByte ; read byte (R16, R17, R20, R21, R22)
|
||||
brcc comReceivePacketToSram_error
|
||||
; compare destination address (accept "00", "FF" and own address)
|
||||
tst r16
|
||||
breq comReceivePacketToSram_acceptAddr
|
||||
cpi r16, 0xff
|
||||
breq comReceivePacketToSram_acceptAddr
|
||||
lds r17, comAddress
|
||||
cp r16, r17
|
||||
breq comReceivePacketToSram_acceptAddr
|
||||
ldi r16, COM_ERR_NOTFORME
|
||||
clc ; not for me
|
||||
ret
|
||||
comReceivePacketToSram_acceptAddr:
|
||||
st X+, r16 ; store dest address
|
||||
; read msg length
|
||||
rcall comReceiveByte ; read packet length (R16, R17, R20, R21, R22)
|
||||
brcc comReceivePacketToSram_error
|
||||
st X+, r16
|
||||
cpi r16, (COM_BUFFER_SIZE-3-COM_BUFFER_OFFS_DATA)+1
|
||||
brcc comReceivePacketToSram_error ; packet too long (TODO: count overruns)
|
||||
inc r16 ; account for checksum byte
|
||||
mov r17, r16
|
||||
comReceivePacketToSram_loop:
|
||||
push r17
|
||||
rcall comReceiveByte ; read byte (R16, R17, R20, R21, R22)
|
||||
pop r17
|
||||
brcc comReceivePacketToSram_error
|
||||
st X+, r16
|
||||
dec r17
|
||||
brne comReceivePacketToSram_loop
|
||||
sec
|
||||
ret
|
||||
comReceivePacketToSram_error:
|
||||
ldi r16, COM_ERR_IO
|
||||
clc
|
||||
ret
|
||||
|
||||
|
||||
COM_RECV_END:
|
||||
.equ MODULE_SIZE_COM_RECV = COM_RECV_END-COM_RECV_BEGIN
|
||||
|
||||
|
||||
214
avr/com_send.asm
214
avr/com_send.asm
@@ -1,214 +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
|
||||
|
||||
COM_SEND_BEGIN:
|
||||
|
||||
|
||||
|
||||
; ---------------------------------------------------------------------------
|
||||
; comSendPacketHandleRepeat
|
||||
;
|
||||
; IN:
|
||||
; - Y: pointer to current buffer (pointed to by comRecvBuffersReadPos)
|
||||
; OUT:
|
||||
; - CFLAG: set if something done, can be called again immediately (otherwise: wait for timer interrupt and retry)
|
||||
; MODIFIED REGS: R15, R17, R22, X (R16, R17, R18, R21, R22)
|
||||
|
||||
comSendPacketHandleRepeat:
|
||||
in r15, SREG
|
||||
cli
|
||||
cbi COM_PORT_ATTN, COM_PINNUM_ATTN ; disable pullup on ATTN
|
||||
cbi COM_DDR_ATTN, COM_PINNUM_ATTN ; set ATTN as input
|
||||
nop ; needed to sample current input
|
||||
sbis COM_PIN_ATTN, COM_PINNUM_ATTN ; ATTN low?
|
||||
rjmp comSendPacketHandleRepeat_adjustRepeat ; jump if it is
|
||||
ldd r16, y+COM_BUFFER_OFFS_FLAGS
|
||||
rcall comSetupRepeat ; setup comRepeatCount if not already done (R16, R17)
|
||||
cbi COM_PORT_ATTN, COM_PINNUM_ATTN ; set ATTN low
|
||||
sbi COM_DDR_ATTN, COM_PINNUM_ATTN ; set ATTN as output
|
||||
Utils_WaitNanoSecs COM_BIT_LENGTH, 0, r22 ; wait for one bit duration
|
||||
rcall comSendPacketHandleBuffer ; (R16, R17, R21, R22)
|
||||
cbi COM_DDR_ATTN, COM_PINNUM_ATTN ; release ATTN line (by setting direction to IN)
|
||||
brcc comSendPacketHandleRepeat_collision
|
||||
; packet sent, adjust stats, release buffer
|
||||
ldi xl, LOW(comStatsPacketsOut)
|
||||
ldi xh, HIGH(comStatsPacketsOut)
|
||||
rcall comDeallocReadBufAndIncrCounter ; (r16, r17, r18)
|
||||
rjmp comSendPacketHandleRepeat_retC
|
||||
comSendPacketHandleRepeat_collision:
|
||||
; increment collisions counter
|
||||
ldi xl, LOW(comStatsCollisions)
|
||||
ldi xh, HIGH(comStatsCollisions)
|
||||
rcall Utils_IncrementCounter16 ; (r18, r19, 22)
|
||||
comSendPacketHandleRepeat_adjustRepeat:
|
||||
; decrement repeat counter (except for vital messages)
|
||||
lds r17, comRepeatCount
|
||||
cpi r17, COM_REPEAT_VITAL
|
||||
breq comSendPacketHandleRepeat_retNC ; vital message, repeat forever
|
||||
dec r17
|
||||
sts comRepeatCount, r17
|
||||
brne comSendPacketHandleRepeat_retNC
|
||||
; dealloc buffer, inc abort counter
|
||||
ldi xl, LOW(comStatsAborted)
|
||||
ldi xh, HIGH(comStatsAborted)
|
||||
rcall comDeallocReadBufAndIncrCounter
|
||||
rjmp comSendPacketHandleRepeat_retC
|
||||
|
||||
comSendPacketHandleRepeat_retNC:
|
||||
out SREG, r15
|
||||
clc
|
||||
ret
|
||||
|
||||
comSendPacketHandleRepeat_retC:
|
||||
out SREG, r15
|
||||
sec
|
||||
ret
|
||||
|
||||
|
||||
|
||||
; ---------------------------------------------------------------------------
|
||||
; comSetupRepeat
|
||||
;
|
||||
; IN:
|
||||
; - R16: priority
|
||||
; OUT:
|
||||
; - CFLAG: set if okay, clear otherwise
|
||||
; MODIFIED REGS: R16, R17
|
||||
|
||||
comSetupRepeat:
|
||||
lds r17, comRepeatCount
|
||||
tst r17
|
||||
brne comSetupRepeat_l99 ; comRepeatCount already setup
|
||||
; set comRepeatCount according to priority
|
||||
andi r16, (COM_BUFFER_FLAGS_PRIO1 | COM_BUFFER_FLAGS_PRIO0) ; r16: flags
|
||||
cpi r16, COM_REPEAT_INFO
|
||||
brne comSetupRepeat_l1
|
||||
ldi r17, COM_REPEAT_INFO
|
||||
rjmp comSetupRepeat_l98
|
||||
comSetupRepeat_l1:
|
||||
cpi r16, COM_REPEAT_NORMAL
|
||||
brne comSetupRepeat_l2
|
||||
ldi r17, COM_REPEAT_NORMAL
|
||||
rjmp comSetupRepeat_l98
|
||||
comSetupRepeat_l2:
|
||||
cpi r16, COM_REPEAT_IMPORTANT
|
||||
brne comSetupRepeat_l3
|
||||
ldi r17, COM_REPEAT_IMPORTANT
|
||||
rjmp comSetupRepeat_l98
|
||||
comSetupRepeat_l3:
|
||||
ldi r17, COM_REPEAT_VITAL
|
||||
comSetupRepeat_l98:
|
||||
sts comRepeatCount, r17
|
||||
comSetupRepeat_l99:
|
||||
ret
|
||||
|
||||
|
||||
|
||||
; ---------------------------------------------------------------------------
|
||||
; comSendPacketHandleBuffer
|
||||
;
|
||||
; Send a packet from the current read buffer (pointed to by comRecvBuffersReadPos).
|
||||
; On success the flag COM_BUFFER_FLAGS_DONE is set in the buffer.
|
||||
; The buffer is not released.
|
||||
;
|
||||
; CAVE: Expects interrupts to be disabled!
|
||||
;
|
||||
; IN:
|
||||
; - Y : pointer to current read buffer
|
||||
; OUT:
|
||||
; - CFLAG: set if okay, clear otherwise
|
||||
; MODIFIED REGS: R16, R17 (R21, R22)
|
||||
|
||||
comSendPacketHandleBuffer:
|
||||
mov xl, yl
|
||||
mov xh, yh
|
||||
ldi r16, COM_BUFFER_OFFS_DATA
|
||||
clr r17
|
||||
add xl, r16
|
||||
adc xh, r17
|
||||
ldd r16, y+(COM_BUFFER_OFFS_DATA+COM_MSG_OFFS_MSGLEN) ; get msg payload length
|
||||
ldi r17, 3
|
||||
add r16, r17 ; add dest addr, msg len and XOR byte
|
||||
rcall comSendPacketFromSram ; send all that
|
||||
brcc comSendPacketHandleBuffer_error
|
||||
ldd r16, y+COM_BUFFER_OFFS_FLAGS
|
||||
ori r16, COM_BUFFER_FLAGS_DONE
|
||||
std y+COM_BUFFER_OFFS_FLAGS, r16
|
||||
sec
|
||||
ret
|
||||
comSendPacketHandleBuffer_error:
|
||||
clc
|
||||
ret
|
||||
|
||||
|
||||
; ---------------------------------------------------------------------------
|
||||
; comSendPacketFromSram
|
||||
;
|
||||
; Send a packet from SRAM
|
||||
;
|
||||
; IN:
|
||||
; - R16: number of bytes to send
|
||||
; - X: pointer to buffer to read from
|
||||
; OUT:
|
||||
; - CFLAG: set if okay, clear otherwise
|
||||
; MODIFIED REGS: R16, R17 (R21, R22)
|
||||
|
||||
comSendPacketFromSram:
|
||||
mov r17, r16
|
||||
comSendPacketFromSram_loop:
|
||||
ld r16, X+
|
||||
rcall comSendByte ; send byte (R16, R21, R22)
|
||||
brcc comSendPacketFromSram_error
|
||||
dec r17
|
||||
brne comSendPacketFromSram_loop
|
||||
sec
|
||||
ret
|
||||
|
||||
comSendPacketFromSram_error:
|
||||
clc
|
||||
ret
|
||||
|
||||
|
||||
|
||||
; ---------------------------------------------------------------------------
|
||||
; comDeallocReadBufAndIncrCounter
|
||||
;
|
||||
; IN:
|
||||
; - X : pointer to counter
|
||||
; OUT:
|
||||
; - nothing
|
||||
; REGS: r16, r17, r21
|
||||
|
||||
comDeallocReadBufAndIncrCounter:
|
||||
rcall COM_BufferDeallocFront ; (r16, r17, r21)
|
||||
ldi r21, 1
|
||||
ld r16, x+
|
||||
ld r17, x
|
||||
add r16, r21
|
||||
dec r21
|
||||
adc r17, r21
|
||||
st x, r17
|
||||
st -x, r16
|
||||
sts comRepeatCount, r21 ; set comRepeatCount to zero
|
||||
ret
|
||||
|
||||
|
||||
|
||||
COM_SEND_END:
|
||||
.equ MODULE_SIZE_COM_SEND = COM_SEND_END-COM_SEND_BEGIN
|
||||
|
||||
|
||||
281
avr/comproto.asm
281
avr/comproto.asm
@@ -40,37 +40,31 @@
|
||||
.equ CPRO_CMD_SYSSTATS = 82
|
||||
|
||||
|
||||
; flags for variable payload enqueue function
|
||||
.equ CPRO_PAYLOAD_FLAGS_SECONDS = 0x01
|
||||
.equ CPRO_PAYLOAD_FLAGS_UID = 0x02
|
||||
.equ CPRO_PAYLOAD_FLAGS_RESERVED1 = 0x04
|
||||
.equ CPRO_PAYLOAD_FLAGS_NUM0 = 0x08
|
||||
.equ CPRO_PAYLOAD_FLAGS_NUM1 = 0x10
|
||||
.equ CPRO_PAYLOAD_FLAGS_NUM2 = 0x20
|
||||
.equ CPRO_PAYLOAD_FLAGS_NUM3 = 0x40
|
||||
.equ CPRO_PAYLOAD_FLAGS_NUM4 = 0x80
|
||||
.equ CPRO_PAYLOAD_FLAGS_SHIFT_NUM = 3
|
||||
|
||||
|
||||
.equ CPRO_PACKET_HAVEADDR_OFFS_ADDRESS = COM_MSG_OFFS_PAYLOAD+4
|
||||
.equ CPRO_PACKET_CLAIMADDR_OFFS_ADDRESS = COM_MSG_OFFS_PAYLOAD+4
|
||||
.equ CPRO_PACKET_DENYADDR_OFFS_ADDRESS = COM_MSG_OFFS_PAYLOAD+4
|
||||
.equ CPRO_PACKET_HAVEADDR_OFFS_ADDRESS = COM2_MSG_OFFS_PAYLOAD+4
|
||||
.equ CPRO_PACKET_CLAIMADDR_OFFS_ADDRESS = COM2_MSG_OFFS_PAYLOAD+4
|
||||
.equ CPRO_PACKET_DENYADDR_OFFS_ADDRESS = COM2_MSG_OFFS_PAYLOAD+4
|
||||
|
||||
|
||||
.equ CPRO_WAITTIME_INITIAL = 10
|
||||
.equ CPRO_WAITTIME_GETADDR = 130
|
||||
.equ CPRO_WAITTIME_CLAIMADDR = 17
|
||||
.equ CPRO_WAITTIME_RECLAIMADDR = 10
|
||||
|
||||
|
||||
; current mode of operation
|
||||
.equ CPRO_MODE_NORMAL = 0 ; normal operation
|
||||
.equ CPRO_MODE_GETADDRSTARTED = 10 ; waiting for HAVE_ADDRESS and ADDRESS_RANGE packets to arrive
|
||||
.equ CPRO_MODE_CLAIMING_ADDR1 = 20 ; CLAIM_ADDRESS sent, waiting for HAVE_ADDRESS packet to reject the claim
|
||||
.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_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
|
||||
|
||||
.equ CPRO_MODE_NOADDRESS = 0x00 ; no address, yet
|
||||
.equ CPRO_MODE_NORMAL = 0x01 ; normal operation
|
||||
.equ CPRO_MODE_SEND_NEED_ADDR = 0x02 ; wait to send need address
|
||||
.equ CPRO_MODE_GETADDRSTARTED = 0x03 ; waiting for HAVE_ADDRESS and ADDRESS_RANGE packets to arrive
|
||||
.equ CPRO_MODE_SEND_CLAIM_ADDR1 = 0x04 ; send CLAIM_ADDRESS as part of reclaiming procedure
|
||||
.equ CPRO_MODE_CLAIMING_ADDR1 = 0x05 ; CLAIM_ADDRESS sent, waiting for HAVE_ADDRESS packet to reject the claim
|
||||
.equ CPRO_MODE_CLAIMING_ADDR2 = 0x06 ; CLAIM_ADDRESS sent, 2nd try
|
||||
.equ CPRO_MODE_CLAIMING_ADDR3 = 0x07 ; CLAIM_ADDRESS sent, 3rd try
|
||||
.equ CPRO_MODE_SENDING_HAVE_ADDR = 0x08 ; waiting for our turn to send HAVE_ADDRESS packet
|
||||
.equ CPRO_MODE_SEND_RECLAIM_ADDR = 0x09 ; send CLAIM_ADDRESS as part of reclaiming procedure
|
||||
.equ CPRO_MODE_RECLAIMING_ADDR = 0x0a ; CLAIM_ADDRESS with the previously used address sent after bootup
|
||||
.equ CPRO_MODE_SEND_DENY_ADDR = 0x0b ; someone claimed our address, send a DENY_ADDR message
|
||||
.equ CPRO_MODE_NEXT_FREE = 0x0c ; next free mode
|
||||
|
||||
|
||||
; ***************************************************************************
|
||||
@@ -80,13 +74,7 @@
|
||||
|
||||
|
||||
cproDataBegin:
|
||||
#ifndef BASE_SYSTEM
|
||||
cproMode: .byte 1 ; "normal", "waitForHaveAddress", "samplingAddresses", "claimAddress"
|
||||
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
|
||||
#endif
|
||||
cproMode: .byte 1
|
||||
cproDataEnd:
|
||||
|
||||
|
||||
@@ -107,42 +95,12 @@ CPRO_Init:
|
||||
clr r16
|
||||
ldi r17, (cproDataEnd-cproDataBegin)
|
||||
rcall Utils_FillSram
|
||||
sec
|
||||
ret
|
||||
|
||||
|
||||
|
||||
CPRO_OnEverySecond:
|
||||
#ifndef BASE_SYSTEM
|
||||
lds r17, cproMode
|
||||
cpi r17, CPRO_MODE_NORMAL
|
||||
breq CPRO_OnEverySecond_done
|
||||
CPRO_OnEverySecond_l1:
|
||||
cpi r17, CPRO_MODE_GETADDRSTARTED
|
||||
brne CPRO_OnEverySecond_l2
|
||||
rjmp cproHandle1sGetAddrStarted
|
||||
CPRO_OnEverySecond_l2:
|
||||
cpi r17, CPRO_MODE_SENDING_HAVE_ADDRESS
|
||||
brne CPRO_OnEverySecond_l3
|
||||
rjmp cproHandle1sSendingHaveAddress
|
||||
CPRO_OnEverySecond_l3:
|
||||
cpi r17, CPRO_MODE_CLAIMING_ADDR1
|
||||
brne CPRO_OnEverySecond_l4
|
||||
rjmp cproHandle1sClaimingAddr12
|
||||
CPRO_OnEverySecond_l4:
|
||||
cpi r17, CPRO_MODE_CLAIMING_ADDR2
|
||||
brne CPRO_OnEverySecond_l5
|
||||
rjmp cproHandle1sClaimingAddr12
|
||||
CPRO_OnEverySecond_l5:
|
||||
cpi r17, CPRO_MODE_CLAIMING_ADDR3
|
||||
brne CPRO_OnEverySecond_l6
|
||||
rjmp cproHandle1sClaimingAddr3
|
||||
CPRO_OnEverySecond_l6:
|
||||
cpi r17, CPRO_MODE_RECLAIMING_ADDR
|
||||
brne CPRO_OnEverySecond_done
|
||||
rjmp cproHandle1sReclaimingAddr
|
||||
CPRO_OnEverySecond_done:
|
||||
|
||||
#ifdef MODULES_COM_WITH_ADDR_PROTO
|
||||
rcall CPRO_Address_Init
|
||||
#endif
|
||||
|
||||
sec
|
||||
ret
|
||||
|
||||
|
||||
@@ -153,204 +111,43 @@ CPRO_OnEverySecond_done:
|
||||
; Try to handle the given packet.
|
||||
;
|
||||
; IN:
|
||||
; - Y : pointer to received buffer
|
||||
; - X : pointer to received buffer
|
||||
; OUT:
|
||||
; - CFLAG: set if handled, cleared otherwise
|
||||
; USED: depending on called routines
|
||||
|
||||
CPRO_OnPacketReceived:
|
||||
ldd r16, y+(COM_BUFFER_OFFS_DATA+COM_MSG_OFFS_CMD)
|
||||
adiw xh:xl, COM2_MSG_OFFS_CMD
|
||||
ld r16, x
|
||||
sbiw xh:xl, COM2_MSG_OFFS_CMD
|
||||
cpi r16, CPRO_CMD_PING
|
||||
brne CPRO_OnPacketReceived_l1
|
||||
rjmp cproHandlePing
|
||||
CPRO_OnPacketReceived_l1:
|
||||
#ifndef BASE_SYSTEM
|
||||
cpi r16, CPRO_CMD_NEED_ADDRESS
|
||||
brne CPRO_OnPacketReceived_l2
|
||||
rjmp cproHandlePckNeedAddr
|
||||
CPRO_OnPacketReceived_l2:
|
||||
cpi r16, CPRO_CMD_HAVE_ADDRESS
|
||||
brne CPRO_OnPacketReceived_l3
|
||||
rjmp cproHandlePckHaveAddr
|
||||
CPRO_OnPacketReceived_l3:
|
||||
cpi r16, CPRO_CMD_ADDRESS_RANGE
|
||||
brne CPRO_OnPacketReceived_l4
|
||||
rjmp cproHandleAddrRange
|
||||
CPRO_OnPacketReceived_l4:
|
||||
cpi r16, CPRO_CMD_DENY_ADDRESS
|
||||
brne CPRO_OnPacketReceived_l5
|
||||
rjmp cproHandleDenyAddr
|
||||
CPRO_OnPacketReceived_l5:
|
||||
cpi r16, CPRO_CMD_CLAIM_ADDRESS
|
||||
brne CPRO_OnPacketReceived_l6
|
||||
rjmp cproHandlePckClaimAddr
|
||||
CPRO_OnPacketReceived_l6:
|
||||
#endif
|
||||
#ifdef MODULES_COM_WITH_ADDR_PROTO
|
||||
rjmp CPRO_Address_OnPacketReceived
|
||||
#else
|
||||
clc
|
||||
ret
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
cproHandlePing:
|
||||
ldd r16, y+(COM_BUFFER_OFFS_DATA+COM_MSG_OFFS_SRCADDR)
|
||||
tst r16
|
||||
adiw xh:xl, COM2_MSG_OFFS_SRCADDR
|
||||
ld r16, x
|
||||
tst r16 ; dont handle src address 0
|
||||
breq cproHandlePing_notHandled
|
||||
rcall CPRO_EnqueuePong
|
||||
ret ; use carry flag from previous call
|
||||
inc r16
|
||||
breq cproHandlePing_notHandled ; dont handle src address 255
|
||||
rcall CPRO_WritePong
|
||||
rjmp COM2_SendPacket ; use carry flag from this routine
|
||||
cproHandlePing_notHandled:
|
||||
clc
|
||||
ret
|
||||
|
||||
|
||||
|
||||
; ---------------------------------------------------------------------------
|
||||
; Enqueue a PING packet.
|
||||
;
|
||||
; IN:
|
||||
; - R16: destination address
|
||||
; OUT:
|
||||
; - CFLAG: set if okay, clear otherwise
|
||||
; MODIFIED REGS: R18, R20 (R15, R16, R17, X, Y)
|
||||
|
||||
CPRO_EnqueuePing:
|
||||
ldi r18, CPRO_CMD_PING
|
||||
ldi r20, COM_BUFFER_PRIO_INFO
|
||||
rjmp cproEnqueueMsgWithCmdAndSrcAddr
|
||||
|
||||
|
||||
|
||||
; ---------------------------------------------------------------------------
|
||||
; Enqueue a PONG packet.
|
||||
;
|
||||
; IN:
|
||||
; - R16: destination address
|
||||
; OUT:
|
||||
; - CFLAG: set if okay, clear otherwise
|
||||
; MODIFIED REGS: R18, R20 (R15, R16, R17, X, Y)
|
||||
|
||||
CPRO_EnqueuePong:
|
||||
ldi r18, CPRO_CMD_PONG
|
||||
ldi r20, COM_BUFFER_PRIO_INFO
|
||||
rjmp cproEnqueueMsgWithCmdAndSrcAddr
|
||||
|
||||
|
||||
|
||||
; ---------------------------------------------------------------------------
|
||||
; Enqueue a simple packet with payload only CMD and source address.
|
||||
;
|
||||
; IN:
|
||||
; - R16: destination address
|
||||
; - R18: command (e.g. CPRO_CMD_PING or CPRO_CMD_PONG)
|
||||
; - R20: priority of the message
|
||||
; OUT:
|
||||
; - CFLAG: set if okay, clear otherwise
|
||||
; MODIFIED REGS: R16, R17, X, Y (R3, R4, R15, R16, R17, R18, R19, R20, R21)
|
||||
|
||||
cproEnqueueMsgWithCmdAndSrcAddr:
|
||||
push r16
|
||||
rcall COM_AllocBufferAndGetXY ; (r16, r17, r21)
|
||||
pop r16
|
||||
brcc cproEnqueueMsgWithCmdAndSrcAddr_error
|
||||
|
||||
ldi r17, CPRO_PAYLOAD_FLAGS_SECONDS
|
||||
push xh
|
||||
push xl
|
||||
push r20
|
||||
rcall cproBeginMsgWithVariablePayload ; (R3, R4, R16, R17, R18, R19, R20, R21, X)
|
||||
pop r20
|
||||
pop xl
|
||||
pop xh
|
||||
rcall comCalcAndAddChecksumByte ; (R16, R17, R18, R19, X)
|
||||
|
||||
; mark buffer as enqueued with PRIO given in R20
|
||||
rcall COM_EnqueuePacket ; (R15, R16)
|
||||
brcc cproEnqueueMsgWithCmdAndSrcAddr_error
|
||||
sec
|
||||
ret
|
||||
cproEnqueueMsgWithCmdAndSrcAddr_error:
|
||||
clc
|
||||
ret
|
||||
|
||||
|
||||
|
||||
; ---------------------------------------------------------------------------
|
||||
; begin packet with variable payload.
|
||||
;
|
||||
; IN:
|
||||
; - R16: destination address
|
||||
; - R17: flags
|
||||
; - R18: command (e.g. CPRO_CMD_PING)
|
||||
; - X : pointer to packet buffer
|
||||
; OUT:
|
||||
; - X : points to end of packet as it was written so far
|
||||
; MODIFIED REGS: R3, R16, R17, R18, R19, R20, R21, X (R4)
|
||||
|
||||
cproBeginMsgWithVariablePayload:
|
||||
; write header (dest address, msg length)
|
||||
st X+, r16 ; destination address
|
||||
mov r16, r17 ; calculate payload size
|
||||
mov r3, r17
|
||||
rcall cproCalcPayloadSize ; (R4, R16, R17)
|
||||
inc r16 ; add CMD byte
|
||||
inc r16 ; add source address byte
|
||||
st X+, r16
|
||||
; write payload
|
||||
st X+, r18 ; 0: CMD
|
||||
lds r16, comAddress ; 1: source address
|
||||
st X+, r16
|
||||
lsr r3 ; shift out CPRO_PAYLOAD_FLAGS_SECONDS
|
||||
brcc cproBeginMsgWithVariablePayload_l1
|
||||
lds r16, timerModuleCounterSecs ; adding of current seconds counter requested
|
||||
st X+, r16
|
||||
lds r16, timerModuleCounterSecs+1
|
||||
st X+, r16
|
||||
lds r16, timerModuleCounterSecs+2
|
||||
st X+, r16
|
||||
lds r16, timerModuleCounterSecs+3
|
||||
st X+, r16
|
||||
cproBeginMsgWithVariablePayload_l1:
|
||||
lsr r3 ; shift out shift out CPRO_PAYLOAD_FLAGS_UID
|
||||
brcc cproBeginMsgWithVariablePayload_l2
|
||||
push xh
|
||||
push xl
|
||||
rcall Utils_ReadUid ; (R16, X)
|
||||
pop xl
|
||||
pop xh
|
||||
st X+, r18
|
||||
st X+, r19
|
||||
st X+, r20
|
||||
st X+, r21
|
||||
cproBeginMsgWithVariablePayload_l2:
|
||||
ret
|
||||
|
||||
|
||||
|
||||
; ---------------------------------------------------------------------------
|
||||
; cproCalcPayloadSize
|
||||
;
|
||||
; Calculate payload size from given flags
|
||||
;
|
||||
; IN:
|
||||
; - R16: flags
|
||||
; OUT:
|
||||
; - R16: payload size
|
||||
; MODIFIED REGS: R4, R16, R17
|
||||
|
||||
cproCalcPayloadSize:
|
||||
clr r4
|
||||
ldi r17, 4
|
||||
lsr r16 ; shift out CPRO_PAYLOAD_FLAGS_SECONDS
|
||||
brcc cproCalcPayloadSize_l1
|
||||
add r4, r17 ; add 4 bytes
|
||||
cproCalcPayloadSize_l1:
|
||||
lsr r16 ; shift out CPRO_PAYLOAD_FLAGS_UID
|
||||
brcc cproCalcPayloadSize_l2
|
||||
add r4, r17 ; add 4 bytes
|
||||
cproCalcPayloadSize_l2:
|
||||
lsr r16 ; shift out reserved1, after this R16 contains CPRO_PAYLOAD_FLAGS_NUM0-4
|
||||
add r16, r4 ; add previous bytes to R16
|
||||
ret
|
||||
|
||||
|
||||
CPRO_END:
|
||||
.equ MODULE_SIZE_CPRO = CPRO_END-CPRO_BEGIN
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
|
||||
163
avr/comproto_addr1.asm
Normal file
163
avr/comproto_addr1.asm
Normal file
@@ -0,0 +1,163 @@
|
||||
; ***************************************************************************
|
||||
; 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. *
|
||||
; ***************************************************************************
|
||||
|
||||
|
||||
; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
; This file contains timer handlers for the address protocol
|
||||
; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
;
|
||||
|
||||
|
||||
; ***************************************************************************
|
||||
; code
|
||||
|
||||
.cseg
|
||||
|
||||
|
||||
|
||||
CPRO_Address_OnTimer:
|
||||
lds r16, cproMode
|
||||
ldi r17, CPRO_MODE_NEXT_FREE
|
||||
ldi zl, LOW(cproAddressOnTimerTable)
|
||||
ldi zh, HIGH(cproAddressOnTimerTable)
|
||||
rjmp Utils_TableJump
|
||||
|
||||
|
||||
cproAddressOnTimerTable:
|
||||
.dw CPRO_StartReclaimAddrProcedure ; CPRO_MODE_NOADDRESS
|
||||
.dw 0 ; CPRO_MODE_NORMAL
|
||||
.dw cproHandle1sNeedAddr ; CPRO_MODE_SEND_NEED_ADDR
|
||||
.dw cproHandle1sGetAddrStarted ; CPRO_MODE_GETADDRSTARTED
|
||||
.dw cproHandle1sSendClaimAddr1 ; CPRO_MODE_SEND_CLAIM_ADDR1
|
||||
.dw cproHandle1sClaimingAddr12 ; CPRO_MODE_CLAIMING_ADDR1
|
||||
.dw cproHandle1sClaimingAddr12 ; CPRO_MODE_CLAIMING_ADDR2
|
||||
.dw cproHandle1sClaimingAddr3 ; CPRO_MODE_CLAIMING_ADDR3
|
||||
.dw cproHandle1sSendingHaveAddress ; CPRO_MODE_SENDING_HAVE_ADDR
|
||||
.dw cproHandle1sSendReclaimAddr ; CPRO_MODE_SEND_RECLAIM_ADDR
|
||||
.dw cproHandle1sReclaimingAddr ; CPRO_MODE_RECLAIMING_ADDR
|
||||
.dw cproHandle1sSendDenyAddr ; CPRO_MODE_SEND_DENY_ADDR
|
||||
|
||||
|
||||
cproHandle1sSendingHaveAddress:
|
||||
rcall CPRO_SendHaveAddress
|
||||
brcs cproHandle1sSendingHaveAddress_okay
|
||||
rcall cproAddressSetTimer1s ; could not send, restart timer 1s and retry later
|
||||
ret
|
||||
cproHandle1sSendingHaveAddress_okay:
|
||||
ldi r16, CPRO_MODE_NORMAL
|
||||
sts cproMode, r16
|
||||
ret
|
||||
|
||||
|
||||
|
||||
cproHandle1sNeedAddr:
|
||||
rcall CPRO_SendNeedAddress
|
||||
brcs cproHandle1sNeedAddr_okay
|
||||
rjmp cproAddressSetTimer1s ; could not send, restart timer 1s and retry later
|
||||
cproHandle1sNeedAddr_okay:
|
||||
ldi r16, CPRO_MODE_GETADDRSTARTED ; wait for incoming messages
|
||||
sts cproMode, r16
|
||||
ldi r18, CPRO_WAITTIME_GETADDR ; set timeout
|
||||
clr r19
|
||||
rjmp cproAddressSetTimer
|
||||
|
||||
|
||||
|
||||
cproHandle1sSendDenyAddr:
|
||||
rcall CPRO_SendDenyAddress
|
||||
brcs cproHandle1sSendDenyAddr_okay
|
||||
rjmp cproAddressSetTimer1s ; could not send, restart timer 1s and retry later
|
||||
cproHandle1sSendDenyAddr_okay:
|
||||
ldi r16, CPRO_MODE_NORMAL ; DENY_ADDR sent, back to normal
|
||||
sts cproMode, r16
|
||||
ret
|
||||
|
||||
|
||||
|
||||
cproHandle1sSendReclaimAddr:
|
||||
lds r19, cproAddrRangeBegin
|
||||
rcall CPRO_SendClaimAddress
|
||||
brcs cproHandle1sSendReclaimAddr_okay
|
||||
rjmp cproAddressSetTimer1s ; could not send, restart timer 1s and retry later
|
||||
cproHandle1sSendReclaimAddr_okay:
|
||||
ldi r16, CPRO_MODE_RECLAIMING_ADDR
|
||||
sts cproMode, r16
|
||||
ldi r18, CPRO_WAITTIME_RECLAIMADDR
|
||||
clr r19
|
||||
rjmp cproAddressSetTimer ; prepare time for next stage
|
||||
|
||||
|
||||
|
||||
cproHandle1sGetAddrStarted:
|
||||
rcall cproGetFirstFreeAddr
|
||||
brcs cproHandle1sGetAddrStarted_gotAddr
|
||||
; no free address, abort TODO: send an error message to bus ("bus full")
|
||||
ldi r16, CPRO_MODE_NOADDRESS
|
||||
sts cproMode, r16
|
||||
ret
|
||||
cproHandle1sGetAddrStarted_gotAddr:
|
||||
ldi r16, CPRO_MODE_SEND_CLAIM_ADDR1
|
||||
sts cproMode, r16
|
||||
rjmp cproAddressSetTimer1s ; start
|
||||
|
||||
|
||||
|
||||
cproHandle1sSendClaimAddr1:
|
||||
lds r19, cproAddrRangeBegin
|
||||
rcall CPRO_SendClaimAddress
|
||||
brcs cproHandle1sClaimSend_okay
|
||||
rjmp cproAddressSetTimer1s ; could not send, restart timer 1s and retry later
|
||||
cproHandle1sClaimSend_okay: ; goto nex stage
|
||||
ldi r16, CPRO_MODE_CLAIMING_ADDR1
|
||||
sts cproMode, r16
|
||||
ldi r18, CPRO_WAITTIME_CLAIMADDR
|
||||
clr r19
|
||||
rjmp cproAddressSetTimer ; prepare timer for next stage
|
||||
|
||||
|
||||
|
||||
cproHandle1sClaimingAddr12:
|
||||
lds r19, cproAddrRangeBegin ; currently claimed address
|
||||
rcall CPRO_SendClaimAddress
|
||||
brcs cproHandle1sClaimingAddr12_okay
|
||||
rjmp cproAddressSetTimer1s ; could not send, restart timer 1s and retry later
|
||||
cproHandle1sClaimingAddr12_okay:
|
||||
lds r16, cproMode
|
||||
inc r16
|
||||
sts cproMode, r16
|
||||
ldi r18, CPRO_WAITTIME_CLAIMADDR
|
||||
clr r19
|
||||
rjmp cproAddressSetTimer ; prepare time for next stage
|
||||
|
||||
|
||||
|
||||
cproHandle1sClaimingAddr3:
|
||||
cproHandle1sReclaimingAddr:
|
||||
; claimed given address 3rd time or addr reclaimed, set address and enter "normal" mode
|
||||
lds r19, cproAddrRangeBegin ; currently claimed address
|
||||
rcall CPRO_SendHaveAddress
|
||||
brcs cproHandle1sClaimingAddr3_okay
|
||||
rjmp cproAddressSetTimer1s ; could not send, restart timer 1s and retry later
|
||||
cproHandle1sClaimingAddr3_okay:
|
||||
in r15, SREG
|
||||
cli
|
||||
lds r16, cproAddrRangeBegin ; currently sent address is in cproAddrRangeBegin
|
||||
sts com2Address, r16 ; write address into eeprom
|
||||
ldi xl, LOW(EEPROM_OFFS_COMADDR)
|
||||
ldi xh, HIGH(EEPROM_OFFS_COMADDR)
|
||||
rcall Utils_WriteEepromIncr ; write address to EEPROM
|
||||
out SREG, r15
|
||||
ldi r16, CPRO_MODE_NORMAL ; set mode to "normal"
|
||||
sts cproMode, r16
|
||||
ret
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
167
avr/comproto_addr2.asm
Normal file
167
avr/comproto_addr2.asm
Normal file
@@ -0,0 +1,167 @@
|
||||
; ***************************************************************************
|
||||
; 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. *
|
||||
; ***************************************************************************
|
||||
|
||||
|
||||
; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
; This file contains packet receiption handlers for the address protocol
|
||||
; +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
||||
|
||||
|
||||
|
||||
; ***************************************************************************
|
||||
; code
|
||||
|
||||
.cseg
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
; ---------------------------------------------------------------------------
|
||||
; CPRO_Address_OnPacketReceived:
|
||||
;
|
||||
; Try to handle the given packet.
|
||||
;
|
||||
; IN:
|
||||
; - X : pointer to received buffer
|
||||
; OUT:
|
||||
; - CFLAG: set if handled, cleared otherwise
|
||||
; USED: depending on called routines
|
||||
|
||||
CPRO_Address_OnPacketReceived:
|
||||
adiw xh:xl, COM2_MSG_OFFS_CMD
|
||||
ld r16, x
|
||||
sbiw xh:xl, COM2_MSG_OFFS_CMD
|
||||
|
||||
ldi r17, (cproPacketTypeTransTableEnd-cproPacketTypeTransTableBegin) & 0xff
|
||||
ldi zl, LOW(cproPacketTypeTransTableBegin)
|
||||
ldi zh, HIGH(cproPacketTypeTransTableBegin)
|
||||
rcall Utils_FindBytePositionInTable
|
||||
brcc CPRO_Address_OnPacketReceived_nc
|
||||
|
||||
ldi r17, (cproPacketTypeTransTableEnd-cproPacketTypeTransTableBegin) & 0xff
|
||||
ldi zl, LOW(cproPacketTypeHandleTable)
|
||||
ldi zh, HIGH(cproPacketTypeHandleTable)
|
||||
rcall Utils_TableJump
|
||||
sec
|
||||
ret
|
||||
CPRO_Address_OnPacketReceived_nc:
|
||||
clc
|
||||
ret
|
||||
|
||||
|
||||
|
||||
cproPacketTypeTransTableBegin:
|
||||
.db CPRO_CMD_PING, CPRO_CMD_NEED_ADDRESS, CPRO_CMD_HAVE_ADDRESS, CPRO_CMD_ADDRESS_RANGE, CPRO_CMD_DENY_ADDRESS, CPRO_CMD_CLAIM_ADDRESS
|
||||
cproPacketTypeTransTableEnd:
|
||||
|
||||
; position within table must be in same order as in table above!
|
||||
cproPacketTypeHandleTable:
|
||||
.dw cproHandlePing, cproHandleNeedAddr, cproHandlePckHaveAddr, cproHandleAddrRange, cproHandleDenyAddr, cproHandleClaimAddr
|
||||
|
||||
|
||||
|
||||
cproHandleNeedAddr:
|
||||
lds r17, cproMode
|
||||
cpi r17, CPRO_MODE_NORMAL
|
||||
brne cproHandleNeedAddr_done
|
||||
; enter CPRO_MODE_SENDING_HAVE_ADDR mode
|
||||
lds r16, com2Address
|
||||
tst r16
|
||||
breq cproHandleNeedAddr_done ; we have no address, don't handle
|
||||
ldi r24, CPRO_MODE_SENDING_HAVE_ADDR ; start singleshot timer for sending HAVE_ADDRESS
|
||||
sts cproMode, r24
|
||||
lds r24, com2Address
|
||||
clr r25
|
||||
adiw r25:r24, 3
|
||||
rjmp cproAddressSetTimer
|
||||
cproHandleNeedAddr_done:
|
||||
sec
|
||||
ret
|
||||
|
||||
|
||||
|
||||
cproHandlePckHaveAddr:
|
||||
lds r17, cproMode
|
||||
cpi r17, CPRO_MODE_GETADDRSTARTED
|
||||
brne cproHandlePckHaveAddr_done
|
||||
; validate address
|
||||
adiw xh:xl, CPRO_PACKET_HAVEADDR_OFFS_ADDRESS
|
||||
ld r16, x
|
||||
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
|
||||
|
||||
|
||||
|
||||
cproHandleClaimAddr:
|
||||
adiw xh:xl, CPRO_PACKET_CLAIMADDR_OFFS_ADDRESS
|
||||
ld r16, x
|
||||
tst r16
|
||||
breq cproHandleClaimAddr_done
|
||||
cpi r16, 0xff
|
||||
breq cproHandleClaimAddr_done
|
||||
lds r17, com2Address
|
||||
tst r17
|
||||
breq cproHandleClaimAddr_done
|
||||
cp r16, r17
|
||||
brne cproHandleClaimAddr_done
|
||||
ldi r16, CPRO_MODE_SEND_DENY_ADDR
|
||||
sts cproMode, r16
|
||||
rcall cproAddressSetTimer1s
|
||||
cproHandleClaimAddr_done:
|
||||
sec
|
||||
ret
|
||||
|
||||
|
||||
|
||||
cproHandleDenyAddr:
|
||||
; check mode
|
||||
lds r17, cproMode
|
||||
cpi r17, CPRO_MODE_CLAIMING_ADDR1
|
||||
brcs cproHandleDenyAddr_notInClaimAddr13Mode
|
||||
cpi r17, CPRO_MODE_CLAIMING_ADDR3+1
|
||||
brcc cproHandleDenyAddr_notInClaimAddr13Mode
|
||||
; we are in one of the three CLAIM_ADDRESS modes and received a DENY_ADDR, check address
|
||||
adiw xh:xl, CPRO_PACKET_CLAIMADDR_OFFS_ADDRESS
|
||||
ld r16, x
|
||||
sbiw xh:xl, CPRO_PACKET_CLAIMADDR_OFFS_ADDRESS
|
||||
lds r17, cproAddrRangeBegin
|
||||
cp r16, r17
|
||||
brne cproHandleDenyAddr_done ; not our currently claimed address, ignore
|
||||
; someone denied us our claimed address, try next
|
||||
rcall cproGetNextFreeAddr
|
||||
brcs cproHandleDenyAddr_gotFreeAddr
|
||||
; no free address, abort TODO: send an error message to bus ("bus full")
|
||||
ldi r16, CPRO_MODE_NOADDRESS
|
||||
sts cproMode, r16
|
||||
ret
|
||||
cproHandleDenyAddr_gotFreeAddr: ; claim next address
|
||||
ldi r16, CPRO_MODE_SEND_CLAIM_ADDR1
|
||||
sts cproMode, r16
|
||||
rcall cproAddressSetTimer1s ; start timer
|
||||
rjmp cproHandleDenyAddr_done
|
||||
cproHandleDenyAddr_notInClaimAddr13Mode: ; reclaim mode?
|
||||
lds r17, cproMode
|
||||
cpi r17, CPRO_MODE_RECLAIMING_ADDR
|
||||
brne cproHandleDenyAddr_done
|
||||
; reclaiming went wrong, go through full address assignment protocol
|
||||
rcall CPRO_StartGetAddrProcedure
|
||||
cproHandleDenyAddr_done:
|
||||
sec
|
||||
ret
|
||||
|
||||
|
||||
33
avr/comproto_ping.asm
Normal file
33
avr/comproto_ping.asm
Normal file
@@ -0,0 +1,33 @@
|
||||
; ***************************************************************************
|
||||
; 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 PING packet.
|
||||
;
|
||||
; IN:
|
||||
; - R16: destination address
|
||||
; - X : buffer to write to
|
||||
; OUT:
|
||||
; - nothing
|
||||
; REGS: R3, R4, R16, R17, R18, X (R19, R20, R21)
|
||||
|
||||
CPRO_WritePing:
|
||||
ldi r18, CPRO_CMD_PING
|
||||
rjmp COM2_WriteMsgWithCmdAndSrcAddr
|
||||
|
||||
|
||||
33
avr/comproto_pong.asm
Normal file
33
avr/comproto_pong.asm
Normal file
@@ -0,0 +1,33 @@
|
||||
; ***************************************************************************
|
||||
; 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 PONG packet.
|
||||
;
|
||||
; IN:
|
||||
; - R16: destination address
|
||||
; - X : buffer to write to
|
||||
; OUT:
|
||||
; - nothing
|
||||
; REGS: R3, R4, R16, R17, R18, X (R19, R20, R21)
|
||||
|
||||
CPRO_WritePong:
|
||||
ldi r18, CPRO_CMD_PONG
|
||||
rjmp COM2_WriteMsgWithCmdAndSrcAddr
|
||||
|
||||
|
||||
58
avr/comproto_recvstats.asm
Normal file
58
avr/comproto_recvstats.asm
Normal file
@@ -0,0 +1,58 @@
|
||||
; ***************************************************************************
|
||||
; 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 COM reception stats packet.
|
||||
;
|
||||
; IN:
|
||||
; - R16: destination address
|
||||
; - X : buffer to write to
|
||||
; OUT:
|
||||
; - nothing
|
||||
; REGS: R3, R4, R16, R17, R18, X (R19, R20, R21)
|
||||
|
||||
CPRO_WriteComRecvStats:
|
||||
ldi r17, COM2_PAYLOAD_FLAGS_UID | (8<<COM2_PAYLOAD_FLAGS_SHIFT_NUM) ; seconds + 8 bytes payload
|
||||
ldi r18, CPRO_CMD_COMRECVSTATS
|
||||
push xh
|
||||
push xl
|
||||
rcall COM2_BeginMsgWithVariablePayload ; (R3, R4, R16, R17, R18, R19, R20, R21, X)
|
||||
lds r16, com2StatsPacketsIn ; packets in
|
||||
st X+, r16
|
||||
lds r16, com2StatsPacketsIn+1
|
||||
st X+, r16
|
||||
lds r16, com2StatsContentError ; CRC errors
|
||||
st X+, r16
|
||||
lds r16, com2StatsContentError+1
|
||||
st X+, r16
|
||||
lds r16, com2StatsIoError ; IO errors
|
||||
st X+, r16
|
||||
lds r16, com2StatsIoError+1
|
||||
st X+, r16
|
||||
lds r16, com2StatsNoBufferError ; no buffer
|
||||
st X+, r16
|
||||
lds r16, com2StatsNoBufferError+1
|
||||
st X+, r16
|
||||
pop xl
|
||||
pop xh
|
||||
rcall com2CalcAndAddChecksumByte ; (R16, R17, R18, R19, X)
|
||||
ret
|
||||
|
||||
|
||||
|
||||
|
||||
53
avr/comproto_sendstats.asm
Normal file
53
avr/comproto_sendstats.asm
Normal file
@@ -0,0 +1,53 @@
|
||||
; ***************************************************************************
|
||||
; 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 ComSendStats packet.
|
||||
;
|
||||
; IN:
|
||||
; - R16: destination address
|
||||
; - X : buffer to write to
|
||||
; OUT:
|
||||
; - nothing
|
||||
; REGS: R3, R4, R16, R17, R18, X (R19, R20, R21)
|
||||
|
||||
CPRO_WriteComSendStats:
|
||||
ldi r17, COM2_PAYLOAD_FLAGS_UID | (6<<COM2_PAYLOAD_FLAGS_SHIFT_NUM) ; UID + 6 bytes payload
|
||||
ldi r18, CPRO_CMD_COMSENDSTATS
|
||||
push xh
|
||||
push xl
|
||||
rcall COM2_BeginMsgWithVariablePayload ; (R3, R4, R16, R17, R18, R19, R20, R21, X)
|
||||
lds r16, com2StatsPacketsOut ; packets out
|
||||
st X+, r16
|
||||
lds r16, com2StatsPacketsOut+1
|
||||
st X+, r16
|
||||
lds r16, com2StatsCollisions ; collisions
|
||||
st X+, r16
|
||||
lds r16, com2StatsCollisions+1
|
||||
st X+, r16
|
||||
lds r16, com2StatsBusyError ; busy
|
||||
st X+, r16
|
||||
lds r16, com2StatsBusyError+1
|
||||
st X+, r16
|
||||
pop xl
|
||||
pop xh
|
||||
rcall comCalcAndAddChecksumByte ; (R16, R17, R18, R19, X)
|
||||
ret
|
||||
|
||||
|
||||
|
||||
90
avr/lcd.asm
90
avr/lcd.asm
@@ -134,39 +134,42 @@ LCD_Fini:
|
||||
|
||||
LCD_SetCursor:
|
||||
in r15, SREG
|
||||
cli
|
||||
mov r1, r18
|
||||
mov r2, r19
|
||||
rcall twiStart ; (R22)
|
||||
ldi r16, (LCD_TWI_ADDRESS*2)
|
||||
rcall twiSendByteExpectAck ; (R16, R17, R18, R22)
|
||||
brcc LCD_SetCursor_error
|
||||
|
||||
ldi r16, LCD_CMD_MODE
|
||||
rcall twiSendByteExpectAck ; (R16, R17, R18, R22)
|
||||
brcc LCD_SetCursor_error
|
||||
mov r16, r2
|
||||
andi r16, 0x07
|
||||
ori r16, 0xb0 ; Set Page Start Address for Page Addressing Mode
|
||||
rcall twiSendByteExpectAck ; (R16, R17, R18, R22)
|
||||
brcc LCD_SetCursor_error
|
||||
mov r16, r1
|
||||
andi r16, 0x0f ; Set Lower Column Start Address
|
||||
rcall twiSendByteExpectAck ; (R16, R17, R18, R22)
|
||||
brcc LCD_SetCursor_error
|
||||
mov r16, r1
|
||||
swap r16
|
||||
andi r16, 0x0f
|
||||
ori r16, 0x10 ; Set Higher Column Start Address
|
||||
rcall twiSendByteExpectAck ; (R16, R17, R18, R22)
|
||||
brcc LCD_SetCursor_error
|
||||
|
||||
rcall twiStop ; (R22)
|
||||
push r15
|
||||
cli
|
||||
mov r1, r18
|
||||
mov r2, r19
|
||||
rcall twiStart ; (R22)
|
||||
ldi r16, (LCD_TWI_ADDRESS*2)
|
||||
rcall twiSendByteExpectAck ; (R16, R17, R18, R22)
|
||||
brcc LCD_SetCursor_error
|
||||
|
||||
ldi r16, LCD_CMD_MODE
|
||||
rcall twiSendByteExpectAck ; (R16, R17, R18, R22)
|
||||
brcc LCD_SetCursor_error
|
||||
mov r16, r2
|
||||
andi r16, 0x07
|
||||
ori r16, 0xb0 ; Set Page Start Address for Page Addressing Mode
|
||||
rcall twiSendByteExpectAck ; (R16, R17, R18, R22)
|
||||
brcc LCD_SetCursor_error
|
||||
mov r16, r1
|
||||
andi r16, 0x0f ; Set Lower Column Start Address
|
||||
rcall twiSendByteExpectAck ; (R16, R17, R18, R22)
|
||||
brcc LCD_SetCursor_error
|
||||
mov r16, r1
|
||||
swap r16
|
||||
andi r16, 0x0f
|
||||
ori r16, 0x10 ; Set Higher Column Start Address
|
||||
rcall twiSendByteExpectAck ; (R16, R17, R18, R22)
|
||||
brcc LCD_SetCursor_error
|
||||
|
||||
rcall twiStop ; (R22)
|
||||
pop r15
|
||||
out SREG, r15
|
||||
sec
|
||||
ret
|
||||
LCD_SetCursor_error:
|
||||
rcall twiStop ; (R22)
|
||||
rcall twiStop ; (R22)
|
||||
pop r15
|
||||
out SREG, r15
|
||||
clc
|
||||
ret
|
||||
@@ -295,23 +298,26 @@ LCD_PrintFromFlash_error:
|
||||
|
||||
LCD_PrintChar:
|
||||
in r15, SREG
|
||||
cli
|
||||
rcall twiStart
|
||||
ldi r16, (LCD_TWI_ADDRESS*2)
|
||||
rcall twiSendByteExpectAck ; (R16, R17, R18, R22)
|
||||
brcc LCD_PrintChar_error
|
||||
ldi r16, LCD_DATA_MODE
|
||||
rcall twiSendByteExpectAck ; (R16, R17, R18, R22)
|
||||
brcc LCD_PrintChar_error
|
||||
|
||||
rcall lcdPrintOneChar
|
||||
brcc LCD_PrintChar_error
|
||||
rcall twiStop
|
||||
push r15
|
||||
cli
|
||||
rcall twiStart
|
||||
ldi r16, (LCD_TWI_ADDRESS*2)
|
||||
rcall twiSendByteExpectAck ; (R16, R17, R18, R22)
|
||||
brcc LCD_PrintChar_error
|
||||
ldi r16, LCD_DATA_MODE
|
||||
rcall twiSendByteExpectAck ; (R16, R17, R18, R22)
|
||||
brcc LCD_PrintChar_error
|
||||
|
||||
rcall lcdPrintOneChar
|
||||
brcc LCD_PrintChar_error
|
||||
rcall twiStop
|
||||
pop r15
|
||||
out SREG, r15
|
||||
sec
|
||||
ret
|
||||
LCD_PrintChar_error:
|
||||
rcall twiStop
|
||||
rcall twiStop
|
||||
pop r15
|
||||
out SREG, r15
|
||||
clc
|
||||
ret
|
||||
|
||||
107
avr/main.asm
107
avr/main.asm
@@ -66,7 +66,7 @@ main:
|
||||
|
||||
main_loop:
|
||||
rcall runModulesUntilIdle
|
||||
; sbi DDRA, PORTA2 ; debug
|
||||
sbi DDRA, PORTA2 ; debug
|
||||
; sbi PINA, PORTA2 ; debug (toggle)
|
||||
; cbi PORTA, PORTA2 ; debug (on)
|
||||
; sbi PORTA, PORTA2 ; debug (off)
|
||||
@@ -111,8 +111,8 @@ initModules:
|
||||
#endif
|
||||
|
||||
#ifdef MODULES_COM
|
||||
rcall Com_Init ; init COM module
|
||||
rcall CPRO_Init ; init COM protocol module
|
||||
rcall Com2_Init ; init COM module
|
||||
rcall CPRO_Init ; init COM protocol module
|
||||
#endif
|
||||
#ifdef MODULES_TWI_MASTER
|
||||
rcall TWI_Master_Init
|
||||
@@ -152,16 +152,17 @@ runModulesUntilIdle:
|
||||
#endif
|
||||
|
||||
#ifdef MODULES_COM
|
||||
; COM module (call until carry flag cleared but at most 10 times to not starve other modules)
|
||||
; COM module (call until carry flag cleared but at most 10 times to not starve other modules)
|
||||
ldi r16, 10
|
||||
runModulesUntilIdle_Com:
|
||||
push r16
|
||||
rcall Com_Run
|
||||
rcall Com2_Run
|
||||
pop r16
|
||||
brcc runModulesUntilIdle_ComEnd
|
||||
dec r16
|
||||
brne runModulesUntilIdle_Com
|
||||
runModulesUntilIdle_ComEnd:
|
||||
runModulesUntilIdle_ComEnd:
|
||||
|
||||
#endif
|
||||
|
||||
; add more modules here
|
||||
@@ -206,9 +207,94 @@ initialWait_l2: ; wait for 10ms
|
||||
|
||||
|
||||
#ifdef MODULES_LCD
|
||||
printSendStats:
|
||||
|
||||
printStartSendPackage:
|
||||
in r15, SREG ; debug
|
||||
push r15
|
||||
cli
|
||||
ldi r18, 1
|
||||
ldi r19, 3
|
||||
rcall LCD_SetCursor
|
||||
ldi r16, 'S'
|
||||
rcall LCD_PrintChar
|
||||
ldi r16, ' '
|
||||
rcall LCD_PrintChar
|
||||
pop r15
|
||||
out SREG, r15
|
||||
ret
|
||||
|
||||
|
||||
printEndSendPackage:
|
||||
in r15, SREG ; debug
|
||||
push r15
|
||||
cli
|
||||
ldi r18, 2
|
||||
ldi r19, 3
|
||||
rcall LCD_SetCursor
|
||||
ldi r16, 'E'
|
||||
rcall LCD_PrintChar
|
||||
pop r15
|
||||
out SREG, r15
|
||||
ret
|
||||
|
||||
|
||||
printTimerMark:
|
||||
in r15, SREG ; debug
|
||||
push r15
|
||||
cli
|
||||
ldi r18, 1
|
||||
ldi r19, 1
|
||||
rcall LCD_SetCursor
|
||||
lds r16, timerModuleCounterSecs
|
||||
rcall LCD_PrintHexByte
|
||||
pop r15
|
||||
out SREG, r15
|
||||
ret
|
||||
|
||||
|
||||
printSendStats:
|
||||
in r15, SREG ; debug
|
||||
push r15
|
||||
cli
|
||||
|
||||
ldi r18, 1
|
||||
ldi r19, 5
|
||||
rcall LCD_SetCursor
|
||||
ldi zl, LOW(textStatsPacketsIn)
|
||||
ldi zh, HIGH(textStatsPacketsIn)
|
||||
rcall LCD_PrintFromFlash
|
||||
lds r18, com2StatsPacketsIn
|
||||
lds r19, com2StatsPacketsIn+1
|
||||
rcall LCD_PrintHexWord
|
||||
|
||||
ldi r18, 1
|
||||
ldi r19, 6
|
||||
rcall LCD_SetCursor
|
||||
ldi zl, LOW(textStatsPacketsOut)
|
||||
ldi zh, HIGH(textStatsPacketsOut)
|
||||
rcall LCD_PrintFromFlash
|
||||
lds r18, com2StatsPacketsOut
|
||||
lds r19, com2StatsPacketsOut+1
|
||||
rcall LCD_PrintHexWord
|
||||
|
||||
ldi r18, 1
|
||||
ldi r19, 7
|
||||
rcall LCD_SetCursor
|
||||
ldi zl, LOW(textStatsPacketsRecvErr)
|
||||
ldi zh, HIGH(textStatsPacketsRecvErr)
|
||||
rcall LCD_PrintFromFlash
|
||||
lds r18, com2StatsBusyError
|
||||
lds r19, com2StatsBusyError+1
|
||||
rcall LCD_PrintHexWord
|
||||
|
||||
pop r15
|
||||
out SREG, r15
|
||||
ret
|
||||
|
||||
#if 0
|
||||
printSendStats:
|
||||
in r15, SREG ; debug
|
||||
push r15
|
||||
in r15, SREG ; debug
|
||||
cli
|
||||
|
||||
ldi r18, 0
|
||||
@@ -290,6 +376,7 @@ printSendStats:
|
||||
pop r15
|
||||
out SREG, r15
|
||||
ret
|
||||
#endif ; if 0
|
||||
#endif
|
||||
|
||||
|
||||
@@ -297,11 +384,12 @@ printSendStats:
|
||||
#ifdef MODULES_SI7021
|
||||
#ifdef MODULES_COM
|
||||
|
||||
#if 0
|
||||
Main_SendValueMsg:
|
||||
in r15, SREG
|
||||
push r15
|
||||
cli
|
||||
lds r16, comAddress ; do we have an address assigned?
|
||||
lds r16, com2Address ; do we have an address assigned?
|
||||
tst r16
|
||||
breq sendValueMsg_done ; no, do nothing
|
||||
; send message for current temp
|
||||
@@ -337,6 +425,7 @@ sendValueMsg_done:
|
||||
pop r15
|
||||
out SREG, r15
|
||||
ret
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef MODULES_LCD
|
||||
|
||||
@@ -158,9 +158,12 @@ timerInitTimers_loop:
|
||||
mov r18, xl
|
||||
or r18, xh
|
||||
breq timerInitTimers_end
|
||||
|
||||
mov r18, r20
|
||||
or r18, r21
|
||||
breq timerInitTimers_writeInitial
|
||||
add r20, r16 ; add counter pos in table so that not all timers elapse at the same time
|
||||
adc r21, r17
|
||||
timerInitTimers_writeInitial:
|
||||
st X+, r20
|
||||
st X, r21
|
||||
inc r16
|
||||
@@ -173,7 +176,6 @@ timerInitTimers_end:
|
||||
|
||||
|
||||
timerRunTimers:
|
||||
; TODO: incremenent uptime counter
|
||||
ldi xl, LOW(timerModuleCounterSecs)
|
||||
ldi xh, HIGH(timerModuleCounterSecs)
|
||||
rcall Utils_IncrementCounter32
|
||||
@@ -187,7 +189,7 @@ timerRunTimers_loop:
|
||||
mov r16, r22
|
||||
andi r16, TIMER_FLAGS_IF_ADDR
|
||||
breq timerRunTimers_l1 ; no need to check address
|
||||
lds r16, comAddress ; check address
|
||||
lds r16, com2Address ; check address
|
||||
tst r16
|
||||
breq timerRunTimers_loop ; no address, ignore counter
|
||||
timerRunTimers_l1:
|
||||
|
||||
@@ -529,6 +529,75 @@ Utils_WriteSeed:
|
||||
|
||||
|
||||
|
||||
; ---------------------------------------------------------------------------
|
||||
; Utils_TableJump
|
||||
;
|
||||
; Jump to a routine using a jump table.
|
||||
; IN:
|
||||
; - r16: position to jump to
|
||||
; - r17: number of entries in table
|
||||
; - Z : pointer to table
|
||||
; OUT:
|
||||
; - depends on called function
|
||||
; REGS: depends on called function
|
||||
|
||||
Utils_TableJump:
|
||||
lds r16, cproMode
|
||||
cp r16, r17
|
||||
brcc Utils_TableJump_ret
|
||||
clr r17
|
||||
add zl, r16
|
||||
adc zh, r17
|
||||
lsl zl ; shift z left for LPM instruction
|
||||
rol zh
|
||||
lpm r16, z+ ; read pointer from table
|
||||
lpm r17, z
|
||||
tst r16
|
||||
brne Utils_TableJump_jmp
|
||||
tst r17
|
||||
brne Utils_TableJump_jmp
|
||||
Utils_TableJump_ret:
|
||||
ret
|
||||
Utils_TableJump_jmp:
|
||||
push r16 ; jump via stack
|
||||
push r17
|
||||
ret
|
||||
|
||||
|
||||
|
||||
; ---------------------------------------------------------------------------
|
||||
; Find position of a given code in a table.
|
||||
;
|
||||
; IN:
|
||||
; - r16: value to translate
|
||||
; - r17: number of entries
|
||||
; - Z : pointer to table
|
||||
; OUT:
|
||||
; - CFLAG: set if translation found, cleared otherwise
|
||||
; - r16: translated value
|
||||
|
||||
Utils_FindBytePositionInTable:
|
||||
lsl zl ; shift z left for LPM instruction
|
||||
rol zh
|
||||
clr r19
|
||||
Utils_TranslateByTable_loop:
|
||||
lpm r18, z+
|
||||
cp r18, r16
|
||||
breq Utils_TranslateByTable_found
|
||||
inc r19
|
||||
dec r17
|
||||
brne Utils_TranslateByTable_loop
|
||||
clc
|
||||
ret
|
||||
Utils_TranslateByTable_found:
|
||||
mov r16, r19
|
||||
sec
|
||||
ret
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
UTILS_END:
|
||||
.equ MODULE_SIZE_UTILS = UTILS_END-UTILS_BEGIN
|
||||
|
||||
|
||||
Reference in New Issue
Block a user