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

PIC18F87J60 UART Receive Errors
Goto page 1, 2  Next
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
JerryR



Joined: 07 Feb 2008
Posts: 167

View user's profile Send private message

PIC18F87J60 UART Receive Errors
PostPosted: Wed Aug 30, 2023 8:46 am     Reply with quote

Hello Group:

I'm have a mature product that uses a PIC18F87J60 controller. All code was compiled using v5.078 PCWH. The controller uses an external 25 MHz crystal. I'm using all UARTS on this device and the suspect UART is number 3.

I am receiving eight bytes at 57600 baud from an external device. These eight bytes are confirmed correct using a logic analyser and o-scope. All eight bytes are processed into an array of proper length.

The first six bytes are received correctly, however, bytes 7 and 8 seem to be shifted one bit. Unfortunately bytes 7 and 8 are checksum, so need these bytes to be correct!

I suspect a baud rate mismatch, maybe?

Hint: other external devices seem to be able to send data successfully to the product.

Question: Is there a way to "tweak" the receive baud rate to see if that improves reception? I'm open to other suggestions,

Sorry, I can't post code here since proprietary.

Thanks group!
gaugeguy



Joined: 05 Apr 2011
Posts: 303

View user's profile Send private message

PostPosted: Wed Aug 30, 2023 9:28 am     Reply with quote

Because there are only discrete steps in setting the baud rate, when 57600 is selected it may actually end up being slightly higher or lower than the desired rate. You can set it to a different, slightly higher or slightly lower baud rate to get the PIC more closely matched to the sender baud.
JerryR



Joined: 07 Feb 2008
Posts: 167

View user's profile Send private message

PostPosted: Wed Aug 30, 2023 9:30 am     Reply with quote

Where are the tweak registers?
gaugeguy



Joined: 05 Apr 2011
Posts: 303

View user's profile Send private message

PostPosted: Wed Aug 30, 2023 9:37 am     Reply with quote

How does your code currently set the baud rate?
Ttelmah



Joined: 11 Mar 2010
Posts: 19529

View user's profile Send private message

PostPosted: Wed Aug 30, 2023 10:26 am     Reply with quote

