illegal_bp

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

illegal_bp

Jump to solution
873 Views
chris_qin
Contributor I

I am a college student and I met a problem when i was learning mc9s12p128.

The command window always warn me that there was a illegal_bp problem when i was debuging use TBDML,but when i try in full chip simulation mode ,there was nothing wrong!

i donnot know the reason,anyone knows?

 

#include "MC9S12P128.h"

void SetBusClock_16M() {

 

CPMUCLKS_PLLSEL = 1; //f(bus)=f(osc)/2   ;fosc = 4m

 

 

CPMUSYNR =0X43; //01000011

                        //fvco = 2*4*(1+1)/1 = 16m

                        //VCOFRQ[7:6]  SYNDIV[5:0]

                        //fVCO= 2*fOSC*(SYNDIV + 1)/(REFDIV + 1) =2*4M*(3+1)=32M

                        //fPLL= fVCO/(2 × POSTDIV)

                        //fBUS= fPLL/2

                        //VCOCLK Frequency Ranges  VCOFRQ[7:6]                       

                        // 32MHz <= fVCO <= 48MHz    00                       

                        // 48MHz <  fVCO <= 64MHz    01                       

                        // Reserved                  10                       

                        // Reserved                  11

CPMUREFDIV = 0X40;//0100 0000

                        //REFFRQ[7:6]  REFDIV[5:0]

                        //fREF = fOSC/(REFDIV + 1)

                        //REFCLK Frequency Ranges  REFFRQ[7:6]                       

                        // 1MHz <= fREF <=  2MHz       00                       

                        // 2MHz <  fREF <=  6MHz       01                       

                        // 6MHz <  fREF <= 12MHz       10                       

                        // fREF >  12MHz               11                                                

                        // pllclock=2*fosc*(1+SYNDIV)/(1+REFDIV)=16MHz;

CPMUPOSTDIV = 0X00;    //fPLL = fVCO/(1+POSTDIV)

 

 

CPMUOSC_OSCE = 1;    //choose osc as bus clock;

while(!(CPMUFLG_UPOSC==1)) {

_asm(nop);

_asm(nop);

}

while(!(CPMUFLG_LOCK==1)) ;   //WHEN PLL IS STEADY

//CPMUCLKS_PLLSEL = 1;        //

}

Labels (1)
0 Kudos
1 Solution
591 Views
RadekS
NXP Employee
NXP Employee

Hi &#25112;&#24378; &#31206;,

  1. Please remove unnecessary command “while (!CPMUFLG_LOCK);” prior writing to CPMUOSC. SYNR, REFDV and POSDIV values are related to external clock value and LOCK status will be lost by setting OSCE bit anyway.
  2. OSCFILT value should be VCOCLK-to-OSCCLK ratio divided by two (must be integer value). In your case (4MHz external crystal and 16MHz bus clock), OSCFILT value should be 4.
  3. Modifying PLLSEL followed by waiting loop doesn’t have sense – it could cause dead loop under specific circumstances. Let’s say that between LOCK (UPOSC) bit check and write into PLLSEL is for example 10 bus cycles. During this time PLL may be unlocked again and write into PLLSEL will be ignored. We have to ensure that PLLSEL bit will be modified when LOCK (UPOSC) bit is 1. Therefore we should try to writing into PLLSEL until this bit will be modified according our demands. For example:

while(CPMUCLKS_PLLSEL)  // PLLSEL=0 check

{

CPMUCLKS_PLLSEL = 0;

}

This is important mainly for PBE mode (when PLLSEL = 0), but it is good habit to use in all modes.


I hope it helps you.

Have a great day,
RadekS

-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------

View solution in original post

4 Replies
591 Views
RadekS
NXP Employee
NXP Employee

Hi &#25112;&#24378; &#31206,

In fact, illegal_bp problem means that debugger gets lost. Typical case is unexpected interrupt or reset of MCU.

Please check whether you didn’t enable any clock interrupt in CPMUINT register and if yes, please check whether you have correctly defined appropriate interrupt routine.

For example:

//==============================================================================

//PLL_LOCK_ISR

//==============================================================================

#pragma CODE_SEG NON_BANKED

interrupt 28 void PLL_LOCK_ISR(void)

{

  lock = CPMUFLG_LOCK;

  if(CPMUFLG_LOCK)

  {

//..your code //LOCK

  }

  else

  {

    //..your code                //UNLOCK

  }

  CPMUFLG = 0x10;      //clear LOCKIF flag

}

#pragma CODE_SEG DEFAULT

About your routine)

I suppose that you want set CPMU module into PEE mode with 4MHz external crystal and 16MHz bus clock. I am right?

You should set CPMUSYNR to 0x03 instead 0x43. VCOCLK is 32MHz.

Since external oscillator cannot be validated without locked PLL (LOCK=1), it has no sense to wait for UPOSC bit and after that wait for LOCK bit. So, line “while(!(CPMUFLG_LOCK==1)) ;  //WHEN PLL IS STEADY” could be removed.

