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

PIC24FJ128GA204 reset
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
georpo



Joined: 18 Nov 2008
Posts: 281
Location: Athens, Greece.

View user's profile Send private message

PIC24FJ128GA204 reset
PostPosted: Thu Oct 29, 2020 12:21 am     Reply with quote

Hello,
I am using the PIC24FJ128GA204 on a battery operated device with e-paper display. When the main task of the device is finished, I want to reduce the cpu clock to save some energy while the display updates and the PIC is just waiting.
Below you can see the fuses:
Code:

#build (stack=1024)

#include <24FJ128GA204.h>

#fuses NOWDT,NODEBUG,NOPROTECT,NOPR,FRC_PLL,OSCIO,CKSFSM

#define CPUCLOCK 16000000

#use delay(clock=CPUCLOCK,int)


When I want to lower the frequency I call the function below:
Code:

void SlowDown(){
   setup_oscillator(OSC_INTERNAL,1000000);
   delay_us(100);
   U1BRG=((1000000/2)/(4*9600))-1;
}


The above works and the power consumption is much lower but occasionally this functions resets the PIC.

Any thoughts?
_________________
George.
Ttelmah



Joined: 11 Mar 2010
Posts: 19515

View user's profile Send private message

PostPosted: Thu Oct 29, 2020 2:23 am     Reply with quote

The way to set the UART baud rate is to use:
Code:

#bit OERR=getenv("BIT:OERR")
#bit FERR=getenv("BIT:FERR")

void SlowDown(){
   int temp;
   setup_oscillator(OSC_INTERNAL,1000000);
   delay_us(100);
   //U1BRG=((1000000/2)/(4*9600))-1;
   while (kbhit(YOURSTREAMNAME)) //throw any grbage received here
   {
       temp=fgetc(YOURSTREAMNAME);
       OERR=0;
       FERR=0;
   }
   set_uart_speed(9600,YOURSTREAMNAME,1000000);
}

Obviously with 'YOURSTREAMNAME' set to match your UART.
There is a potential issue if any data is received after the oscillator
speed is changed but before the new UART speed is selected, with
a framing error being triggered.
I'd have expected a problem to be more likely when changing back to the
high speed, since the PLL does take some time to synchronise in this
direction.
What I post shows how the UART speed should be changed, and how to
flush any UART errors if something arrives during the change.
Your RX interrupt needs to be disabled before calling the function to
change speed.
georpo



Joined: 18 Nov 2008
Posts: 281
Location: Athens, Greece.

View user's profile Send private message

PostPosted: Thu Oct 29, 2020 2:42 am     Reply with quote

The UART is used only for TX for sending debug messages to the PC.
So I do not receive anything.

After changing to low freq and updating the display the device sleeps so there is no changing back to the high speed.

There is no streamname. My tx function is:
Code:

void TX232 (unsigned char x){   
   while(U1TXBF);  //wait for TX buffer to empty
   U1TXREG=x;   // transmit
}

printf(TX232,"Hello");



You think that the UART resets the PIC?
I could comment out the change UART speed and see how it goes.
_________________
George.
Ttelmah



Joined: 11 Mar 2010
Posts: 19515

View user's profile Send private message

PostPosted: Thu Oct 29, 2020 3:09 am     Reply with quote

Is the UART RX line 'floating'?. If so it could be picking up something.
General rule for anything involving 'low power', is that no line should
ever be left floating. All lines should either be driven by the PIC, or
pulled up/down external to the chip (up is the idle state for RS232,
so up preferably for the RX).
When you switch down to low power, does anything else happen?.
Are you turning things off etc?.
Personally, rather than delaying for 100mSec, I'd actually loop waiting
for the LOCK bit from the oscillator.So:
Code:

#bit LOCK=getenv("BIT:LOCK")

   //then when you change speed
   while (LOCK==0)
      delay_cycles(10); //wait for oscillator to switch
georpo



Joined: 18 Nov 2008
Posts: 281
Location: Athens, Greece.

View user's profile Send private message

PostPosted: Thu Oct 29, 2020 3:30 am     Reply with quote

I have not remapped the U1RX pin to a physical pin.
The device has a complex task of receiving packets through the AT86RF212B, store data to external ram and then update the display.
If anything was wrong I would have noticed so far.
Only after changing to low speed with my function then occasionally it resets the PIC.

I send out a message to the PC terminal before calling the function and another message after returning from the function.
Also there is a "Wake" message to the PC when the device wakes up.

So for many times it works OK but sometimes I get the "before" message and then it resets and I get the "wake" message.

When I stopped calling the SlowDown function everything is good.
After the SlowDown I do not turn of anything. Just waiting for the display to finish by checking the busy pin and then put the PIC to SLEEP.

Very good point about the waiting for the LOCK bit.
Also I do not wait for 100mS. It is 100uS.
Could this reset the PIC?
_________________
George.
Ttelmah



Joined: 11 Mar 2010
Posts: 19515

View user's profile Send private message

PostPosted: Thu Oct 29, 2020 3:43 am     Reply with quote

