; *************************************************************************** ; 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 ; --------------------------------------------------------------------------- ; @routine CPRO_WriteReportValue @global ; Write a REPORT_VALUE packet. ; ; @return nothing ; @param R16 destination address ; @param R17 value id ; @param R19:R18 value ; @param R21:R20 denom (e.g. 100, meaning value must be divided by 100) ; @param R22 value type ; @param X buffer to write to ; @clobbers R16 (R17, R18, R19, R20, R21) CPRO_WriteReportValue: rcall CPRO_PrepareReportValue ; (R16, R17, R18, R19, R20, R21) ; set msg id adiw xh:xl, CPRO_PACKET_VALUE_OFFS_MSGID ldi r18, 1 lds r16, com2LastMsgId lds r17, com2LastMsgId+1 add r16, r18 dec r18 adc r17, r18 sts com2LastMsgId, r16 sts com2LastMsgId+1, r17 st X+, r16 st X+, r17 sbiw xh:xl, CPRO_PACKET_VALUE_OFFS_MSGID+2 ; go back to begin of msg ; calc and add checksum rcall com2CalcAndAddChecksumByte ; (R16, R17, R18, R19, X) sbiw xh:xl, 17 ; go back to beginning of message ret ; @end ; --------------------------------------------------------------------------- ; @routine CPRO_PrepareReportValue @global ; Write a REPORT_VALUE packet (except the checksum byte). ; ; @return nothing ; @param R16 destination address ; @param R17 value id ; @param R19:R18 value ; @param R21:R20 denom (e.g. 100, meaning value must be divided by 100) ; @param R22 value type ; @param X buffer to write to ; @clobbers R16 (R17, R18, R19, R20, R21) CPRO_PrepareReportValue: st X+, r16 ; dest address ldi r16, 14 ; msg code+src address+12 payload bytes st X+, r16 ; msg len ldi r16, CPRO_CMD_VALUE_REPORT st X+, r16 ; msg code lds r16, com2Address st X+, r16 ; src address adiw xh:xl, 6 ; skip uid (4 bytes), msg/ref id (2 bytes) st X+, r17 ; value id st X+, r22 ; value type st X+, r18 ; value (low) st X+, r19 ; value (high) st X+, r20 ; denom (low) st X+, r21 ; denom (high) sbiw xh:xl, 12 ; go back to UID (12=16 back, 4 forward) rcall COM2_AddUidToBuffer ; (r16, r18, r19, r20, r21) clr r16 st X+, r16 ; msg id (low) st X+, r16 ; msg id (high) sbiw xh:xl, 10 ; go back to beginning of message ret ; @end ; --------------------------------------------------------------------------- ; @routine CPRO_WriteSetValueResponse @global ; Write response to a SET_VALUE request. ; ; @return nothing ; @param R16 message code (CPRO_CMD_VALUE_SET_ACK or CPRO_CMD_VALUE_SET_NACK) ; @param X buffer to write to ; @param Y buffer with received setValueRequest message ; @clobbers R16, R17, R18, R19, (Y) CPRO_WriteSetValueResponse: rcall cproInvertValueMsg ; (R16, R17, R18, R19, Y) ; add checksum byte rcall com2CalcAndAddChecksumByte ; (R16, R17, R18, R19, X) sbiw xh:xl, 16 ; go back to beginning of message ret ; @end ; --------------------------------------------------------------------------- ; @routine CPRO_WriteGetValueResponse @global ; Write response to a SET_VALUE request. ; ; @return nothing ; @param R16 message code (CPRO_CMD_VALUE_SET_ACK or CPRO_CMD_VALUE_SET_NACK) ; @param R19:R18 value ; @param R21:R20 denom (e.g. 100, meaning value must be divided by 100, 0=don't change) ; @param X buffer to write to ; @param Y buffer with received setValueRequest message ; @clobbers R16, R17, R18, R19, (R20, R21, Y) CPRO_WriteGetValueResponse: push r18 push r19 rcall cproInvertValueMsg ; (R16, R17, R18, R19, Y) pop r19 pop r18 ; replace values adiw xh:xl, CPRO_PACKET_VALUE_OFFS_VALUE st X+, r18 ; value (low) st X+, r19 ; value (high) st X+, r20 ; denom (low) st X+, r21 ; denom (high) sbiw xh:xl, CPRO_PACKET_VALUE_OFFS_VALUE+4 ; add checksum byte rcall com2CalcAndAddChecksumByte ; (R16, R17, R18, R19, X) sbiw xh:xl, 13 ; go back to beginning of message ret ; @end ; --------------------------------------------------------------------------- ; @routine cproInvertValueMsg ; Write response to a SET_VALUE request. ; ; @return nothing ; @param R16 message code (CPRO_CMD_VALUE_SET_ACK or CPRO_CMD_VALUE_SET_NACK) ; @param X buffer to write to ; @param Y buffer with received setValueRequest message ; @clobbers R16, R17, R18, R19, (Y) cproInvertValueMsg: ; copy received message into new message mov r19, r16 ldi r18, 16 ; message size without checksum byte rcall Utils_Copy_SDRAM ; (R17, R18, X, Y) sbiw xh:xl, 16 ; go back to beginning of message ; exchange src and dest address adiw xh:xl, 3 ; src address ld r16, X lds r17, com2Address st X, r17 ; set our src address sbiw xh:xl, 3 st X, r16 ; set old src address as destination address ; replace msg code adiw xh:xl, 2 ; msg code st X, r19 sbiw xh:xl, 2 ; replace UID adiw xh:xl, CPRO_PACKET_VALUE_OFFS_UID rcall COM2_AddUidToBuffer ; (r16, r18, r19, r20, r21) sbiw xh:xl, CPRO_PACKET_VALUE_OFFS_UID+4 ; go back to beginning of message ret ; @end ; --------------------------------------------------------------------------- ; @routine CPRO_SendSetValueResponse @global ; Write response to a SET_VALUE request. ; ; @return CFLAG set if okay, cleared on error ; @param R16 message code (CPRO_CMD_VALUE_SET_ACK or CPRO_CMD_VALUE_SET_NACK) ; @param X buffer to write to ; @param Y buffer with received setValueRequest message ; @clobbers Y, (R16, R17, R18, R19, R22) CPRO_SendSetValueResponse: push xh push xl mov yh, xh mov yl, xl ldi xl, LOW(com2SendBuffer) ldi xh, HIGH(com2SendBuffer) rcall CPRO_WriteSetValueResponse ; (R16, R17, R18, R19, Y) rcall COM2_SendPacket ; (r18, r19, r22, X) pop xl pop xh ret ; @end ; --------------------------------------------------------------------------- ; @routine CPRO_SendGetValueResponse @global ; Write response to a GET_VALUE request. ; ; @return CFLAG set if okay, cleared on error ; @param R16 message code (CPRO_CMD_VALUE_SET_ACK or CPRO_CMD_VALUE_SET_NACK) ; @param R19:R18 value ; @param R21:R20 denom (e.g. 100, meaning value must be divided by 100, 0=don't change) ; @param X buffer to write to ; @param Y buffer with received getValueRequest message ; @clobbers Y, (R16, R17, R18, R19, R22) CPRO_SendGetValueResponse: push xh push xl mov yh, xh mov yl, xl ldi xl, LOW(com2SendBuffer) ldi xh, HIGH(com2SendBuffer) rcall CPRO_WriteGetValueResponse ; (R16, R17, R18, R19, Y) rcall COM2_SendPacket ; (r18, r19, r22, X) pop xl pop xh ret ; @end