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

PIC18F452 #int_RDA gets clobbered when using Write_EEProm()

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



Joined: 15 Sep 2003
Posts: 226

View user's profile Send private message

PIC18F452 #int_RDA gets clobbered when using Write_EEProm()
PostPosted: Sat Nov 06, 2004 8:39 pm     Reply with quote

After making a change to some working code it stopped receiving data on the RS-232.

The change involved several lines of code including some calls to Write_EEprom();
As the RS-232 is set to run at 1.25 Mega Baud I focused on that as the reason for lack of reception, after all it is a very high Baud rate, however it is TTL connected to another PIC and the distance is less than 1 inch, and has worked before.

Slowly working backwards and ending up with 9600 Baud it still refused to receive data.

Next step was to remove the other code changes.
I did this step by step until RS-232 data reception started to work.

The offending line of code is a call to Write_EEprom();

Looking at the LST file for other known good code the call to Write_EEprom() looks different.

The first thing I noticed in the code that does not work, is
CLRF FAA

Not knowing what FAA is, I looked it up in the data sheet and it is has no function, and a search produces nothing!

From the data sheet:
FABh RCSTA
FAAh --------
FA9h EEADR

What exaclty is FAA register used for ? Microchip does not mention it in the data sheets I have.

LST listing for calls to :- Write_EEprom(Address, Val )

Works
070E: MOVFF 627,FAA
0712: MOVFF 626,FA9
0716: MOVFF 628,FA8
071A: BCF FA6.6
071C: BCF FA6.7
071E: BSF FA6.2
0720: MOVFF FF2,00
0724: BCF FF2.7
0726: MOVLB F
0728: MOVLW 55
072A: MOVWF FA7
072C: MOVLW AA
072E: MOVWF FA7
0730: BSF FA6.1
0732: BTFSC FA6.1
0734: BRA 0732
0736: BCF FA6.2
0738: MOVF 00,W
073A: IORWF FF2,F
073C: MOVLB 0
073E: RETLW 00

Does not work
0126: CLRF FAA
0128: MOVFF 176,FA9
012C: MOVFF 177,FA8
0130: BCF FA6.6
0132: BCF FA6.7
0134: BSF FA6.2
0136: MOVFF FF2,00
013A: BCF FF2.7
013C: MOVLB F
013E: MOVLW 55
0140: MOVWF FA7
0142: MOVLW AA
0144: MOVWF FA7
0146: BSF FA6.1
0148: BTFSC FA6.1
014A: BRA 0148
014C: BCF FA6.2
014E: MOVF 00,W
0150: IORWF FF2,F
0152: MOVLB 0
0154: RETLW 00

Compiler is PCH 3.212
Mark



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

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

PostPosted: Sat Nov 06, 2004 11:32 pm     Reply with quote

FAA is the EEADRH register. It is used on those devices with more than 256 bytes of eeprom, like your 6720's
Guest








Still does not make sense
PostPosted: Sun Nov 07, 2004 10:09 am     Reply with quote

Mark wrote:
FAA is the EEADRH register. It is used on those devices with more than 256 bytes of eeprom, like your 6720's


Thanks, I wonder why CCS uses it in code for PIC18F452 ?

0126: CLRF FAA

Does not make sense to me to be using a register which is not described for the PIC18F452.
Not only is it wrong it also eats ROM space.
Mark



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

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

PostPosted: Sun Nov 07, 2004 10:24 am     Reply with quote

Here is some snippets from Microchips bootloader:

Code:
WriteEE   

   movff   POSTINC0, EEDATA

   movlw   b'00000100'      ; Setup for EEData
   movwf   EECON1
   rcall   StartWrite      
   btfsc   EECON1, WR      ; Write and wait
   bra   $ - 2

   infsnz   EEADR, F      ; Adjust EEDATA pointer
   incf   EEADRH, F

   decfsz   COUNTER, F      
   bra   WriteEE         ; Not finished then repeat

   bra   SendAcknowledge      ; Send acknowledge



and

