CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

Errors writing to program memory in 16f1825

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
pmaggi



Joined: 05 Jun 2013
Posts: 10

View user's profile Send private message

Errors writing to program memory in 16f1825
PostPosted: Sun Apr 27, 2014 3:25 pm     Reply with quote

Hi, I'm trying to make some kind of loader but I'm having problems writting into program memory.

First, I load the data in an array (dato_ld)

Code:
   addr=make16(dato_ld[0],dato_ld[1]);
   addr=addr/2;
   cuenta=dato_ld[2];
   if(cuenta!=0){
      for(x=0;x<cuenta;x++)
         buffer[x]=dato_ld[x+3];
         
      write_program_memory(addr, buffer, cuenta);
   }

In dato_ld[0] and [1] I have the address where to write the data
In dato_ld[2] I have how many bytes to write
And from dato_ld[3] to the end I have the data itself

When there is no pre loaded data in the destination, I can record without any trouble, however if there is any kind of data, it records garbage.

This PIC does not need to erase program memory before writing to it, at least CCS doesn't allow to use erase_program_eeprom instruction, so I'm stuck here.

Any suggestion of what I am doing wrong? I'm using CCS 4.120.

Thanks
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Sun Apr 27, 2014 6:21 pm     Reply with quote

Quote:
This PIC does not need to erase program memory before writing to it

The 16F1826 data sheet says this:
Quote:
11.3.3 WRITING TO FLASH PROGRAM MEMORY
Before writing to program memory, the word(s) to be
written must be erased or previously unwritten.



Quote:

I'm using CCS 4.120.
At least CCS doesn't allow to use erase_program_eeprom instruction

That function compiles without errors with vs. 5.025. See the program below:
Code:

#include <16F1826.h>
#fuses INTRC_IO, NOWDT
#use delay(clock=4M)

//======================
void main()     
{
int16 addr = 0x400;

erase_program_eeprom(addr);

}




Before writing to program memory, the word(s) to be
written must be erased or previously unwritten.
pmaggi



Joined: 05 Jun 2013
Posts: 10

View user's profile Send private message

PostPosted: Sun Apr 27, 2014 7:03 pm     Reply with quote

Thanks, I will upgrade the compiler and try it.
pmaggi



Joined: 05 Jun 2013
Posts: 10

View user's profile Send private message

PostPosted: Sun Apr 27, 2014 7:38 pm     Reply with quote

I tryed your code and it compile without any problem, but if I specify a 16f1825 instead of a 16f1826 it fails and says

*** Error 112 "prueba.c" Line 10(1,1): Function used but not defined: ... erase_program_eeprom 618 SCR=937

The 16f1825 data sheets also says that the memory has to be erased before writing to it but for some reason CCS fails to compile...

Try your code using a 16f1825...
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Sun Apr 27, 2014 7:44 pm     Reply with quote

You're right. Somehow I accidentally read your post as 16F1826.
I will look into this further and try to come up with a work-around if possible.
Ttelmah



Joined: 11 Mar 2010
Posts: 19552

View user's profile Send private message

PostPosted: Mon Apr 28, 2014 12:30 am     Reply with quote

Before going on, lets ask a question. Why?....
These chips have EEPROM, and this is much easier to use than program memory. Why not use this?.

On these chips the flash row is 32 words.
Remember that the program memory is 14bits wide. So you can't write a pair of bytes like 0xFFFF to a word, only the low 14bits will be stored. Your code is going to need to be aware of the limitations this brings....

Aaah. I see later you refer to a loader, which should then be OK, aand makes sense. The write_program_memory function is meant to erase _automatically_, but only when you write to the first byte of a row. If you are writing to addresses that don't align to the rows, then it'd behave as you see, or if the erase doesn't work on your compiler. Haven't got 4.120 handy.

Within these limitations, if CCS on your compiler version is not handling an erase, it should be 'doable' with:
Code:

#define delay_2 delay_cycles(1);delay_cycles(1) //used to ensure two NOP's

#byte EEADRH=getenv("SFR:EEADRH")
#byte EEADRL=getenv("SFR:EEADRL")
#byte EECON2=getenv("SFR:EECON2")
#bit CFGS=getenv("BIT:CFGS")
#bit WREN=getenv("BIT:WREN")
#bit FREE=getenv("BIT:FREE")
#bit EEPGD=getenv("BIT:EEPGD")

void erase_page(int16 address)
{
   //Mask address to the low word - 64 byte mask
   address&=0xFFC0;
   EEADRL=make8(address,0);
   EEADRL=MAKE8(address,1); //load address
   EEPGD=TRUE;
   CFGS=FALSE;
   FREE=TRUE;
   WREN=TRUE;
   EECON2=0x55;
   EECON2=0xAA; //unlock
   WR=TRUE; //trigger erase
   delay_2; //two NOP's
   WREN=FALSE;
}

Now, I've not tested this (it was bodged out of some other code I had for a chip where the erase was not working), but structurally looks right (assuming 4.120 knows the bit names). Remember GIE needs to be off before this is called.

Best Wishes
pmaggi



Joined: 05 Jun 2013
Posts: 10

View user's profile Send private message

PostPosted: Mon Apr 28, 2014 6:00 am     Reply with quote

Thanks, I will try this approach.

The loader is for a smart switch controlled trough RF. What I am trying to implement is a way of changing the firmware trough RF without having to take it apart.
Everything is working fine except for the writing to program memory Wink
Ttelmah



Joined: 11 Mar 2010
Posts: 19552

View user's profile Send private message

PostPosted: Mon Apr 28, 2014 8:00 am     Reply with quote

Strategic important thing to be aware of. Just how long the flash memory takes to do things. It takes 2.5mSec (worst case) to perform a block write/erase. During this time the processor completely stops. You need to ensure the serial stops when data is being written. Also to change one byte in a row, you have to read the entire row, modify the one byte in RAM, erase the row, and write the whole row back.
pmaggi



Joined: 05 Jun 2013
Posts: 10

View user's profile Send private message

PostPosted: Mon Apr 28, 2014 8:12 am     Reply with quote

Thanks, I just send 16 data bytes at a time, and don't send more until receiving the acknowledge from the pic. That part works ok, I'm able to write quite long pieces of code in free zones of memory without any problem.
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group