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 support@ccsinfo.com

write_program_memory PIC10F322
Goto page 1, 2, 3  Next
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
amarquez



Joined: 24 Jun 2009
Posts: 11

View user's profile Send private message

write_program_memory PIC10F322
PostPosted: Mon Jul 30, 2012 4:27 am     Reply with quote

Hello everyone!
I need to save two bytes, I am using the functions read / write_program_memory (), since, the PIC10F322 has no eeprom.
I can not write to program memory
Can anyone help me?
Code:

#include <10F322.h>

#device adc=8

#FUSES WDT_SW                   //Watch Dog Timer by Software
#FUSES INTRC                    //Internal RC Osc
#FUSES BROWNOUT               //brownout reset
#FUSES NOMCLR                   //Master Clear pin used for I/O
#FUSES NOPROTECT
#FUSES PUT
#FUSES NOWRT

#use delay(clock=4M)
#use rs232(baud=300,parity=N,rcv=PIN_A3,bits=8,stop=1)   

#org 0x01FA, 0x01FB {}
#define ADD_OFFSET 0x1FA
#define ADD_FREQ 0x01FB

int offset=16;
int freq=155;
 
void main(){
   setup_adc_ports(sAN0);
   setup_adc(ADC_CLOCK_DIV_8);
   set_tris_a(0b1101);
   setup_wdt(WDT_OFF);
 
   write_program_memory(ADD_OFFSET,offset,2);//OFFSET
   while(TRUE){

           Vin=read_adc(ADC_START_AND_READ);
           if ((Vin >=105)&&(Vin <=230)){
               offset=read_program_memory(ADD_OFFSET,offset,2);
               if(Vin <=125){
                     offset=offset-28;       
               }else{
                     offset=((offset*26)/100)-4;   
                     write_program_memory(ADD_OFFSET,offset,2);//OFFSET   
               }           
           }else{
               offset=0;
           }

   }
}

Ttelmah



Joined: 11 Mar 2010
Posts: 19255

View user's profile Send private message

PostPosted: Mon Jul 30, 2012 5:03 am     Reply with quote

First key thing, is that flash memory, unlike EEPROM, does not have individual byte erase connections. Erases have to be in _pages_. Pages on this chip, are 16bytes. The write_program memory function, will erase the page automatically, _if_ (and only if) you write to the first location in a page.
So, your reserved area, needs to start on a page boundary, and the area should be 16 locations long.

Second problem then is that the program memory, is organised as 14bit words, written to as two 8bit bytes. So you can only write a full byte to every other location in the memory. The extra two bits are lost, when you write to the intermediate locations. You'll need to split your value to write, into two 8bit values are write these to even locations in the memory.

Then, the address used for the function, is the _byte_ address, but the memory is organised as words. You need to double the word address to get the byte address.
Code:

#org 0x01F0, 0x01FF {} //Make this a page
#define ADD_OFFSET 0x1F0*2
#define ADD_FREQ 0x01F2*2 //Byte addresses

void write_int16_to_progmem(int16 address, int16 val) {
   int8 buffer[4];
   buffer[0]=make8(val,0); //first byte
   buffer[1]=buffer[3]=0; //6bit locations
   buffer[2]=make8(val,1); //second byte
   write_program_memory(address,buffer,4);
}

int16 get_int16_from_progmem(int16 address) {
   int8 buffer[4];
   read_program_memory(address,buffer,4);
   return(make16(buffer[2],buffer[0]));
}


This shows how to write and read a 16bit value from the program memory on these chips (Ugh....).

The whole page is erased, when you write to the first location in the page. So you need to save the second value before doing this, if you don't want to lose it. Also to change the second value, you have to retrieve the first value, then write it back (which erases the page), then write the second value....

What you show, would kill the chip very quickly. Neither EEPROM, or flash is suitable for things that are changed at all often. You are writing every time round the loop. About once every 3mSec. That will kill the chip in about 8 hours....

Best Wishes
amarquez



Joined: 24 Jun 2009
Posts: 11

View user's profile Send private message

PostPosted: Mon Jul 30, 2012 5:37 am     Reply with quote

