; *************************************************************************** ; 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. * ; *************************************************************************** ; --------------------------------------------------------------------------- ; receive packet into buffer pointed to by X. ; ; IN: ; - R16: COM address to listen to ; - R17: maximum value for accepted msg data (i.e. buffersize minus 3) ; - X : buffer to receive to ; OUT: ; - CFLAG: set if okay (packet received), cleared on error ; - R16: error code if CFLAG is cleared ; REGS: r16, r17, r18, X (r19, r20, r21, r22) com2ReceivePacketRaw: mov r18, r17 push r16 ; read destination address rcall com2ReceiveByte ; read byte (R16, R17, R20, R21, R22) pop r17 ; pop from R16 to R17 brcc com2ReceivePacketRaw_ioError ; compare destination address (accept "FF" and own address) cp r16, r17 breq com2ReceivePacketRaw_acceptAddr cpi r16, 0xff breq com2ReceivePacketRaw_acceptAddr ldi r16, COM2_ERROR_NOTFORME rjmp com2ReceivePacketRaw_error ; clc/ret com2ReceivePacketRaw_acceptAddr: st X+, r16 ; store dest address, lock buffer ; read msg length rcall com2ReceiveByte ; read packet length (R16, R17, R20, R21, R22) brcc com2ReceivePacketRaw_ioError st X+, r16 cp r16, r18 ; (COM2_BUFFER_SIZE-3) brcc com2ReceivePacketRaw_contentError ; packet too long inc r16 ; account for checksum byte mov r17, r16 com2ReceivePacketRaw_loop: push r17 rcall com2ReceiveByte ; read byte (R16, R17, R20, R21, R22) pop r17 brcc com2ReceivePacketRaw_ioError st X+, r16 dec r17 brne com2ReceivePacketRaw_loop rjmp com2PacketsSecRet com2ReceivePacketRaw_ioError: ldi r16, COM2_ERROR_IOERROR rjmp com2PacketsClcRet com2ReceivePacketRaw_contentError: ldi r16, COM2_ERROR_DATAERROR com2ReceivePacketRaw_error: rjmp com2PacketsClcRet ; --------------------------------------------------------------------------- ; send packet over wire, handle ATTN line. ; ; IN: ; - x : ptr to buffer to send ; OUT: ; - CFLAGS: set if okay, cleared otherwise (errorcode in R16) ; REGS: R16, R22 (R17, R21, X) COM2_SendPacketWithAttn: push r15 in r15, SREG 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_SendPacketWithAttn_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 rcall com2WaitForOneBitLength ; wait for one bit duration (R22) rcall com2WaitForOneBitLength ; wait for another bit duration (R22) 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 ; (r16, r17, r21, r22, X) cbi COM_DDR_ATTN, COM_PINNUM_ATTN ; release ATTN line (by setting direction to IN) brcc COM2_SendPacketWithAttn_ioError ; packet successfully sent out SREG, r15 pop r15 rjmp com2PacketsSecRet COM2_SendPacketWithAttn_ioError: ldi r16,COM2_ERROR_COLLISION rjmp COM2_SendPacketWithAttn_retNc COM2_SendPacketWithAttn_lineBusyError: ldi r16,COM2_ERROR_BUSY COM2_SendPacketWithAttn_retNc: pop r15 out SREG, r15 rjmp com2PacketsClcRet ; --------------------------------------------------------------------------- ; wait for one bit length (minus cycles for call and ret). ; ; IN: ; - nothing ; OUT: ; - nothing ; REGS: r22 com2WaitForOneBitLength: Utils_WaitNanoSecs COM_BIT_LENGTH, 7, r22 ; wait for one bit duration (minus RCALL/RET) 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 com2PacketsClcRet dec r17 brne com2SendPacket_loop sec ret com2PacketsClcRet: clc ret com2PacketsSecRet: sec ret