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 / write_program_eeprom woes

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



Joined: 22 Sep 2004
Posts: 3

View user's profile Send private message

write_program_memory / write_program_eeprom woes
PostPosted: Wed Sep 22, 2004 2:17 pm     Reply with quote

Hello,

I know this is similar to a lot of other posts, but I haven't been able to find an answer in the forum yet. I'm trying to write program memory on a 16F87, with the eventual goal of writing a bootloader-type thing. I'm using PCM 3.186.

I'm experimenting by trying to copy one instruction or so from one code block, and write it to an arbitrary location as a test. I think I've got my fuses set correctly, but it's not working.

Code:
//Configuration Fuses:
//   Word  1: 2F38   NOWDT NOPUT MCLR NOBROWNOUT NOLVP NOCPD NOWRT NODEBUG CCPB3 NOPROTECT INTRC_IO

unsigned int16 i,j;
i = read_program_eeprom(0x40b);
// works fine, i == 0x130D (bcf 0xd, 0x6)

write_program_eeprom(0x690, i);
// doesn't seem to do anything

j = read_program_eeprom(0x690);
// j == 0x3FFF, default

write_program_memory(0x690, &i, 2);
// never returns

I've tried wrapping the calls inside
Code:
DISABLE_INTERRUPTS(GLOBAL);
//...
ENABLE_INTERRUPTS(GLOBAL);
like I'd seen suggested in some posts, but it didn't seem to have any effect.

Can anyone see what I'm doing wrong?

Thanks,
Arya
arya



Joined: 22 Sep 2004
Posts: 3

View user's profile Send private message

PostPosted: Mon Sep 27, 2004 2:37 pm     Reply with quote

Alright, nevermind, NOLVP was the problem.
arya



Joined: 22 Sep 2004
Posts: 3

View user's profile Send private message

PostPosted: Wed Sep 29, 2004 7:26 pm     Reply with quote

I take it back! LVP doesn't seem to be related.

It works intermittently, mostly not, but every few resets, so.

erase_program_eeprom() always seems to work, but neither write_program_eeprom(addr, inst) nor my own write routine (below) work reliably. About 2% of the time, they do work. And then I'm terribly confused. Hard resets between retries.

Help! (I would rather use compiler built-ins).

Code:

struct {
   int rd : 1;
   int wr : 1;
   int wren : 1;
   int wrerr : 1;
   int free : 1;
   int unused1 : 2;
   int eepgd : 1;
} EECON1_S;
#byte EEDATA    = 0x10c
#byte EEADR    = 0x10d
#byte EEDATH    = 0x10e
#byte EEADRH    = 0x10f
#byte EECON1_S    = 0x18c
#byte EECON2    = 0x18d

// this function's supposed to write to program memory 0x690 - 0x693
// erase_program_eeprom(0x680) has already been called,
//    which clears 0x680 - 0x6bff
// loop has been unrolled, out of desperation
// interrupts are disabled!
void write_routine2() {
   EECON1_S.eepgd = 1;
   EECON1_S.wren = 1;
   EEADRH = 0x06;

   EEADR  = 0x90;
   EEDATA = 0x01;
   EEDATH = 0x23;
   EECON2 = 0x55;
   EECON2 = 0xAA;
   EECON1_s.wr = 1;
#asm
   nop
   nop
#endasm   

   EEADR  = 0x91;
   EEDATA = 0x45;
   EEDATH = 0x67;
   EECON2 = 0x55;
   EECON2 = 0xAA;
   EECON1_s.wr = 1;
#asm
   nop
   nop
#endasm   

   EEADR  = 0x92;
   EEDATA = 0x89;
   EEDATH = 0xab;
   EECON2 = 0x55;
   EECON2 = 0xAA;
   EECON1_s.wr = 1;
#asm
   nop
   nop
#endasm   

   EEADR  = 0x93;
   EEDATA = 0xcd;
   EEDATH = 0xef;
   EECON2 = 0x55;
   EECON2 = 0xAA;
   EECON1_s.wr = 1;
#asm
   nop
   nop
#endasm   
   
}
asmallri



Joined: 12 Aug 2004
Posts: 1634
Location: Perth, Australia

View user's profile Send private message Send e-mail Visit poster's website

PostPosted: Thu Sep 30, 2004 12:21 am     Reply with quote

There are some things better left to assembler Very Happy

You forgot the delay for write completion or alternatively, check the previous write has completed before the next write.

Code:
   bsf   EECON1,EEPGD   ; Point to program memory
   bsf   EECON1,WREN   ; enable write operation

   ; force global interrupts to be disabled
WWEE1   bcf   Intcon,GIE   ; disable global interrupts
   btfsc   Intcon,GIE   ; are global interrupts disabld?
   goto   WWEE1      ; No - try again

   movlw   0x55
   movwf   EECON2      ; write control sequence
   movlw   0xAA
   movwf   EECON2      ; write control sequence
   bsf   EECON1,WR      ; write the data
   bsf   Intcon,GIE   ; enable global interrupts

WaitWR
;   Clrwdt
   btfsc   EECON1,WR      ; wait for write to finish
   goto   WaitWR
Trampas



Joined: 04 Sep 2004
Posts: 89
Location: NC

View user's profile Send private message MSN Messenger

PostPosted: Thu Sep 30, 2004 6:57 am     Reply with quote

I have been fighting the same monster. Except I have been bitten in the butt so many times using CCS intrensic functions like the read/write program memory functions. That I decided to start writting my own functions. So here is a link to some code to use to write your own read/writes... http://forum.microchip.com/m.asp?m=55318

Don't forget that the program memory is written 8 bytes at a time. That is if you have to write 8 bytes before the first gets written.

Trampas
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