; ***************************************************************************
; 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




