|
|
View previous topic :: View next topic |
Author |
Message |
KTrenholm
Joined: 19 Dec 2012 Posts: 43 Location: Connecticut, USA
|
PIC18F24K22 (Rev A1) EUSART bug workaround? [SOLVED] |
Posted: Fri Jan 17, 2014 12:53 pm |
|
|
Hi all,
EDIT:
Forgot the compiler version:
I am on PCWHD 4.132
I'm hoping to get a little bit of advice about a possible workaround for a silicon bug in the A1 revision of the PIC18F24K22 micro.
The bug is the issue with a 1/256 chance of missing the start bit of a serial transmission when BRGH and BRG16 are not both = 1.
(See errata 5.1 in the following document:
http://ww1.microchip.com/downloads/en/DeviceDoc/80512F.pdf)
Naturally this means that my serial receive function is unreliable and misses characters and transmissions fairly frequently.
Is there an easy workaround for this issue that I can implement while keeping the #USE RS232 and fprintf and other serial functions working?
Simply setting the BRGH and BRG16 bits manually locks up serial operations (not a surprise as the baud rate probably gets mangled by me setting the bits). Perhaps there is a workaround that doesn't require me to write all the serial send and receive code manually?
Will distributors be able to provide the latest revision of the silicon if requested? I see no marking on the chip that denotes revision. Seems I can only determine it via reading memory.
The code written for receiving serial transmissions into an array has been used in many of my projects and has proved reliable, so I'm fairly certain my issues are stemming from this bug in the silicon. I'll still post it just in case.
Code: |
#USE RS232 (STREAM=PCCTRL, BAUD=9600, PARITY=N, XMIT=PIN_C6, RCV=PIN_C7, BITS=8, STOP=1)
#INT_RDA
void RDA_isr(void)
{
#USE FAST_IO(A)
#USE FAST_IO(B)
long timeout = 0;
char c;
restart_wdt();
output_toggle(PWR_R_LED);
while (kbhit(PCCTRL) &&(++timeout<50000)) {
//Get String until encounter <CR><LF>
c = fgetc(PCCTRL);
if (c != 13) {
if (c!= 10) {
if(rs232DataByte < BUFFER_DATA_SIZE) {
rs232MsgInBuff[rs232DataByte++] = toupper(c);
}
}
}
else {
//Only copy over complete messages for processing
memcpy(rs232MsgInBuff2,rs232MsgInBuff,BUFFER_DATA_SIZE);
memset(rs232MsgInBuff, '\0', sizeof(rs232MsgInBuff));
rs232DataByte = 0;
}
}
}
|
Thanks in advance for any suggestions. I would like to avoid writing manual serial routines from scratch if possible.
Last edited by KTrenholm on Mon Jan 20, 2014 10:53 am; edited 1 time in total |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Fri Jan 17, 2014 2:53 pm |
|
|
A macro can be written. I will try to do that now.
Yes, you can request a particular silicon revision from Digikey.
At least, I did this successfully in the past. |
|
|
KTrenholm
Joined: 19 Dec 2012 Posts: 43 Location: Connecticut, USA
|
|
Posted: Fri Jan 17, 2014 3:37 pm |
|
|
PCM programmer wrote: | A macro can be written. I will try to do that now.
Yes, you can request a particular silicon revision from Digikey.
At least, I did this successfully in the past. |
Awesome. Thanks for the quick reply.
Pretty sure I've narrowed this down to the silicon errata. The serial bootloader I use has a built in option to use BRGH and BRG16 and when I use the option I get no dropped data and it writes and verifies via RS232 with no problems. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Fri Jan 17, 2014 4:49 pm |
|
|
Here's the macro and a test program, all in one. There are a couple
magic values for the UART registers. The values are the standard values
that the compiler uses for those two registers, and the BRGH is set in TXSTA1.
I tested this program with the #use delay set to 4M and 16M. It produces
the same ASM code as CCS does in compiler vs. 5.016.
Code: |
#include <18F24K22.h>
#fuses INTRC_IO, NOWDT
#use delay(clock=4M)
#use rs232(baud=9600, UART1, ERRORS)
//------------------------------------------
#bit BRG16 = getenv("BIT:BRG16")
#byte SPBRG1 = getenv("SFR:SPBRG1")
#byte SPBRGH1 = getenv("SFR:SPBRGH1")
#byte TXSTA1 = getenv("SFR:TXSTA1")
#byte RCSTA1 = getenv("SFR:RCSTA1")
// This macro runs the UART with BRG16=1 and BRGH=1,
// which is the recommended fix for the baud rate errata
// on the 18F*K22 series PICs. (Ref. Microchip ds80512F.pdf)
// This macro will be automatically substituted by
// the compiler for the built-in function, set_uart_speed().
// Put in the normal #use rs232() statement at the top of
// your program, then call set_uart_speed() near the start
// of main() with your desired baud rate. You should use
// a constant (eg., 9600) as your baud rate parameter.
#define set_uart_speed(baud) \
BRG16 = 1; \
SPBRG1 = make8(((getenv("CLOCK") + (baud *2)) / (baud * 4)) -1, 0); \
SPBRGH1 = make8(((getenv("CLOCK") + (baud *2)) / (baud * 4)) -1, 1); \
TXSTA1 = 0xA6; \
RCSTA1 = 0x90
//========================
void main()
{
set_uart_speed(9600);
while(1);
} |
|
|
|
KTrenholm
Joined: 19 Dec 2012 Posts: 43 Location: Connecticut, USA
|
|
Posted: Mon Jan 20, 2014 10:53 am |
|
|
PCM Programmer you are a boss.
Seems to be working just fine on v4.132.
Thanks so much for the quick help. |
|
|
|
|
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
|