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_eeprom and interrupts

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








write_eeprom and interrupts
PostPosted: Mon Jan 26, 2004 4:56 am     Reply with quote

I'm using PCW3.178 and 18F458.

In my application INT_TIMER0 controls the multiplexing of
a 3-digit LED display, INT_RDA the incoming RS232 chars.
The program on the F458, after the power-up, displays
a startup message on the LED display, then send two times
the same information via RS232 and becomes operating
changing in the same time the displayed message.

One implemented feature allows to dowload from
a PC a set of parameters to be written into the EEPROM.
Such a "write parameters" routine is separated into two
blocks: the first-one receives the parameters from the
serial port and writes them into a RAM vector; the
second-one transfers the RAM content to the eeprom,
simply with a for-loop.

Sometimes (1 of 5) the write parameters routine fails:
the 18F458 reset itself, displays the startup
message, send one time only the message over RS232
and then remain hanged. What I can see is that the
INT_TIMER0 continue to work (the display is correctly
multiplexed).

INT_TIMER0 period is about 1.64ms.

Restarting the board, I can see that what has failed is the
write_eeprom: reading back the eeprom, at least one
location is corrupted (0xFF value).

Well, I tried to disable the interrupts before each
write_eeprom call and re-enable it after each-one:
it seems to fix the problem, never more problems.
I know the write_eeprom has inside the global interrupts
disabling, so adding a disable_interrupts(GLOBAL)
should not change the substance, but something
happened.
For example the LED display flickering during the eeprom
writing (about 40 locations) changes a lot. The flickering
can be explained by the interruptions on the multiplexing
due to the write eeprom times (~5ms versus the 1.64ms
of the mux time).
Before the fix there was a sort of indefinite visual shot,
something like an interruption in the multiplexing but very
short;
after the fix, there is some tenth of second of fickering
of all digits in the same way but not at the same time,
that seems more reasonable thinking that the write
parameter procedure takes 40x5ms = 200ms, more
or less.

What of different? The first, and for the moment unique,
thing is that in the disable_interrupts(GLOBAL)

.................... disable_interrupts(GLOBAL);
03E0: NOP(FFFF)
03E2: BCF FF2.6
03E4: BCF FF2.7 <-------
03E6: BTFSC FF2.7
03E8: GOTO 03E4

when the global bit is reset the program waits until
it is effectively reset (why?).
The write_eeprom has inside such a bit reset, but not
the following waiting loop

.................... write_eeprom(add, data);
0BCA: CLRF FAA
0BCC: MOVFF 18F,FA9
0BD0: MOVFF 190,FA8
0BD4: BCF FA6.6
0BD6: BCF FA6.7
0BD8: BSF FA6.2
0BDA: MOVF FF2,W
0BDC: MOVWF 00
0BDE: BCF FF2.7 <-----
0BE0: MOVLB F
0BE2: MOVLW 55
0BE4: MOVWF FA7
0BE6: MOVLW AA
0BE8: MOVWF FA7
0BEA: BSF FA6.1
0BEC: BTFSC FA6.1
0BEE: GOTO 0BEC
0BF2: BCF FA6.2
0BF4: MOVF 00,W
0BF6: IORWF FF2,F


Does someone know something more about that?

Thanks a lot
Fabio
Mark



Joined: 07 Sep 2003
Posts: 2838
Location: Atlanta, GA

View user's profile Send private message Send e-mail

PostPosted: Mon Jan 26, 2004 7:52 am     Reply with quote

What would happen if an interrupt occurred while disabling the interrupts? Maybe it is possible that the interrupt would get serviced. However, the return from interrupt would set the bit back which is not what the user wanted. Maybe this is why but it is only my guess
FabioPIC



Joined: 26 Jan 2004
Posts: 11

View user's profile Send private message Visit poster's website

PostPosted: Mon Jan 26, 2004 9:16 am     Reply with quote

It could be, but in that case why Microchip suggests such a
way for eeprom writing (the same implemented by CCS)?
---
[/img]
Mark



Joined: 07 Sep 2003
Posts: 2838
Location: Atlanta, GA

View user's profile Send private message Send e-mail

PostPosted: Mon Jan 26, 2004 9:29 am     Reply with quote

The disabling in the eeprom write routine is just to prevent anything from happening during the 55 AA WR part of the routine. The chance of 2 interrupts occurring so close together and one occuring on the disable instruction is very slim but it would still be possible in which case there would be an error.
FabioPIC



Joined: 26 Jan 2004
Posts: 11