I've been testing the code and I can not write to program memory. Continuing with the same problem.
amarquez



Joined: 24 Jun 2009
Posts: 11

View user's profile Send private message

PostPosted: Tue Jul 31, 2012 12:18 am     Reply with quote

I tested it on different areas of free memory in the execution of the function 'write_program_memory( address, dataptr, count )', the pic10F322 not work.
Could be a bad implementation of the function for this PIC?
Ttelmah



Joined: 11 Mar 2010
Posts: 19255

View user's profile Send private message

PostPosted: Tue Jul 31, 2012 12:46 am     Reply with quote

Yes, it could.
Very new PIC.
One thing though, are you delaying at the start of your code, before you call these functions?. This is required (errata 1). There must be at least 100uSec delay after power on, before trying to write to the flash.

Best Wishes
amarquez



Joined: 24 Jun 2009
Posts: 11

View user's profile Send private message

PostPosted: Tue Jul 31, 2012 1:14 am     Reply with quote

I have introduced a delay before writing to the flash, and locks in the execution of writing.
Ttelmah



Joined: 11 Mar 2010
Posts: 19255

View user's profile Send private message

PostPosted: Tue Jul 31, 2012 2:31 am     Reply with quote

Are you sure, or could it be the delay?. There have been a _lot_ of problems with delays on the 10F/12F chips not working as they should on various compiler versions....
I'd guess though that the unlock sequence is not working right, in which case you either need to dismantle the assembler, and see if you can spot the error, go DIY, or log a problem with CCS.

Best Wishes
amarquez



Joined: 24 Jun 2009
Posts: 11

View user's profile Send private message

PostPosted: Wed Aug 01, 2012 4:46 am     Reply with quote

The problem is not the delays.
I'm trying to assembler.
Ttelmah



Joined: 11 Mar 2010
Posts: 19255

View user's profile Send private message

PostPosted: Wed Aug 01, 2012 7:15 am     Reply with quote

OK. It is just on these chips there have been reported problems with certain delays causing completely spurious results....
You are aware that code _will_ stall for 2mSec while any write/erase operation takes place, and that interrupts _must_ be disabled before these are called?.

Best Wishes
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Wed Aug 01, 2012 5:46 pm     Reply with quote

There are bugs in the flash memory read/write routines. Are you sure
you want to do this ? Because if you type in the routines from the 10F322
data sheet, you might use a considerable portion of the Flash memory
that is available. These are small PICs, with only 512 words of Flash.

I wrote a little program to test reading a word from Flash. If you are
just playing around, I don't think it's worth the effort to finish all the
routines. Or at least, it may not be worth my effort.

But the following program does work. It displays "1234" on the TeraTerm
window on my PC. I have pin A2 connected to a Max232 chip, which
then connects to the PC with a cable. This was tested with vs. 4.135.
There also appear to be some problems with printf displaying control
characters and strings. I just used putc() to do the CR and LF chars.
Code:

#include <10F322.H>
#fuses INTRC,NOWDT,BROWNOUT,PUT,MCLR
#use delay(clock=4M)
#use rs232(baud=9600, xmit=PIN_A2)

#define FLASH_ADDR  0x1F0  // Use last 16 words of flash for testing

// Initialize the test area in flash to all 0's when
// the PIC is programmed.
#rom FLASH_ADDR = {0x1234,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0} 


#byte PMADRL = 0x20
#byte PMADRH = 0x21
#byte PMDATL = 0x22
#byte PMDATH = 0x23
#byte PMCON1 = 0x24
#byte PMCON2 = 0x25

#bit  RD     = PMCON1.0
#bit  WR     = PMCON1.1
#bit  CFGS   = PMCON1.7

int16 read_program_word(int16 addr) 
{
int16 retval;

PMADRL = addr;       
PMADRH = addr >> 8; 
CFGS = 0;           
RD   = 1;           
#asm nop #endasm
#asm nop #endasm
retval = make16(PMDATH, PMDATL);
return(retval);
}

//====================================
void main(void)
{
int16 result;

result = read_program_word(FLASH_ADDR);
printf("%lx ", result);

putc(0x0d);
putc(0x0a);

while(1);
}
amarquez



