Files
aqhomecontrol/avr/com_send.asm
2023-04-08 13:05:05 +02:00

209 lines
5.9 KiB
NASM

; ***************************************************************************
; 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
; ---------------------------------------------------------------------------
; 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