View user's profile Send private message Visit poster's website

PostPosted: Tue Jan 27, 2004 2:33 am     Reply with quote

So, the question is: is the simple BCF FF2.7 "enough" or
we need instead

03E4: BCF FF2.7
03E6: BTFSC FF2.7
03E8: GOTO 03E4
?

If the simple bit clear is enough, why CCS implemented the
above bit test loop? Could it happen the bit doesn't get cleared
at the first attempt? Why? In that case, what could happen in the
write_eeprom when an interrupt occur, so bad to perform a
processor reset?
Aart
Guest







Eeprom Write
PostPosted: Tue Jan 27, 2004 6:50 am     Reply with quote

Here is some code I wrote after running into a similar problem. This was a while ago but this is what I can remember:

The CCS code disables the global interrupt while its waiting for the write cycle to complete - waste.

void v_WrEemByte(int16 i16Addr, int8 i8Dat)
{
while (wr); //keep it here till finished (write flag) - other interrupts can still happen
EECON1 = 0x00;
EEADRH = make8(i16Addr,1);
EEADR = make8(i16Addr,0);
EEDATA = i8Dat;
wren = 1;
//the following sequence is defined in the documentation
disable_interrupts(global);
EECON2 = 0x55;
EECON2 = 0xAA;
wr = 1;
enable_interrupts(global);
}
//-------------------------------------

Aart
FabioPIC



Joined: 26 Jan 2004
Posts: 11

View user's profile Send private message Visit poster's website

PostPosted: Tue Jan 27, 2004 10:20 am     Reply with quote

OK Aart, so both we had the same problem and both found
the same solution (the CCS disable_interrupts(global)).

Still open my previous question about the loop necessity
to clear the GIE bit: where CCS did get the idea from?

---
Fabio
Gerrit



Joined: 15 Sep 2003
Posts: 58

View user's profile Send private message

PostPosted: Tue Jan 27, 2004 12:29 pm     Reply with quote

FabioPIC,

CCS (and other) use this techniek to be sure the interupt is disabled.

Explanation:

When an interupt appears it will finisch the command that it is working
on and than serve the interrupt.

If the line disable interupt is running and an interrupt appears it will
finisch the disable interrupt and jumps to the interrupt, however you
cleared the global interrupt.

After the interrupt is finisched the interrupt will restore the global interupt
flag. and goto the line after you disabled the interrupt ( with no gloabal
interrupt disabled).

By checking for the global interrupt flag after you cleared it, you are
sure that it is disabled else there was an interrupt when you wanted to
disable it.


I hope I have explained you a little bit in my simple englisch?



Regards,


Gerrit
FabioPIC



Joined: 26 Jan 2004
Posts: 11

View user's profile Send private message Visit poster's website

PostPosted: Tue Jan 27, 2004 1:09 pm     Reply with quote

Hi Gerrit, and thanks for your explaination.

If what you say is correct, what Microchip suggest on the
data sheet about the write eeprom is wrong: they cannot
assure no interrupts will come during eeprom writing time
(several milliseconds) ... well, I suppose they want to do that.
Isn't it?

Fabio
Mark



Joined: 07 Sep 2003
Posts: 2838
Location: Atlanta, GA

View user's profile Send private message Send e-mail

PostPosted: Tue Jan 27, 2004 2:08 pm     Reply with quote

Doesn't matter about the write time. They don't want any extra cycles between the 55 & AA sequence.
Guest








PostPosted: Fri Feb 06, 2004 6:49 am     Reply with quote

Hi,

To be able to write to EEPROM you need to go through a special sequence. (standard procedure with a lot of EEPROM and flash devices) While executing that sequence, possible interrupts can have the effect that the code will execute but the EEPROM write action does not happen. Note you only have to disable the interupts for a couple of intructions - not the complete 4-5mS it takes to do the EEPROM write.

Aart
FabioPIC



Joined: 26 Jan 2004
Posts: 11

View user's profile Send private message Visit poster's website

PostPosted: Fri Feb 06, 2004 12:27 pm     Reply with quote

Hi Aart,

in your first reply you said you had a problem similar
to mine, and you solved it writing your own write_eeprom
code. The difference I can see between your code and the CCS's
one is the disable_interrupts(global) in place of the simple
GIE bit clear (you eliminated the wait for end of writing, but
this is not relevant for the case ... I suppose).
Have I understod correctly your first answer?
If yes, how the disable_interrupts(global) fixed the
problem we had?

Fabio
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