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.

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:
As stated in the other thread, you can use the assembly language routine in the datasheet.
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.

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:
Keep in mind that you still have to erase 1kB at a time.
That's why you want to "Align" the data with a 1k boundary.
Bookmarks