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/.gitignore | 8 + boiler-monster/pic/16f88.lkr | 76 ++++++ boiler-monster/pic/Makefile | 22 ++ boiler-monster/pic/build.asm | 2 + boiler-monster/pic/docs/otgw-big-sch.png | Bin 0 -> 77271 bytes boiler-monster/pic/docs/pinout.txt | 33 +++ boiler-monster/pic/gateway.asm | 296 +++++++++++++++++++++++ boiler-monster/pic/selfprog.asm | 391 +++++++++++++++++++++++++++++++ 8 files changed, 828 insertions(+) create mode 100644 boiler-monster/pic/.gitignore create mode 100644 boiler-monster/pic/16f88.lkr create mode 100644 boiler-monster/pic/Makefile create mode 100644 boiler-monster/pic/build.asm create mode 100644 boiler-monster/pic/docs/otgw-big-sch.png create mode 100644 boiler-monster/pic/docs/pinout.txt create mode 100644 boiler-monster/pic/gateway.asm create mode 100644 boiler-monster/pic/selfprog.asm (limited to 'boiler-monster/pic') diff --git a/boiler-monster/pic/.gitignore b/boiler-monster/pic/.gitignore new file mode 100644 index 0000000..f8ab154 --- /dev/null +++ b/boiler-monster/pic/.gitignore @@ -0,0 +1,8 @@ +*.err +*.swp +*.swo +*.lst +*.o +*.hex +*.map +*.cod diff --git a/boiler-monster/pic/16f88.lkr b/boiler-monster/pic/16f88.lkr new file mode 100644 index 0000000..b2b3e95 --- /dev/null +++ b/boiler-monster/pic/16f88.lkr @@ -0,0 +1,76 @@ +// File: 16F88_g.lkr +// Generic linker script for the PIC16F88 processor + +#IFDEF _DEBUG + +LIBPATH . + +CODEPAGE NAME=page0 START=0x0 END=0x7FF +CODEPAGE NAME=page1 START=0x800 END=0xEFF +CODEPAGE NAME=debug START=0xF00 END=0xFFF PROTECTED +CODEPAGE NAME=.idlocs START=0x2000 END=0x2003 PROTECTED +CODEPAGE NAME=.device_id START=0x2006 END=0x2006 PROTECTED +CODEPAGE NAME=.config START=0x2007 END=0x2009 PROTECTED +CODEPAGE NAME=eedata START=0x2100 END=0x21FF PROTECTED + +DATABANK NAME=sfr0 START=0x0 END=0x1F PROTECTED +DATABANK NAME=sfr1 START=0x80 END=0x9F PROTECTED +DATABANK NAME=sfr2 START=0x100 END=0x10F PROTECTED +DATABANK NAME=sfr3 START=0x180 END=0x18F PROTECTED + +SHAREBANK NAME=dbgnobnk START=0x70 END=0x70 PROTECTED +SHAREBANK NAME=dbgnobnk START=0xF0 END=0xF0 PROTECTED +SHAREBANK NAME=dbgnobnk START=0x170 END=0x170 PROTECTED +SHAREBANK NAME=dbgnobnk START=0x1F0 END=0x1F0 PROTECTED + +SHAREBANK NAME=sfrnobnk START=0x71 END=0x7F +SHAREBANK NAME=sfrnobnk START=0xF1 END=0xFF PROTECTED +SHAREBANK NAME=sfrnobnk START=0x171 END=0x17F PROTECTED +SHAREBANK NAME=sfrnobnk START=0x1F1 END=0x1FF PROTECTED + +DATABANK NAME=gpr0 START=0x20 END=0x6F +DATABANK NAME=gpr1 START=0xA0 END=0xEF +DATABANK NAME=gpr2 START=0x110 END=0x16F +DATABANK NAME=gpr3 START=0x190 END=0x1E4 +DATABANK NAME=dbg3 START=0x1E5 END=0x1EF PROTECTED + +SECTION NAME=PROG0 ROM=page0 // ROM code space +SECTION NAME=PROG1 ROM=page1 // ROM code space +SECTION NAME=DEBUG ROM=debug // ICD debug executive +SECTION NAME=IDLOCS ROM=.idlocs // ID locations +SECTION NAME=DEVICEID ROM=.device_id // Device ID +SECTION NAME=DEEPROM ROM=eedata // Data EEPROM + +#ELSE + +LIBPATH . + +CODEPAGE NAME=page0 START=0x0 END=0x7FF +CODEPAGE NAME=page1 START=0x800 END=0xFFF +CODEPAGE NAME=.idlocs START=0x2000 END=0x2003 PROTECTED +CODEPAGE NAME=.device_id START=0x2006 END=0x2006 PROTECTED +CODEPAGE NAME=.config START=0x2007 END=0x2009 PROTECTED +CODEPAGE NAME=eedata START=0x2100 END=0x21FF PROTECTED + +DATABANK NAME=sfr0 START=0x0 END=0x1F PROTECTED +DATABANK NAME=sfr1 START=0x80 END=0x9F PROTECTED +DATABANK NAME=sfr2 START=0x100 END=0x10F PROTECTED +DATABANK NAME=sfr3 START=0x180 END=0x18F PROTECTED + +SHAREBANK NAME=sfrnobnk START=0x70 END=0x7F +SHAREBANK NAME=sfrnobnk START=0xF0 END=0xFF PROTECTED +SHAREBANK NAME=sfrnobnk START=0x170 END=0x17F PROTECTED +SHAREBANK NAME=sfrnobnk START=0x1F0 END=0x1FF PROTECTED + +DATABANK NAME=gpr0 START=0x20 END=0x6F +DATABANK NAME=gpr1 START=0xA0 END=0xEF +DATABANK NAME=gpr2 START=0x110 END=0x16F +DATABANK NAME=gpr3 START=0x190 END=0x1EF + +SECTION NAME=PROG0 ROM=page0 // ROM code space +SECTION NAME=PROG1 ROM=page1 // ROM code space +SECTION NAME=IDLOCS ROM=.idlocs // ID locations +SECTION NAME=DEVICEID ROM=.device_id // Device ID +SECTION NAME=DEEPROM ROM=eedata // Data EEPROM + +#FI diff --git a/boiler-monster/pic/Makefile b/boiler-monster/pic/Makefile new file mode 100644 index 0000000..31ab11c --- /dev/null +++ b/boiler-monster/pic/Makefile @@ -0,0 +1,22 @@ +AFLAGS=-k -p 16F88 -k +LDFLAGS=-m -s 16f88.lkr + +PROG=gateway +ASRCS=${PROG}.asm selfprog.asm +OBJS=${ASRCS:%.asm=%.o} +LSTS=${ASRCS:%.asm=%.err} +ERRS=${ASRCS:%.asm=%.lst} + +default:${PROG}.hex + +%.o:%.asm + gpasm ${AFLAGS} -c -o $@ $< + +${PROG}.hex:${OBJS} + gplink ${LDFLAGS} -o $@ ${OBJS} + + +clean: + /bin/rm -f ${PROG}.hex ${PROG}.map ${PROG}.cod ${OBJS} ${LSTS} ${ERRS} + + diff --git a/boiler-monster/pic/build.asm b/boiler-monster/pic/build.asm new file mode 100644 index 0000000..67d0747 --- /dev/null +++ b/boiler-monster/pic/build.asm @@ -0,0 +1,2 @@ +#define build "1" +#define tstamp "17:59 20-10-2015" diff --git a/boiler-monster/pic/docs/otgw-big-sch.png b/boiler-monster/pic/docs/otgw-big-sch.png new file mode 100644 index 0000000..114e65b Binary files /dev/null and b/boiler-monster/pic/docs/otgw-big-sch.png differ diff --git a/boiler-monster/pic/docs/pinout.txt b/boiler-monster/pic/docs/pinout.txt new file mode 100644 index 0000000..a3db674 --- /dev/null +++ b/boiler-monster/pic/docs/pinout.txt @@ -0,0 +1,33 @@ + +headers: + +left + +GND - STM32 +GPIO_B <- STM32 B9 +GPIO_A <- STM32 B8 +5V -> STM32 +LED_D -> STM32 B7 +LED_C -> STM32 B6 +LED_B -> NC +LED_A -> NC + + +middle + +GND - NC +NC - NC +NC - +PIC RX <- STM32 B10 +PIC TX -> STM32 B11 +*RESET <- STM32 B1 + + +right + +5V -> MR3020 +NC +GND - MR3020 + + + 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 diff --git a/boiler-monster/pic/selfprog.asm b/boiler-monster/pic/selfprog.asm new file mode 100644 index 0000000..9e18769 --- /dev/null +++ b/boiler-monster/pic/selfprog.asm @@ -0,0 +1,391 @@ + title "Self Programming" + list b=8, r=dec + +;######################################################################## +; Self programming, based on Microchip AN851 +;######################################################################## +; This code has been optimized for size so it would fit in 0x100 code words. +; To achieve this, some special tricks had to be used. As a result the code +; may be a little hard to read +; +; The functionality differs from that described in AN851 in the following +; respects: +; 1. No auto baud detection. Communication must take place at 9600 baud. +; 2. Dropped the first that was used for auto baud detection. +; 3. Dropped the third address byte as it would always be 0. +; 4. The code does not check the last byte of EEPROM data memory to enter boot +; mode. Instead it transmits a character and waits up to 1 second for +; a character. +; 5. The code is designed to be placed in the highest part of memory. That way +; it doesn't interfere with the interrupt code address. It does rely on the +; main program to call the self-program code at an appropriate time. +; 6. Due to the location of the boot loader code, it cannot be protected using +; the code protection bits in the configuration word. This means that the +; boot loader code can also be updated, if necessary. +; 7. The Erase Flash command has been implemented for the PIC16F device. +; 8. The device reset command is 0x08, not any command with a 0 length. +; 9. The version command can be called with a data length of 1-3 words. It will +; report the following information: +; 1. Version +; 2. Boot loader start address +; 3. Boot loader end address +; The software used to reflash the device can use the last two pieces of +; information to determine which part of memory should not be touched. + +#include "p16f88.inc" + + errorlevel -302, -306 + +#define MAJOR_VERSION 1 +#define MINOR_VERSION 1 + +#define STX 0x0F +#define ETX 0x04 +#define DLE 0x05 + +CHKSUM equ 0x70 +COUNTER equ 0x71 +RXDATA equ 0x72 +TXDATA equ 0x73 +TEMP equ 0x74 + +DATA_BUFF equ 0x10 ;Start of receive buffer +COMMAND equ 0x10 ;Data mapped in receive buffer +DATA_COUNT equ 0x11 +ADDRESS_L equ 0x12 +ADDRESS_H equ 0x13 +PACKET_DATA equ 0x14 + +#define SELFRESET PORTB,1 +#define RX PORTB,2 +#define TX PORTB,5 + +#ifdef SELFPROGNEW + #define SELFPROG SelfProgNew + #define STARTADDRESS 0x0700 +#else + #define SELFPROG SelfProg + #define STARTADDRESS 0x0f00 +#endif + + global SELFPROG +SELFPROG code STARTADDRESS + ;Do not go into selfprog mode after a watchdog timeout reset +SELFPROG btfss STATUS,NOT_TO + return ;Let the main code handle a timeout + + bcf INTCON,GIE ;Ignore interrupts + + banksel OSCCON + movlw b'01100000' ;Internal oscillator set to 4MHz + movwf OSCCON ;Configure the oscillator + + ;Set the LEDS as outputs +#ifndef LVP + movlw b'00100111' +#else + movlw b'00101111' +#endif + movwf TRISB + + ;Configure the comparators and voltage reference + ;Allow communication between thermostat and boiler to continue + ;while reprogramming the device + movlw b'11100111' ;Pins 3 and 4 are digital ouputs + movwf TRISA + movlw b'00000111' ;A0 through A2 are used for analog I/O + movwf ANSEL + movlw b'11100110' ;Voltage reference at 1.25V + movwf CVRCON + movlw b'00000110' ;Two common reference comps with output + movwf CMCON + + ;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 = 7 - 1:256 Prescaler + movlw b'11010111' + movwf OPTION_REG + + movlw 25 ;9600 baud + movwf SPBRG + movlw b'00100110' + movwf TXSTA ;High speed, Asynchronous, Enabled + bcf STATUS,RP0 + bsf RCSTA,SPEN ;Enable serial port + bsf RCSTA,CREN ;Enable receive + + ;Clear the LEDS + movlw b'11111111' + movwf PORTB + + clrf TMR0 + movlw 1 + call Pause +;Notify the external programming software (Pause returns ) + call WrRS232 +;Programmer should react within 1 second + movlw 16 + call Pause + btfss PIR1,RCIF +;No data received, resume the normal program + return +;Check that the received character is + call RdRS232 + skpz +;Other serial data received, resume normal program + return + + bsf STATUS,IRP +ReSync movlw DATA_BUFF + movwf FSR + clrf CHKSUM +GetNextDat call RdRS232 ;Get the data + skpnz + goto ReSync ;Found unprotected STX + xorlw STX ^ ETX ;Check for ETX + skpnz + goto CheckSum ;Yes, examine checksum + xorlw ETX ^ DLE ;Check for DLE + skpnz + call RdRS232 ;Yes, get the next byte + movfw RXDATA + movwf INDF ;Store the data + addwf CHKSUM,F ;Get sum + incf FSR,F + goto GetNextDat + +CheckSum tstf CHKSUM + skpz + goto StartOfLine + bsf STATUS,RP1 + movfw ADDRESS_L + movwf EEADR + movfw ADDRESS_H + movwf EEADRH + movlw PACKET_DATA + movwf FSR + movfw DATA_COUNT + movwf COUNTER +CheckCommand +#ifdef SELFPROGNEW + movlw high ($ + 0x800) +#else + movlw high $ +#endif + movwf PCLATH + movfw COMMAND + sublw 8 + sublw 8 + skpc + goto StartOfLine + addwf PCL,F + goto ReadVersion ;0 Read Version Information + goto ReadProgMem ;1 Read Program Memory + goto WriteProgMem ;2 Write Program Memory + goto EraseProgMem ;3 Erase Program Memory + goto ReadEE ;4 Read EEDATA Memory + goto WriteEE ;5 Write EEDATA Memory + goto StartOfLine ;6 Read Config Memory + goto StartOfLine ;7 Write Config Memory + goto VReset ;8 Reset + +VersionData data (MAJOR_VERSION << 8) | MINOR_VERSION +#ifdef SELFPROGNEW + data SELFPROG + 0x800, SelfProgEnd + 0x800 +#else + data SELFPROG, SelfProgEnd +#endif + +ReadVersion movlw low VersionData + movwf EEADR +#ifdef SELFPROGNEW + movlw high (VersionData + 0x800) +#else + movlw high VersionData +#endif + movwf EEADRH + movlw DATA_BUFF + 2 + movwf FSR +ReadProgMem bsf STATUS,RP0 + bsf EECON1,EEPGD + bsf EECON1,RD + nop + nop + bcf STATUS,RP0 + movfw EEDATA + movwf INDF + incf FSR,F + movfw EEDATH + movwf INDF + incf FSR,F + incf EEADR,F + skpnz + incf EEADRH,F + decfsz COUNTER,F + goto ReadProgMem +WritePacket movlw DATA_BUFF + subwf FSR,W +WritePacketJ1 movwf COUNTER + movlw STX + call WrRS232 + clrf CHKSUM + movlw DATA_BUFF + movwf FSR +SendNext movfw INDF + addwf CHKSUM,F + incf FSR,F + call WrData + decfsz COUNTER,F + goto SendNext + comf CHKSUM,W + addlw 1 + call WrData ;WrData returns + call WrRS232 +StartOfLine bcf STATUS,RP1 + call RdRS232 ;Look for a start of line + skpnz + goto ReSync + goto StartOfLine + +WriteProgMem movlw b'10000100' + call LoadEECon1 + movlw b'11111100' + andwf EEADR,F + movlw 4 + movwf TEMP +Lp1 movfw INDF + movwf EEDATA + incf FSR,F + movfw INDF + movwf EEDATH + incf FSR,F + call StartWrite + decfsz TEMP,F + goto Lp1 + decfsz COUNTER,F + goto WriteProgMem + goto WritePacketJ1 + +EraseProgMem movlw b'10010100' + call LoadEECon1 + movlw 0x1F + iorwf EEADR,F + call StartWrite + decfsz COUNTER,F + goto EraseProgMem + goto WritePacketJ1 + +ReadEE bsf STATUS,RP0 + clrf EECON1 + bsf EECON1,RD + bcf STATUS,RP0 + movfw EEDATA + movwf INDF + incf FSR,F + incf EEADR,F + decfsz COUNTER,F + goto ReadEE + goto WritePacket + +WriteEE movlw b'00000100' + call LoadEECon1 + movfw INDF + movwf EEDATA + incf FSR,F + call StartWrite + decfsz COUNTER,F + goto WriteEE + goto WritePacketJ1 + +WrData movwf TXDATA + xorlw STX + skpnz + goto WrDLE + xorlw STX ^ ETX + skpnz + goto WrDLE + xorlw ETX ^ DLE + skpz + goto WrNext +WrDLE movlw DLE + call WrRS232 +WrNext movfw TXDATA +WrRS232 clrwdt + bcf STATUS,RP1 +WaitTxEmpty btfss PIR1,TXIF + goto WaitTxEmpty + movwf TXREG + retlw ETX + +RdRS232 btfsc RCSTA,OERR + goto VReset +RdLp1 clrwdt + btfss PIR1,RCIF + goto RdLp1 + movfw RCREG + movwf RXDATA + xorlw STX + return + +LoadEECon1 bsf STATUS,RP0 + movwf EECON1 + bcf STATUS,RP0 + return + +StartWrite clrwdt + bsf STATUS,RP0 + movlw 0x55 + movwf EECON2 + movlw 0xAA + movwf EECON2 + bsf EECON1,WR +WaitEEWrite btfsc EECON1,WR ;Skipped when writing program memory + goto WaitEEWrite ;Skipped when writing program memory + bcf STATUS,RP0 + incf EEADR,F + skpnz + incf EEADRH,F + retlw 1 ;Return length of acknowledgement + +Pause clrwdt + btfsc PIR1,RCIF + return + btfss INTCON,TMR0IF + goto Pause + bcf INTCON,TMR0IF + addlw -1 + skpz + goto Pause + retlw ETX + +;Reset the device via an external connection from an I/O pin to the reset pin. +VReset bcf STATUS,RP1 + bcf SELFRESET ;Prepare the output latch + bsf STATUS,RP0 + bcf SELFRESET ;Switch the pin to output + +;If resetting via the output pin doesn't work, restore all used registers to +;their power-on defaults and jump to address 0. +;Do not simply return because the code that called this routine may have been +;wiped and reprogrammed to something completely different. + movlw b'11111111' + movwf TRISA + movwf TRISB + movwf OPTION_REG + movwf ANSEL + movlw b'00000111' + movwf CMCON + clrf TXSTA + clrf SPBRG + clrf STATUS + clrf RCSTA + clrf INTCON + clrf PCLATH + clrwdt +SelfProgEnd goto 0 + + end -- cgit v1.2.3