;********************************************************************
; Tiny Bootloader dsPIC series Size=100words
; claudiu.chiculita@ugal.ro
; http://www.etc.ugal.ro/cchiculita/software/picbootloader.htm
;********************************************************************
.include "p24FV16KM202.inc"
config __FOSCSEL, FNOSC_FRCPLL
config __FOSC, POSCMOD_NONE
.equ FOSC, 32000000
.equ baud, 115200
.equ IdTypePIC, 0xA0
.equ max_flash, 0x2000 ;PIC max address
.equ first_address, max_flash - 100
.global __reset
.section .bss
buff: .space 4
buffer: .space 128+6
;REGISTRY:
;W0 imediat, param nvmcon
;W1 Receive
;W2 PUTCH need?
;W3 count rcv
;W4 memory buffer pointer
;W5 ^
;W6 for
;W7 temp
;W8
;W9 Erase/Write Flag
;W10 delay1
;W11 delay2
;W12 EA Write
;W13 crc
;W14 void(black hole)
;W15 stack
.macro PUTCH car
MOV.B \car, W2
MOV W2,U1TXREG
.endm
.text
;*************************************
; Relocated user Reset Vector
;*************************************
.org first_address
CLR W0
CLR W0
CLR W0
CLR W0
;*************************************
; Bootloader
;*************************************
__reset:
BootloaderEntry:
;MOV #__SP_init, W15
;MOV #__SPLIM_init, W0
;MOV W0, SPLIM
;NOP
init_uart:
;Initialize and Enable UART1 for Tx and Rx
MOV #0x8000, W0 ;bit15=UARTEN bit10=ALTIO
MOV W0, U1MODE
MOV #0x0400, W0 ;bit10=UTXEN
MOV W0, U1STA
MOV #(((FOSC/baud)-32)/64), W0 ;?Initialize Baud rate (divide INSTRUCTION Cycle)
MOV W0, U1BRG ;to baud
;wait for computer
MOV #buff, W4
RCALL Receive
SUB.B #0xC1, W1 ;Expect C1h
BRA NZ, way_to_exit
PUTCH #IdTypePIC ;send PIC type
MainLoop:
PUTCH #'K' ; "-Everything OK, ready and waiting."
mainl:
CLR W13 ;chksum
MOV #buff, W4
MOV #4, W6
dorcv4:
RCALL Receive
DEC W6, W6
BRA NZ, dorcv4
MOV buff, W12
MOV buff+2, W3
MOV W3, TBLPAG
;test W3.H to find out what to do
MOV #(96+1), W6
dorcvB:
RCALL Receive
DEC W6, W6
BRA NZ, dorcvB
CP0 W13 ;check crc
BRA Z, chksumok
ziieroare: ;CRC failed
PUTCH #'N'
BRA mainl
chksumok:
;-----------------------------------------------------
;ERASE
TBLWTL W0,[W12] ;dummy
MOV #0x4041,W0
CLRWDT
RCALL Key_Sequence
;Load_Write_Latch:
MOV #buffer,W4
edtbl3:
MOV #31, W2
TBLWTL.B [W4++], [W12++]
TBLWTL.B [W4++], [W12--]
TBLWTH.B [W4++], [W12]
DEC W2, W2
BRA NZ, edtbl3
INC2 W12, W12
MOV #0x4001,W0
RCALL Key_Sequence
BRA MainLoop
;-------------------------------------------------------------
Key_Sequence: ; Expects a NVMCON value in W0
MOV W0,NVMCON
MOV #0x55,W0 ; Write the key sequence
MOV W0,NVMKEY
MOV #0xAA,W0
MOV W0,NVMKEY
BSET NVMCON,#WR ; Start the write cycle
NOP
NOP
RETURN
;-------------------------------------------------------------
Receive:
MOV #(1000*(FOSC/1000)/(7*4096)), W10 ; ms waiting
rpt2:
MOV #1000, W11
rpt1:
BTSS U1STA, #URXDA
BRA norcv
MOV U1RXREG, W1 ;return read data in W
MOV.B W1, [W4++]
ADD.B W1, W13, W13 ;compute checksum
RETURN
norcv:
CLRWDT
DEC W11, W11
BRA NZ, rpt1
DEC W10, W10
BRA NZ, rpt2
timeout:
way_to_exit:
CLR U1MODE ; deactivate UART
BRA first_address
.end