FLL LOCKING PROBLEM

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

FLL LOCKING PROBLEM

811 Views
Robinwithu
Senior Contributor I

Hi All,

 

I am having problem while checking the FLL is locked or not in FEI mode  for MC9S08RN8 , 8 bit controller.

 

Here is my code

 

 

 

#include <hidef.h> /* for EnableInterrupts macro */

#include "derivative.h" /* include peripheral declarations */

 

  volatile byte NV_FTRIM_INIT  @0x0000FF6E  ;  // LSB     ICS_C4

  volatile byte NV_ICSTRM_INIT @0x0000FF6F  ;  // MSB     ICS_C3      

 

 

    // Main Programm is working at 20Mhz = 512 * 39062.5 = 20Mhz    =>    39062.5 is a Default Factory Trimmed frequency  in ICS_C3 & ICS_C4 Registers

 

 

    void main(void)

  

    {

 

         DisableInterrupts;

     

        if ( NV_ICSTRM_INIT != 0xFFU) {                                              // 0xFF6FU  Test if the device trim value is stored on the specified address

          

            ICS_C3    =  NV_ICSTRM_INIT ;                                            // This Registers are not Define in Derivative.h file thats why we have to define this Environment Variable before the start of code

            ICS_C4    = ((NV_FTRIM_INIT)  & 0x01U);                                    // Trim the internal clock  :((NV_FTRIM_INIT) & 0x01U);

          

          }

      

      

         ICS_C1 = 0x04;                                                                 // internal reference clock to FLL and FLL is generating 16000-20000 Khz  ; Ref. Freqeuncy  is set at 31250-39250 Hz * 512 = Appx.16-20 Mhz

         ICS_C2 = 0x00;                                                                // BDIV = 00, Freq is now 16-20Mhz  

 

          while (ICS_S_LOCK==0);

          {

            __asm("NOP");

 

          }                                                                                    // [0] FLL is currently unlocked, [1] FLL is currently locked.

                                                                                                                         

        

        

          PORT_PTAOE = 0x02;                                                     // PORTA pinA1 Output enabled

          PORT_PTAD = 0x00;                                                        // Initialise PORTA1 pin

          while (1) {PORT_PTAD = 0x02;}                                             // Set PORTA1 pin in forever loop

 

 

       }

 

 

Actually it's never coming out of First while loop to toggle the PORTA pin A1.But as soon as i do the changes while (ICS_S_LOCK==1);  the PORTA pin A1 start toggling after appx. 6 msec n i.e. cause of WDT.

 

 

Some useful information:

 

1) I am using FEI mode  and setting BDIV =0; (Internal reference frequency is at Default value which is 39062.5 Hz, BUS Freq. 20Mhz)

2) In Debugging mode the same code is working fine , which means it comes out of while loop n set the  PORTA pin A1 , n it reset cause of Watchdog timer.

3) After flashing the code in controller it never comes out from first while loop (FLL is locked checking) and the PORTA pin A1 is always low on Oscilloscope.

 

Any kind of Help and Suggestions are  appreciated. Arpita Agarwal, Manish Sharma,bigmac, Derrick Klotz

 

Thanks and Kind Regards,

Robin

Labels (1)
Tags (3)
0 Kudos
3 Replies

488 Views
Robinwithu
Senior Contributor I

Hi bigmac,arpitaagarwal-b37570,

The problem is solved , it was WDT. I disable the WDT and now the above code is working fine, but oscillator is taking 21 msec instant of 2 msec to stabilize. can you guys please tell me why? or am i doing something wrong?

Thanks n kind Regards,

Robin

0 Kudos

488 Views
Derrick
NXP Employee
NXP Employee

Hi Robin,

Exactly how are you measuring the FLL acquisition time?  In your case, this parameter applies from the time the reference is trimmed but I don't see how you could be measuring this externally (i.e., via a port pin).  I suggest toggling a port pin just before the internal reference is trimmed and then again just after the wait for lock.

For situations like this I often like to see the code the Processor Expert generates.  I initiated a simple project using the S08RN8, trimmed the internal reference for 39.0625kHz and set the bus at 20MHz.  Here is the relevant resulting generated code:

void _EntryPoint(void)

