|
|
View previous topic :: View next topic |
Author |
Message |
Hans Wedemeyer
Joined: 15 Sep 2003 Posts: 226
|
PIC18F452 #int_RDA gets clobbered when using Write_EEProm() |
Posted: Sat Nov 06, 2004 8:39 pm |
|
|
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
|
|
Posted: Sat Nov 06, 2004 11:32 pm |
|
|
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 |
Posted: Sun Nov 07, 2004 10:09 am |
|
|
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
|
|
Posted: Sun Nov 07, 2004 10:24 am |
|
|
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... |
Posted: Sun Nov 07, 2004 11:12 am |
|
|
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
|
|
Posted: Sun Nov 07, 2004 11:45 am |
|
|
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
|
|
Posted: Sun Nov 07, 2004 12:32 pm |
|
|
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
|
|
Posted: Sun Nov 07, 2004 1:02 pm |
|
|
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() |
Posted: Sun Nov 07, 2004 3:07 pm |
|
|
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
|
|
Posted: Sun Nov 07, 2004 5:46 pm |
|
|
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
|
|
Posted: Sun Nov 07, 2004 6:53 pm |
|
|
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 |
Posted: Sun Nov 07, 2004 6:56 pm |
|
|
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
|
|
Posted: Sun Nov 07, 2004 7:01 pm |
|
|
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. |
|
|
|
|
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
|