• AVR Freaks

Hot!Strange Software Reset Behavior on PIC24EP512GU810 using LPRC

Author
dkark
New Member
  • Total Posts : 10
  • Reward points : 0
  • Joined: 2015/10/26 06:24:52
  • Location: 0
  • Status: offline
2021/01/23 17:35:02 (permalink)
0

Strange Software Reset Behavior on PIC24EP512GU810 using LPRC

I am adding a "very low speed" mode to my PIC24 which has been operating the main application for years, and I am seeing very strange software reset behavior when using LPRC as a main clock (to continuously run a long time doing some periodic housekeeping).
 
If I do a software reset without modifying the oscillators (using asm("reset")) I get the expected 0x43 RCON code when entering main(). When I switch to LPRC clock and reset, I get 0xC3, and when I reset the oscillator to it's primary speed and reset, I get 0x03. ox03 is problematic because I need to differentiate between power-on reset, and return from slow mode software reset. What's strange is even when I go back to the main oscillator configuration, I don't get the same results the second time as the first time.
 
The power supply is rock solid through these resets.
 
Looking for any hints or if anyone has any known bugs or workarounds:
 
Here's the code, run and reset at 3 different places (with the restart RCON codes in comments)

// Still running on main oscillator from ConfigureOscillator    
//    asm ("reset"); // Restarts the device (RCON code received 0x43))
    
    ConfigureOscillatorLPRC();
#undef FCY
#define FCY (32768/2) // Reset the frequency so the delay macros work below this line
    
    __delay_ms(100);
    // asm ("reset"); // Restart the device (RCON code received 0xc3)
    
#undef FCY
#define FCY             SYS_FREQ/2 // 60 MIPS at 120 MHz
    ConfigureOscillator();  // Restore fast oscillator
    __delay_ms(100);
    asm("reset"); // Restart the device (RCON code received 0x03)

 
 
And here's the Oscillator configuration routines:

void ConfigureOscillator(void)
{

        _PLLPRE = 0;  // 6MHZ/2 = 3MHZz
        _PLLDIV = 78; // * 80 (78+2) = 240MHz
        _PLLPOST = 0; // / 2 = 120 MHz (60 MIPS)

        __builtin_write_OSCCONH(0x03); // Net new Clock Source to PLL
        __builtin_write_OSCCONL(0x01);  /* Start clock switching */

        while(OSCCONbits.COSC != 0x3);
        while(OSCCONbits.LOCK != 1);

        // Configuring the auxiliary PLL, since the primary
        // oscillator provides the source clock to the auxiliary
        // PLL, the auxiliary oscillator is disabled. Note that
        // the AUX PLL is enabled. The input 6MHz clock is divided
        // by 2, multiplied by 24 and then divided by 1. Wait till
        // the AUX PLL locks.

        // 6MHz / 2 (pre) * 16 (M) / 1 (post) = 48 MHz
        
        ACLKCON3bits.AOSCMD = 0; // Discable the Aux Xtal OSC
        ACLKCON3bits.SELACLK = 1; // Aux clk comes from Aux PLL
        ACLKCON3bits.ASRCSEL = 1; // Prmary Oscilator is SRC for Aux PLL
        ACLKCON3bits.FRCSEL = 0; // Not using Fast RC for clock
        ACLKCON3bits.APLLPRE = 1; // Divide input Osc by 2 (6MHz->3MHz)
        ACLKDIV3 = 0x1;  // Multiply by 16 (3 * 16 = 48MHz)
        ACLKCON3bits.APLLPOST = 7; // Divide 48 MHz PLL OUtput by 1 for 48 MHz

        ACLKCON3bits.ENAPLL = 1;
        while(ACLKCON3bits.APLLCK != 1);
        
}

void ConfigureOscillatorLPRC(void)
{
        /* Disable Watch Dog Timer */
        RCONbits.SWDTEN = 0;
        
        ACLKCON3bits.ENAPLL = 0; // Disable the auxiliary PLL
        
        __builtin_write_OSCCONH(0x05); // Net new Clock Source to LPRC
        __builtin_write_OSCCONL(0x01);  /* Start clock switching */

        while(OSCCONbits.COSC != 0x05);

}


 
 
post edited by dkark - 2021/01/24 05:29:01
#1

3 Replies Related Threads

    dkark
    New Member
    • Total Posts : 10
    • Reward points : 0
    • Joined: 2015/10/26 06:24:52
    • Location: 0
    • Status: offline
    Re: Strange Software Reset Behavior on PIC24EP512GU810 using LPRC 2021/01/23 21:21:53 (permalink)
    0
    I'm interested if anyone else has seen issues with the RCON return value, but I do have a workaround. I'm using a "persistent" variable to set a signature value into it before exiting the low power section of code. I use a asm("goto __reset") to restart the unit. When it restarts I check for the 32 bit signature value to know it came from the low power mode, versus some other random value it would see if it were actually powered off.
    #2
    NorthGuy
    Super Member
    • Total Posts : 6518
    • Reward points : 0
    • Joined: 2014/02/23 14:23:23
    • Location: Northern Canada
    • Status: offline
    Re: Strange Software Reset Behavior on PIC24EP512GU810 using LPRC 2021/01/23 22:05:37 (permalink)
    5 (1)
    Few considerations:
     
    asm("goto __reset")

     
    simply jumps to 0 and shouldn't change RCON.
     
    asm("reset")

     
    is a real reset and should set the SWR bit.
     
    RCON never clears itself. It's up to you to clear it and make sure the records of past resets are erased. Otherwise, you'll always get POR and BOR, and possibly other remnants.
    #3
    dkark
    New Member
    • Total Posts : 10
    • Reward points : 0
    • Joined: 2015/10/26 06:24:52
    • Location: 0
    • Status: offline
    Re: Strange Software Reset Behavior on PIC24EP512GU810 using LPRC 2021/01/24 05:19:31 (permalink)
    0
    After further research, it looks like you can't switch from LPRC mode straight back into Xtal PLL mode. It really wasn't hitting the "goto __reset" instruction in the example, It seems I was getting a clock failure reset which showed as a POR/BOR reset. When I went from LPRC mode to pure Xtal Mode (No PLL), it continued running to the reset instruction, and is now carrying the SWR flag into RCON. 
    post edited by dkark - 2021/01/24 07:28:09
    #4
    Jump to:
    © 2021 APG vNext Commercial Version 4.5