diff --git a/avr/modules/owimaster/0BUILD b/avr/modules/owimaster/0BUILD new file mode 100644 index 0000000..8038787 --- /dev/null +++ b/avr/modules/owimaster/0BUILD @@ -0,0 +1,12 @@ + + + + + + main.asm + + + + + + diff --git a/avr/modules/owimaster/main.asm b/avr/modules/owimaster/main.asm new file mode 100644 index 0000000..c1dc609 --- /dev/null +++ b/avr/modules/owimaster/main.asm @@ -0,0 +1,172 @@ +; *************************************************************************** +; 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<