5 #include "p16f1455.inc"
8 __config _CONFIG1, 0xFCC
9 ;; __CONFIG _CONFIG1, _FOSC_INTOSC & _WDTE_SWDTEN & _PWRTE_ON & _MCLRE_ON & _CP_OFF & _BOREN_ON & _CLKOUTEN_OFF & _IESO_OFF & _FCMEN_OFF
11 __config _CONFIG2, 0x16CF
12 ; __CONFIG _CONFIG2, _WRT_OFF & _CPUDIV_NOCLKDIV & _USBLSCLK_48MHz & _PLLMULT_3x & _PLLEN_DISABLED & _STVREN_ON & _BORV_LO & _LPBOR_ON & _LVP_OFF
15 #define max_flash 0x2000
18 ; 16F1455 errata says self-program only works <= 4MHz clock
22 #include "spbrgselect.inc"
24 ; This is the smallest multiple of 32 that the bootloader
25 ; code fits into (minus the 4 for the remapped section)
28 ; fit remap section in end of previous page
29 ; so we dont need to rewrite the bootloader page
30 remap_addr set max_flash - loader_size - 4
45 ; ############ RESET ############
46 ; This is the normal reset vector
47 ; when a program is loaded, its version of these 4 will be moved
48 ; and replaced with our code to jump to the bootloader
55 ; after this is the normal reset vector and rest of the loaded program
66 ; BSF PORTA,5 ; green on
67 ; BCF PORTA,4 ; red off
71 ; At the far end of memory...
72 ; this is the relocated boot sector
77 GOTO Main ; pretend program loaded
81 ; immediately followed by out bootloader
85 ; First configure the pin
86 ; 16f1455 RX=RC5 TX=RC4
88 ; BSF TRISC,5 ; RC5 as input
89 ; BCF TRISC,4 ; RC4 as output
93 BTFSC PORTC,5 ; RC5 is Clear (break state) carry on
94 BRA AppVector ; Was not clear, launch app instead
96 ; Lets start the bootloader properly
99 MOVWF OSCCON ; 4Mhz clock mode
101 BRA $-1 ; wait until oscillator is ready
102 MOVLW b'00011001' ; Activate watchdog, 4 seconds
106 ; Set the baud rate and enable uart
108 MOVLW b'00100100' ; TXEN=1 SYNC=0 BRGH=1
115 MOVLW b'10010000' ; SPEN CREN
119 ; debug RA5 green, RA4 red
125 ; BCF PORTA,5 ; green off
126 ; BSF PORTA,4 ; red on
128 ; Send the 'we heard you' ACK symbol
137 ; Wait for PC to drop the break condition
144 MOVLW 0x06 ; 0x8006 Device ID
157 ; Transmit location of bootloader, and thus top of flash
158 MOVLW high(remap_addr)
161 MOVLW low(remap_addr)
164 ; transmit csum to complete the welcome message
167 ; Wait here for instructions
172 MOVWF cmd ; keep it to re-examine
174 ; command 'R' read a row (32 words)
179 ; command 'W' write a row (32 words)
193 ReadByte ; put it in W
211 SendCRC ; copy the crc in as the thing to send
213 SendByte ; that is in W
222 SendError ; Say there was an error (must be an in subr)
227 ReadLine ; read a row
230 MOVWF PMADRH ; store the high byte
233 ANDLW 0xE0 ; align to 32 word
234 MOVWF PMADRL ; store the low byte
235 CALL ReadCRC ; read the checksum
237 SKPZ ; if crc-checksum !=0 goto Error
239 ; now lets send a record back to the host
240 MOVLW row_size ; 32 words
242 CLRF crc ; reset crc for outgoing message
243 MOVLW 'R' ; warn that we are writing
246 MOVF PMADRH,W ; say what the start address is
247 ANDLW 0x7F ; top bit is always set, duh
255 BCF PMCON1,CFGS ; read program not config
259 MOVF PMDATH,W ; send high byte
262 MOVF PMDATL,W ; send low byte
265 ; Assumption: this is 32 word aligned, will never cross boundary
266 INCF PMADRL,F ; increment address
268 BRA ReadLoop ; go around again
269 ; finished sending program words
270 CALL SendCRC ; send the crc
271 ; done, go back for next command
274 WriteLine ; write a row
277 MOVWF PMADRH ; store the high byte
280 ANDLW 0xE0 ; align to 32 word
281 MOVWF PMADRL ; store the low byte
282 ; lets just store the bytes in buff until we are sure the checksum is good
288 ; read row_size * 2 bytes
296 ; now read the crc and test
297 CALL ReadCRC ; read the checksum
299 SKPZ ; if crc-checksum !=0 goto Error
301 ; everything is fine, commit to memory
302 ; first we have to erase the row
304 BCF PMCON1,CFGS ; program
305 BSF PMCON1,FREE ; erase
306 BSF PMCON1,WREN ; enable writes
311 BSF PMCON1,WR ; commit
313 NOP ; CPU goes to sleep for 2mS
314 BCF PMCON1,WREN ; disable writes
315 ; now move the FSR back to the start
321 MOVLW row_size ; need to do this once per word
324 ; setup for writing to latches
326 BSF PMCON1,WREN ; enable writes
327 BCF PMCON1,CFGS ; program
328 BCF PMCON1,FREE ; write not erase this time
329 BSF PMCON1,LWLO ; into the latches
339 ; just a latching write
345 BSF PMCON1,WR ; commit
348 INCF PMADRL,F ; move along
351 BCF PMCON1,LWLO ; real thing this time
356 BSF PMCON1,WR ; commit
358 NOP ; cpu stalls for 2mS
359 ; and we are finished
360 BCF PMCON1,WREN ; disable writes
361 ; tell the other end we finished
362 CLRF crc ; reset crc for outgoing message
363 MOVLW 'W' ; confirm the write command
366 MOVF PMADRH,W ; say what the start address is
367 ANDLW 0x7F ; top bit is always set, duh
371 ANDLW 0xE0 ; align to 32 word