Not mapping it to a pin, means it will be floating internally. Connected to
RPI31, which has no physical connection. Now, since the idle state for the
UART, is a '1' this means the receive will be continually receiving
characters. Shouldn't 'matter', but when you are looking for the cause
of an oddity, everything should be considered as a potential problem.
georpo



Joined: 18 Nov 2008
Posts: 281
Location: Athens, Greece.

View user's profile Send private message

PostPosted: Thu Oct 29, 2020 3:50 am     Reply with quote

I am afraid all oddities happen to me Rolling Eyes
I could even disable the UART completely. It is only used to send debug messages to the PC. Not for the device operation.
Maybe set up an RX interrupt and read the RXREG in the ISR?
This should take care of " receiving characters"
_________________
George.
Ttelmah



Joined: 11 Mar 2010
Posts: 19515

View user's profile Send private message

PostPosted: Thu Oct 29, 2020 5:08 am     Reply with quote

Except you would still have the potential for errors when the clock rate
changes. The automatic error handling present on the smaller PIC's
doesn't function the same on the PIC24/30/33.
Try with it disabled. If the problem remains, then you have ruled out one
this. Have you tried waiting for the clock to lock?.
georpo



Joined: 18 Nov 2008
Posts: 281
Location: Athens, Greece.

View user's profile Send private message

PostPosted: Thu Oct 29, 2020 5:15 am     Reply with quote

I have not yet tried waiting for the clock to lock. I will try it later in the afternoon.
If it does not solve the problem I will try with UART disabled.

Once again Ttelmah thanks for your time. I will post the results here.

Edit:

The "waiting for the clock to lock" did not change anything. It is a good tactic so I keep it anyway. I will try disabling the UART and modify my TX function to return; and do nothing.
_________________
George.
Ttelmah



Joined: 11 Mar 2010
Posts: 19515

View user's profile Send private message

PostPosted: Thu Oct 29, 2020 7:03 am     Reply with quote

Is there anything else done between the 'before' message and the function?.
Is there anything else done between the function and the 'after' message?.
georpo



Joined: 18 Nov 2008
Posts: 281
Location: Athens, Greece.

View user's profile Send private message

PostPosted: Thu Oct 29, 2020 7:31 am     Reply with quote

No, I am sure.

Code:

void TX232 (unsigned char x){   
   while(U1TXBF);  //wait for TX buffer to empty
   U1TXREG=x;   // transmit
}

void SlowDown(){
   setup_oscillator(OSC_INTERNAL,1000000);
    while (LOCK==0) delay_cycles(10);
   delay_us(100);
   U1BRG=((1000000/2)/(4*UARTBAUD))-1;
   printf(TX232,"\n\rClock:1MHz");
}


Code:

printf(TX232,"\r\nBefore");
SlowDown();
printf(TX232,"\r\nAfter");


Now I will disable UART completely.
_________________
George.
jeremiah



Joined: 20 Jul 2010
Posts: 1349

View user's profile Send private message

PostPosted: Thu Oct 29, 2020 10:03 am     Reply with quote

Out of curiosity have you checked the errata document to see if this is a known bug? Some chips have issues with the oscillator system that cause resets.
Ttelmah



Joined: 11 Mar 2010
Posts: 19515

View user's profile Send private message

PostPosted: Thu Oct 29, 2020 10:30 am     Reply with quote

I had a look. Couldn't see one.

Like you, it is one of the first things I think of when an 'inexplicable' issue
appears... Very Happy
georpo



Joined: 18 Nov 2008
Posts: 281
Location: Athens, Greece.

View user's profile Send private message

PostPosted: Thu Oct 29, 2020 11:40 am     Reply with quote

I disabled the UART. No change.

Now I am running a loop:
Code:

   printf(TX232,"\n\rWake.");
   delay_ms(2000);
   SlowDown();
   delay_ms(120);
   printf(TX232,"\n\rReset.");
   delay_ms(100);   
   reset_cpu();

So the proper sequence is :
Code:

Wake.
Clock:1MHz
Reset.


If for example I see:
Code:

Wake.
Clock:1MHz
Wake.


Then the PIC reset after the clock change.

I also notice that the delay_ms() function takes too long because it is calculating based on 16MHz and not 1MHz.
Maybe this is the problem? How can I change this?
_________________
George.
georpo



Joined: 18 Nov 2008
Posts: 281
Location: Athens, Greece.

View user's profile Send private message

PostPosted: Thu Oct 29, 2020 11:58 am     Reply with quote

And I caught it.

From Putty terminal during normal operation:
Code:

Wake.
Clock:1MHz
Reset.
Wake.
Clock:1MHz
Reset.
Wake.
Clock:1MHz
Reset.
Wake.
Clock:1MHz
Reset.
Wake.
Clock:1MHz
Reset.
Wake.
Clock:1MHz
Reset.


And the reset:

Code:

Wake.
Clo!
Wake.
Clock:1MHz
Reset.


Could not even finish the transmission of "Clock:1MHz"
_________________
George.
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