![](templates/subSilver/images/CCSLogo.jpg) |
![CCS C Software and Maintenance Offers](templates/subSilver/images/forumAd6.jpg) |
View previous topic :: View next topic |
Author |
Message |
newguy
Joined: 24 Jun 2004 Posts: 1903
|
I wish I knew a Microchip rep... |
Posted: Mon Jul 18, 2005 10:58 pm |
|
|
...so that I could shove this 18F4610 right up his you know what.
I have a device I'm developing. Very complicated, lots of code, can't post it here either. Uses an 18F4610.
My tried & true interrupt driven USART code (can be found here: http://www.ccsinfo.com/forum/viewtopic.php?t=22221&highlight=intrda) works for receive on this pile of crap processor. The transmit doesn't. By the way, if I try the same code on an 18F452, it works flawlessly. Unfortunately, I can't use an 18F452 because I need the extra memory of the 4610.
Anyway, it does work for a very short period of time, then it gives up the ghost and stops transmitting. I've read the errata sheets for the 4610, and they acknowledge a problem when using the EUSART in 9 bit mode, but I'm not using that mode, only the regular old 8 bit.
It's like it works for a few bytes, but if I transmit many in rapid succession, phht. It just stops.
The errata sheets say something about this problem in 9 bit mode screwing up the baud rate generator. I know this isn't the case because the thing keeps receiving long after the transmit is lost, so it seems that maybe this is a new problem.
Argh. Anyone know what my next move should be? Do I contact Microchip or CCS or both?
I hate spending 12+ hours chasing a problem not of my own making.
![Evil or Very Mad](images/smiles/icon_evil.gif) |
|
![](templates/subSilver/images/spacer.gif) |
asmallri
Joined: 12 Aug 2004 Posts: 1634 Location: Perth, Australia
|
|
Posted: Mon Jul 18, 2005 11:31 pm |
|
|
Your code modifies the same variables both inside and ouside of the interrupt handlers. When doing this you need to disable the corresponding interrupt in the mainline. Remember that the PIC can be interrupted inside a single c statement as the statement may produce mutiple assembler instructions. The same applies, abeit to a lesser extent, when testing variables that are modified in the interrupt handler. For this reason your code has race conditions that could cause the effects you are observing. _________________ Regards, Andrew
http://www.brushelectronics.com/software
Home of Ethernet, SD card and Encrypted Serial Bootloaders for PICs!! |
|
![](templates/subSilver/images/spacer.gif) |
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Mon Jul 18, 2005 11:39 pm |
|
|
I looked at the code in your link. I see a problem with the receive
interrupt routine. You're setting a flag if you receive one character.
Then in your main loop, you poll this flag and increment a counter.
But this defeats the whole purpose of an interrrupt-driven receive fifo.
You are forced to poll this flag at a rate faster than 960 Hz, or you'll
miss characters. Suppose 5 bytes come in rapid fire. Suppose you
can't poll your flag in the main loop for a while, because you're
sending chars to your LCD routine which has delays in it, or for
some other reason. Then
your main loop will increment your count by 1, but you really have
5 bytes in the buffer.
Ideally, you should have a counter inside the isr, or do it the way CCS
does it and only fetch chars if the head and tail indexes don't match.
I think you should take out those routines from your current code,
and substitute the CCS code from EX_SISR.C and EX_STISR.C.
I know you said it runs on an 18F452. I would try it anyway. |
|
![](templates/subSilver/images/spacer.gif) |
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
|
Posted: Tue Jul 19, 2005 4:08 am |
|
|
Andrew is right about the race conditions in the transmit functions, especially the manipulation of tx_counter in both the isr and bputc() is very dangerous.
Why do you disable the Tx interrupt when you are finished sending all data? Enable it once at program startup and leave it like that and your code will become smaller, faster and you remove one of the race conditions in doing so. |
|
![](templates/subSilver/images/spacer.gif) |
Mark
Joined: 07 Sep 2003 Posts: 2838 Location: Atlanta, GA
|
|
Posted: Tue Jul 19, 2005 9:29 am |
|
|
ckielstra wrote: | Why do you disable the Tx interrupt when you are finished sending all data? | I didn't look at any code but to my knowledge you need to disable the transmit interrupt when done or else it will continue to fire. The flag bit is controlled by the hardware when the buffer is empty. |
|
![](templates/subSilver/images/spacer.gif) |
Neutone
Joined: 08 Sep 2003 Posts: 839 Location: Houston
|
|
Posted: Tue Jul 19, 2005 9:29 am |
|
|
ckielstra wrote: | Why do you disable the Tx interrupt when you are finished sending all data? |
The Tx interupt fires when the Tx buffer is empty. If it is enabled while you are not sending you will not run any other code. |
|
![](templates/subSilver/images/spacer.gif) |
Mark
Joined: 07 Sep 2003 Posts: 2838 Location: Atlanta, GA
|
|
Posted: Tue Jul 19, 2005 9:30 am |
|
|
Beat ya to it ![Razz](images/smiles/icon_razz.gif) |
|
![](templates/subSilver/images/spacer.gif) |
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
|
Posted: Tue Jul 19, 2005 11:10 am |
|
|
Thanks Mark and Neutone!
My current RS-232 routines only use the Rx interrupt, good to know the Tx is different in this respect. |
|
![](templates/subSilver/images/spacer.gif) |
newguy
Joined: 24 Jun 2004 Posts: 1903
|
|
Posted: Tue Jul 19, 2005 11:45 am |
|
|
asmallri wrote: | Your code modifies the same variables both inside and ouside of the interrupt handlers. When doing this you need to disable the corresponding interrupt in the mainline. Remember that the PIC can be interrupted inside a single c statement as the statement may produce mutiple assembler instructions. The same applies, abeit to a lesser extent, when testing variables that are modified in the interrupt handler. For this reason your code has race conditions that could cause the effects you are observing. |
Andrew,
I promised the wife that someday I'd take her to Australia. I owe you a beer when I go. Hell, I owe you 6.
You're right - tx_counter gets modified in & out of the TBE ISR. That was the issue. I've since modified the bputc() function so that the TBE interrupt, if on, gets turned off immediately, then gets turned back on just before bputc() exits. That fixed it.
And for the record, if any Microchip reps are reading this, I won't try to shove a 44 TQFP up your zhoppa.
PCM, the actual code I'm using is based on the one in the link. Mine is slightly different. I use the RDA interrupt to listen for a string from a GPS receiver - no more than about 80 characters maximum. I don't actually assert a flag until the entire string has been received, then I sort through it in the main routine. The GPS spits out this one string once per second. After I get the entire string, there are no incoming characters, so I don't have to worry about missing anything. The RDA routine to grab the GPS string, and the functions to search through it work flawlessly 100% of the time. Now so does the TX routine. And thanks for the pointers to the CCS examples. I'll check them out.
I still don't understand why the code worked on a '452, but not on the '4610. Everything is the same - baud rate (38,400), code, everything. I guess that one processor is a little quicker than the other, or perhaps the compiler inserted extraneous code in one but not the other. Who knows? Oh well, it's fixed, and that's the important part.
In case you're wondering, my app gets the GPS string, as I mentioned. Then it immediately starts transmitting characters to a different device. Up to about 140 bytes can be transmitted, with at least about 30 being sent every time.
If I cut back on the number of bytes being sent, then the code would work. However, if I tried to send more than 6 bytes, then it would cut out. Like I said, it's fixed now.
Thanks to everyone for their input. I should have asked earlier - I would have a few more clumps of hair if I did. ![Very Happy](images/smiles/icon_biggrin.gif) |
|
![](templates/subSilver/images/spacer.gif) |
asmallri
Joined: 12 Aug 2004 Posts: 1634 Location: Perth, Australia
|
|
Posted: Tue Jul 19, 2005 6:03 pm |
|
|
Quote: | I promised the wife that someday I'd take her to Australia. I owe you a beer when I go. Hell, I owe you 6. |
I look forward to collecting :-) _________________ Regards, Andrew
http://www.brushelectronics.com/software
Home of Ethernet, SD card and Encrypted Serial Bootloaders for PICs!! |
|
![](templates/subSilver/images/spacer.gif) |
newguy
Joined: 24 Jun 2004 Posts: 1903
|
|
Posted: Tue Jul 19, 2005 6:10 pm |
|
|
asmallri wrote: | Quote: | I promised the wife that someday I'd take her to Australia. I owe you a beer when I go. Hell, I owe you 6. |
I look forward to collecting :-) |
Well, if I ever book the plane tickets, you can be sure I'll be in touch. ![Very Happy](images/smiles/icon_biggrin.gif) |
|
![](templates/subSilver/images/spacer.gif) |
|
|
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
|