Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

Problem writing to program flash on pic24FJ64GA004

Status
Not open for further replies.

Diver300

Well-Known Member
Most Helpful Member
I've been using the pic24FJ64GA004 for some time, and I now want to store some data in the flash program memory.

I ran Microchip's examples for erasing and writing code and they work fine on their own, but I can't get writing to work after I have erased a block.

The code:-
Turns on an LED
Erases a block of flash
Turns off the LED
waits about a second
Turns on the LED
Loads some data into the holding registers
Writes that data into the flash
Then it flashes the LED for ever.

The code always gets to the end. If I run it as is, the block gets erased but nothing gets written. If I disable the erase, the data gets written as expected.

Here is my code. The parts in capitals are Microchip's examples.

Code:
.include "p24FJ64GA004.inc"

config __CONFIG2, IESO_OFF & FNOSC_FRC & FCKSM_CSECMD & OSCIOFNC_ON & IOL1WAY_OFF & I2C1SEL_SEC & POSCMOD_EC
config __CONFIG1, JTAGEN_OFF & GCP_OFF & GWRP_OFF & BKBUG_OFF & COE_OFF & ICS_PGx1 & FWDTEN_OFF & WINDIS_OFF & FWPSA_PR32 & WDTPS_PS32768

.text 

red_led_reg				= LATA
red_led					= 1

	bclr	TRISA, #1
	bset	red_led_reg, #red_led			

PROG_ADDR = 0x1000

; Set up NVMCON for block erase operation
	MOV #0x4042, W0 ;
	MOV W0, NVMCON ; Initialize NVMCON
; Init pointer to row to be ERASED
	MOV #tblpage(PROG_ADDR), W0 ;
	MOV W0, TBLPAG ; Initialize PM Page Boundary SFR
	MOV #tbloffset(PROG_ADDR), W0 ; Initialize in-page EA[15:0] pointer
	TBLWTL W0, [W0] ; Set base address of erase block
	MOV #0x55, W0
	MOV W0, NVMKEY ; Write the 55 key
	MOV #0xAA, W1 ;
	MOV W1, NVMKEY ; Write the AA key
	BSET NVMCON, #WR ; Start the erase sequence
	NOP ; Insert two NOPs after the erase
	NOP ; command is asserted
	BTSC NVMCON, #15 ; Wait for the sequence to be completed
	BRA $-2 ;
	bclr	red_led_reg, #red_led

	mov		#0x100, w0
pause_loop:
	repeat #0x2000
	nop
	dec		w0, w0
	bra		NZ, pause_loop		;Pause for about a second.

	bset	red_led_reg, #red_led

setup_table_example:
; Set up NVMCON for row programming operations
	MOV #0x4001, W0 ;
	MOV W0, NVMCON ; Initialize NVMCON
; Set up a pointer to the first program memory location to be written
; program memory selected, and writes enabled
	MOV #0x0000, W0 ;
	MOV W0, TBLPAG ; Initialize PM Page Boundary SFR
	MOV #0x1000, W0 ; An example program memory address
; Perform the TBLWT instructions to write the latches

	mov		#64, w4
	clr	 	W3 ;
program_save_loop:
;This just writes some rubbish into the buffer
	MOV #0x4142, W2 ;
	TBLWTL W2, [W0] ; Write PM low word into program latch
	TBLWTH W3, [W0++] ; Write PM high byte into program latch
	inc		w3, w3
	dec		w4, w4
	bra		NZ, program_save_loop

	MOV #0x55, W0
	MOV W0, NVMKEY ; Write the 55 key
	MOV #0xAA, W1 ;
	MOV W1, NVMKEY ; Write the AA key
	BSET NVMCON, #WR ; Start the erase sequence
	NOP ; 2 NOPs required after setting WR
	NOP ;
	BTSC NVMCON, #15 ; Wait for the sequence to be completed
	BRA $-2 ;

led_flash:
	bclr	red_led_reg, #red_led
	repeat #0x2000
	nop
	bset	red_led_reg, #red_led
	repeat #0x2000
	nop
	bra	led_flash	;stop here


.org	0xdf0
	.pword 0x123456, 0x123456		;Put something in memory so that I can see when it has been erased
	.pword 0x123456, 0x123456 
	.pword 0x123456, 0x123456 
	.pword 0x123456, 0x123456 
	.pword 0x123456, 0x123456
 	.pword 0x123456, 0x123456  
	.pword 0x123456, 0x123456 
	.pword 0x123456, 0x123456 
	.pword 0x123456, 0x123456
 	.pword 0x123456, 0x123456  
	.pword 0x123456, 0x123456

