Mike Harrison wrote: >I've now implemented this scheme on the current project. >A limit on the sizing of the 'resident' eeprom copying routine is the 32 word row erasability >boundaries, so if the code can't be squeezed below 32 words, there is no benefit in using any less >than 64, so this could be used to add some of the various 'protection' options I outlined in my >original post, or to move the setup code into the resident area to free space in the application >area. > > Actually, I squeeze the 32 14-bit words into 32 pairs of 7-bit characters, a MS and an LS 7-bit character. I then add d'14' to each one to ensure that those characters are not confused with (or whatever terminator is used). This makes serial transmission of the downloader easier. One can also squeeze 64 7-bit characters (448 bits) can be reduced to 56 8-bit bytes, for the purpose of squeezing 4096 14-bit words into 3584 16-bit words. >My first attempt put the resident part at 37 words, so i just HAD to do some squeezing to get it >down to one row, just to prove it could be done...! > >The total code overhead for enabling the in-system reprogrammability came to 50 (decimal!) words, >18 words setup within the application code and 32 for the copy code which lives in the top row of >program space. > >Having all the setup within the application code area instead of the fixed 'resident' section >maximises the possibility for future code squeezing/sharing if things start to get really tight, but >care must be taken to ensure that it will work correctly in all circumstances. > >Flash-program time for the 16F818 is about 0.7 seconds, so even without any additional protection >mechanisms, the 'potential disaster' window is pretty short. > >..and for those of you that didn't read/understand the original post, this technique is only >seriously advantageous for systems that ALREADY HAVE a suitable external eeprom/serial flash, and >communications system as part of the main application, and where in-system reprogrammability can be >regarded as a useful addition rather than a mission-critical necessity!!! > >----------------------------------------------------------------------------------------------------------------- >here's the code - obviously will need tweaking to suit other apps, but the 'get byte' is a seperate >routine and should be fairly easy to modify (once you understand the strange bits done to save >space..!) > >; 16F818 eeprom-copy flash loader >; (C) Mike Harrison 2005 >; copies from external ST M25Pxx serial flash, address 000000, LSB first > >wordcount equ 070 ; variables in shared bank to allow access regardless of page bit settings >rowcount equ 071 > >; setup code - resides in application area > >copyflash ; copy ext serial flash to program memory. SPI already set up, ints disabled >; setup for SPI eeprom read > clrf intcon ; ensure ints off > > movlw 3 ; serial flash read command > call sendspi ; uses spi routine which is already parts of main app code (asserts /CS) > call sendspi_0 ; address bytes 2..0, sends 0 > call sendspi_0 > call sendspi_0 > > movlw 1< movwf status ; ensure rp0 and irp clear > movlw sspbuf > movwf fsr ; use indf/fsr to allow access to sspbuf without page switching. > > clrf eeadr-100 ; zero PIC flash address > clrf eeadrh-100 > movlw loaderstart/d'32' ; number of rows to program > movwf rowcount > > goto loaderstart > >end of application code >;------------------------------------------------------------------------------------------------ > > > org 3e0 > >; start of resident loader section. > >loaderstart >eraseloop ; erase and program one row of 32 bytes > movlw (1< call flash_write ; erase row > movwf wordcount ; 32 words to program ( value 32 returned by flash_write retlw) >wordloop > call get_ssp ; get LSbyte from eeprom > movwf eedata-100 > call get_ssp ; get MSbyte from eeprom > movwf eedath-100 > movlw (1< call flash_write > incf eeadr-100 ; increment flash address > skpnz > incf eeadrh-100 ; address msb > decfsz wordcount > goto wordloop > decfsz rowcount > goto eraseloop > > goto force_pc ; exit address to force re-entry to PC mode > > ; the exit address would typically be a well-defined, non-movable address in the app.code, e.g.0002 > ; an alternative would be to use "goto $" to loop infinitely and force a reset when the watchdog > ; times out. > >get_ssp ; get byte from spi > > movwf indf ; (fsr-> sspbuf), initiate SSP read > call sspdelay ; delay to allow spi to happen ( SPI clock is osc/4, so takes about 8 instruction >times) > movf indf,w > return > >flash_write ; do flash erase or write sequence, w = eecon1 value, assumes rp1 set > > bsf status,rp0 ; page 3 > movwf eecon1-180 ; select program memory, row erase, write enable > movlw 055 ; write sequence > movwf eecon2-180 > movlw 0aa > movwf eecon2-180 > bsf eecon1-180,wr ; start write/erase > >sspdelay ; entry point used for SPI wait delay > goto $+1 ; long NOP, used to extend ssp wait delay. > clrwdt ; avoid watchdog spoiling your day. placed here to maximise ssp delay time > ; wont be executed after flash write but will be when ssp is read > bcf status,rp0 > retlw 020 ; number of words per row, used after erase > > > > > -- Note: To protect our network, attachments must be sent to attach@engineer.cotse.net . 1-866-263-5745 USA/Canada http://beam.to/azengineer -- http://www.piclist.com PIC/SX FAQ & list archive View/change your membership options at http://mailman.mit.edu/mailman/listinfo/piclist