summaryrefslogtreecommitdiffstats
path: root/boiler-monster/pic/gateway.asm
blob: b1c6324e2b96ba40eee1cc95e5ecb257be50b7bc (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
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