Post your clock setup & UART setups.
It is not likely to be a baud problem. If it was it is just as likely to affect
earlier bytes as the last two. So also show how the serial is being handled
(interrupt?).
What is the actual format of the data?. What is it coming from?. How
is it being connected (RS232 / RS485?).
Do you check the UART error bits in your receive? (Add ERRORS to the
RS232 setup, and read RS232_ERRORS after each byte is received.
JerryR



Joined: 07 Feb 2008
Posts: 167

View user's profile Send private message

PostPosted: Wed Aug 30, 2023 4:28 pm     Reply with quote

Hello guys and thanks for your quick replies. Sorry for tardy response, out fighting another fire.

As I mentioned, the product using this code is very mature and I was asked to add another board, connected through a short header, to serial port 3. I agree with Ttelmah that the same baud rate mismatch should affect the earlier bytes as well, but they are un-corrupted. But, all eight bytes are processed in the same manner.

Here's how the serial UART3 is set up:
#use rs232(stream=ETH,baud=57600,xmit=PIN_E7,rcv=PIN_E6,parity=N,bits=8,ERRORS)

Clock setup:
#use delay(clock=25000000)

Handling incoming bytes UART3 (ETH):


Code:

            if(kbhit(ETH))
            {
                ethByte = fgetc(ETH);
               handleEdb((unsigned int8)ethByte);
            }
 

void handleEdb(uint8_t data)
{
    if(inCmdBuf >= USART_RX_BUF_SZ)
    {
        inCmdBuf = 0;
        ciSTATE = READING_HEADER;
    }
    cmdBuf[inCmdBuf++] = data;
    uint16_t ccsum = 0;
    uint16_t i;

    switch(ciState)
    {
        case READING_HEADER:

            if(inCmdBuf == sizeof(cmdHdr_t))
            {
                // check the length.  If the length > 0 then read the body
                // otherwise process the message.
                if(hdr->len == 0)
                {
                    processCmd();
                    inCmdBuf = 0;
                   
                }
                else
                {
                    if(hdr->len > (USART_RX_BUF_SZ - sizeof(cmdHdr_t) - sizeof(uint16_t)))
                    {
                        // length is too long.  bail
                        inCmdBuf = 0;
                        ciState = READING_HEADER;
                    }
                    else
                    {
                        body = (uint8_t*)(hdr+1);
                        ciState = READING_BODY;
                    }
                }
            }

        break;

        case READING_BODY:

            if(inCmdBuf == (sizeof(cmdHdr_t) + hdr->len))
            {
                csum= &cmdBuf[inCmdBuf];
                ciState = READING_CRC;
            }

        break;

        case READING_CRC:

            if(inCmdBuf == (sizeof(cmdHdr_t) + hdr->len + sizeof(uint16_t)))
            {
                i = hdr->len;
                while(i--)
                {
                    ccsum = Fletcher16(*(body++), ccsum);
                }

                if(ccsum == *csum)
               
                {
                    body = (uint8_t*)(hdr+1);
                    processCmd();
                }

                ciState = READING_HEADER;
                inCmdBuf = 0;
            }

        break;
    }
}
temtronic



Joined: 01 Jul 2010
Posts: 9232
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Thu Aug 31, 2023 5:26 am     Reply with quote

wow, I'm really curious about this 'pain'
hard to believe it's a timing issue, if the other UARTS are rock solid...
but 'shifted bits' does say ' timing'... BTDT on very long wires (15 miles...)

as for hardware, if you used a 14,745,600 xtal, the UART timing would be bang on ( 14,745,600 / 256 = 57,600 ). I'm assuming you can't go faster than 25MHz, so 29,xxx,xxx xtal can't be used.

I'm wondering if there's something else delaying the process ??
Maybe you cut a small test program, send known data to UART3 and see what happens ?

You've posted a 'good' head scratcher for sure !!
JerryR



Joined: 07 Feb 2008
Posts: 167

View user's profile Send private message

PostPosted: Thu Aug 31, 2023 6:08 am     Reply with quote

Hi Temtronic!

Yeah, it’s got me stuck right now. Like as it’s been said earlier, why it’s not affecting the earlier bytes is a mystery.

The “new” board that’s being developed uses an Atmel controller, and it’s possible that there’s a timing issue there that my logic analyser ignores. That would explain the other two uarts working well. AND I do know, from talking yesterday with an Engineer who worked with another add on board that he had to hand select the crystal for its Atmel processor. But this board’s transmit routine should be even more uniform, so, again, why only the last two bytes?

I’m going to hook my good scope up to the Atmel board and critically look at the 232 data coming from it. Might not be the receive after all.

Thanks for the added eyes! I’ll keep the group posted.

All the best
temtronic



Joined: 01 Jul 2010
Posts: 9232
Location: Greensville,Ontario

View user's profile Send private message

PostPosted: Thu Aug 31, 2023 7:06 am     Reply with quote

hmmm...
he had to hand select the crystal for its Atmel processor.

as in EACH PCB, he had to do this
or
just 'do the math' to get the optimum xtal for the project

FWIW, in the early days of the 18F46K22, I could link both UARTS in 'series' to a PC and dump hours of data at 1 megabaud without losing a bit of data.

Perhaps use a 'terminal program' as a 'sniffer' instead of the logic analyzer ? I used an 'old' PC ,that had 2 REAL comports (RS-232,9 pins),Win98SE and RealTerm as my 'diagnostic' tool.....

I'll be real interested into WHAT is causing the problem !

Jay
Ttelmah



Joined: 11 Mar 2010
Posts: 19529

View user's profile Send private message

PostPosted: Thu Aug 31, 2023 7:53 am     Reply with quote

I really would suspect something is running out of time in this handling.
25MHz, is only 6.25MIPS. At 57600bps, a byte is 138uSec. So you have
just 868 instructions per byte. Now, assuming that lots of other things
may be happening before the code gets round to the kbhit test again,
I'd be suspicious that if you tested the error byte you may well find
that possibly an overrun error has occurred by the time you get back to
this.
Add a serial interrupt buffer for this. You can do this easily by letting the
compiler generate one for you:

#use rs232(stream=ETH,baud=57600,xmit=PIN_E7,rcv=PIN_E6,parity=N,bits=8,ERRORS, RECEIVE_BUFFER=16)

So long as the global interrupt is enabled for something, the compiler will
automatically add a software 16byte serial interrupt driven receive buffer
for you. Your code can otherwise stay the same.

See if this changes things.
JerryR



Joined: 07 Feb 2008
Posts: 167

View user's profile Send private message

PostPosted: Thu Aug 31, 2023 9:59 am     Reply with quote

Well guys- Critical measurements of the baud rate of the Atmel based board under development shows a bit width of 17.2uS, which corresponds to a baud rate of 58,139.

Interesting observation Ttelmah! I'll check to see if an overrun has occurred as well. I'll also add a buffer as you suggest. I'll also try shutting down other interrupts during reception to see if that improves things. There is a LOT of stuff going on in the processor!

The real problem is that my client doesn't want me to touch the Microchip code unless absolutely necessary. But I'll do what I have to do.

Yes, Temtronics, he had to custom pick a crystal (16 MHz originally, 18.432MHz final pick). I'm also thinking someone else had travelled this road before me. I might put this guy under a spot light and make him talk Evil or Very Mad

More to come... THANKS for y'alls interest.
dyeatman



Joined: 06 Sep 2003
Posts: 1934
Location: Norman, OK

View user's profile Send private message

PostPosted: Thu Aug 31, 2023 12:07 pm     Reply with quote

One other thing, according to the datasheet the PLL can up the 25MHZ clock to 41.667MHZ
which would give more time with minimal s/w changes. Using a buffer
would give even more time.
_________________
Google and Forum Search are some of your best tools!!!!
JerryR



Joined: 07 Feb 2008
Posts: 167

View user's profile Send private message

PostPosted: Thu Aug 31, 2023 12:58 pm     Reply with quote

Another good suggestion dyeatman thank you.
Ttelmah



Joined: 11 Mar 2010
Posts: 19529

View user's profile Send private message

PostPosted: Fri Sep 01, 2023 6:06 am     Reply with quote

OK.

First thing to do is add BRGH1OK to your #USE RS232. The compiler normally
defaults to assuming this is not OK, and setting this will allow the baud rate
to be closer to a genuine 57600.
Then is the Atmel baud rate is 58139. Specify this as the rate to use on the
PIC. It'll actually probably select 58411, which I think is the closest the
PIC can get from your oscillator.
However understand that since bits are sent LSb first, it'd only be the
high bits that would change with a baud rate error. This is why I think
your problem is not actually this.
JerryR



Joined: 07 Feb 2008
Posts: 167

View user's profile Send private message

PostPosted: Fri Sep 01, 2023 9:26 am     Reply with quote

Ttelmah:

Yes, I'm starting to agree with you that timing is the real problem, not baud rate mismatch. Attempted the buffer, which made great sense, but compiler didn't like it because Pin E6 (RX) isn't a native UART receive pin .Mad

I think there is a software derived buffer implemented on one of the two hardware UARTs.

I'm looking to confirm the timing issue, however, by looking for UART errors and making sure other interrupts are not flaking out the latter bytes. Might try a PLL to speed things up to see what effect that might have.

More later...
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Goto page 1, 2  Next
Page 1 of 2

 
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