Sparky1039 0 Posted November 25, 2016 Report Share Posted November 25, 2016 I believe I have uncovered a compiler bug with the EUSART receive peripheral on the PIC18F26K22. Working on a larger application I found that my tried and true UART receive library functions were not working properly. However, the transmit processes do work correctly. Thinking I may have made some simple mistake I wrote a smaller test application to validate that my project code wasn't the culprit. This test code exhibited the same problems, lack of receive response. I then ported this test code over to another compiler and it worked perfectly. Analyzing the problem with Proteus VSM the SourceBoost version is not reading the RC1REG register. I see the RC1IF interrupt flag get set but when the code reads the RC1REG receive register I see garbage. On top of this, since it's not reading the register contents the receive interrupt flag never gets auto-cleared. So my code is stuck reading the same garbage bytes (0xAE) forever, locking up the PIC from processing other tasks except for higher priority interrupt processes. When I monitored the test code with Proteus from the other compiler I see proper operation. As a secondary check I also tried this test code on real hardware and the behavior is exactly mirrors Proteus. I haven't studied the ASM output in great detail to maybe see where the problem lay, and honestly don't have time to do it. I need to focus on porting my application over to another compiler so I can get my project completed on time. Hopefully the SB authors can take a look into this area and offer a quick fix saving me a lot of work porting. Quote Link to post Share on other sites
JorgeF 0 Posted November 26, 2016 Report Share Posted November 26, 2016 Hi Well... I'm not one of the authors, but... Can you show us show code, maybe from one of the small test apps you made. Best regards Jorge Quote Link to post Share on other sites
Sparky1039 0 Posted November 26, 2016 Author Report Share Posted November 26, 2016 (edited) The problem is my UART functions are a compiled library so there isn't much to see. I have been using this library for years without issue on many different 8-bit PICs (16F and 18F). It's only with the recent use of the 26K22 have I encountered this problem. I've ported my project over to Mchip XC8 and everything is working fine so I don't have high incentive to spend much effort on debugging this problem. However when time permits I may put together a special simplified test code block example. UPDATE: test code below. // UART receive bug test code. // Target: PIC18F26K22 // SourceBoost C V7.30 #include <system.h> #pragma CLOCK_FREQ 12000000 #pragma OPTIMIZE "1" #pragma config FOSC = HSMP, FCMEN = OFF, IESO = OFF, PLLCFG = OFF, PRICLKEN = ON #pragma config BOREN = OFF, BORV = 250, PWRTEN = ON #pragma config WDTEN = OFF, WDTPS = 256, PBADEN = OFF #pragma config MCLRE = EXTMCLR, HFOFST = ON #pragma config STVREN = ON, LVP = OFF, XINST = OFF #pragma config DEBUG = OFF, CCP2MX = PORTC1, CCP3MX = PORTB5 char tempByte = 0; void main () { trisa = 0x00; trisb = 0x00; trisc = 0x90; ansela = 0x00; anselb = 0x00; anselc = 0x00; pie1.RC1IE = 0; pir1.RC1IF = 0; baudcon1.BRG16 = 1; spbrg = 25; // 115200 baud spbrgh = 0; rcsta = 0x90; txsta = 0x24; while (1) { while (!pir1.RC1IF) asm nop; tempByte = RC1REG; delay_us (20); txreg1 = tempByte; // echo back char delay_us (20); } } SB UART Test.zip Edited November 27, 2016 by Sparky1039 Quote Link to post Share on other sites
JorgeF 0 Posted November 28, 2016 Report Share Posted November 28, 2016 (edited) Hi I spotted at least one bug in the posted code that is enought to mess things. You are loading "tempByte" with the address of the receive register and not with its contents, and echoing back that value (truncated to the lower 8 bits) instead of the received character. In the include file "pic18f26k22.h", "RC1REG" is defined as a constant with the value "0xfae", the address of the receive register for EUSART1. The register itself is accessed with "rc1reg". Extracted from "...\program files\sourceboost\include\pic18f26k22.h" #define RC1REG 0x00000FAE ....... volatile char rc1reg @RC1REG; The SB convention is uppercase for numeric constants (addresses) and lowercase for the variables that access the registers at those addresses. Just like with "pir1","ansela", "anselb",....., and so on (Boost C user manual). Besides that, by not reading the contents of the receive register RC1IF never gets cleared (can't be cleared in code only by reading the receive register - section 16.1.2.4 @ page 265 of the datasheet), so the PIC will send back an endless string of garbagge (0xae) after receiving the first character. Another thing to keep an eye on. The PIC18F26K22 errata shows 2 silicon bugs on the USART (section 6 @ page 5). BTW, you don't need the 20 uS delay, the transmit and receive sections of the EUSART are independent, so there is no risk of chocking it by overlapping operation. HIH Best regards Jorge Another thing to keep an eye on. The PIC18F26K22 errata shows 2 silicon bugs on the USART (section 6 @ page 5). Edited November 28, 2016 by JorgeF Quote Link to post Share on other sites
Sparky1039 0 Posted November 29, 2016 Author Report Share Posted November 29, 2016 // In the include file "pic18f26k22.h", "RC1REG" is defined as a constant with the value "0xfae", the address of the receive register for EUSART1. The register itself is accessed with "rc1reg". Yes, you are right about the RC1REG identifier. I had it upper case and as you pointed out it needs to be lower case. This is was an artifact of porting back and forth between SB and XC8 and hence the illusion of being a bug. I'm surprised SB didn't flag this as a warning. If anything I wish there were more consistency by compiler makers on hardware register naming conventions. Either way good catch on this. The clue was right there in front of me when the received byte was 0xAE. If I had only put the register address and the truncated result together I could have saved myself a lot of grief and delay. // BTW, you don't need the 20 uS delay, the transmit and receive sections of the EUSART are independent, so there is no risk of chocking it by overlapping operation. Yes I know. I added the delay and extra variable for debugging purposes only so I can set a break point more easily vs. through a watch window conditional in order to view register and variable contents. // Another thing to keep an eye on. The PIC18F26K22 errata shows 2 silicon bugs on the USART (section 6 @ page 5). I am aware of these and currently using A4 silicon with no problems. Thanks for the help Quote Link to post Share on other sites
JorgeF 0 Posted December 3, 2016 Report Share Posted December 3, 2016 (edited) // In the include file "pic18f26k22.h", "RC1REG" is defined as a constant with the value "0xfae", the address of the receive register for EUSART1. The register itself is accessed with "rc1reg". Yes, you are right about the RC1REG identifier. I had it upper case and as you pointed out it needs to be lower case. This is was an artifact of porting back and forth between SB and XC8 and hence the illusion of being a bug. I'm surprised SB didn't flag this as a warning. If anything I wish there were more consistency by compiler makers on hardware register naming conventions. Either way good catch on this. The clue was right there in front of me when the received byte was 0xAE. If I had only put the register address and the truncated result together I could have saved myself a lot of grief and delay. // BTW, you don't need the 20 uS delay, the transmit and receive sections of the EUSART are independent, so there is no risk of chocking it by overlapping operation. Yes I know. I added the delay and extra variable for debugging purposes only so I can set a break point more easily vs. through a watch window conditional in order to view register and variable contents. // Another thing to keep an eye on. The PIC18F26K22 errata shows 2 silicon bugs on the USART (section 6 @ page 5). I am aware of these and currently using A4 silicon with no problems. Thanks for the help Hi Yes, I've BTDT, and still do it from time to time. But I tend to agree with the SB approach. One of the least disputed "de facto rules" of code stiling is that full uppercase names are for constants. This rule was already out there when I started to learn programming, more than 35 years ago. And I never saw it discussed on anything I've read about code stilling and its evolution since then. But some "enlightened brain" in Microchip decided that the names of the SFRs should match the way they are written in the datasheet, a kind of an "housewife approach" that, in M$ theory, would make it easier for the user. Like any big company they act like they own the world and the truth, and we get stuck with their silly ways. As for flagging it with a warning, or better, not flagging it, its perfectly correct, besides beeing an error in this specific situiation (program logic), its not an error in "C", neither syntatic or semantic, its simply an assignement of a constant value to a variable wich is perfectly legal. EDIT: Typos corrections. Just my 2 cents... Best regards Jorge Edited December 5, 2016 by JorgeF Quote Link to post Share on other sites
Recommended Posts
Join the conversation
You are posting as a guest. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.