After writing CPMUCLKS register, it is recommended to read back CPMUCLKS register to make sure that write of PLLSEL, RTIOSCSEL and COPOSCSELwas successful. For example:

  while(CPMUCLKS_PLLSEL)  // PLLSEL=0 check

  {

  CPMUCLKS_PLLSEL = 0;  

  }

Since BDM communication depends on bus clock, I would like to recommend run code trough PLL setting function. Transient states during stepping over code could cause unexpected communication problems.


I hope it helps you.

Have a great day,
RadekS

-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------

0 Kudos
591 Views
chris_qin
Contributor I

Hey ,thank you very much for you help!Before i saw your message,i read the datasheet over and over again,then i found that when i  added "CPMUPROT_PROT =0; CPMUCLKS_PLLSEL = 1;"before i set the register,the problem disappeared!!i do`nt know why because according to the datasheet,it is the default value! This is my code blow,but i found i can not set register "CPMUOSC"!when i  wrote to it,the value did not change when i  was debugging by TBDML,so the osc won`t work.Maybe i missed something importent...unhappy...

#include "PEE_BusClock.h"

void Set_PEE(byte _synr, byte _refdiv, byte _postdiv) {

  CPMUPROT_PROT =0;

  CPMUCLKS_PLLSEL = 1;

  while(!CPMUCLKS_PLLSEL);

  CPMUSYNR = _synr;

  CPMUPOSTDIV = _postdiv;

  CPMUREFDIV = _refdiv;

 

  while (!CPMUFLG_LOCK);

  CPMUOSC= CPMUOSC_OSCE_MASK+CPMUOSC_OSCBW_MASK+CPMUOSC_OSCFILT1_MASK;//enable external osc OSCE

 

  while(!CPMUFLG_UPOSC) {   //if osc up?

   

   // you can check for timeout here with error message report

  }                       

  //while(!CPMUFLG_LOCK){     //if PLL LOCKED?

   // you can check for timeout here with error message report

  //}

 

  //SET CLOCK

  CPMUCLKS_PLLSEL = 1;      //Bus = F(PLL)/2

  //CPMUCLKS_COPOSCSEL = 1;  //COP IS clocked from osc

  while (CPMUCLKS != 0B10000000) {

     asm nop;

  }

            

}

//OSC = 4M

void SetBusClock16M_OSC4M() {

   ECLKCTL_NECLK = 0;                      // enable ECLK output

  Set_PEE(0X03,0X40,0X00);

}

/*

void SetBusClock24M_OSC4M() {

   ECLKCTL_NECLK = 0;                      // enable ECLK output

  Set_PEE(0X01,0X80,0X70);

 

}

void SetBusClock25M_OSC4M() {

   ECLKCTL_NECLK = 0;                      // enable ECLK output

  Set_PEE(0X58,0X03,0X00);

 

}

//OSC = 8M

void SetBusClock16M_OSC8M(){

   ECLKCTL_NECLK = 0;                      // enable ECLK output

  Set_PEE(0X01,0X80,0X00);

}

void SetBusClock24M_OSC8M(){

   ECLKCTL_NECLK = 0;                      // enable ECLK output

  Set_PEE(0X02,0X80,0X00);

}void SetBusClock25M_OSC8M(){

   ECLKCTL_NECLK = 0;                      // enable ECLK output

  Set_PEE(0X58,0X07,0X00);

}

*/

0 Kudos
592 Views
RadekS
NXP Employee
NXP Employee

Hi &#25112;&#24378; &#31206;,

  1. Please remove unnecessary command “while (!CPMUFLG_LOCK);” prior writing to CPMUOSC. SYNR, REFDV and POSDIV values are related to external clock value and LOCK status will be lost by setting OSCE bit anyway.
  2. OSCFILT value should be VCOCLK-to-OSCCLK ratio divided by two (must be integer value). In your case (4MHz external crystal and 16MHz bus clock), OSCFILT value should be 4.
  3. Modifying PLLSEL followed by waiting loop doesn’t have sense – it could cause dead loop under specific circumstances. Let’s say that between LOCK (UPOSC) bit check and write into PLLSEL is for example 10 bus cycles. During this time PLL may be unlocked again and write into PLLSEL will be ignored. We have to ensure that PLLSEL bit will be modified when LOCK (UPOSC) bit is 1. Therefore we should try to writing into PLLSEL until this bit will be modified according our demands. For example:

while(CPMUCLKS_PLLSEL)  // PLLSEL=0 check

{

CPMUCLKS_PLLSEL = 0;

}

This is important mainly for PBE mode (when PLLSEL = 0), but it is good habit to use in all modes.


I hope it helps you.

Have a great day,
RadekS

-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------

591 Views
chris_qin
Contributor I

thank you very much !

0 Kudos