Jump to content


Photo

Pic18F26K22 Eusart Receive Bug


5 replies to this topic

#1 Sparky1039

Sparky1039

    Regular

  • EstablishedMember
  • Pip
  • 36 posts
  • Location:Colorado USA

Posted 25 November 2016 - 06:11 PM

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.

 



#2 JorgeF

JorgeF

    Super Enthusiast

  • EstablishedMember
  • PipPipPip
  • 273 posts
  • Gender:Male
  • Location:ES @ Europe, third rock from the Sun

Posted 26 November 2016 - 01:51 PM

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



#3 Sparky1039

Sparky1039

    Regular

  • EstablishedMember
  • Pip
  • 36 posts
  • Location:Colorado USA

Posted 26 November 2016 - 08:22 PM

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);
    }
}

Attached Files


Edited by Sparky1039, 27 November 2016 - 08:00 AM.


#4 JorgeF

JorgeF

    Super Enthusiast

  • EstablishedMember
  • PipPipPip
  • 273 posts
  • Gender:Male
  • Location:ES @ Europe, third rock from the Sun

Posted 28 November 2016 - 10:54 PM

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 by JorgeF, 28 November 2016 - 11:01 PM.


#5 Sparky1039

Sparky1039

    Regular

  • EstablishedMember
  • Pip
  • 36 posts
  • Location:Colorado USA

Posted 29 November 2016 - 06:49 PM

// 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


#6 JorgeF

JorgeF

    Super Enthusiast

  • EstablishedMember
  • PipPipPip
  • 273 posts
  • Gender:Male
  • Location:ES @ Europe, third rock from the Sun

Posted 03 December 2016 - 11:59 AM

 

// 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 by JorgeF, 05 December 2016 - 12:42 PM.




Reply to this topic



  


1 user(s) are reading this topic

0 members, 1 guests, 0 anonymous users