From 9d87c925a9eaa4fc256be3173c14a20d1469472d Mon Sep 17 00:00:00 2001 From: fishsoupisgood Date: Wed, 9 Sep 2020 11:53:37 +0100 Subject: everything, mostly, working --- pic/selfprog.asm | 391 ------------------------------------------------------- 1 file changed, 391 deletions(-) delete mode 100644 pic/selfprog.asm (limited to 'pic/selfprog.asm') 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 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