Once i had a project , a gps looger on for a sd card, where i managed to update the software with a binary file written to the sacard. its a kind of bootloader which reads the card and write the binary file into the flash. it was for the mega8 and because of the limited space the software can handle only a simplified fat12 system where the uploadfile has to be the first file on the card with a fixed length. all was programmed in bascom and inline assembler but for devices like atmega368 it its probably easy to adapt to arduino.
but making it reliable its time consuming process !
regards
Code Snippet:
'*****************************************************************
' start der assembler bios funktionen
' in der nrww section des flash
'*****************************************************************
$boot = $e00 ' Boot Size = 512 Words
' entrypoint at $1c00, leave 1Kb for bootloader
$asm
_nrww:
' Mega8 Fuse Bit Settings
' 1(unprogrammed) , ponyprog x=checked=programmed=0
' (x) Boostsz1 1K Bootsize
' ( ) Boostsz0 0C00-0FFF
' (x) Boostrst reset start at 0C00
' (x) Cksel3 Cksel 0..3 = 0100 = 8MHz
' ( ) Cksel2
' (x) Cksel1
' (x) Cksel0
rjmp _skip_vectors
jmp $0002 ' Interrupt Vector Table
jmp $0004 '
jmp $0006 '
jmp $0008 '
jmp $000A '
jmp $000C '
jmp $000E '
jmp $0010 '
jmp $0012 '
jmp $0004 '
_skip_vectors:
cli ' clear interrupts
ldi r16,&h00 ' disable flashwrite
sts {d_flash},r16
Ldi r16,&h04 ' initialize Stackpointer to 045F
!Out sph,r16
Ldi r16,&h5f
!Out spl,r16
ldi r16,170 ' oscillator calibration byte
!out Osccal,r16
' 0=input
ldi r16,&B00101100 ' portb = 2,3,5 = output
!out ddrb,r16
ldi r16,&B00011100 ' portd 2,3,4 = output
!out ddrd,r16
ldi r16,103 ' baud rate register set to 4800 at 8MHz
!out ubrr,r16
ldi r16,&h18 ' uart ucsrb TX+RX enable
!out ucsrb,r16
rcall _pr_crlf ' print cr lf
_chk_f0:
sbi portb,0 ' set taster pullup
sbi portb,2 ' set card ss
sbi Spcr,spe ' enable spi
sbi Spcr,mstr ' spi Master
sbi Spcr,spr1 ' Clock rate fck/4 = 125KHz
cbi Spcr,spr0
rcall _spi_init ' init card
clr r17 ' jump on read error <> 0
cpse r18,r17
rjmp _chk_f_error1
nop
ldi r16,&h00 ' disable flashwrite
sts {d_flash},r16
_chk_f1: ' this section is done 2 times
' 1.read 7k of mmc, calculate crc and compare
' to crc in 2 last bytes of last block, when
' ok perform section 2. and write 7K to flash
ldi r18,00 ' get l_bladr Hi byte (only 12 bit)
ldi r17,01 ' from eeprom P_lsn_ee
rcall _ee_read
andi r16,&B00001111 ' use only first first 4096 blocks
mov r14,r16 ' store to r14
rcall _pr_hex
ldi r18,00 ' get l_bladr lo byte (only 12 bit)
ldi r17,00
rcall _ee_read
mov r13,r16 ' store to r13
rcall _pr_hex
rcall _pr_crlf
clr r16
sts &h01f2,r16 ' clear l_bladr hi 16 bit
sts &h01f3,r16
clr r16
sts &h1fd,r16 ' clear variable crc
sts &h1fe,r16
ldi r16,14 ' read 14 blocks ( 7K in mmc)
mov r12,r16 ' r12 counter
clr zl ' clear page adress for bootloader
clr zh
_chk_f2: ' loop over 14 blockreads
sts &h01f0,r13 ' get l_bladr (only 16 bit)
sts &h01f1,r14
push zl
push zh
lds r10,&h1fd ' push crc
lds r11,&h1fe
ldi r17,C_read_block
sts {cmd},r17
rcall _spi_readblock
clr r17 ' jump on read error <> 0
cpse r18,r17
rjmp _chk_f_error1
sts &h1fd,r10 ' pop crc
sts &h1fe,r11
rcall _crc16blbu
pop zh
pop zl
rcall _boot_loader ' write block to flash in 2. pass
ldi r16,1 ' l_bladr=l_bladr+1
add r13,r16
clr r16
adc r14,r16
dec r12 ' end loop 14x
brne _chk_f2
lds r16,{d_flash} ' 2. pass done ?
cpi r16,&h55 ' then
brne _chk_f2a ' exit
rjmp _chk_f_out
' now read block #16
_chk_f2a:
lds r10,&h1fd ' push crc
lds r11,&h1fe
ldi r16,1 ' l_bladr=l_bladr+1
add r13,r16
clr r16
adc r14,r16
sts &h01f0,r13 ' put l_bladr (only 16 bit)
sts &h01f1,r14
ldi r17,C_read_block
sts {cmd},r17
rcall _spi_readblock
clr r17 ' jump on read error
cpse r18,r17
rjmp _chk_f_error1
sts &h1fd,r10 ' pop crc
sts &h1fe,r11
' rcall _pr_h_dump
lds r16,&h1fe ' print calculated crc from
rcall _pr_hex ' file
lds r16,&h1fd
rcall _pr_hex
rcall _pr_crlf
lds r16,&h3ff ' print crc in last block
rcall _pr_hex
lds r16,&h3fe
rcall _pr_hex
rcall _pr_crlf
lds r16,&h3fe ' compare crc of 7K flash with
lds r17,&h1fd ' crc signature in last bytes of file
cp r16,r16 ' in block #16
brne _chk_f_out
lds r16,&h3ff
lds r17,&h1fe
cp r16,r17
brne _chk_f_out ' if crc fails out
' crc test ok > ready to burn flash
_chk_f_ok1:
ldi r20,50 ' load value 50 for diddle led when crc ok
ldi r16,&B00001000 ' led on
!out portd,r16
_chk_f_ok2:
in r16,portd ' diddle leds loop as ok message
ldi r17,&B00001100
eor r16,r17
!out portd,r16
clr xh
clr xl
rcall _waitmicro
sbis pinb,0 ' keypressed
rjmp _chk_f3 ' yes, continue writeflash
dec r20
brne _chk_f_ok2
rjmp _chk_f_out
_chk_f3:
lds r16,{d_flash} '
cpi r16,&h55
brne _chk_f4
clr r16 ' disable flashwrite and do block readloop
sts {d_flash},r16
rjmp _chk_f5
_chk_f4: ' write 55 signature to enable lpm
ldi r16,&h55 ' in flashwrite and do block readloop
sts {d_flash},r16 ' again for 2. pass
rjmp _chk_f1
_chk_f5:
_chk_fore:
rjmp _chk_fore
_chk_f_error1:
ldi r16,&h45 ' E = Error
rcall _pr_cout
mov r16,r18 ' print Errorc