Joined: 24 Jun 2009
Posts: 11

View user's profile Send private message

PostPosted: Thu Aug 02, 2012 5:09 am     Reply with quote

I appreciate the effort. I'm not playing.
I understand that the PIC10F322 is new and may have errors of routines, I need to work with it.

CFGS PMCON registry is bit 6? ('# bit CFGS = PMCON1.7')
You could check me erase and write routines?
I think the erase routine is correct, but I can not write to the flash.

Thank you.
Code:

#byte PMADRL = 0x20
#byte PMADRH = 0x21
#byte PMDATL = 0x22
#byte PMDATH = 0x23
#byte PMCON1 = 0x24
#byte PMCON2 = 0x25

#byte INTCON = 0x0B

#bit  RD     = PMCON1.0
#bit  WR     = PMCON1.1
#bit  WREN   = PMCON1.2
#bit  WRERR  = PMCON1.3
#bit  FREE   = PMCON1.4
#bit  LWLO   = PMCON1.5
#bit  CFGS   = PMCON1.6

#bit  GIE    = INTCON.7

void erase_program_word(int16 addr)
{
   GIE = 0;
   PMADRL = addr;       
   PMADRH = addr >> 8;
   CFGS = 0;
   FREE = 1;
   WREN = 1;
   //unlock sequence
      PMCON2 = 0x55;
      PMCON2 = 0xAA;
      WR = 1;
      #asm nop #endasm
      #asm nop #endasm
   WREN = 0;
   GIE = 1;

}

void write_program_word(int16 addr, int16 data)
{
   GIE = 0;
   PMADRL = addr;       
   PMADRH = addr >> 8;
   CFGS = 0;
   FREE = 0;
   LWLO = 1;
   WREN = 1;
   PMDATL = data;       
   PMDATH = data >> 8;
   //unlock sequence
      PMCON2 = 0x55;
      PMCON2 = 0xAA;
      WR = 1;
      #asm nop #endasm
      #asm nop #endasms 
   LWLO = 0;
   WREN = 0;
   GIE = 1;
}
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Thu Aug 02, 2012 12:32 pm     Reply with quote

You're right about the CFGS bit. That was a mistake. It is bit 6.
It worked because it defaults to 0.
amarquez



Joined: 24 Jun 2009
Posts: 11

View user's profile Send private message

PostPosted: Thu Aug 09, 2012 1:06 am     Reply with quote

Routine does not work "write_program_word(int16 addr, int16 data)"
Can anyone help me?
temtronic



Joined: 01 Jul 2010
Posts: 9131
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Thu Aug 09, 2012 4:50 am     Reply with quote

I don't have or use that PIC but..
generally speaking...

It'd help if you told us what doesn't work.Is the correct data not at the correct address?Is only the lower byte correct,but at the wrong address?Is anything right or is it all wrong? What address/data should you have and what did you get?
Is the data/address correct when reading the PIC using say ,MPLAB, but your display program shows 'errors'?
There's a LOT of combinations..and without knowing what you have vs. what you expect it's nearly impossible to help.


This is assuming the PIC and the rest of your program is running right.

You've probably made a lot of changes since the op so maybe show us all of your new code.

hth
jay
amarquez



Joined: 24 Jun 2009
Posts: 11

View user's profile Send private message

PostPosted: Wed Aug 22, 2012 4:31 am     Reply with quote

The problem is in LWLO bit of the PMCON1 register. Clear the LWLO bit before unlock sequence.

Code:
void write_program_word(int16 addr, int16 data)
{
   GIE = 0;
   PMADRL = addr;       
   PMADRH = addr >> 8;
   CFGS = 0;
   FREE = 0;
   LWLO = 1;
   WREN = 1;
   PMDATL = data;       
   PMDATH = data >> 8;
    LWLO = 0;
   //unlock sequence
      PMCON2 = 0x55;
      PMCON2 = 0xAA;
      WR = 1;
      #asm nop #endasm
      #asm nop #endasms
   
   WREN = 0;
   GIE = 1;
}
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Goto page 1, 2, 3  Next
Page 1 of 3

 
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