summaryrefslogtreecommitdiffstats
path: root/pic/selfprog.asm
diff options
context:
space:
mode:
authorfishsoupisgood <github@madingley.org>2020-09-09 11:53:37 +0100
committerfishsoupisgood <github@madingley.org>2020-09-09 11:53:37 +0100
commit9d87c925a9eaa4fc256be3173c14a20d1469472d (patch)
tree50d63f87a47a0eac3f5b8058850184bcd4e6ee95 /pic/selfprog.asm
parentdafd8cf2fdcdd637cc06f760d318cf8391b1a294 (diff)
downloadheating-9d87c925a9eaa4fc256be3173c14a20d1469472d.tar.gz
heating-9d87c925a9eaa4fc256be3173c14a20d1469472d.tar.bz2
heating-9d87c925a9eaa4fc256be3173c14a20d1469472d.zip
everything, mostly, working
Diffstat (limited to 'pic/selfprog.asm')
-rw-r--r--pic/selfprog.asm391
1 files changed, 0 insertions, 391 deletions
diff --git a/pic/selfprog.asm b/pic/selfprog.asm
deleted file mode 100644
index 9e18769..0000000
--- a/pic/selfprog.asm
+++ /dev/null
@@ -1,391 +0,0 @@
- 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 <STX> 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 <ETX> character and waits up to 1 second for
-; a <STX> 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 <ETX>)
- 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 <STX>
- 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 <ETX>
- 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