; *************************************************************************** ; copyright : (C) 2024 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 OWIMASTER_BEGIN: ; --------------------------------------------------------------------------- ; @routine OwiMaster_Init @global ; ; @return CFLAG set if okay, clear on error OwiMaster_Init: cbi OWI_DDR, OWI_PINNUM ; set to input cbi OWI_PORTOUT, OWI_PINNUM ; disable internal pullup sec ret ; @end ; --------------------------------------------------------------------------- ; @routine OwiMaster_Reset @global ; ; Cave: Needs interrupts to be disabled! ; ; @return r16 0xff if slave presence signal received, 0x00 otherwise ; @clobbers r22 OwiMaster_Reset: ; send RESET pulse (min. 480usec) sbi OWI_DDR, OWI_PINNUM ; set to output cbi OWI_PORTOUT, OWI_PINNUM ; set value to zero Utils_WaitNanoSecs 500000, 0, r22 cbi OWI_DDR, OWI_PINNUM ; set to input ; if present slave pulls line low for 60 usecs (we check after 30 usecs) Utils_WaitNanoSecs 30000, 0, r22 clr r16 sbic OWI_PORTIN, OWI_PINNUM rjmp OwiMaster_Reset_done dec r16 rcall owiWaitForDataState1ms ; wait for line pulled up OwiMaster_Reset_done: ret ; @end ; --------------------------------------------------------------------------- ; @routine OwiMaster_SendByte @global ; Cave: Needs interrupts to be disabled! ; ; @param r16 byte to send ; @clobbers r16, r21, r22 OwiMaster_SendByte: cbi OWI_DDR, OWI_PINNUM ; set to input cbi OWI_PORTOUT, OWI_PINNUM ; set value to zero ldi r21, 8 OwiMaster_SendByte_loop: sbi OWI_DDR, OWI_PINNUM ; set to output lsr r16 ; bit to send -> CARRY brcs OwiMaster_SendByte_setHigh OwiMaster_SendByte_setLow: Utils_WaitNanoSecs 60000, 0, r22 ; set to low for 60 usecs ("0") cbi OWI_DDR, OWI_PINNUM ; set to output Utils_WaitNanoSecs 5000, 0, r22 ; set to low for 5 usecs ("1") rjmp OwiMaster_SendByte_loopEnd OwiMaster_SendByte_setHigh: Utils_WaitNanoSecs 5000, 0, r22 ; set to low for 5 usecs ("1") cbi OWI_DDR, OWI_PINNUM ; set to output Utils_WaitNanoSecs 60000, 0, r22 ; keep high for remainder of write slot OwiMaster_SendByte_loopEnd: dec r21 brne OwiMaster_SendByte_loop ret ; @end ; --------------------------------------------------------------------------- ; @routine OwiMaster_RecvByte @global ; ; Receive a byte (slot size about 70 usecs) ; Cave: Needs interrupts to be disabled! ; ; @return r16 byte received ; @return CFLAG set if okay, cleared on error ; @clobbers r17, r20, r21, r22 OwiMaster_RecvByte: cbi OWI_DDR, OWI_PINNUM ; set to input cbi OWI_PORTOUT, OWI_PINNUM ; set value to zero clr r17 ldi r20, 8 OwiMaster_RecvByte_loop: sbi OWI_DDR, OWI_PINNUM ; set to output Utils_WaitNanoSecs 5000, 0, r22 ; set to low for 5 usecs ("1") cbi OWI_DDR, OWI_PINNUM ; set to input Utils_WaitNanoSecs 5000, 0, r22 ; wait for 5 usecs sec sbic OWI_PORTIN, OWI_PINNUM ; sample line rjmp OwiMaster_RecvByte_recv1 Utils_WaitNanoSecs 55000, 0, r22 clc ; shift-in ZERO rjmp OwiMaster_RecvByte_shiftIn OwiMaster_RecvByte_recv1: Utils_WaitNanoSecs 55000, 0, r22 sec OwiMaster_RecvByte_shiftIn: ror r17 Utils_WaitNanoSecs 5000, 0, r22 ; time between bits OwiMaster_RecvByte_loopEnd: dec r20 brne OwiMaster_RecvByte_loop mov r16, r17 sec ret OwiMaster_RecvByte_error: clc ret ; @end ; --------------------------------------------------------------------------- ; @routine owiWaitForDataState1ms ; ; @return CFLAG set if state reached, cleared otherwise ; @param r16 state to wait for (00 for low, 0xff for high) ; @clobbers r21, r22 owiWaitForDataState1ms: ldi r21, 10 owiWaitForDataState1ms_loop: in r22, OWI_PORTIN eor r22, r16 andi r22, (1<