From 9d87c925a9eaa4fc256be3173c14a20d1469472d Mon Sep 17 00:00:00 2001 From: fishsoupisgood Date: Wed, 9 Sep 2020 11:53:37 +0100 Subject: everything, mostly, working --- boiler-monster/pic/gateway.asm | 296 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 296 insertions(+) create mode 100644 boiler-monster/pic/gateway.asm (limited to 'boiler-monster/pic/gateway.asm') 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 -- cgit v1.2.3