Changing BLOCK_SIZE to 2 will not work.
In order to write 1 word at a time, the WPROG bit must be set in EECON1, and WRITECODE does not set that bit.
For example, using the following code it tries to write 100 BYTEs to Flash. At each word location it writes the address of that word. The results were read back with a U2 programmer.
The image on the left is with BLOCK_SIZE = 64. Only 64 out of the 100 BYTEs actually gets written. This is the normal operation of WRITECODE.
The image on the right is with BLOCK_SIZE = 2.
It was still writing 64 bytes at a time, but it was doing it for every 2 bytes.
The holding registers don't get cleared, and the data gets really messed up.
It ends up writing 128 bytes with BAD Data.
As stated in the other thread, you can use the assembly language routine in the datasheet.Code:; Bad program -- do not use -- ; FlashAddr VAR WORD Idx VAR WORD Wvar VAR WORD ;----[Get address of Flash Data Area]------------------------------------------- ; ASM CHK?RP _FlashAddr movlw low(_FlashData) movwf _FlashAddr movlw high(_FlashData) movwf _FlashAddr + 1 ENDASM ; ;----[The Main Program]--------------------------------------------------------- FOR Idx = FlashAddr to FlashAddr+100 STEP 2 Wvar = Idx WRITECODE Idx, Wvar NEXT Idx STOP ; ;----[This is where the Data will be saved in Flash]---------------------------- @ org $+1023 & 0FC00h ; align to 1KB boundary FlashData:
Or, here's an adaptation that allows you to write 1 WORD at a time.
You can see in this image that it writes the correct data.
Keep in mind that you still have to erase 1kB at a time.Code:Pause 100 FlashAddr VAR WORD Idx VAR WORD Wvar VAR WORD ; ;----[Get address of Flash Data Area]------------------------------------------- ASM CHK?RP _FlashAddr movlw low(_FlashData) movwf _FlashAddr movlw high(_FlashData) movwf _FlashAddr + 1 ENDASM ; ;----[The Main Program]--------------------------------------------------------- FOR Idx = FlashAddr to FlashAddr+100 STEP 2 Wvar = Idx GOSUB WRITEWORD NEXT Idx ; STOP ; ;------------------------------------------------------------------------------- WRITEWORD: TBLPTRU = 0 ; Load TBLPTR with the base address TBLPTRH = Idx.HighByte TBLPTRL = Idx.LowByte ; The TBLPTR must be loaded with an even address TABLAT = Wvar.LowByte ; LSB of word to be written @ TBLWT*+ TABLAT = Wvar.highByte ; MSB of word to be written @ TBLWT* ; The last table write must not increment the table ASM ; PROGRAM_MEMORY BSF EECON1, WPROG ; enable single word write BSF EECON1, WREN ; enable write to memory MOVE?TT INTCON,GIE, R0,0 ; save state of GIE BCF INTCON,GIE ; disable interrupts MOVLW 0x55 MOVWF EECON2 ; write 0x55 MOVLW 0xAA MOVWF EECON2 ; write 0xAA BSF EECON1, WR ; start program (CPU stall) MOVE?TT R0,0, INTCON,GIE ; restore GIE state BCF EECON1, WPROG ; disable single word write BCF EECON1, WREN ; disable write to memory ENDASM RETURN ; ;----[This is where the Data will be saved in Flash]---------------------------- @ org $+1023 & 0FC00h ; align to 1KB boundary FlashData:
That's why you want to "Align" the data with a 1k boundary.




Bookmarks