Any ideas what I'm doing wrong?
 
I have solved it.

The code was erasing, pausing and writing like it was supposed to.

The problem was that when I came to read the flsah on the PICKIT2, the PICKIT2 let the program run for a moment, and the first bit erased the block of flash again.

Now the code does pause, erase, pause and write. When the PICKIT2 let the program run for a moment, it didn't get to the end of the pause, so no extra erase happened.
 
hi can u please tell me how did u feed the addess using tblpag and tblwrl options.

for example if i want to erase a page from 0x002c00,
TBLPAG=0x00//upper byte
__builtin_tblwtl(0x002c00, 0xFFFF); //dummy write to lower address


( or) i have to feed the ouble of the adress, for 0x2c00 --> 0x5800?

i juct filled some data in flash area and executed the following program. but it didnt eraae the page. what might be wrong?

i could see in the SFR register window, WRERR bit is set ans nvmkey is 0.
TBLPAG=0x00 //upper byte
__builtin_tblwtl(0x002c00, 0xFFFF);

diable interrupts;



/* Write the KEY Sequence */

NVMKEY=0x55;

NVMKEY=0xAA



/* Start the erase operation */



NVMCON|=0x8000; // ERASE_INIT;



Nop()

Nop()



/* Wait till the Erase operation completes */

while(NVMCON_WR);
 
I've never really understood all the table offsets. i just let MPLAB take care of it.

In my code I used:-

Code:
	MOV #tblpage(PROG_ADDR), W0 ;
	MOV W0, TBLPAG ; Initialize PM Page Boundary SFR

and I think that is different from your:-

Code:
TBLPAG=0x00 //upper byte

apart from the obvious fact that you are writing in C while I use assembly code.

My code comes fairly directly from the data sheet, and there is an example in C there.
 
flash erasing

plz tell me how to use the assembly fully or atleast for address feeding table operations. after that setting nvmcon, initiating operation and all i can use builtin function. and i neeed any c example. or how to use assembly... the datasheet asm option is confusing
 
flash erase and program

application note 1094 in microchip website is useful. **broken link removed**
 
flash programming

hi,

Two things i want to clarify.
1)
i have done the flash programming using table instructions.
As per controller manual,
if u want to program an area we have to store the data in RAM, modify that data and then write the modified data in to write latches through table write instructions.

but without saving also we can just feed the data thro latches na, saving step is necessary and should be followed?

2)
i have used the put the code for programming ( please refer the code below) . this does not have tbl read operations, only write. and this has written the fed data into memory. only one problem comes, from 100th byte to some extent the data is corrupted., then till end its programmed correctly, i.e a little portion is corrupted. what might be the reason for this??

#include "p33Fxxxx.h"


//extern void WordProgram(void);

int main(void)
{


//C_UINT32 GppPM_Source_Address[1024]={24,32,45,67,86,45,34,21};
C_UINT32 GppPM_Destination_WordAddress =0x2C00;

typedef union tuReg32
{
C_UINT32 Val32;

struct
{
C_UINT16 LW;
C_UINT16 HW;
} Word;

char Val[4];
} uReg32;

int Size,Size1;
uReg32 LuiPM_Temp;
uReg32 LuiPM_TempAddr;
uReg32 LuiPM_TempData;



for(Size = 0,Size1=0; Size < 512; Size++)
{

LuiPM_Temp.Val[0]=0x55;
LuiPM_Temp.Val[1]=0x66;
LuiPM_Temp.Val[2]=0x77;
LuiPM_Temp.Val[3]=0;
Size1+=3;

TBLPAG=0x00;
NVMCON=0x4001;// row program

// WriteLatch(0x00,
// GppPM_Destination_WordAddress,LuiPM_Temp.Word.HW,
// LuiPM_Temp.Word.LW
// );

__builtin_tblwtl(GppPM_Destination_WordAddress,LuiPM_Temp.Word.LW);
__builtin_tblwth(GppPM_Destination_WordAddress,LuiPM_Temp.Word.HW);

// WriteMem(0x4001);

__builtin_write_NVM();
while(NVMCONbits.WR);
GppPM_Destination_WordAddress =
GppPM_Destination_WordAddress+2;

}






}
 
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top