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

dsPIC UART error recovery

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
AlastairM



Joined: 28 Apr 2008
Posts: 36

View user's profile Send private message

dsPIC UART error recovery
PostPosted: Wed Mar 04, 2026 3:41 am     Reply with quote

dsPIC33CH128MP202 dual core (this code is on the master)
compiler 5.123
sorry! code rather complex so here are the relevant bits snipped out:
Code:

#include <33CH128MP202.h>
#use delay(internal=20MHz)

#define MODBUS_SERIAL_RX_PIN PIN_B15
#define MODBUS_SERIAL_TX_PIN PIN_B14
#define MODBUS_SERIAL_BAUD 9600
#define MODBUS_SERIAL_STOP_BITS  1
#define MODBUS_PARITY "NONE"

#pin_select U1TX=MODBUS_SERIAL_TX_PIN
#pin_select U1RX=MODBUS_SERIAL_RX_PIN
#use rs232(baud=MODBUS_SERIAL_BAUD, UART1, bits=8, stop=MODBUS_SERIAL_STOP_BITS, parity=N, stream=MODBUS_SERIAL, errors)

The incoming data is read in interrupt INT_RDA and works perfectly for hours of testing. Unless the power is cycled and occasionally the UART dies!
The Modbus serial port is connected to a WiFi module which at power turn on sends some debug info to the PIC which, I think, occasionally kills the UART (completely fixed by a _MCLR_ reset)
My workaround is to delay the WiFi module from sending serial data at turn on and minimise the data sent.
But my main query is why isn't the UART1 error state fixed by a getc() like it should be with ERRORS switch utilised in the #USE RS232?
Are there any other ways the UART1 can be temporarily killed? (there is a second UART for debug so I can see that the program is running as intended but the INT_RDA isn't triggered. (I can see incoming data on the 'scope)
What error bits / debugging would be best to test my hypothesis of why it's not working? - I've run out of ideas!
Thanks
Alastair
newguy



Joined: 24 Jun 2004
Posts: 1930

View user's profile Send private message

PostPosted: Wed Mar 04, 2026 5:23 pm     Reply with quote

It's been a while since I looked into the issue of UART error conditions and a great deal has been lost to the fog of time but I do remember that in the end I was grateful that CCS will handle these things for me. From what I recall clearing UART error conditions wasn't as straightforward as I thought it was but the processor's data sheet will help guide you.

Have you read the relevant UART status/control registers and examined/printed them when running normally and when the lockup occurs? I've downloaded the data sheet for the processor and there are a number of bits in various registers that seem to be asserted when various error conditions arise. If you know the specific errors, clearing them should be rather straightforward.

The most straightforward brute force approach would be to use the processor's PMD (peripheral module disable) to kill the UART's power entirely, then re-enable and reconfigure it. I'd consider this to be your last resort though; you should be able to monitor the UART's status registers and be able to remedy the problem without resorting to this extreme. Indeed, your observation that a /MCLR reset restores operation would point toward a register somehow getting loaded with an incorrect value under certain hard to duplicate conditions.
AlastairM



Joined: 28 Apr 2008
Posts: 36

View user's profile Send private message

PostPosted: Wed Mar 04, 2026 6:05 pm     Reply with quote

Hi, thanks for the reply.
I should probably just stop the external module from streaming data so soon after turn on but it's easier to clear the error at the dsPIC end for now...

When the fault occurs FERR and OERR are set in U1STA (23C).
OERR, I think, is the flag which means the UART has stalled.
as a quick fix I look for OERR to be set and then in the main loop read characters until it clears. Once cleared the interrupt fires again and everything works as expected Very Happy
Code:

if(OERR) 
{
   fprintf(MASTER_RS232,"\r\nError!");
   while(kbhit(MODBUS_SERIAL))
   {
      fgetc(MODBUS_SERIAL);
      fprintf(MASTER_RS232,"\r\nClearing error!");
      delay_ms(200);
   }
}

It must be a race condition as the #USE RS232 command sets up the UART while characters are being received from the external WiFi module and kills it before the Rx interrupt is set up and able to read the characters. After this point the interrupt doesn't fire and fgetc() in the interrupt routine doesn't get called and so can't clear the fault.
The above code reads 7 times and then everything works again. I think the buffer is 4 deep so I'm not sure why it reads so many times (the WiFi module is idle at this point)
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
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