KDS 3.0
SDK 1.2
processor: kl03
using freedom board.
Using openSDA debugger
Hello dear freescale comunity,
In my application, I switch between 8MHz/8MHz and 48MHz/24MHz clock for the core/bus speed. It all works fine... except when I use the timer in between. If I use the itmer then my application goes into reset vector.
The line that seems to fail is:
SIM_CLKDIV1 = SIM_CLKDIV1_OUTDIV4(1); //Divide bus/flash clock by 2
and
SIM_CLKDIV1 = ~SIM_CLKDIV1_OUTDIV4_MASK; //Set bus speed to 8Mhz
I appreciate your help with this.
Thank you!
The full code to reproduce the problem is below:
#include "fsl_device_registers.h"
#include "fsl_port_hal.h"
#include "fsl_gpio_hal.h"
#include "fsl_tpm_driver.h"
#define TPM_INSTANCE 0
int main(void)
{
volatile unsigned int i,j;
CLOCK_SYS_EnablePortClock(PORTB_IDX);
//Set ports as GPIO
configure_gpio();
while(1) {
__asm("CPSID i"); // Disable interrupts
MCG_MC = MCG_MC_HIRCEN_MASK;
MCG_C1 &= ~MCG_C1_CLKS_MASK; // Enable Main Clock Source of the 48MHz
while(MCG_S & MCG_S_CLKST_MASK) { }; //Wait until 48 Mhz clock gets selected
SIM_CLKDIV1 = SIM_CLKDIV1_OUTDIV4(1); //Divide bus/flash clock by 2
__asm("CPSIE i"); // Disable interrupts
//Enable clock to timer
SIM_SCGC6 |= SIM_SCGC6_TPM0_MASK;
SIM_SOPT2 |= SIM_SOPT2_TPMSRC(kTpmClockSourceModuleHighFreq);
////////////// Works if I comment all the timer stuff
/*
TPM0_C0SC = TPM_CnSC_CHF_MASK ; //Clear ch0 flag and stop timer1, channel0
TPM0_SC &= ~TPM_SC_CMOD_MASK; //Make sure TPM is disabled
TPM0_CNT = 0;
TPM0_MOD = 65535u;
TPM0_C0SC = 0; //Count up
TPM0_SC |= TPM_SC_TOF_MASK; //Clear overflow flag if any
TPM0_SC |= TPM_SC_CMOD(kTpmClockSourceModuleClk); //Fire it up
//*/
PTB -> PTOR|=0x1<<10;
for(i=0;i<10;i++) { }
////////////// Works if I comment all the timer stuff
/*
TPM0_SC = 0; //Stop counter
j = TPM0_CNT & TPM_CNT_COUNT_MASK;
TPM0_CNT = 0x0; //Clear count
TPM0_MOD = 0x0; //Clear mod
*/
__asm("CPSID i"); // Disable interrupts
SIM_SCGC6 &= ~SIM_SCGC6_TPM0_MASK;
SIM_SOPT2 &= ~SIM_SOPT2_TPMSRC_MASK;
MCG_C2 = MCG_C2_IRCS(1);
MCG_C1 = MCG_C1_IRCLKEN(1);
MCG_C1 = MCG_C1_CLKS(1); //Run at 8MHz
while(MCG_S & MCG_S_CLKST_MASK != 0x1) { } //Wait until clock is selected
SIM_CLKDIV1 = ~SIM_CLKDIV1_OUTDIV4_MASK; //Set bus speed to 8Mhz
MCG_SC = MCG_SC_FCRDIV(0x0); //0x07 = Divide 2Mhz clock by 128=15.625kHz
MCG_MC =0;
__asm("CPSIE i"); // Enable interrupts
}
return 0;
}
void configure_gpio(void) {
unsigned int i;
PORT_HAL_SetMuxMode(PORTB_BASE_PTR, 10u,kPortMuxAsGpio); //Switch pin attached to PB0 ---not anymore
GPIO_HAL_SetPinDir(GPIOB_BASE_PTR, 10u, kGpioDigitalOutput); //Sensing on port B0
}
////////////////////////////////////////////////////////////////////////////////
// EOF
////////////////////////////////////////////////////////////////////////////////
As a follow up.
I notice there are two errors in my code:
MCG_C1 = MCG_C1_CLKS(1); //Run at 8MHz
should be
MCG_C1 |= MCG_C1_CLKS(1); //Run at 8MHz
SIM_CLKDIV1 = ~SIM_CLKDIV1_OUTDIV4_MASK; //Set bus speed to 8Mhz
should be
SIM_CLKDIV1 &= ~SIM_CLKDIV1_OUTDIV4_MASK; //Set bus speed to 8Mhz
The problem remains though
Hi,
What kind of reset will happen if you run the timer code?
I would recommend customer to check Example code on how to configure the TPM as PWM in the FRDM-KL25 board.
Wish it helps.
Have a great day,
Ma Hui
-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------
Hello,
I looked at the code. But I don't think it is very relevant. First, I use (for most of the part) bare metal code. Secondly, the timer works ok in count-up mode. Finally, changing the clocks work fine if I don't have the timer.
The problem arises when I mix them together. I need to double check this, but I am pretty sure I was getting a lockup event. i.e.:
RCM->SRS1->LOCKUP bit is on.
Thank you,
-Carlos
Hi Carlos,
The reason could cause Kinetis core enter into lockup status as below: 1> An incorrect Clock mode transition occurs 2> Or the clock part is over-clocked 3> Or Code executes after POR, if a part memory is not programmed 4> Broken external oscillator if using external clock as reference clock.
Please change the code order, first change the SIM_CLKDIV1 register, then change the MCG work mode.
Such as:
__asm("CPSID i"); // Disable interrupts
SIM_CLKDIV1 = SIM_CLKDIV1_OUTDIV4(1); | //Divide bus/flash clock by 2 |
MCG_MC = MCG_MC_HIRCEN_MASK;
MCG_C1 &= ~MCG_C1_CLKS_MASK; // Enable Main Clock Source of the 48MHz
while(MCG_S & MCG_S_CLKST_MASK) { }; //Wait until 48 Mhz clock gets selected
__asm("CPSIE i"); // Disable interrupts
Wish it helps.
Have a great day,
Ma Hui
-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------