; *************************************************************************** ; copyright : (C) 2025 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. * ; *************************************************************************** .equ UARTSOFT_WAITFORSYNCSTART = 200 ; *************************************************************************** ; code .cseg uartSoftWaitAndReadSyncByte: ; wait for begin of startbit ldi r24, LOW(UARTSOFT_WAITFORSYNCSTART) ldi r25, HIGH(UARTSOFT_WAITFORSYNCSTART) uartSoftWaitAndReadSyncByte_loop0: sbis COM_DATA_INPUT, COM_DATA_PIN rjmp uartSoftWaitAndReadSyncByte_gotStartBit sbiw r25:r24, 1 brne uartSoftWaitAndReadSyncByte_loop0 uartSoftWaitAndReadSyncByte_error: ; timeout clc ret uartSoftWaitAndReadSyncByte_gotStartBit: clr r25 clr r24 ; count cycles while DATA low (count length of startBit) uartSoftWaitAndReadSyncByte_loopLow: ; 5 cycles per loop +3 cycles to leave loop sbic COM_DATA_INPUT, COM_DATA_PIN ; +2 (skip)/+1 (no skip) rjmp uartSoftWaitAndReadSyncByte_startDataBit1 ; +0 (skip) / +2 (no skip) adiw r25:r24, 1 ; +1 brne uartSoftWaitAndReadSyncByte_loopLow ; +2 rjmp uartSoftWaitAndReadSyncByte_error uartSoftWaitAndReadSyncByte_startDataBit1: clr r25 clr r24 ldi r17, 4 uartSoftWaitAndReadSyncByte_loopData: ; count cycles while DATA high (count length of dataBit) uartSoftWaitAndReadSyncByte_loopDataHigh: ; 5 cycles per loop +3 cycles to leave loop sbis COM_DATA_INPUT, COM_DATA_PIN ; +2 (skip)/+1 (no skip) rjmp uartSoftWaitAndReadSyncByte_startLowDataBit ; +0 (skip) / +2 (no skip) adiw r25:r24, 1 ; +1 brne uartSoftWaitAndReadSyncByte_loopDataHigh ; +2 ; too long LOW rjmp uartSoftWaitAndReadSyncByte_error uartSoftWaitAndReadSyncByte_startLowDataBit: ; count cycles while DATA low (count length of dataBit) uartSoftWaitAndReadSyncByte_loopDataLow: ; 5 cycles per loop +3 cycles to leave loop sbic COM_DATA_INPUT, COM_DATA_PIN ; +2 (skip)/+1 (no skip) rjmp uartSoftWaitAndReadSyncByte_startHighDataBit ; +0 (skip) / +2 (no skip) adiw r25:r24, 1 ; +1 brne uartSoftWaitAndReadSyncByte_loop4 ; +2 ; too long LOW rjmp uartSoftWaitAndReadSyncByte_error uartSoftWaitAndReadSyncByte_startHighDataBit: dec r17 brne uartSoftWaitAndReadSyncByte_loopData ; calc average (8 values) lsr r25 ; /2 ror r24 lsr r25 ; /4 ror r24 lsr r25 ; /8 ror r24 sec ret ; @end uartSoftReceiveByte: ; wait for begin of startbit ldi r24, LOW(UARTSOFT_WAITFORSYNCSTART) ldi r25, HIGH(UARTSOFT_WAITFORSYNCSTART) uartSoftReceiveByte_waitForBeginOfStartBit: sbis COM_DATA_INPUT, COM_DATA_PIN rjmp uartSoftReceiveByte_gotBeginOfStartBit sbiw r25:r24, 1 brne uartSoftReceiveByte_waitForBeginOfStartBit uartSoftReceiveByte_error: ; timeout clc ret uartSoftReceiveByte_gotBeginOfStartBit: clr r25 clr r24 ; count cycles while DATA low (count length of startBit) uartSoftReceiveByte_waitForEndOfStartBit: ; 5 cycles per loop sbic COM_DATA_INPUT, COM_DATA_PIN ; +2 (skip)/+1 (no skip) rjmp uartSoftReceiveByte_gotEndOfStartBit ; +0 (skip) / +2 (no skip) adiw r25:r24, 1 ; +1 brne uartSoftWaitAndReadSyncByte_loopLow ; +2 rjmp uartSoftReceiveByte_error uartSoftReceiveByte_gotEndOfStartBit: ; r25:r24=counter equivalent for length of startbit clr r16 ldi r17, 8 uartSoftReceiveByte_bitLoop: ; TODO: receive 8bits, wait for start of endbit ret uartSoftCountDataLow: ; 5 cycles per loop +5 cycles outside (+3 cycles RCALL) sbic COM_DATA_INPUT, COM_DATA_PIN ; +2 (skip)/+1 (no skip) rjmp uartSoftCountDataLow_ok ; +0 (skip) / +2 (no skip) adiw r25:r24, 1 ; +1 brne uartSoftCountDataLow ; +2 clc ret uartSoftCountDataLow_ok: sec ret ; @end uartSoftCountDataHigh: ; 5 cycles per loop +5 cycles outside (+3 cycles RCALL) sbis COM_DATA_INPUT, COM_DATA_PIN ; +2 (skip)/+1 (no skip) rjmp uartSoftCountDataHigh_ok ; +0 (skip) / +2 (no skip) adiw r25:r24, 1 ; +1 brne uartSoftCountDataHigh ; +2 clc ret uartSoftCountDataHigh_ok: sec ; +1 ret ; +4 ; @end uartSoftWaitBitTime: ; 5 cycles per loop +5 cycles outside (+3 cycles RCALL) uartSoftWaitBitTime_loop: nop ; +1 nop ; +1 sbiw r25:r24, 1 ; +1 brne uartSoftWaitBitTime_loop ; +2 nop ; +1 ret ; +4 ; @end