Files
aqhomecontrol/avr/modules/tcrt1000/main.asm
2024-12-15 22:15:00 +01:00

190 lines
4.5 KiB
NASM

; ***************************************************************************
; 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. *
; ***************************************************************************
.equ TCRT1K_INTERVAL = 7
.equ TCRT1K_LIMIT = 170
.equ TCRT1K_STATE_OPEN = 255
.equ TCRT1K_STATE_CLOSED = 0
.equ TCRT1K_FLAGS_REPORT_CHANGE_BIT = 0
; ***************************************************************************
; data
.dseg
tcrt1kDataBegin:
tcrt1kTimer: .byte 1
tcrt1kLastState: .byte 1
tcrt1kLastValue: .byte 1
tcrt1kStateCounter: .byte 1
tcrt1kFlags: .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
TCRT1K_Every100ms:
lds r16, tcrt1kTimer
dec r16
breq TCRT1K_Every100ms_readValue
sts tcrt1kTimer, r16
cpi r16, 2
breq TCRT1K_Every100ms_ledOn
cpi r16, 1
breq TCRT1K_Every100ms_startMeasure
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
cbi TCRT1K_LED_PORT, TCRT1K_LED_PIN ; LED off
sts tcrt1kLastValue, r16
cpi r16, TCRT1K_LIMIT
ldi r16, TCRT1K_STATE_CLOSED
brcs TCRT1K_Every100ms_checkChange
ldi r16, TCRT1K_STATE_OPEN
TCRT1K_Every100ms_checkChange:
lds r17, tcrt1kLastState
cp r16, r17
brne TCRT1K_Every100ms_stateChanged
lds r16, tcrt1kStateCounter
inc r16
brne TCRT1K_Every100ms_incStateCounter
ret
TCRT1K_Every100ms_incStateCounter:
sts tcrt1kStateCounter, r16
cpi r16, 1 ; report change after one interval
breq TCRT1K_Every100ms_reportChange
cpi r16, 2 ; report change after two intervals
breq TCRT1K_Every100ms_reportChange
cpi r16, 10 ; report change after ten intervals
breq TCRT1K_Every100ms_reportChange
ret
TCRT1K_Every100ms_reportChange:
lds r16, tcrt1kFlags
ori r16, (1<<TCRT1K_FLAGS_REPORT_CHANGE_BIT)
sts tcrt1kFlags, r16
ret
TCRT1K_Every100ms_stateChanged:
sts tcrt1kLastState, r16 ; store new state
clr r16
sts tcrt1kStateCounter, r16
TCRT1K_Every100ms_end:
ret
; @end
TCRT1K_Run:
lds r16, tcrt1kFlags
andi r16, (1<<TCRT1K_FLAGS_REPORT_CHANGE_BIT)
breq TCRT1K_Run_retnc
rcall TCRT1K_SendState
brcc TCRT1K_Run_retnc
lds r16, tcrt1kFlags
andi r16, ~(1<<TCRT1K_FLAGS_REPORT_CHANGE_BIT)
sts tcrt1kFlags, r16
sec
ret
TCRT1K_Run_retnc:
clc
ret
TCRT1K_SendState:
lds r16, com2Address
tst r16
brne TCRT1K_SendState_haveAddress
clc
ret
TCRT1K_SendState_haveAddress:
ldi r16, 0xff ; destination address
ldi r17, VALUE_ID_TCRT1K ; value id
ldi r22, AQHOME_VALUETYPE_DOOR
lds r18, tcrt1kLastState ; value
clr r19
ldi r20, 1 ; denominator
; lds r20, tcrt1kLastValue
clr r21
ldi xl, LOW(com2SendBuffer)
ldi xh, HIGH(com2SendBuffer)
rcall CPRO_WriteReportValue
rjmp COM2_SendPacket