Remove the debug LED controls
[bootloader] / mybootload.X / main.asm
CommitLineData
9c66c9ff
JM
1 radix dec
2
3 errorlevel -302
4
5#include "p16f1455.inc"
6
7; CONFIG1
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
10; CONFIG2
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
13
14
15#define max_flash 0x2000
16#define row_size 32
17
18; 16F1455 errata says self-program only works <= 4MHz clock
19xtal EQU 4000000
20baud EQU 19200
21
22#include "spbrgselect.inc"
23
24; This is the smallest multiple of 32 that the bootloader
25; code fits into (minus the 4 for the remapped section)
26loader_size set 224
27
28; fit remap section in end of previous page
29; so we dont need to rewrite the bootloader page
30remap_addr set max_flash - loader_size - 4
31
32; Variables
33 cblock 0x20
34 buffer:80
35 endc
36
37 ; common ram section
38 cblock 0x70
39 cmd
40 crc
41 i
42 tmp
43 endc
44
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
49
50Start CODE 0x0000
51 MOVLP high(StartBoot)
52 GOTO StartBoot
53 NOP
54 NOP
55; after this is the normal reset vector and rest of the loaded program
56
57
58; simple test program
59Main
b339b9f7
JM
60; banksel ANSELA
61; CLRF ANSELA
62; banksel TRISA
63; CLRF TRISA
64; CLRF TRISC
65; banksel PORTA
66; BSF PORTA,5 ; green on
67; BCF PORTA,4 ; red off
68; SLEEP
9c66c9ff
JM
69
70
71; At the far end of memory...
72; this is the relocated boot sector
73 ORG remap_addr
74AppVector
75; NOP
76 MOVLP high(Main)
77 GOTO Main ; pretend program loaded
78 NOP
79 NOP
80
81; immediately followed by out bootloader
82 ORG remap_addr+4
83StartBoot
84
85 ; First configure the pin
86 ; 16f1455 RX=RC5 TX=RC4
87; banksel TRISC
88; BSF TRISC,5 ; RC5 as input
89; BCF TRISC,4 ; RC4 as output
90 banksel PORTC
91 CLRF PORTC
92
93 BTFSC PORTC,5 ; RC5 is Clear (break state) carry on
94 BRA AppVector ; Was not clear, launch app instead
95
96 ; Lets start the bootloader properly
97 banksel OSCCON
98 MOVLW b'00110100'
99 MOVWF OSCCON ; 4Mhz clock mode
100 BTFSS OSCSTAT,HFIOFR
101 BRA $-1 ; wait until oscillator is ready
102 MOVLW b'00011001' ; Activate watchdog, 4 seconds
103 MOVWF WDTCON
104
105SetBaud
106 ; Set the baud rate and enable uart
107 banksel TXSTA
108 MOVLW b'00100100' ; TXEN=1 SYNC=0 BRGH=1
109 MOVWF TXSTA
110 banksel SPBRGL
111 MOVLW spbrg_value
112 MOVWF SPBRGL
113 CLRF SPBRGH
114 banksel RCSTA
115 MOVLW b'10010000' ; SPEN CREN
116 MOVWF RCSTA
117
118; debug lights
119; debug RA5 green, RA4 red
b339b9f7
JM
120; banksel ANSELA
121; CLRF ANSELA
122; banksel TRISA
123; CLRF TRISA
124; banksel PORTA
125; BCF PORTA,5 ; green off
126; BSF PORTA,4 ; red on
9c66c9ff
JM
127
128 ; Send the 'we heard you' ACK symbol
129 CLRF crc
130 MOVLW 0x06
131 CALL SendByte
132 MOVLW 'B'
133 CALL SendByte
134 MOVLW 'L'
135 CALL SendByte
136
137 ; Wait for PC to drop the break condition
138 banksel PORTC
139 BTFSS PORTC,5
140 BRA $-1
141
142 ; Transmit device ID
143 banksel PMADRL
144 MOVLW 0x06 ; 0x8006 Device ID
145 MOVWF PMADRL
146 CLRF PMADRH
147 BSF PMCON1,CFGS
148 BSF PMCON1,RD
149 NOP
150 NOP
151 MOVF PMDATH,W
152 CALL SendByte
153 banksel PMDATL
154 MOVF PMDATL,W
155 CALL SendByte
156
157 ; Transmit location of bootloader, and thus top of flash
158 MOVLW high(remap_addr)
159 CALL SendByte
160
161 MOVLW low(remap_addr)
162 CALL SendByte
163
164 ; transmit csum to complete the welcome message
165 CALL SendCRC
166
167 ; Wait here for instructions
168CmdLoop
169 CLRWDT
170 CLRF crc
171 CALL ReadByte
172 MOVWF cmd ; keep it to re-examine
173
174 ; command 'R' read a row (32 words)
175 SUBLW 'R'
176 SKPNZ
177 BRA ReadLine
178
179 ; command 'W' write a row (32 words)
180 MOVFW cmd
181 SUBLW 'W'
182 SKPNZ
183 BRA WriteLine
184
185 ; command 'B' reboot
186 MOVFW cmd
187 SUBLW 'B'
188 SKPNZ
189 BRA DoBoot
190
191 BRA CmdLoop
192
193ReadByte ; put it in W
194 banksel PIR1
195 BTFSS PIR1, RCIF
196 BRA $-1
197 banksel RCREG
198 MOVF RCREG,W
199 ADDWF crc,F
200 RETURN
201
202ReadCRC
203 banksel PIR1
204 BTFSS PIR1, RCIF
205 BRA $-1
206 banksel RCREG
207 MOVF RCREG,W
208 RETURN
209
210
211SendCRC ; copy the crc in as the thing to send
212 MOVF crc,W
213SendByte ; that is in W
214 ADDWF crc,F
215 banksel PIR1
216 BTFSS PIR1, TXIF
217 BRA $-1
218 banksel TXREG
219 MOVWF TXREG
220 RETURN
221
222SendError ; Say there was an error (must be an in subr)
223 MOVLW 'E'
224 CALL SendByte
225 BRA CmdLoop
226
227ReadLine ; read a row
228 CALL ReadByte
229 banksel PMADRH
230 MOVWF PMADRH ; store the high byte
231 CALL ReadByte
232 banksel PMADRL
233 ANDLW 0xE0 ; align to 32 word
234 MOVWF PMADRL ; store the low byte
235 CALL ReadCRC ; read the checksum
236 SUBWF crc,W
237 SKPZ ; if crc-checksum !=0 goto Error
238 BRA SendError
239; now lets send a record back to the host
240 MOVLW row_size ; 32 words
241 MOVWF i
242 CLRF crc ; reset crc for outgoing message
243 MOVLW 'R' ; warn that we are writing
244 CALL SendByte
245 banksel PMADRH
246 MOVF PMADRH,W ; say what the start address is
247 ANDLW 0x7F ; top bit is always set, duh
248 CALL SendByte
249 banksel PMADRL
250 MOVF PMADRL,W
251 CALL SendByte
252
253ReadLoop
254 banksel PMCON1
255 BCF PMCON1,CFGS ; read program not config
256 BSF PMCON1,RD
257 NOP
258 NOP
259 MOVF PMDATH,W ; send high byte
260 CALL SendByte
261 banksel PMDATL
262 MOVF PMDATL,W ; send low byte
263 CALL SendByte
264 banksel PMADRL
265 ; Assumption: this is 32 word aligned, will never cross boundary
266 INCF PMADRL,F ; increment address
267 DECFSZ i,F ; i--
268 BRA ReadLoop ; go around again
269 ; finished sending program words
270 CALL SendCRC ; send the crc
271 ; done, go back for next command
272 BRA CmdLoop
273
274WriteLine ; write a row
275 CALL ReadByte
276 banksel PMADRH
277 MOVWF PMADRH ; store the high byte
278 CALL ReadByte
279 banksel PMADRL
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
283 banksel FSR0L
284 MOVLW high(buffer)
285 MOVWF FSR0H
286 MOVLW low(buffer)
287 MOVWF FSR0L
288 ; read row_size * 2 bytes
289 MOVLW row_size * 2
290 MOVWF i
291WriteLineRead
292 CALL ReadByte
293 MOVWI FSR0++
294 DECFSZ i,F
295 BRA WriteLineRead
296 ; now read the crc and test
297 CALL ReadCRC ; read the checksum
298 SUBWF crc,W
299 SKPZ ; if crc-checksum !=0 goto Error
300 BRA SendError
301 ; everything is fine, commit to memory
302 ; first we have to erase the row
303 banksel PMCON1
304 BCF PMCON1,CFGS ; program
305 BSF PMCON1,FREE ; erase
306 BSF PMCON1,WREN ; enable writes
307 MOVLW 0x55
308 MOVWF PMCON2
309 MOVLW 0xAA
310 MOVWF PMCON2
311 BSF PMCON1,WR ; commit
312 NOP
313 NOP ; CPU goes to sleep for 2mS
314 BCF PMCON1,WREN ; disable writes
315 ; now move the FSR back to the start
316 banksel FSR0L
317 MOVLW high(buffer)
318 MOVWF FSR0H
319 MOVLW low(buffer)
320 MOVWF FSR0L
321 MOVLW row_size ; need to do this once per word
322 MOVWF i
323
324 ; setup for writing to latches
325 banksel PMCON1
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
330
331LatchWord
332 MOVIW FSR0++
333 MOVWF PMDATH
334 MOVIW FSR0++
335 MOVWF PMDATL
336 DECFSZ i,F
337 BRA LatchWrite
338 BRA CommitWrite
339 ; just a latching write
340LatchWrite
341 MOVLW 0x55
342 MOVWF PMCON2
343 MOVLW 0xAA
344 MOVWF PMCON2
345 BSF PMCON1,WR ; commit
346 NOP
347 NOP
348 INCF PMADRL,F ; move along
349 BRA LatchWord
350CommitWrite
351 BCF PMCON1,LWLO ; real thing this time
352 MOVLW 0x55
353 MOVWF PMCON2
354 MOVLW 0xAA
355 MOVWF PMCON2
356 BSF PMCON1,WR ; commit
357 NOP
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
364 CALL SendByte
365 banksel PMADRH
366 MOVF PMADRH,W ; say what the start address is
367 ANDLW 0x7F ; top bit is always set, duh
368 CALL SendByte
369 banksel PMADRL
370 MOVF PMADRL,W
371 ANDLW 0xE0 ; align to 32 word
372 CALL SendByte
373 CALL SendCRC
374 ; finished writing
375 BRA CmdLoop
376
377DoBoot
378 RESET
379
380EndBoot
381 END
382