📄 webasto.s
字号:
; ============================================================; Remote control of the Webasto water heater;; This program monitors the right turn light for the short pulses from; the central door locking system (+/- 200 msec) that confirm a remote; "door close" command. When 2 or 3 pulses of less than 250 msec are; received with a pause of 1 to 3 seconds between consecutive pulses,; the heater is switched on (3 pulses) or off (2 pulses).;; When a correct sequence is detected, it it confirmed by slowly; flashing the right turn signal 2 (on) or 1 (off) times.; ; Before the heater is switched on or off, there is a delay of 10; seconds during which the command may be aborted by sending another; "door close" or "door open" signal. An aborted command is confirmed; by 3 short flashes of the right turn signal.; ; The heater is switched on by simulating 2 presses of the lower-right; button. It is switched off by simulating 1 press of the same button.; After the heater is switched off, there is an additional delay of; 20 seconds to make sure the heater control unit is switched off; before the next command is issued (the control unit has a timeout of; 30 seconds).;; Functions of the diagnostic LEDs:; red 1) short blink when the detection cycle is restarted; 2) lights when the control unit button is activated; green 1) signals the detection of the right turn signal; 2) lights when the feedback signal relay is activated;; Note: I suggest setting the fuse byte of the ATtiny12 to 0x12; to enable the brown-out detector.;; Copyright (C) 2005, 2006 Dick Streefland;; This is free software, licensed under the terms of the GNU General; Public License as published by the Free Software Foundation.; ============================================================.section .text.equ CLOCK, 1200000 ; internal clock frequency (Hz).equ RATE, 250 ; timer interrupt rate (Hz).equ WAIT, 10 ; waiting time before action is performed (sec).equ HEATER_TIMEOUT, 30 ; heater control unit timeout (sec); the argument of MSEC2TICKS should be lower than 256*1000/RATE = 1024#define MSEC2TICKS(msec) (RATE * (msec) / 1000)#define SECOND 1000 // Duh!#define MAX_PULSE 250 // max. pulse width of close signal (msec)#define FEEDBACK_WIDTH 666 // width of feedback signal (msec)#define ABORT_PAUSE 600 // pause before abort signal (msec)#define ABORT_WIDTH 150 // width of abort signal pulse (msec)#define ABORT_PULSES 3 // number of abort signal pulses#define BUTTON_PULSE 500 // width of simulated button press (msec)#define RESTART_FLASH 50 // width of flash at restart (msec).equ PINB, 0x16.equ DDRB, 0x17.equ PORTB, 0x18.equ IN_LIGHT, 0 ; turn light input.equ OUT_BUTTON, 1 ; webasto control unit button.equ OUT_RELAY, 2 ; relay for feedback signal.equ OUT_RED, 3 ; red LED (active low).equ OUT_GREEN, 4 ; green LED (active low).equ EECR, 0x1c ; EEPROM Control Register.equ EEMWE, 2 ; - Master Write Enable.equ EEWE, 1 ; - Write Enable.equ EERE, 0 ; - Read Enable.equ EEDR, 0x1d ; EEPROM Data Register.equ EEAR, 0x1e ; EEPROM Address Register.equ TCNT0, 0x32 ; Timer Counter 0.equ TCCR0, 0x33 ; Timer/Counter0 Control Register.equ MCUCR, 0x35 ; MCU Control Register.equ TIMSK, 0x39 ; Timer/Counter Interrupt Mask Register.equ GIMSK, 0x3b ; General Interrupt Mask Register.equ SREG, 0x3f ; Status Register; ------------------------------------------------------------; Register definitions; ------------------------------------------------------------#define TICKS r0 // counts timer interrupts (saturating)#define LIGHT r1 // debounced turn light input#define SREG_SAVE r2 // interrupt: SREG save#define TEMP r16 // temporary usage#define ITEMP r17 // interrupt: temp#define COUNT r18 // counts door close signals#define VALUE r19 // input for wait_for#define TIMEOUT r20 // input for wait_for#define DELAY r21 // input for delay; ------------------------------------------------------------; Vector table; ------------------------------------------------------------ rjmp reset ; RESET reti ; External interrupt request 0 rjmp change ; I/O pins rjmp timer ; Timer/counter 0 overflow reti ; EEPROM ready reti ; Analog comparator; ------------------------------------------------------------; Program start; ------------------------------------------------------------reset: ; init I/O sbi DDRB, OUT_BUTTON sbi DDRB, OUT_RELAY sbi PORTB, OUT_RED sbi DDRB, OUT_RED sbi PORTB, OUT_GREEN sbi DDRB, OUT_GREEN ; initializer timer ldi TEMP, 0x03 out TCCR0, TEMP ; set prescaler to 64 ldi TEMP, 0x02 out TIMSK, TEMP ; enable timer interrupt ; setup pin change interrupt ldi TEMP, 0x20 out GIMSK, TEMP ; pin change interrupt ; initialize registers clr LIGHT ; enable interrupts sei ; enable all interrupts; ------------------------------------------------------------; Count "door close" pulses.; ------------------------------------------------------------restart: cbi PORTB, OUT_RED ldi DELAY, MSEC2TICKS(RESTART_FLASH) rcall delay sbi PORTB, OUT_RED rjmp test0zzz0: ldi TEMP, 0x30 ; enable "Powerdown" sleep mode out MCUCR, TEMP sleep ; go to sleep, while waiting for low input ldi TEMP, 0x20 ; enable "Idle" sleep mode out MCUCR, TEMPtest0: rcall wait_low brne zzz0 rcall wait_high breq zzz0 ; must be idle for 1 secondzzz1: ldi TEMP, 0x30 ; enable "Powerdown" sleep mode out MCUCR, TEMP sleep ; go to sleep, while waiting for high input ldi TEMP, 0x20 ; enable "Idle" sleep mode out MCUCR, TEMP rcall wait_high brne zzz1 clr COUNTloop: inc COUNT cbi PORTB, OUT_GREEN rcall wait_low sbi PORTB, OUT_GREEN brne restart ; pulse too wide ==> restart rcall wait_high breq restart ; pause < 1 sec ==> restart rcall wait_high breq loop ; pause 1-2 sec ==> continue rcall wait_high breq loop ; pause 2-3 sec ==> continue; ------------------------------------------------------------; Check for 2 or 3 pulses.; ------------------------------------------------------------ dec COUNT breq restart cpi COUNT, 3 brsh restart; ------------------------------------------------------------; Confirm the command.; ------------------------------------------------------------ ldi DELAY, MSEC2TICKS(FEEDBACK_WIDTH) mov TEMP, COUNTconfirm: cbi PORTB, OUT_GREEN sbi PORTB, OUT_RELAY rcall delay cbi PORTB, OUT_RELAY sbi PORTB, OUT_GREEN rcall delay dec TEMP brne confirm; ------------------------------------------------------------; Wait a little, while checking for an abort pulse.; ------------------------------------------------------------ ldi TEMP, WAITcountdown: rcall wait_high breq abort dec TEMP brne countdown; ------------------------------------------------------------; Simulate 1 or 2 button presses on the heater control unit.; ------------------------------------------------------------ mov TEMP, COUNTpress: ldi DELAY, MSEC2TICKS(BUTTON_PULSE) cbi PORTB, OUT_RED sbi PORTB, OUT_BUTTON rcall delay cbi PORTB, OUT_BUTTON sbi PORTB, OUT_RED rcall delay dec TEMP brne press; ------------------------------------------------------------; After the heater is switched off, wait some more to make; sure the heater control unit is switched off before the next; command is issued.; ------------------------------------------------------------ cpi COUNT, 1 brne 2f ldi TEMP, (HEATER_TIMEOUT - WAIT) ldi DELAY, MSEC2TICKS(SECOND)1: rcall delay dec TEMP brne 1b2:; ------------------------------------------------------------; Done. Restart.; ------------------------------------------------------------ rjmp restart; ------------------------------------------------------------; The command was aborted. Confirm and restart.; ------------------------------------------------------------abort: rcall wait_low ldi DELAY, MSEC2TICKS(ABORT_PAUSE) rcall delay rcall wait_low ldi DELAY, MSEC2TICKS(ABORT_WIDTH) ldi TEMP, ABORT_PULSESflash: cbi PORTB, OUT_GREEN sbi PORTB, OUT_RELAY rcall delay cbi PORTB, OUT_RELAY sbi PORTB, OUT_GREEN rcall delay dec TEMP brne flash rjmp restart; ------------------------------------------------------------; Wait for a high input on LIGHT, with a 1 second timeout.; ------------------------------------------------------------wait_high: ldi TIMEOUT, MSEC2TICKS(SECOND) ser VALUE rjmp wait_for; ------------------------------------------------------------; Wait for a low input on LIGHT, with a timeout of MAX_PULSE msec.; ------------------------------------------------------------wait_low: ldi TIMEOUT, MSEC2TICKS(MAX_PULSE) clr VALUE rjmp wait_forwait_for: clr TICKS1: cp LIGHT, VALUE breq 2f sleep cp TICKS, TIMEOUT brlo 1b clz2: ret; ------------------------------------------------------------; Delay for DELAY ticks.; ------------------------------------------------------------delay: clr TICKS1: cp TICKS, DELAY brlo 1b ret; ------------------------------------------------------------; Timer interrupt handler; ------------------------------------------------------------timer: ldi ITEMP, 256-(CLOCK/64/RATE) out TCNT0, ITEMP ; reload counter in SREG_SAVE, SREG ; save SREG ser ITEMP cpse ITEMP,TICKS inc TICKS ; update ticks, saturating at 255 lsl LIGHT sbic PINB, 0 inc LIGHT ; shift one bit into LIGHT out SREG, SREG_SAVE ; restore SREG reti; ------------------------------------------------------------; Pin change interrupt handler; ------------------------------------------------------------change: reti; ------------------------------------------------------------; Identification; ------------------------------------------------------------ .align 4, 0xff .asciz "Copyright 2005, Dick Streefland" .asciz "2005-03-18" .align 4, 0xff
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -