View previous topic :: View next topic |
Author |
Message |
Tom-H-PIC
Joined: 08 Sep 2003 Posts: 105 Location: New Castle, DE
|
Fail-Safe Clock Monitor How Too? |
Posted: Fri Mar 26, 2021 8:08 am |
|
|
Hello all
I have searched the forum and googled this a number of times with very poor results.
So I'm looking for some information and help.
Working with DSPIC33EP512GP506 and I have the current compiler but this project is using 5.072.
This project would benefit from the “Fail-Safe Clock Monitor”.
So if I understand correctly the fail-safe clock monitor will keep the DSP executing code when the main oscillator fails.
So if I understand this correctly, if the main oscillator crystal gets shorted or fails due to shock, etc., the fail-safe clock monitor will switch the system clock to the fast RC oscillator and at the same time generate an interrupt?
I have not spent a lot of time in the lab on this yet. But I did try and see if it worked the way I have the DSP configured now, but no, it does not. And that was the expected outcome but just testing.
So currently the config is as follows:
Fuses
Code: |
#FUSES WDT //Watch Dog Timer
#FUSES CKSFSM //Clock Switching is enabled, fail Safe clock monitor is enabled
#FUSES NOJTAG //JTAG disabled
|
Startup code:
Code: | setup_oscillator( OSC_CRYSTAL, 140000000, 16000000); |
So I assume that I have to have a fuse for the FRC_PLL.
Then how do I set the “setup_oscillator” call and do I have to have two “setup_oscillator” like below?
Code: |
setup_oscillator( OSC_CRYSTAL, 140000000, 16000000);
setup_oscillator(OSC_INTERNAL, 140000000); |
And last I assume the oscillator switch is automatic if the main crystal fails?
Thank you all in advance for the help! |
|
![](templates/subSilver/images/spacer.gif) |
Ttelmah
Joined: 11 Mar 2010 Posts: 19369
|
|
Posted: Fri Mar 26, 2021 8:28 am |
|
|
Yes, the clock switching is automatic.
But when FSCM operates, you have just one speed. 7.37MHz. No PLL etc.
The system runs at the internal oscillator frequency _only_.
It is designed for 'recovery' (so perhaps a friendly shutdown, and warning
message), not normal operation.
You can detect FSCM, by having an oscillator fail trap interrupt. Since this
is a 'trap' it has priority over any other interrupt etc..
In this you can have a use delay statement to tell the code that it is now
running at 7.37MHz. |
|
![](templates/subSilver/images/spacer.gif) |
Tom-H-PIC
Joined: 08 Sep 2003 Posts: 105 Location: New Castle, DE
|
|
Posted: Fri Mar 26, 2021 8:37 am |
|
|
So if I understand you correct.
The only fuse I need is the
Code: | #FUSES CKSFSM //Clock Switching is enabled, fail Safe clock monitor is enabled |
And I do not need the second setup oscillator line at all?
So it should have work for me when I was in the lab. I guess I will need to go back and retry after adding the trap. |
|
![](templates/subSilver/images/spacer.gif) |
Tom-H-PIC
Joined: 08 Sep 2003 Posts: 105 Location: New Castle, DE
|
|
Posted: Wed Apr 28, 2021 12:13 pm |
|
|
Hello all
I'm back to this project after being side tracked.
Ok so I have the code created and I'm up to testing it.
The question how do I simulate a clock failure of the main oscillator?
The board I'm using for development is an older revision of a production board.
So all the parts are soldered in place.
I tried shorting the two oscillator pins to each other but that did not trigger an oscillator failure trap.
I tried adding a capacitor across the pins oscillator pins and this stop all execution and the processor reset.
So has someone done or simulate an oscillator failure?
If so how was it done?
It maybe my code is not working but I don’t think that is the issues right now.
Well I may be missing the boat all together also.
Any comments or help would be greatly appreciated. |
|
![](templates/subSilver/images/spacer.gif) |
bkamen
Joined: 07 Jan 2004 Posts: 1611 Location: Central Illinois, USA
|
|
Posted: Wed Apr 28, 2021 1:01 pm |
|
|
If I were doing it - I'd somehow socket the crystal/oscillator and just pull it.
I realize some crystals and oscillators are reaaaallly tiny these days...
so maybe leaving the crystal/oscillator unpopulated and then just running a coax to a signal generator would be the next option. _________________ Dazed and confused? I don't think so. Just "plain lost" will do. :D |
|
![](templates/subSilver/images/spacer.gif) |
temtronic
Joined: 01 Jul 2010 Posts: 9174 Location: Greensville,Ontario
|
|
Posted: Wed Apr 28, 2021 2:43 pm |
|
|
I'd have thought shorting one pin of the two OSC XTAL pins to GROUND would 'kill' the clock ??? |
|
![](templates/subSilver/images/spacer.gif) |
bkamen
Joined: 07 Jan 2004 Posts: 1611 Location: Central Illinois, USA
|
|
Posted: Wed Apr 28, 2021 2:50 pm |
|
|
temtronic wrote: | I'd have thought shorting one pin of the two OSC XTAL pins to GROUND would 'kill' the clock ??? |
Well, the OSC Input -- but I wouldn't do the output side unless I knew for sure doing so didn't damage the driver. _________________ Dazed and confused? I don't think so. Just "plain lost" will do. :D |
|
![](templates/subSilver/images/spacer.gif) |
Tom-H-PIC
Joined: 08 Sep 2003 Posts: 105 Location: New Castle, DE
|
|
Posted: Mon May 03, 2021 12:05 pm |
|
|
Hello all
This is where I am now
So shorting the crystal inputs to anything totally stop the processor.
Or the oscillator is not switching over. (This appears to be the situation).
I have now removed the crystal from the board and have it taped on so I can remove it at any time for testing osc failure.
But the results with the crystal removed is the processor stops not a thing happens.
Reinstall the crystal and it’s off and running again.
So I have look at the fuses and configuration word 6 that I thing is FOSC = 0xFF3A.
This is telling me that “Clock switching is enabled, Fail-Safe Clock Monitor is enabled”.
So I'm not see what I'm missing?
Below is the small test program that I have been using for testing.
And again any comments or help would be greatly appreciated!
main.c
Code: |
#include <04302021-0010 Rev - osc testing main.h>
#INT_TIMER1
void timer1_isr(void)
{
one_ms = TRUE;
}
#INT_OSCFAIL
void oscfail_isr(void)
{
user1 = 1;
}
void main()
{
/*******************************************************************************
* Initialize Oscillator and turn off ADC pins
*******************************************************************************/
setup_oscillator( OSC_CRYSTAL, 140000000, 16000000);
setup_wdt (WDT_1S);
setup_wdt(WDT_OFF);
/*******************************************************************************
* Initialize Data Direction Registers
*******************************************************************************/
//Set Data direction register
set_tris_a(0b0000001000000001); // Port A set 1 = input 0 = output
set_tris_b(0b0000000000000010); // Port B set 1 = input 0 = output
set_tris_c(0b0000000000000000); // Port C set 1 = input 0 = output
set_tris_d(0b0000000000000000); // Port D set 1 = input 0 = output
set_tris_e(0b0000000000000000); // Port E set 1 = input 0 = output
set_tris_f(0b0000000000000001); // Port F set 1 = input 0 = output
set_tris_g(0b0000000011000000); // Port G set 1 = input 0 = output
/*******************************************************************************
* Initialize Timers
*******************************************************************************/
//Timer clock (Fp or Fcy) is 70mhz
setup_timer1(TMR_INTERNAL |TMR_DIV_BY_64, 1093); //PWM out for dimming 500Hz = 2187 1k = 1093
/*******************************************************************************
* Initialize Interrupts
*******************************************************************************/
enable_interrupts(INT_TIMER1);
enable_interrupts(INTR_GLOBAL);
while(TRUE)
{
/*******************************************************************************
* TASK SCHEDULER this is a 1 mil second timer / scheduler
*******************************************************************************/
if (one_ms){ //Reset the mil second flag from timer 2
one_ms = FALSE;
restart_wdt();
if (--heart_Timer == 0){
if (heart) { //Heartbeat LED is on turn off
heart_Timer = heart_off_ms; //Set heart off time
heart = 0;
}
else { //Heartbeat LED is off turn on
heart_Timer = heart_on_ms; //Set heart on time
heart = 1; //Turns on HeartBeat LED
}
}
//can add code here for scheduler
}
}
}
|
header
Code: |
#include <33EP512GP506.h>
#device ICSP=1
//#device ICD=TRUE
//#use delay(clock=140000000,crystal=16000000)
#use delay(clock=140000000)
#FUSES NOWDT //No Watch Dog Timer
#FUSES CKSFSM //Clock Switching is enabled, fail Safe clock monitor is enabled
#bit heart = 0x0E34.8 //D8 PIN_C0 heart bet, port C bit 0 #bit heart = 0x0E24.0
#define heart_off_ms 700 //The number of times that the 1ms timer interrupts for 1000ms heartbeat
#define heart_on_ms 300 //The on Ms for the heart LED
#bit user1 = 0x0E34.6 //D6 PIN_D6 LED High = ON, vailed on Rev D and below
int1 one_ms;
int16 heart_Timer = heart_off_ms,Test_1;
|
|
|
![](templates/subSilver/images/spacer.gif) |
newguy
Joined: 24 Jun 2004 Posts: 1903
|
|
Posted: Mon May 03, 2021 4:03 pm |
|
|
Don't you need a backup oscillator running (one of the internal variants) in order for the processor to be able to recognize that the main oscillator failed and then switch to the (already running) backup? |
|
![](templates/subSilver/images/spacer.gif) |
temtronic
Joined: 01 Jul 2010 Posts: 9174 Location: Greensville,Ontario
|
|
Posted: Mon May 03, 2021 4:20 pm |
|
|
hmmm....
Not necessarily.... could be done with a simple WDT circuit.
As long as the main clock 'feeds' the WDT (a retriggerable one shot - 74122 ?), the WDT disables power to the 'failsafe' clock. When the main clock fails, WDT times out, then supplies power to 'failsafe' clock. |
|
![](templates/subSilver/images/spacer.gif) |
newguy
Joined: 24 Jun 2004 Posts: 1903
|
|
Posted: Mon May 03, 2021 6:54 pm |
|
|
You'll have to download Microchip's Oscillator chapter from that dsPIC's Family Reference Manual (FRM). Document 70580C, page 34/44: Fail-Safe Clock Monitor.
When the clock switching fuses are enabled (there are 2 bits: confirm that your fuses are actually doing what you need/want), the LPRC runs at all times except when the device is in sleep mode. That allows the LPRC to essentially clock or monitor the main oscillator. If the main oscillator stops ticking for any reason, the FSCM then detects this and triggers a clock switchover.
Read the documentation and ensure that the fuses are being set to what you require. I suspect that because there are 2 bits that perhaps you have things half enabled because of an oversight. Also ensure that the LPRC is actually running by causing a switchover to it: then toggle an LED or something to let you know that it switched. Do this before attempting the FSCM functionality. Confirm the LPRC is working and that you can switch between oscillators, then look at all the fuses and what the config registers are being set to at the bottom of the list file. There has to be a mismatch somewhere. Just try to find if it's an oversight on your part or perhaps a compiler bug. |
|
![](templates/subSilver/images/spacer.gif) |
Ttelmah
Joined: 11 Mar 2010 Posts: 19369
|
|
Posted: Tue May 04, 2021 12:56 am |
|
|
What you are showing is a system running off the internal oscillator. So no
FSCM. If this is stopping when you short the crystal pin, than this implies that
the act of doing this is actually 'spiking' the processor into a not operational
state.
Seriously, if you are doing this with a wire for example, you could be
introducing massive amounts of RF interference into the PIC input at this point.
Don't.
If you want to test/demo stopping the oscillator, either use an external
clock generator, and use it's stop button, or add the circuitry to disable the
clock cleanly. So (for example), put an OR gate in the line between the
crystal and the PIC oscillator input, and have the second input to this fed
with a suitable debounce capacitor and pull up resistor with a switch to start/
stop the output. |
|
![](templates/subSilver/images/spacer.gif) |
Tom-H-PIC
Joined: 08 Sep 2003 Posts: 105 Location: New Castle, DE
|
|
Posted: Tue May 04, 2021 7:44 am |
|
|
Thank you all for having a look and making suggestions.
Temtronic
Yes there are a number of these circuits around if googled.
I spent about a week prototyping and messing with these circuits and was never able to get them to be staple and reliable.
Also there is a number of issues with this approach that would have to be overcome as in startup that is all I can think of off the top of my head right now.
Thanks for the suggestion.
Newguy
Yes you are correct I don’t think that I have or have done anything to start or make sure I have a second oscillator running.
Yes I have the Oscillator manual for the DSPIC (70580C) and did read it at the beginning of this phase of development.
But I guess I should have gone back and review it sooner because I did miss the fuse setting where called out in there.
So I think that I have configured the FOSC with 0x3A that is assuming that configuration word 6 is the FOSC location.
I'm using the IDC-U80 and software CCSLoad to read the configuration words. And it only gives the word number not the address.
Is there a way to read FUSE in code?
I have the development copy of the production software I can stuff in that check the FUSEs if I can read from code.
Yes from suggestion I'm work on the LPRC to make sure it’s running.
Thank you.
Ttelmah
Understood I figured it was not good for the DSPIC about the third time I did it so stopped.
Thank you for the input. |
|
![](templates/subSilver/images/spacer.gif) |
newguy
Joined: 24 Jun 2004 Posts: 1903
|
|
Posted: Tue May 04, 2021 7:16 pm |
|
|
Tom-H-PIC wrote: |
Is there a way to read FUSE in code? |
At the bottom of the list file is the complete configuration word list, as you already know. You need to compare those settings with the config words in the data sheet, chapter 27 Special Features. That chapter lists the config words, which holds all the fuses. Work through what needs to be set, what the config words would then be, and compare with the list file.
It's a bit convoluted but it's the only way I'm aware of. |
|
![](templates/subSilver/images/spacer.gif) |
Ttelmah
Joined: 11 Mar 2010 Posts: 19369
|
|
Posted: Wed May 05, 2021 12:32 am |
|
|
You can use read_config_memory to read the config bytes into a RAM
buffer, but you'll have to work out which bytes you need (remember there
is the user ID, device ID and the actual fuses in this area...).
Generally what is in the .lst file is a lot easier. |
|
![](templates/subSilver/images/spacer.gif) |
|