; *************************************************************************** ; 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 CPRO_CMD_PING = 10 .equ CPRO_CMD_PONG = 11 .equ CPRO_CMD_COMSENDSTATS = 20 .equ CPRO_CMD_COMRECVSTATS = 21 .equ CPRO_CMD_TWIBUSMEMBER = 30 .equ CPRO_CMD_DEBUG = 40 .equ CPRO_CMD_VALUE = 51 ; was 50 when sending timestamp instead of uid .equ CPRO_CMD_NEED_ADDRESS = 60 .equ CPRO_CMD_HAVE_ADDRESS = 61 .equ CPRO_CMD_CLAIM_ADDRESS = 62 .equ CPRO_CMD_DENY_ADDRESS = 63 .equ CPRO_CMD_ADDRESS_RANGE = 64 .equ CPRO_CMD_FLASH_START = 70 .equ CPRO_CMD_FLASH_END = 71 .equ CPRO_CMD_FLASH_ADDR = 72 .equ CPRO_CMD_FLASH_DATA = 73 .equ CPRO_CMD_FLASH_RSP = 74 .equ CPRO_CMD_DEVICE = 80 .equ CPRO_CMD_MEMSTATS = 81 .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_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 ; *************************************************************************** ; data .dseg 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 cproDataEnd: ; *************************************************************************** ; code .cseg CPRO_BEGIN: CPRO_Init: ; preset SRAM data area ldi xh, HIGH(cproDataBegin) ldi xl, LOW(cproDataBegin) 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: #endif ret ; --------------------------------------------------------------------------- ; CPRO_OnPacketReceived: ; ; Try to handle the given packet. ; ; IN: ; - Y : 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) 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 clc ret cproHandlePing: ldd r16, y+(COM_BUFFER_OFFS_DATA+COM_MSG_OFFS_SRCADDR) tst r16 breq cproHandlePing_notHandled rcall CPRO_EnqueuePong ret ; use carry flag from previous call 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