summaryrefslogtreecommitdiffstats
path: root/boiler-monster/pic/gateway.asm
diff options
context:
space:
mode:
Diffstat (limited to 'boiler-monster/pic/gateway.asm')
-rw-r--r--boiler-monster/pic/gateway.asm296
1 files changed, 296 insertions, 0 deletions
diff --git a/boiler-monster/pic/gateway.asm b/boiler-monster/pic/gateway.asm
new file mode 100644
index 0000000..b1c6324
--- /dev/null
+++ b/boiler-monster/pic/gateway.asm
@@ -0,0 +1,296 @@
+ title "OpenTherm Gateway"
+ list p=16F88, b=8, r=dec
+
+;Copyright (c) 2009 Schelte Bron
+
+#define version "4.2"
+#define phase "." ;a=alpha, b=beta, .=production
+#define patch "5" ;Comment out when not applicable
+;#define bugfix "1" ;Comment out when not applicable
+#include build.asm
+
+;See the file "license.txt" for information on usage and redistribution of
+;this file, and for a DISCLAIMER OF ALL WARRANTIES.
+
+#ifndef LVP
+ __config H'2007', B'10111101110100'
+#else
+ __config H'2007', B'10111111110100'
+#endif
+ __config H'2008', B'11111111111111'
+
+ errorlevel -302
+
+;#######################################################################
+;Comparator 1 is used for requests. The input is connected to the thermostat.
+;In monitor mode, the output is connected to the boiler.
+;Comparator 2 is used for responses. The input is connected to the Boiler.
+;In monitor mode, the output is connected to the thermostat.
+
+;The AUSART is configured for full duplex asynchronous serial communication at
+;9600 baud, 8 bits, no parity. It is used for reporting about opentherm messages
+;and receiving commands.
+
+;Analog input 0 is used to measure the voltage level on the opentherm line to
+;the thermostat. This way the code can distinguish between a real opentherm
+;thermostat and a simple on/off thermostat. An opentherm thermostat will keep
+;the line at a few volts (low) or between 15 and 18 volts (high). An on/off
+;thermostat will either short-circuit the line (0 volts) or leave the line open
+;(20+ volts).
+
+#include "p16f88.inc"
+
+;Define the speed of the PIC clock
+#define mhzstr "4"
+
+;BAUD contains the SPBRG value for 9600 baud
+ constant BAUD=25
+
+ extern SelfProg
+
+;Variables accessible from all RAM banks
+ UDATA_SHR
+loopcounter res 1
+
+Bank0data UDATA 0x20
+rxbuffer res 16 ;Serial receive buffer
+
+;Variables for longer lasting storage
+rxpointer res 1
+txpointer res 1
+
+temp res 1
+
+Bank1data UDATA 0xA0
+
+Bank1values UDATA 0xE0
+
+Bank2data UDATA 0x110
+Bank2values UDATA 0x160
+
+Bank3data UDATA 0x190
+;Use all available RAM in bank 3 for the transmit buffer
+ constant TXBUFSIZE=80
+txbuffer res TXBUFSIZE
+Bank3values UDATA 0x1E0
+
+;I/O map
+#define MasterIn CMCON,C1OUT
+#define SlaveIn CMCON,C2OUT
+#define SlaveOut PORTA,3
+#define MasterOut PORTA,4
+#define RXD PORTB,2
+#define TXD PORTB,5
+#define CCP1 PORTB,0
+#define LED_A PORTB,3
+#define LED_B PORTB,4
+#define LED_C PORTB,6
+#define LED_D PORTB,7
+#define RSET PORTB,1 ;Used by self-programming
+
+#define SlaveMask b'00001000'
+#define MasterMask b'00010000'
+
+package macro pkg
+pkg code
+pkg
+ endm
+
+pcall macro rtn
+ lcall rtn
+ pagesel $
+ endm
+
+;Skip the next instruction (bit 7 of PCLATH is always 0)
+skip macro
+ btfsc PCLATH,7
+ endm
+
+;Get the output of the active comparator into the carry bit
+getcompout macro
+ bsf STATUS,RP0
+ rlf CMCON,W ;Get the output of comparator 2
+ bcf STATUS,RP0
+ btfsc Request ;A request goes through comparator 1
+ addlw b'10000000' ;Cause a carry if C1OUT is high
+ endm
+
+;The first thing to do upon a reset is to allow the firmware to be updated.
+;So no matter how buggy freshly loaded firmware is, if the first two command
+;have not been messed up, the device can always be recovered without the need
+;for a PIC programmer. The self-programming code times out and returns after
+;a second when no firmware update is performed.
+;
+
+ResetVector code 0x0000
+ lcall SelfProg ;Always allow a firmware update on boot
+ lgoto Start ;Start the opentherm gateway program
+
+InterruptVector code 0x0004
+ retfie ;End of interrupt routine
+
+ package Interrupt
+
+;########################################################################
+; Main program
+;########################################################################
+
+ package Main
+Break tstf RCREG ;Clear the RCIF interrupt flag
+ bcf STATUS,RP1
+ bcf STATUS,RP0 ;bank 0
+ movlw 128
+ call Pause
+ pcall SelfProg ;Jump to the self-programming code
+Start bcf STATUS,RP1
+ bcf STATUS,RP0 ;bank 0
+ clrf PORTB ;Flash the LED's on startup
+ bsf STATUS,RP0
+ movlw b'01100000' ;Internal oscillator set to 4MHz
+ movwf OSCCON ;Configure the oscillator
+
+ ;Configure I/O pins
+ ;Power on defaults all pins to inputs
+ ;Port A
+ ;Pins 0 and 1 are used as comparator inputs
+ ;Pin 2 is used as VREF (must be configured as input!)
+ ;Pins 3 and 4 are (comparator) ouputs
+ ;Pin 5 is master reset input
+ ;Pins 6 and 7 are GPIO
+ movlw b'11100111'
+ movwf TRISA
+
+ ;Port B
+ ;Pins 2 and 5 are used by the USART and don't need to be configured
+ ;Pins 3, 4, 6, and 7 are used to indicate events for debugging
+#ifndef LVP
+ movlw b'00100111'
+#else
+ ;Can't use RB3 if LVP is enabled
+ movlw b'00101111'
+#endif
+ movwf TRISB
+
+ movlw b'11'
+ movwf PCON
+
+ ;Configure Timer 0 & Watchdog Timer
+ ;Bit 7 RBPU = 1 - Port B pull up disabled
+ ;Bit 6 INTEDG = 1 - Interrupt on rising edge
+ ;Bit 5 T0CS = 0 - Internal clock
+ ;Bit 4 T0SE = 1 - High to low transition
+ ;Bit 3 PSA = 0 - Prescaler assigned to Timer 0
+ ;Bit 2-0 PS = 5 - 1:64 Prescaler
+ movlw b'11010101'
+ movwf OPTION_REG
+
+
+ ;Configure comparator module
+ ;Bit 7 C2OUT = R/O
+ ;Bit 6 C1OUT = R/O
+ ;Bit 5 C2INV = 0 - Not inverted
+ ;Bit 4 C1INV = 0 - Not inverted
+ ;Bit 3 CIS = 0 - Irrelevant
+ ;Bit 2-0 = 3 - Common reference / 6 - with outputs
+ movlw b'00000011' ;Common reference mode
+ movwf CMCON
+
+ movlw b'00000111' ;A0 through A2 are used for analog I/O
+ movwf ANSEL
+
+ ;Configure the serial interface
+ movlw BAUD
+ movwf SPBRG
+ bsf TXSTA,BRGH ;9600 baud
+ bcf TXSTA,SYNC ;Asynchronous
+ bsf TXSTA,TXEN ;Enable transmit
+ bcf STATUS,RP0
+ bsf RCSTA,SPEN ;Enable serial port
+ bsf RCSTA,CREN ;Enable receive
+
+ ;Configure A/D converter
+ movlw b'01000001' ;A/D on, channel 0, Fosc/8
+ movwf ADCON0
+
+ ;Configure the voltage reference module
+ ;The reference voltage must be set to 1.3V
+ ;Bit 7 VREN = 1 - VREF Enabled
+ ;Bit 6 VROE = 1 - Output on pin RA2
+ ;Bit 5 VRR = 1 - Low range
+ ;Bit 3-0 VR = 6 - 1.25V (7 - 1.46V)
+ movlw b'11100110'
+ bsf STATUS,RP0
+ movwf CVRCON ;Set the reference voltage
+
+
+ clrf STATUS
+ bcf PIR2,CMIF ;Clear any comparator interrupt
+
+ movlw 0x41
+ movwf TXREG
+
+
+
+
+MainLoop clrwdt
+
+ ; Copy CMCON bits 7 and 6 from to PORTB bits 7 and 6 (comparitor outputs to LED_C and LED_D pins)
+ bsf STATUS,RP0
+ movfw CMCON
+ bcf STATUS,RP0
+
+ andlw b'11000000'
+ iorwf PORTB,F
+ iorlw b'00111111'
+ andwf PORTB,F
+
+ ; Copy PORTA bits 7 and 6 to PORTA bits 4 and 3 (GPIO inputs to transmitter outputs)
+ rrf PORTA,W
+ movwf temp
+ rrf temp,F
+ rrf temp,W
+
+ andlw b'00011000'
+ iorwf PORTA,F
+ iorlw b'11100111'
+ andwf PORTA,F
+
+ ; And port B bits 4 and 3 (LED_A and LED_B)
+
+ andlw b'00011000'
+ iorwf PORTB,F
+ iorlw b'11100111'
+ andwf PORTB,F
+
+
+ btfss PIR1,RCIF ;Activity on the serial receiver?
+ goto MainLoop
+ tstf RCREG
+
+ ;FERR is only relevant if RCIF is set
+ btfsc RCSTA,FERR ;Check for framing error (break)
+ goto Break
+ btfss RCSTA,OERR ;Check for overrun error
+ goto serial_recv
+ bcf RCSTA,CREN ;Procedure to clear an overrun error
+ bsf RCSTA,CREN ;Re-enable the serial interface
+serial_recv movfw RCREG
+ ;movwf TXREG
+ xorlw 0x4
+ skpnz
+ goto Break
+ goto MainLoop
+
+Pause clrwdt
+ btfsc PIR1,RCIF
+ return
+ btfss INTCON,TMR0IF
+ goto Pause
+ bcf INTCON,TMR0IF
+ addlw -1
+ skpz
+ goto Pause
+ return
+
+
+ end