{

  /* ### MC9S08RN16_48 "Cpu" init code ... */

  /*  PE initialization code after reset */

  /* WDOG_CNT: CNT=0xC520 */

  setReg16(WDOG_CNT, 0xC520U);         /* First part of the WDG unlock sequence */

  /* WDOG_CNT: CNT=0xD928 */

  setReg16(WDOG_CNT, 0xD928U);         /* Second part of the WDG unlock sequence */

  /* WDOG_TOVAL: TOVAL=4 */

  setReg16(WDOG_TOVAL, 0x04U);         

  /* WDOG_CS2: WIN=0,FLG=0,??=0,PRES=0,??=0,??=0,CLK=1 */

  setReg8(WDOG_CS2, 0x01U);            

  /* WDOG_CS1: EN=0,INT=0,UPDATE=0,TST=0,DBG=0,WAIT=0,STOP=0 */

  setReg8(WDOG_CS1, 0x00U);            /* Disable watchdog */

  /* Common initialization of the write once registers */

  /* SYS_SOPT1: FWAKE=0,STOPE=0 */

  clrReg8Bits(SYS_SOPT1, 0x03U);       

  /* PMC_SPMSC1: LVWIE=0,LVDRE=1,LVDSE=1,LVDE=1,BGBDS=0,BGBE=0 */

  clrSetReg8Bits(PMC_SPMSC1, 0x23U, 0x1CU);

  /* PMC_SPMSC2: LVDV=0,LVWV=0 */

  clrReg8Bits(PMC_SPMSC2, 0x70U);      

  /*  System clock initialization */

  /*lint -save  -e923 Disable MISRA rule (11.3) checking. */

  if (*(uint8_t*)0xFF6FU != 0xFFU) {   /* Test if the device trim value is stored on the specified address */

    ICS_C3 = *(uint8_t*)0xFF6FU;       /* Initialize ICS_C3 register from a non volatile memory */

    ICS_C4 = (uint8_t)((*(uint8_t*)0xFF6EU) & (uint8_t)0x01U); /* Initialize ICS_C4 register from a non volatile memory */

  }

  /*lint -restore Enable MISRA rule (11.3) checking. */

  /* ICS_C1: CLKS=0,RDIV=0,IREFS=1,IRCLKEN=1,IREFSTEN=0 */

  setReg8(ICS_C1, 0x06U);              /* Initialization of the ICS control register 1 */

  /* ICS_C2: BDIV=0,LP=0,??=0,??=0,??=0,??=0 */

  setReg8(ICS_C2, 0x00U);              /* Initialization of the ICS control register 2 */

  /* ICS_C4: LOLIE=0,CME=0 */

  clrReg8Bits(ICS_C4, 0xA0U);          

  /*** End of PE initialization code after reset ***/

  /*lint -save  -e950 Disable MISRA rule (1.1) checking. */

  __asm   jmp _Startup ;               /* Jump to C startup code */

  /*lint -restore Enable MISRA rule (1.1) checking. */

}

The reset vector points to _EntryPoint().  We can see that the very first thing that the code does is disable the watchdog :smileygrin:.  It then configures a few write-once registers and trims the internal reference.  Following this it configures the Internal Clock Source and doesn't bother to wait for the FLL to lock.  I find this to be a bit curious, but it does essentially equate to the information provided in the reference manual in Example 7.3.1.1 "FEI mode initialization routine":

/* the following code segment demonstrates setting ICS to FEI mode generating 20MHz bus*/

ICS_C2 = 0x00;

ICS_C1 = 0x04; /* internal reference clock to FLL */

ICS_C2 = 0x00; /* BDIV = 0, no prescalar */

ICS_C3 = TRIM_VALUE_39K0625HZ; /* FLL output 20MHz, TRIM_VALUE_39K0625HZ is ~0x50 typically */

I guess that changing the internal reference from 32.768kHz to 39.0625kHz presents little risk of clocking problems.  But I would prefer to err on the side of caution and wait for the FLL to lock as you do.  Although you should measure the FLL acquisition time as I mention above.

Your code snippet starts at main() but what's happening before this?  Or is the reset vector pointing to main() - which is usually a bad idea.  Using Processor Expert the reset vector points to _EntryPoint(), which is the hardware initialization routine.  Once complete, code execution jumps to _Startup(), the software initialization routine.  The standard ANSII C software initialization is usually a three-step procedure that performs:

   - a "zero out" (initializing global and static variables to zero), then

   - a "copy down" (initializing all non-zero global and static variables), then

   - initialization of the stack pointer

_Startup ends by jumping directly to main().

So there can be a lot going on prior to main() executing.  I suggest taking a look at where your code starts coming out of reset.

Best Regards,

Derrick

488 Views
Robinwithu
Senior Contributor I

Hi Derrick

Thank you for Reply , i will do as you said and will let you know the result.Few points i would like to bring in focus.

1) like as you said changing the internal trim frequency from 32768hz to 39062 hz   have effect on start up time of oscillator but in my case the default frequency is 39062 hz , it's given in datasheet. (changing the Trim value does have effect on Start-up time)

2) you are right i am toggling the port pin after trim code so i will correct that .

3) before main () program , in this case i don't have any kind of variables or macro's , only

#include <hidef.h> /* for EnableInterrupts macro */

#include "derivative.h" /* include peripheral declarations */

  volatile byte NV_FTRIM_INIT  @0x0000FF6E  ;  // LSB     ICS_C4

  volatile byte NV_ICSTRM_INIT @0x0000FF6F  ;  // MSB     ICS_C3 

that's all what i have before my main code.

Thanks and Kind Regards,

Robin

0 Kudos