Hi,
I am not sure what the problem is, but for some reason, I am stuck in FRZ mode.
It might be stuck in 'Stop Mode', since the NOTRDY = 1 and LMPACK = 1.
I'm not sure if this is related or not, but I can't seem to enter DRUN mode, only RUN0 mode.
We are running on new hardware, So I am led to believe this might be some sort of hardware issue.
Is there any reason, other than hardware, that it would not transition into DRUN mode?
I used the clock initialization example in "MPC574xC_Clock_Calculator_Rev6.xlsm"
The code gets stuck in the while(MC_ME.GS.B.S_MTRANS) loop.
I can transition to mode 4 (RUN0), but it will not transition to mode 3 (DRUN).
I'm not sure if this is directly related to the CAN issue or not?
MC_ME.PCTL[70].R = 1; /* Might not even need this. All peripherals might be set */
//CAN_0_config_pins(); /* pins aren't needed at this point */
//CAN_FlexCAN_0_config_rx_msg_buffers(); /* Don't need these either */
int i = 0;
/* Module disable */
CAN_0.MCR.B.MDIS = 1;
/* Select Clock */
CAN_0.CTRL1.B.CLKSRC = 0;
/* Module enable */
CAN_0.MCR.B.MDIS = 0;
CAN_0.MCR.B.HALT = 1;
CAN_0.MCR.B.FRZ = 1;
while(0 == CAN_0.MCR.B.FRZACK ){} /* <----- Stuck */
while(0 == CAN_0.MCR.B.NOTRDY ){}
CAN_0.MCR.B.SOFTRST = 1;
while(1 == CAN_0.MCR.B.SOFTRST == 1){};
This is the SysClk_Init() function. It will successfully transition to mode RUN0, but will not transition to Default DRUN mode.
void SysClk_Init(void)
{
MC_CGM.AC5_SC.R = 0x01000000; //Connect FXOSC to the FMPLL input.
//Set FMPLL to MHz with 16 MHz FXOSC reference.
PLLDIG.PLLDV.R = 0x04010028; //PREDIV = 0, MFD = 40, RFDPHI = 1, RFDPHI1 = 2
PLLDIG.PLLFD.R = 0x00000000; //PLL fractional numerators
PLLDIG.PLLCAL3.R = 0x00004000; //PLL fractional denominator
//Turn on clock sources and select system clock source
MC_ME.DRUN_MC.R = 0x00130172; //Configure DRUN mode settings with sysclk FMPLL_PHI0 (160 MHz).
MC_ME.ME.R = 0;
MC_ME.ME.R = 0x0000A4FD; /* Enable RUN1-3, STOP0, STANDBY0 */
MC_ME.RUN_PC[0].R = 0x000000FE; //Enable peripherals to run in all modes
//Configure the oscillator divided clocks
SIRC.CTL.R = 0x00000011; //SIRC_DIV_CLK is SIRC divided by 1 (0.128 MHz).
FIRC.CTL.R = 0x00000011; //FIRC_DIV_CLK is FIRC divided by 1 (16 MHz).
SXOSC.CTL.B.OSCDIV = 0x00; //SXOSC_DIV_CLK is SXOSC divided by 1 (0.032 MHz).
//FXOSC.CTL.B.OSCDIV = 0x00; //FXOSC_DIV_CLK is FXOSC divided by 1 (16 MHz).
/* Change to RUN0 */
/* write new mode and key */
MC_ME.MCTL.R = 0x40005AF0ul;
/* write new mode and inverted key */
MC_ME.MCTL.R = 0x4000A50Ful;
while(MC_ME.GS.B.S_MTRANS); //Wait for mode transition to complete
while(MC_ME.GS.B.S_CURRENT_MODE != 0x4); //Verify DRUN is the current mode
//Mode transition to DRUN mode:
MC_ME.MCTL.R = 0x30005AF0; //Enter DRUN mode & Key
MC_ME.MCTL.R = 0x3000A50F; //Enter DRUN mode & Inverted Key
while(MC_ME.GS.B.S_MTRANS); //Wait for mode transition to complete
while(MC_ME.GS.B.S_CURRENT_MODE != 0x3); //Verify DRUN is the current mode
}
P.S. I wonder if I need to transition to DRUN mode if the mode is already mode 3?
Something else seems to not work if I skip the mode switch and just assume its in mode DRUN already.
Thank you,
Hello Mr.Christopher,
We are also facing same problem,
Did you find any solution for this ISSUE?
Note:
We are using Internal Oscillator 16Mhz and FMPll output as 160Mhz
please provide your feedback.
The development board was using a different XTAL than the Project board.
If your only using 1 board, have to ensure all the clock settings are correct.
I know it's tough.
Sorry for the late response. Hope you got it working.
Hello Christopher,
could you please share some simple example project, which demonstrates your issue? I will check the project on my side and I will let you know, where is the problem.
Regards,
Martin
Hi Martin,
Ok, a little insight.
I am going to fix the DRUN issue before moving to the CAN problem.
I am using the MPC5748G EVB development board for development, which is using the 40MHz clock.
Our production board is using a 16 MHz clock.
When I set up the Production board clock using the "MPC574xC_Clock_Calculator_Rev6.xlsm", it will fail to enter DRUN mode.
I went back and used the old initialization and at least now, it can transition to DRUN mode.
Perhaps I must not be setting up the clock calculator correctly, or I have to do something else if I am using a 16 MHz external clock?
The old initialization seems to do a lot more than what the clock generator code does, but whatever it does, it seems to work.
The commented SycClk_Init() is the clock calculator that doesn't transition to DRUN mode.
I am using MPC5746C.h Revision 4.0.0
/*----------------------------------------------------------------------------
** Function : MCAL_Mcu_Init
** Description :
** Precondition : Startup executed
** Postcondition: None
** Parameters : None
** Return value : None
**--------------------------------------------------------------------------*/
void MCAL_Mcu_Init(void)
{
/* This method fails to enter DRUN mode */
//SysClk_Init();
/* These are the original initialization routines */
MCAL_Mcu_Config_Pheripheral_Clocks();
MCAL_Mcu_Config_Main_Clocks();
MCAL_Mcu_Config_Modes();
MCAL_Mcu_Set_Mode();
MCAL_Mcu_Config_eMIOS_Clocks();
}
static void MCAL_Mcu_Config_Pheripheral_Clocks(void)
{
/**
* DE = 0 Divider disabled
* DIV = 0
*/
MC_CGM.CLKOUT1_DC.R = 0x00000000ul;
/**
* Clockout1 = 8 FXOSC
*/
MC_CGM.CLKOUT1_SC.R = 0x08000000ul;
/**
* S160 - System Clock / 1 = 64MHz
* DE = 1 enable clock divider
* DIV = 0 divide by (DIV+1)
*/
MC_CGM.SC_DC0.R = 0x80000000ul;
/**
* S80 - System Clock / 1 = 64MHz
* DE = 1 enable clock divider
* DIV = 0 divide by (DIV+1)
*/
MC_CGM.SC_DC1.R = 0x80000000ul;
/**
* S40 - System Clock / 2 = 32MHz
* DE = 1 enable clock divider
* DIV = 1 divide by (DIV+1)
*/
MC_CGM.SC_DC2.R = 0x80010000ul;
/**
* Read Only 0x80030000
* F40 - System Clock / 4 = 16MHz
* DE = 1 enable clock divider
* DIV = 3 divide by (DIV+1)
*/
/*MC_CGM.SC_DC3.R = 0x80030000ul;*/
/**
* Read Only 0x80010000
* F80 - System Clock / 2 = 32MHz
* DE = 1 enable clock divider
* DIV = 1 divide by (DIV+1)
*/
/*MC_CGM.SC_DC4.R = 0x80010000ul;*/
/**
* FS80 - System Clock / 1 = 64MHz
* DE = 1 enable clock divider
* DIV = 7 divide by (DIV+1)
*
* Must be equal to DC1 (MPC5746C ref manual rev 2, 3/2015 p 661)
*
*/
MC_CGM.SC_DC5.B.DIV = MC_CGM.SC_DC1.B.DIV;
MC_CGM.SC_DC5.B.DE = TRUE;
/**
* Read Only 0x80070000
* F20 - System Clock / 8 = 8MHz (F20 clock is fixed at /8)
* DE = 1 enable clock divider
* DIV = 7 divide by (DIV+1)
*/
/*MC_CGM.SC_DC6.R = 0x80070000ul;*/
/**
* Aux Clock 2(ENET0/ENET1) Source Selection
* SELCTL = 0 F40
*/
MC_CGM.AC2_SC.R = 0x00000000ul;
/**
* Read Only
* Aux Clock 3(TRNG) Source Selection
* SELCTL = 0
*/
/*MC_CGM.AC3_SC.R = 0x01000000ul;*/
/**
* Aux Clock 5(PLL) Source Selection
* SELCTL = 1 FXOSC
*/
MC_CGM.AC5_SC.R = 0x01000000ul;
/**
* Aux Clock 6(CLKOUT_0) Source Selection
* SELCTL = 2 PLL
*/
MC_CGM.AC6_SC.R = 0x02000000ul;
/**
* Aux Clock 8(SPI0) Source Selection
* SELCTL = 0 F40
*/
MC_CGM.AC8_SC.R = 0x00000000ul;
/**
* Aux Clock 9(FlexCAN0) Source Selection
* SELCTL = 1 FXOSC
*/
/*MC_CGM.AC9_SC.R = 0x01000000ul;*/
MC_CGM.AC9_SC.R = 0x00000000ul;
}
/*
* PLL should be off when this is called
*/
static void MCAL_Mcu_Config_Main_Clocks(void)
{
/*
* Fast External Oscillator Control Register
*
* OSCBYP = 0 Oscillator Output Used
* OSCM = ?
* EOCV: Don't change micro default value
* M_OSC = 0 Mask Interrupt
* OSCDIV: 0 (divide by 1)
* I_OSC
*/
//FXOSC.CTL.B.OSCBYP = FALSE;
//FXOSC.CTL.B.M_OSC = FALSE;
//FXOSC.CTL.B.OSCDIV = 0u;
/*
* Slow External Oscillator Control Register
*
*/
/*SXOSC.CTL.R = 0x00000000ul;*/
/*
* Slow Internal RC Oscillator (SIRC) Control Register
* DIV = 0 : /1
*/
SIRC.CTL.R = 0x00000000ul;
/*
* Fast Internal Oscillator (FIRC) Control Register
* DIV = 0 Divide by 1
*/
FIRC.CTL.R = 0x00000000ul;
/**
* Its unused but it "must be greater than MFN".
*/
PLLDIG.PLLCAL3.R = 0x09C3C000ul;
/*
* For 16MHz Charger Board
* Fpll = Fvco / (2^(RFDPHI+1))
*
* Fvco = (Fref / PREDIV) * (MFD + (MFN / (MFDEN + 1)))
*
* MFN = 0
* PREDIV = 2 (DIVIDE by 2)
* MFD = 128 (Multiply by 128)
* RFDPHI = 3 (Divide by 16)
* RFDPHI1 = 3 (Divide by 16)
*
* Fvco = (16MHz / 2) * 128
* = 1024MHz
*
* Fpll = 1024MHz / 2^4
* = 64MHz
*/
PLLDIG_PLLDV = 0x06032080ul;
/*
* For 40MHz Charger Board
* Fpll = Fvco / (2^(RFDPHI+1))
*
* Fvco = (Fref / PREDIV) * (MFD + (MFN / (MFDEN + 1)))
*
* MFN = 0
* PREDIV = 5 (DIVIDE by 5)
* MFD = 128 (Multiply by 128)
* RFDPHI = 3 (Divide by 16)
* RFDPHI1 = 3 (Divide by 16)
*
* Fvco = (40MHz / 5) * 128
* = 1024MHz
*
* Fpll = 1024MHz / 2^4
* = 64MHz
*
*/
/*PLLDIG_PLLDV = 0x06035080ul;*/
/**
* DTDHDIS = 1
* MFN = 0;
*/
PLLDIG_PLLFD = 0x00010000ul;
/*
* PLL Modulation Register
*
* SSCGBYP = 1 (Spread Spectrum Modulation is bypassed)
*/
PLLDIG_PLLFM = 0x40000000ul;
}
static void MCAL_Mcu_Config_Modes(void)
{
/* Additionally Enabled Modes: RUN1 (for bootloader until changed) */
MC_ME.ME.R = 0x0000003Dul;
/* Set all used peripherals to use Low Power Config 0 and Run config 0 */
/* PCTL should be configured on AFTER the clocks are configured on.
*
* Also enable RTI timers AFTER these clocks have been configured and activated.
* See clocking overview in 5746C ref manual
*/
/* Set Run Config 0 to be on in all possible modes.
* RUN3, RUN2, RUN1, RUN0, DRUN, SAFE
*/
MC_ME.RUN_PC[0].R = 0x000000FCul;
/* Set Low Power Peripheral Config 0 to be default in all low power modes.
* This means all peripherals that use this config will be off.
*/
MC_ME.LP_PC[0].R = 0x00000000ul;
/* At this point nothing should ever turn off. Thus, no matter the mode we
* will be on external clock with PLL. Hopefully, this does not affect the
* bootloader. It shouldn't since we go there by way of reset.
*/
/*
* Ensure PLL is off. This is the mode after reset. Here we will configure
* the PLL before we switch modes into one operating with the PLL.
*
* PWRLVL = 0 (default)
* PDO = 0 (no auto safe gating)
* MVRON = 1 (main volt reg on) (read only)
* FLAON = 3 (Flash in run mode)
* SXOSCON = 0 (32kHz external osc off)
* SIRCON = 1 (128kHz internal RC osc ON) (used by SWT)
* PLLON = 0
* FXOSCON = 1 (external osc on)
* FIRCON = 1 (16MHz int osc on)
* SYSCLK = 0 (sysclk uses 16MHz internal RC)
*/
MC_ME.DRUN_MC.R = 0x001300B0ul;
/*
* PWRLVL = 0 (default)
* PDO = 0 (no auto safe gating)
* MVRON = 1 (main volt reg on) (read only)
* FLAON = 3 (Flash in run mode)
* SXOSCON = 0 (32kHz external osc off)
* SIRCON = 1 (128kHz internal RC osc ON)
* PLLON = 1
* FXOSCON = 1 (external osc on)
* FIRCON = 1 (16MHz int osc on)
* SYSCLK = 2 (sysclk uses PLL)
*/
MC_ME.RUN_MC[0].R = 0x001300F2ul;
MC_ME.RUN_MC[1].R = 0x001300F2ul;
MC_ME.RUN_MC[2].R = 0x001300F2ul;
MC_ME.RUN_MC[3].R = 0x001300F2ul;
/*
* Stop Mode Default
*
* PWRLVL = 0 (default)
* PDO = 0 (no auto safe gating)
* MVRON = 1 (main volt reg on)
* FLAON = 1 (Flash in power down mode)
* SXOSCON = 0 (32kHz external osc off)
* SIRCON = 0 (128kHz internal RC osc off)
* PLLON = 0
* FXOSCON = 0 (external osc off)
* FIRCON = 1 (16MHz int osc on)
* SYSCLK = 0 (sysclk uses 16MHz internal)
*/
/*MC_ME.STOP_MC.R = 0x00110010ul;*/
/*
* Standby Mode Default
*
* PWRLVL = 0 (default)
* PDO = 1 (auto safe gating)
* MVRON = 0 (main volt reg off)
* FLAON = 1 (Flash in power down mode)
* SXOSCON = 0 (32kHz external osc off)
* SIRCON = 0 (128kHz internal RC osc off)
* PLLON = 0
* FXOSCON = 0 (external osc off)
* FIRCON = 1 (16MHz int osc on)
* SYSCLK = 0 (No System Clock)
*/
/*MC_ME.STANDBY_MC.R = 0x0081001Ful;*/
MC_ME.PCTL[1].B.RUN_CFG = 0x1; /* eMIOS 0: select peri. cfg. RUN_PC[1] */
//MC_ME.PCTL[2].B.RUN_CFG = 0x1; /* eMIOS 1: select peri. cfg. RUN_PC[1] */
}
static void MCAL_Mcu_Set_Mode(void)
{
// MC_ME.MCTL.R = 0xA0005AF0; /* Enter STOP mode and key */
// MC_ME.MCTL.R = 0xA000A50F; /* Enter STOP mode and inverted key */
// while (MC_ME.GS.B.S_MTRANS) {} /* Wait for STOP mode transition to complete */
/* Change to RUN0 */
/* write new mode and key */
MC_ME.MCTL.R = 0x40005AF0ul;
/* write new mode and inverted key */
MC_ME.MCTL.R = 0x4000A50Ful;
/* Wait on transition */
while(MC_ME.GS.B.S_MTRANS);
/* transition automatically waits on FXOSC and PLL Lock if those are on for the mode
* See Clock Sources section 8.9
*/
}
void MCAL_Mcu_Config_eMIOS_Clocks(void)
{
/*
* Generic eMIOS config here.
*
*0 RSVD
*1 MDIS
*2 FRZ
*3 GTBE 1
* 0001
*4 ETB
*5 GPREN 1
*6 NA
*7 NA
* 0100
*8 NA
*9 NA
*10 NA
* 0x0
*11 NA
*12 NA
*13 NA
*14 NA
* 0x0
*15 NA
*16 GPRE
*17 GPRE
*18 GPRE
*19 GPRE
* 0x0
*20 GPRE
*21 GPRE 1
*22 GPRE 1
*23 GPRE 1
* 0x7
*24 NA
*25 NA
*26 NA
*27 NA
* 0x0
*28 NA
*29 NA
*30 NA
*31 NA
* 0x0
*
* MDIS = 0: Clock Running
* FRZ = 0: Do not stop in debug mode
* GTBE = 1: Global Time Base Enabled
* GPREN = 1: Global Prescaler Enabled
* GPRE = 3: Global Prescaler 63 (FS80 / (prescaler +1)
* 64MHz / (7 +1)
* 8MHz
*/
/* eMIOS_0.MCR.B.GTBE = 1; */
/* eMIOS_0.MCR.B.GPREN = 1; */
/* eMIOS_0.MCR.B.GPRE = 0x7; */
/* eMIOS_0_MCR = 0x14000700ul; */
/* eMIOS_1_MCR = 0x14000700ul; */
/* EMIOS 0 Configuration */
eMIOS_0.MCR.B.GPREN = 0; /* Disable global pre-scaler (reset default) */
eMIOS_0.MCR.B.GPRE = 79; /* Divide 80 MHz clock to module by 80 */
eMIOS_0.MCR.B.FRZ = 0; /* No Freeze channel registers in debug mode if channel FREN=0 */
}
//Enable XOSC, PLL0, PLL1, and enter LPU_STANDBY with LPU_SYS_CLK as system clock (160 MHz).
void SysClk_Init(void)
{
MC_CGM.AC5_SC.R = 0x00000000; //Connect FIRC to the FMPLL input.
//Set FMPLL to MHz with 16 MHz FIRC reference.
PLLDIG.PLLDV.R = 0x04010028; //PREDIV = 0, MFD = 40, RFDPHI = 1, RFDPHI1 = 2
PLLDIG.PLLFD.R = 0x00000000; //PLL fractional numerators
PLLDIG.PLLCAL3.R = 0x00004000; //PLL fractional denominator
//Turn on clock sources and select system clock source
MC_ME.DRUN_MC.R = 0x001301F2; //Configure RUN0 mode settings with sysclk FMPLL_PHI0 (160 MHz).
MC_ME.RUN_MC[0].R = 0x001301F2; //Configure RUN0 mode settings with sysclk FMPLL_PHI0 (160 MHz).
//Configure the oscillator divided clocks
SIRC.CTL.R = 0x00000011; //SIRC_DIV_CLK is SIRC divided by 1 (0.128 MHz).
FIRC.CTL.R = 0x00000011; //FIRC_DIV_CLK is FIRC divided by 1 (16 MHz).
SXOSC.CTL.B.OSCDIV = 0x00; //SXOSC_DIV_CLK is SXOSC divided by 1 (0.032 MHz).
//FXOSC.CTL.B.OSCDIV = 0x00; //FXOSC_DIV_CLK is FXOSC divided by 1 (40 MHz).
MC_ME.RUN_PC[0].R = 0x000000FE; //Enable peripherals to run in all modes
//Mode transition to RUN0 mode:
//MC_ME.MCTL.R = 0x40005AF0; //Enter RUN0 mode & Key
//MC_ME.MCTL.R = 0x4000A50F; //Enter RUN0 mode & Inverted Key
//while(MC_ME.GS.B.S_MTRANS); //Wait for mode transition to complete
//while(MC_ME.GS.B.S_CURRENT_MODE != 0x4); //Verify RUN0 is the current mode
MC_ME.MCTL.R = 0x40005AF0; //Enter RUN0 mode & Key
MC_ME.MCTL.R = 0x4000A50F; //Enter RUN0 mode & Inverted Key
while(MC_ME.GS.B.S_MTRANS); //Wait for mode transition to complete
while(MC_ME.GS.B.S_CURRENT_MODE != 0x4); //Verify RUN0 is the current mode
}
I noticed a difference in the Fpll.
The one that works is using a 64 MHz Fpll (FMPLL_PHI0).
I tried to setup the (FMPLL_PHI0) for 160 MHz, similar to using the 40 MHz oscillator.
That is one difference I noticed. That and the following 2 Register settings.
PLLDIG_PLLFD = 0x00010000ul; /* DTDHDIS = 1 (Dither Disabled) */
PLLDIG_PLLFM = 0x40000000ul; /* SSCGBYP = 1 (Spread Spectrum Modulation is bypassed) */
I am not quite sure why those registers are set the way they are?
* Fpll = Fvco / (2^(RFDPHI+1))
*
* Fvco = (Fref / PREDIV) * (MFD + (MFN / (MFDEN + 1)))
*
* MFN = 0
* PREDIV = 2 (DIVIDE by 2)
* MFD = 128 (Multiply by 128)
* RFDPHI = 3 (Divide by 16)
* RFDPHI1 = 3 (Divide by 16)
*
* Fvco = (16MHz / 2) * 128
* = 1024MHz
*
* Fpll = 1024MHz / 2^4
* = 64MHz
*/
PLLDIG_PLLDV = 0x06032080ul;
Thank you,