I'm using the F28034 micro controller for realtime motor control and on startup check to see if crystal is present and if it is found to not be present it will switch to the internal oscillator 1 and throw a HW fault. I'm using the recommendation seen in 3.2.3.1 in sprugl8c (system control and interrupt datasheet). Using CPU timer 2 off the crystal to see if its present. The problem is that I'm seeing crystal failure with this method and I believe it is not really breaking. I believe this because I removed that check and had it always startup using the crystal and watch the CLOCKFAIL flag which never indicated that there was a clock failure. Here is the code snippet of my check. I should note that the only items done before this in startup is copying ISRs to RAM which works fine. I have also placed a US_DELAY (ti macro) of 5 ms. This is here to allow the rails to stabilize on startup before checking the crystal.
bool CheckExternalCrystal(void)
{
bool crystalWorks = false;
int i = 0;
EALLOW;
//set timer2 to known state
CpuTimer2Regs.TCR.bit.TSS = 1; // turn off timer 2
CpuTimer2Regs.TCR.bit.TRB = 1; // reset timer2 (timer = period) CpuTimer2Regs.TIM = CpuTimer2Regs.PRD
//set timer 2 to run off external crystal
SysCtrlRegs.CLKCTL.bit.TMR2CLKPRESCALE = 0; // set prescaler to 0
SysCtrlRegs.CLKCTL.bit.TMR2CLKSRCSEL = 1; // set timer 2 clk source to external crystal
//turn on timer 2
CpuTimer2Regs.TCR.bit.TSS = 0; // turn on timer 2
EDIS;
//delay to allow timer to start
for (i = 0; i <100; i++);
//check for timer 2's operation
if (CpuTimer2Regs.TIM.all == CpuTimer2Regs.PRD.all) //checks that timer is counting by comparing timer value, to reset value
{
crystalWorks = false; // redundent false (external crystal doesn't work)
}
else
{
crystalWorks = true; //if timer value is different that rest value, crystalWorks = true
}
EALLOW;
// reset timer registers
CpuTimer2Regs.TCR.bit.TSS = 1; //turn off timer 2
CpuTimer2Regs.TCR.bit.TRB = 1; // reset timer2 (timer = period) CpuTimer2Regs.TIM = CpuTimer2Regs.PRD
SysCtrlRegs.CLKCTL.bit.TMR2CLKSRCSEL = 0; // set timer 2 clk source to oscillator
CpuTimer2Regs.TCR.bit.TSS = 0; // turn on timer 2
EDIS;
return crystalWorks; //return crystal status
}
After the return it will than decide which clock to choose. Note that some of the comments could be wrong since I was doing a bit of playing around with it. Can you guys take a peek at this to see if I'm missing something or did something incorrectly.
Thanks!