|
|
View previous topic :: View next topic |
Author |
Message |
object01
Joined: 13 May 2004 Posts: 90 Location: Nashville, TN
|
UART problems on 2620 |
Posted: Mon Nov 01, 2004 4:28 pm |
|
|
While CCS is moving to a different office, I'm hoping this group can provide some insight into a problem I'm having with the 2620. So far, I'm leaning toward it being a compiler bug, but I'll definitely entertain it being something wrong with my code. :)
The device we're working with basically amounts to a PIC18F2620 connected to a cellular modem. We use the 2620's hardware UART for communication to/from the modem. We had been using the PIC18F2320 with total success, but had to upgrade to the 2620 due to lack of ROM. But when we switched, we discovered a bad UART problem.
This code is my test program. Works fine on a 2320, but not on a 2620:
Code: | #include <18F2620.h>
#include <stddef.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#fuses INTRC_IO,DEBUG,NOWDT,NOPUT,BROWNOUT,NOLVP,NOPROTECT,NOCPD,MCLR
#use delay(clock=8000000)
#use rs232(DEBUGGER, stream=DEBUGGER)
#use rs232 (baud=9600, xmit=PIN_C6, rcv=PIN_C7, errors, stream=UART) // Using the hardware USART
#include <input.c>
#define RX_BUFFER_SIZE 32
char rx_buffer[RX_BUFFER_SIZE]; // The receive buffer for the hardware UART
int8 rx_in_bp = 0; // These are "pointers" but act more like indexes
int8 rx_bp = 0;
int8 DELAY_WADB = 1; // Used by waitAndDumpBuffer()
void main() {
memset(rx_buffer, 0, RX_BUFFER_SIZE);
enable_interrupts(GLOBAL);
enable_interrupts(INT_RDA);
fprintf(DEBUGGER, "fprintf works\n");
fputs("fputs works", DEBUGGER);
printf("printf works\n");
puts("puts works");
fprintf(UART, "AT\r\n");
while(1) {}
}
#int_rda
void UART_echo() {
int8 old_pointer;
rx_buffer [rx_in_bp] = getc (UART); // Put the newly received character into the buffer
old_pointer = rx_in_bp; // Save the pointer in case the buffer is now full
// tracec(rx_buffer[rx_in_bp]); // THIS DOES NOT WORK, EVEN WITH PHONE SET TO 9600 BAUD
rx_in_bp = (rx_in_bp + 1) % RX_BUFFER_SIZE; // Advance the buffer pointer
if (rx_in_bp == rx_bp) { // If the pointers are equal then the buffer is full
rx_in_bp = old_pointer; // Restore the buffer pointer and do not advance it
} // This is a good place for a buffer full flag
// If full, the next character will overwrite the last
} |
This program was originally written to test a problem we discovered with the 2620 and the printf/fprintf functions. While puts and fputs seem to work, printf and fprintf produce garbage when the NOXINST fuse is not used.
Once we realized NOXINST was necessary to make printf and fprintf work, we tried communicating with the modem, sending it "AT\r\n" and expecting "\r\nOK\r\n" in response.
"\r\nOK\r\n" is represented by the following in hex and binary:
Code: | 0D 0A 4F 4B 0D 0A
0000 1101 0000 1010 0100 1111 0100 1011 0000 1101 0000 1010 |
Instead, we were receiving (in rx_buffer):
Code: | 0D 0A 8F 8B 0D 0A
0000 1101 0000 1010 1000 1111 1000 1011 0000 1101 0000 1010 |
This seems to indicate that the high nibble of each byte, when not 0000, is not being received properly. More generally, it indicates that communication from PIC to modem is well-formed, but communication from modem to PIC is not.
CCS suggested:
"This indicates a slight baud rate mismatch. The PIC clock is a little to fast (maybe 4%). What kind of oscillator do you use?"
We replied that we use the chip's internal oscillator. And not only that, but if an oscillator were the problem, wouldn't communication be affected in both directions? We haven't heard back from CCS since then (10/19).
I'm out of ideas and would really appreciate any suggestions.
--
Jeff S. |
|
|
Haplo
Joined: 06 Sep 2003 Posts: 659 Location: Sydney, Australia
|
|
Posted: Mon Nov 01, 2004 4:39 pm |
|
|
The problems due to small baud-rate mismatch are usually non-deterministic. I have a few questions:
1-Does the problem occur everytime the modem sends something to the PIC?
2-Have you tried a different PIC/board?
3-Can you hook up a scope to the line and check the waveforms? |
|
|
object01
Joined: 13 May 2004 Posts: 90 Location: Nashville, TN
|
|
Posted: Mon Nov 01, 2004 4:56 pm |
|
|
Haplo wrote: | The problems due to small baud-rate mismatch are usually non-deterministic. I have a few questions:
1-Does the problem occur everytime the modem sends something to the PIC?
2-Have you tried a different PIC/board?
3-Can you hook up a scope to the line and check the waveforms? |
1. Using the specified test program, yes.
2. Not yet; I'm waiting on more boards to be built.
3. Truthfully, I wouldn't know what to look for.
--
Jeff S. |
|
|
asmallri
Joined: 12 Aug 2004 Posts: 1635 Location: Perth, Australia
|
|
Posted: Mon Nov 01, 2004 5:01 pm |
|
|
Quote: | if an oscillator were the problem, wouldn't communication be affected in both directions? |
No. It is dependant on the UART's capabilities. Some HW and SW uart implementation resynchonize on each transition of the data stream. Whereas a simple HW or SW UART will resynchronize only on the start bit.
Regards, Andrew |
|
|
object01
Joined: 13 May 2004 Posts: 90 Location: Nashville, TN
|
|
Posted: Mon Nov 01, 2004 5:03 pm |
|
|
asmallri wrote: | Quote: | if an oscillator were the problem, wouldn't communication be affected in both directions? |
No. It is dependant on the UART's capabilities. Some HW and SW uart implementation resynchonize on each transition of the data stream. Whereas a simple HW or SW UART will resynchronize only on the start bit.
Regards, Andrew |
Which is responsible for synchronizing? The PIC's internal machinery or the code generated by the compiler?
--
Jeff S. |
|
|
asmallri
Joined: 12 Aug 2004 Posts: 1635 Location: Perth, Australia
|
|
Posted: Mon Nov 01, 2004 5:12 pm |
|
|
object01 wrote: |
Which is responsible for synchronizing? The PIC's internal machinery or the code generated by the compiler?
--
Jeff S. |
If resynchronization is support, it is a UARTs function to do this. The PIC's HW implementation does not do this. I do not know if the CCS compiler does this for software. The point is that it is possible that error free transmission in one direction does not means error free transmission in the other direction when there is a significant clock error.
Another point to remember is that the sample point (where the HW or SW UART determines a bit is a one of a zero) does not necessarily occur at the same point in the data stream between different hw and sw uart implementations. The CCS software uart has a feature that enables you to change the sample position - you may find this helpful.
Andrew |
|
|
object01
Joined: 13 May 2004 Posts: 90 Location: Nashville, TN
|
|
Posted: Wed Nov 10, 2004 2:38 pm |
|
|
Haplo wrote: | The problems due to small baud-rate mismatch are usually non-deterministic. I have a few questions:
1-Does the problem occur everytime the modem sends something to the PIC?
2-Have you tried a different PIC/board?
3-Can you hook up a scope to the line and check the waveforms? |
I've had a heck of a time trying to get CCS back on the phone since their lines were restored, so I'm posting some followup information here in hopes somebody might be able to help solve this problem.
To reiterate, yes, this problem happens for all data sent to the PIC from the phone, so long as the high nibble is non-zero.
We've now experienced the behavior on two different PIC18F2620s. The second time we tried, we tied the TX and RX pins together on the chip and found that data gotten by getc() was incorrectly received: high nibble corrupted.
While talking to Mark @ CCS, he suggested I check the timing of the PIC, to determine whether the PIC's OSCTUNE register needing tweaking. He had me write the following:
Code: | output_high(PIN_A1);
delay_ms(60000);
delay_ms(60000);
delay_ms(60000);
output_low(PIN_A1); |
I could find no unusual timings.
Then Mark suggested we checked the waveform and verified that the signal going into the PIC's RX pin was valid and correct - the timing of the bits was very accurate and precise. The PIC's RX pin was definitely receiving "\r\nOK\r\n", but interpreting {\r,\n,0x8F,0x8C,\r,\n}.
We examined the LST, and Mark noticed something odd about the way my version of 3.212 was producing getc() code. So he sent me a replacement PCH.DLL to try. Though it generated slightly different code, it did not produce any difference in the data we received. I can produce the lists for both the old PCH.DLL and new PCH.DLL I used, if wanted.
Then, mark suggested that I try inserting literal characters into my buffer from inside the ISR, in an effort to determine if something about the ISR itself is causing the corruption. So, I modified the ISR like so:
Code: | #int_rda
void UART_echo() {
int8 old_pointer;
// *************
//rx_buffer [rx_in_bp] = getc (UART); // Put the newly received character into the buffer - failure!
rx_buffer[rx_in_bp] = 'O'; // Verify that literal is inserted into buffer without corruption: success! getc() produces corrupted 'O': 0x8F rather than 0x4F. getc() returns 0xCF with RX & TX tied together on another PIC.
// My criteria for success is the contents of rx_buffer[], examined via a Watch in the IDE.
// *************
old_pointer = rx_in_bp; // Save the pointer in case the buffer is now full
// tracec(rx_buffer[rx_in_bp]); // THIS DOES NOT WORK, EVEN WITH PHONE SET TO 9600 BAUD
rx_in_bp = (rx_in_bp + 1) % RX_BUFFER_SIZE; // Advance the buffer pointer
if (rx_in_bp == rx_bp) { // If the pointers are equal then the buffer is full
rx_in_bp = old_pointer; // Restore the buffer pointer and do not advance it
} // This is a good place for a buffer full flag
// If full, the next character will overwrite the last
} |
I have not been able to report these results to Mark except by emailing support@ccsinfo.com, and I haven't received a status message on that ticket yet.
At this point, I'm stuck, so I'm starting to review the possibility of writing inline asm for getc() using examples from Microchip. If anyone can shed any more light on this, I would -really- appreciate it. CCS tech support is almost totally out-of-pocket now.
--
Jeff S. |
|
|
Humberto
Joined: 08 Sep 2003 Posts: 1215 Location: Buenos Aires, La Reina del Plata
|
|
Posted: Wed Nov 10, 2004 4:00 pm |
|
|
Quote: |
To reiterate, yes, this problem happens for all data sent to the PIC from the phone, so long as the high nibble is non-zero.
|
Itīs possible to test the hardware sending a well know characters string to the PIC?
Ie: 0x55 0x05 0x00 0x0A 0xAA ....0x55 0x05 0x00 0x0A 0xAA ...to isolate the problem and the PIC and to see if the problem is stable and repetitive?
FYI CCS has
full ICD support for PIC18F2320
and beta test for the PIC18F2620
Not sure if it has a direct relation with your problem, but...
Humberto |
|
|
object01
Joined: 13 May 2004 Posts: 90 Location: Nashville, TN
|
|
Posted: Wed Nov 10, 2004 4:28 pm |
|
|
Humberto wrote: | Quote: |
To reiterate, yes, this problem happens for all data sent to the PIC from the phone, so long as the high nibble is non-zero.
|
Itīs possible to test the hardware sending a well know characters string to the PIC?
Ie: 0x55 0x05 0x00 0x0A 0xAA ....0x55 0x05 0x00 0x0A 0xAA ...to isolate the problem and the PIC and to see if the problem is stable and repetitive?
FYI CCS has
full ICD support for PIC18F2320
and beta test for the PIC18F2620
Not sure if it has a direct relation with your problem, but...
Humberto :roll: |
A cellular modem is connected to the PIC's UART, and we're sending "AT\r\n" to the phone. This elicits the known string, "\r\nOK\r\n". We know the phone is returning that by scoping it, so therefore we know phone is receiving the "AT\r\n", and therefore the PIC seems to be -sending- data correctly.
Now, you've seen what we get in the PIC's buffer rather than the expected string. That's 100% repeatable. It is never anything other than 0D0A8F8B0D0A. We tried what you're suggesting (I think), by turning the phone's local echo on, and essentially using it as a sounding board. We sent the following characters and got these responses, 100% consistently:
Code: | U
Expected: 01010101
Received: 10010101
xor = 11000000
J
Expected: 10101010
Received: 10001010
xor = 00100000
p
Expected: 01110000
Received: 11110000
xor = 10000000 |
We got similar results wiring the PIC's TX and RX together, then having the PIC send those characters to itself. The bit pattern was only a little different, but per-character results were 100% repeatable. That leads me to believe it might indeed be an oscillator tuning problem, so I'm experimenting with OSCTUNE right now. I inspected rs232_errors and saw the framing error bit set, which doesn't make sense because the data coming back from the phone is as close to 9600 baud as I would expect to see. (I'll remeasure and post exact measurements later; I didn't write them down. But at any rate, this phone worked just fine with a 2320.)
Regarding 2620 having only beta support, CCS told us by phone that the 2620 was supported fully, after we had Microchip's techies speak to them and sort some things out. I suspect they have not updated their support sheet, which wouldn't be the first time.
--
Jeff S. |
|
|
object01
Joined: 13 May 2004 Posts: 90 Location: Nashville, TN
|
|
Posted: Wed Nov 10, 2004 4:37 pm |
|
|
Just ran the following test program on the PIC with RX and TX tied together (no oscillator tuning; running at 8MHz). I had the PIC send 'O' to itself. Scoped the data coming out of the PIC, and it was 104.22us per bit, only 0.06us away from 9600 baud proper.
Whereas rx_buffer should be full of 0x4F, it instead was full of 0xCF.
--
Jeff S. |
|
|
drh
Joined: 12 Jul 2004 Posts: 192 Location: Hemet, California USA
|
|
Posted: Wed Nov 10, 2004 4:49 pm |
|
|
Download errata document DS80200A from the Microchip web site. _________________ David |
|
|
object01
Joined: 13 May 2004 Posts: 90 Location: Nashville, TN
|
|
Posted: Wed Nov 10, 2004 4:51 pm |
|
|
drh wrote: | Download errata document DS80200A from the Microchip web site. |
Mark and I checked that and didn't see anything applicable. What page are you looking at?
--
Jeff S. |
|
|
Mark
Joined: 07 Sep 2003 Posts: 2838 Location: Atlanta, GA
|
|
Posted: Wed Nov 10, 2004 6:23 pm |
|
|
Can you hook a Xtal up to it? |
|
|
Ttelmah Guest
|
|
Posted: Thu Nov 11, 2004 3:37 am |
|
|
First thing to remember, is that RS232 is sent LSB first. Hence a timing error, will show in the high bits, which is exactly what you are seeing. It is also worth realising that many other devices ave timing problems. I have seen PC's who's serial clocks are as much as 4% in error on some baud rates. Hence it could simply be that the bit time of the modem is fractionally wrong, and that a tiny shift of only a fraction percent in the timing on the PIC, is the classic 'straw', with the difference in sampling strategy etween the PIC, and the modem, making the problem only show in one direction.
Now you posted a timing, showing a five digit value (do you really have test equipment calibrated to this accuracy, for measuring intervals)....
I'd write a test program for the 2320, very similar to the one you have tried, except simply toggling a pin, and looping. The waveform will be assymetric, since the loop will take some time, but the frequency will be directly related to the clock frequency of the chip. If you have a DFM, use this to measure the frequency, and then repeat the test with the 2620. Unless they are exactly the same (to within a fraction of a percent), consider using OSCTUNE to adjust the latter chip to match the first.
Now the one thing that really 'worries' me, is that you seem to be saying you are seeing the same bit change/loss, if you loop the output of the PIC back to it's own input?. If so, this rules out the timing, since the timing in both directions will be coming from the same source...
As far as I can see, the errata sheets for this chip, have nothing affecting the UART, _except_ that the correct 'tris' setting for the transmit pin has altered from the data sheet. Though your problem is on receive, it'd be worth looking at this.
The other thing that seriously affects the timing of the sampling, is the transition 'point' for the signals. I have seen no reference to what supply voltage you are running the chips at. The data sheets for the two chips, 'agree' as to what the inputs consider to be a logic high, and a logic low, but only specify this for the 4.5v and above voltage range. It would be quite possible that the input structures on the 'nanoWatt' chips, are fractionally different, and require the voltage to go very slightly lower than the other chips to be 'seen' as a 0. This could then cause a slight mistiming, depending on the output drive involved, and the capacitance present on the board. If you have a digital sampling scope, I'd suggest grabbing one 'character' of the incoming data in single shot mode, and looking at the edges, and levels of the signals.
Best Wishes |
|
|
object01
Joined: 13 May 2004 Posts: 90 Location: Nashville, TN
|
|
Posted: Thu Nov 11, 2004 9:53 am |
|
|
Ttelmah wrote: | Now you posted a timing, showing a five digit value (do you really have test equipment calibrated to this accuracy, for measuring intervals).... |
I just read what our digital scope reported after positioning its cursors to measure the interval. We use a Tektronix TDS1002.
Ttelmah wrote: | If you have a DFM, use this to measure the frequency, and then repeat the test with the 2620. Unless they are exactly the same (to within a fraction of a percent), consider using OSCTUNE to adjust the latter chip to match the first. |
What is a DFM? I experimented with OSCTUNE yesterday, and these were some of my results (modified only the last 5 bits of OSCTUNE) measuring a single 9-bit character captured on the scope, then measured with its cursors. At three notches to maximum, the phone could still understand what the PIC was saying, but the PIC got worse at interpreting the response -- CRLF started to get corrupted from 0x0D0A to 0x1D1A, and "OK" went from 0x8F8B to 0x9F9B.
Code: | frequency 0b10000 (minimum): ~120us per bit
frequency 0b00000 (center / 0):
beginning of start bit: -120us
ending of last data bit: 820us
9 bits == 940us == 104.44us per bit
frequency 0b00001 (1 notch to maximum):
beginning of start bit: -1us
ending of last data bit: 926us
9 bits == 927us == 103us per bit
frequency 0b00010 (2 notches to maximum):
beginning of start bit: -1us
ending of last data bit: 919us
9 bits == 920us == 102.22us per bit
frequency 0b00011 (3 notches to maximum):
beginning of start bit: -4us
ending of last data bit: 910us
9 bits == 910us == 101.11us per bit
frequency 0b01111 (maximum / 16):
beginning of start bit: -10us
ending of last data bit: 730us
9 bits == 740us == 82.22us per bit |
Ttelmah wrote: | Now the one thing that really 'worries' me, is that you seem to be saying you are seeing the same bit change/loss, if you loop the output of the PIC back to it's own input?. If so, this rules out the timing, since the timing in both directions will be coming from the same source... |
That's exactly what's happening. We soldered the two pins together, and received exactly the same problem. I'll be using PCH to examine the contents of RCREG shortly, if possible, though PCH won't let me examine OSCTUNE (address is "unimplemented"; blank in RAM and always 0 in a watch).
Ttelmah wrote: | As far as I can see, the errata sheets for this chip, have nothing affecting the UART, _except_ that the correct 'tris' setting for the transmit pin has altered from the data sheet. Though your problem is on receive, it'd be worth looking at this. |
I'll have a look.
Ttelmah wrote: | The other thing that seriously affects the timing of the sampling, is the transition 'point' for the signals. I have seen no reference to what supply voltage you are running the chips at. |
Mark asked basically the same question. We verified to him that the signal levels were acceptable: about 80mV to 5.12V powering the chip from the ICD-U40 (using the hidden jumper). About 30mV to 4.2V powered from our device. What am I looking for when looking "at the edges," as you suggest?
--
Jeff S. |
|
|
|
|
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
|