Files
aqhomecontrol/avr/modules/tcrt1000/main2.asm
2025-06-15 17:46:06 +02:00

147 lines
3.6 KiB
NASM

; ***************************************************************************
; 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 TCRT1K_INTERVAL = 7
;.equ TCRT1K_LIMIT = 170
.equ TCRT1K_LIMIT = 100
.equ TCRT1K_FLAGS_VALID_BIT = 7
.equ TCRT1K_FLAGS_VALUE_BIT = 0
; ***************************************************************************
; data
.dseg
tcrt1kDataBegin:
tcrt1kTimer: .byte 1
tcrt1kFlags: .byte 1
tcrt1kLastValue: .byte 1
tcrt1kDataEnd:
; ***************************************************************************
; code
.cseg
; ---------------------------------------------------------------------------
; @routine TCRT1K_Init
;
; Init module.
;
; @return CFLAG always set
TCRT1K_Init:
; preset SRAM data area
ldi xh, HIGH(tcrt1kDataBegin)
ldi xl, LOW(tcrt1kDataBegin)
clr r16
ldi r17, (tcrt1kDataEnd-tcrt1kDataBegin)
rcall Utils_FillSram
; setup pins
sbi TCRT1K_LED_DDR, TCRT1K_LED_PIN ; set DATA port as output
cbi TCRT1K_LED_PORT, TCRT1K_LED_PIN ; LED off
cbi TCRT1K_ADC_PORT, TCRT1K_ADC_PIN ; disable internal pullup for ADC
cbi TCRT1K_ADC_DDR, TCRT1K_ADC_PIN ; set ADC port as input
ldi r16, TCRT1K_ADC_MUX ; select input pin, use Vcc as reference voltage
out ADMUX, r16
ldi r16, (1 << ADLAR)
out ADCSRB, r16
ldi r16, (1 << ADEN) | (1 << ADPS1) | (1 << ADPS0) ; enable, prescaler 8
out ADCSRA, r16
ldi r16, TCRT1K_INTERVAL
sts tcrt1kTimer, r16
sec
ret
TCRT1K_Fini:
sec
ret
; ---------------------------------------------------------------------------
; @routine TCRT1K_Every100ms @global
;
TCRT1K_Every100ms:
lds r16, tcrt1kTimer
dec r16
breq TCRT1K_Every100ms_readValue
sts tcrt1kTimer, r16
cpi r16, 1
breq TCRT1K_Every100ms_startMeasure
cpi r16, 2
breq TCRT1K_Every100ms_ledOn
ret
TCRT1K_Every100ms_ledOn:
sbi TCRT1K_LED_PORT, TCRT1K_LED_PIN ; LED on
ret
TCRT1K_Every100ms_startMeasure:
sbi ADCSRA, ADSC ; start conversion
ret
TCRT1K_Every100ms_readValue:
sbic ADCSRA, ADSC
ret ; return if bit still set, leave tcrt1kTimer at "1"
; conversion complete, read value
ldi r16, TCRT1K_INTERVAL ; restart timer
sts tcrt1kTimer, r16
in r16, ADCH ; read value from ADC
sts tcrt1kLastValue, r16
cbi TCRT1K_LED_PORT, TCRT1K_LED_PIN ; LED off
; convert to 1/0
lds r17, tcrt1kFlags
cbr r17, (1<<TCRT1K_FLAGS_VALUE_BIT) ; clear value bit
cpi r16, TCRT1K_LIMIT ; ADC value < LIMIT?
brcs TCRT1K_Every100ms_valueSet ; yes: keep value bit zero
sbr r17, (1<<TCRT1K_FLAGS_VALUE_BIT) ; no: set value bit
TCRT1K_Every100ms_valueSet:
sbr r17, (1<<TCRT1K_FLAGS_VALID_BIT) ; set valid bit
sts tcrt1kFlags, r17
ret
; @end
; ---------------------------------------------------------------------------
; @routine TCRT1K_GetValue @global
;
; @return CFLAG set if there is a value, cleared otherwise (standard api)
; @return R16 value (0=door closed, 1=door open)
; @clobbers R16
TCRT1K_GetValue:
lds r16, tcrt1kFlags
sbrs r16, TCRT1K_FLAGS_VALID_BIT
rjmp TCRT1K_GetValue_retNc
andi r16, (1<<TCRT1K_FLAGS_VALUE_BIT)
sec
ret
TCRT1K_GetValue_retNc:
clc
ret
; @end