Code:
; Setup the appropriate registers.
Setup   clrf   EECON1
   setf   EEADR         ; Point to last location
   setf   EEADRH         
   bsf   EECON1, RD      ; Read the control code
   incfsz   EEDATA, W
   bra   RVReset         ; If not 0xFF then normal reset

   bcf   TRISC, 6      ; Setup tx pin
;   bsf   TRISC, 7      ; Setup rx pin

   movlw   b'10010000'      ; Setup rx and tx
   movwf   RCSTA1
   movlw   b'00100110'      
   movwf   TXSTA1


Note that they also use this register. This is a generic bootloader that will work for all 18F's. I guess CCS just took a lazier approach and decided to waste an instruction on those devices that do not have more than 256 bytes. I can't really blame them though. it would be more of a head ache to determine which ones had what and make sure that get it right for future chips. I have not seen a problem using this register though.
Guest








CCS should not be so lazy...
PostPosted: Sun Nov 07, 2004 11:12 am     Reply with quote

Can't agree with "can't blame them because..."

CCS is supposed to output clean code (#&^#$&^%$&^ spit)

How much trouble would it be...
They already know the chip type from the header file.

Anyway, this does not cure the problem I'm having, just one call to Write_EEprom() kills rs-232 reception. !

A search revealed this is an old problem for PIC16 chips. Some one had a solution for that using asm verson of Write_EEprom().

I also tried an ASM version of Write_EEProm() based upon the MicroChip's PIC18 data sheet ( a little different to the PIC16 version), this did not use the FAA register.

It did not help, same problem one call to Write_EEProm() and RS-232 reception is dead .
Charlie U



Joined: 09 Sep 2003
Posts: 183
Location: Somewhere under water in the Great Lakes

View user's profile Send private message

PostPosted: Sun Nov 07, 2004 11:45 am     Reply with quote

Hans,

Don't forget that Microchip "strongly recommends" that all interrupts be disabled during the Data EEPROM write cycle. From your code you can see that CCS is doing just that. During the entire time that the code is waiting for the write to complete, interrupts are disabled.

These lines:

0720: MOVFF FF2,00
0724: BCF FF2.7

save the contents of the INTCON reg (FF2) and turn interrupts off (bit 7 is the GIE)

and these lines:

0738: MOVF 00,W
073A: IORWF FF2,F

turn interrupts back on.

The self-timed EEPROM write typically takes 4 ms, which is an eternity for your 1.25 Mbaud data. Also, 4ms is approximately 4 full character times at 9600 baud. So, as a result, even at 9600 baud, you could be trying to receive up to 4 characters over the serial port while the EEPROM write is waiting to complete.

So my guess is that it isn't the code, it's the EEPROM write wait time with interrupts disabled that is affecting your program.
Gerrit



Joined: 15 Sep 2003
Posts: 58

View user's profile Send private message

PostPosted: Sun Nov 07, 2004 12:32 pm     Reply with quote

Hello Hans,

I think Charlie U is right about disabling interrupts on write cycle.

But what CCS is doing is waiting until the byte is written to enable the
interrupt again.

According Microchip you only need to disable the interrupt when writing
the 55, FF sequence.
You do not need to wait till the byte is written to eeprom (can take from 1 to 10 ms) you can check before the next write cycle if the last byte was written.


advice write your own eeprom_write function that only does what you want and need.


Could you explain at what rate, and how mutch data you need to write to eeprom. Maybe there is a other solution.



regards,

Gerrit
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Sun Nov 07, 2004 1:02 pm     Reply with quote

Quote:
After making a change to some working code it stopped receiving data on the RS-232


Quote:
The self-timed EEPROM write typically takes 4 ms, which is an eternity for
your 1.25 Mbaud data. Also, 4ms is approximately 4 full character times
at 9600 baud. So, as a result, even at 9600 baud, you could be trying to
receive up to 4 characters over the serial port while the EEPROM write is
waiting to complete.


Everything said so far in this thread points to an overrun error in the
RS232 receiver. This will lock up the receiver.

Are you using the ERRORS parameter in your #use rs232() statement ?
If not, you should try it. You'll still lose characters but if the receiver
locks up, it will now be automatically cleared.
JerryI
Guest







PIC18F452 #int_RDA gets clobbered when using Write_EEProm()
PostPosted: Sun Nov 07, 2004 3:07 pm     Reply with quote

From Readme file for compiler;

I don't know if it will help.

New directive to prevent WRITE_EEPROM from hanging while
the write takes place:
#device WRITE_EEPROM=ASYNC
If you use this do not write to the EERPOM from both an ISR
and outside an ISR.
future



Joined: 14 May 2004
Posts: 330

View user's profile Send private message

PostPosted: Sun Nov 07, 2004 5:46 pm     Reply with quote

A piece of code from my app.

It will save the entire cfg struct to eeprom. I have another 4 interrupts working with it.

To call it use:

Code:
               {            bit_set(pir2,epif);                   //
                 enable_interrupts(int_eeprom); }                 //


Code:
#int_eeprom                                                       //
void eeprom_isr(void) {                                           //
    //;==========================================================;//
    /*;               wr - write eeprom complete                 ;*/
    //;==========================================================;//
        if(eecnt<sizeof(cfg)) {                                   //
            eeadr=eecnt;                                          //
            eedata=*(&cfg+eecnt);                                 //
            bit_clear(eecon1,eepgd);                              // point to data memory
            bit_set(eecon1,wren);                                 // enable writes
            eecon2=0x55;                                          // write 55h
            eecon2=0xAA;                                          // write AAh
            bit_set(eecon1,wr);                                   // set wr to begin write
                eecnt++;                                          // increment index pointer
            } else {                                              //
               eecnt=0;                                           //
               disable_interrupts(int_eeprom);                    //
        }                                                         //
}                                                                 //
Guest








PostPosted: Sun Nov 07, 2004 6:53 pm     Reply with quote

Charlie U wrote:
Hans,
So my guess is that it isn't the code, it's the EEPROM write wait time with interrupts disabled that is affecting your program.

Charlie,
Thanks for your observations and yes you are correct IF my code is doing Write_EEProm() and expecting data to come in.

IT IS NOT. The only time the code writes to eeprom is when saving variables, at that time there are NO RS-232 communications. It's a very controlled environment.

In fact the only time a request if made for data there is no other activity. PIC 1 pulls a line low and PIC 2 responds by sending four bytes. PIC 1 recieves then into a buffer.
PIC2 puts a 30 uS delay between sending the bytes, this allows time for PIC 1 to get the byte and stuf it in the buffer. It all works very well IF the code never makes a call to Write_EEProm().

That's what makes it so frustratiing. The code works if I comment out the call to Write_EEPROM() and that line of code is far away from the code that requests data from the other PIC.

Again thanks for your input.
Guest








Re: PIC18F452 #int_RDA gets clobbered when using Write_EEPro
PostPosted: Sun Nov 07, 2004 6:56 pm     Reply with quote

JerryI wrote:
From Readme file for compiler;

I don't know if it will help.

New directive to prevent WRITE_EEPROM from hanging while
the write takes place:
#device WRITE_EEPROM=ASYNC
If you use this do not write to the EERPOM from both an ISR
and outside an ISR.


Thanks I'll try that.

No I do not call Write_EEProm() from inside any ISR.... !

The call to Write_EEProm() happens under controlled conditions and nothing else is happening.
Guest








PostPosted: Sun Nov 07, 2004 7:01 pm     Reply with quote

future wrote:
A piece of code from my app.
It will save the entire cfg struct to eeprom. I have another 4 interrupts working with it.


Thanks... thinking about it, the CCS code should work...

I did a asm based upon the data sheet and it did not cure the problem.

I just hooked up ICD-2 and found the silicon for this PIC18F452 is rev b5 .

Nothing special in the errata that would help this issue, I'm not using fast interrupts.

Just to make sure I'm ordering some more up to date chips tomorrow.
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