/* * Counting example using the LPO clock and the prescale feature * * Sets compare value to 250. Thus when using the 1Khz LPO clock with * LPTMR0_PSR[PRESCALE]=0x4, it will take 8 seconds for Timer Compare Flag * to be set. (1Khz clock/32=31.25Hz clock) * * If prescaler was not used, then timer would only wait .25 seconds. * */ void lptmr_prescale() { int compare_value=250; //value must be less than 0xFFFF or 65535 printf("\n\n****************************\n"); printf("LPTMR Time Counting Example with Prescaler\n"); //Reset LPTMR module lptmr_clear_registers(); /* Configure LPTMR */ LPTMR0_CMR=LPTMR_CMR_COMPARE(compare_value); //Set compare value LPTMR0_PSR=LPTMR_PSR_PCS(0x1)|LPTMR_PSR_PRESCALE(0x4); //Use LPO clock and divide by 32 printf("LPTMR using LPO clock with PRESCALE=4 and compare value=250 (8 seconds)\n"); printf("Press a key to start counter\n"); in_char(); //wait for keyboard press LPTMR0_CSR|=LPTMR_CSR_TEN_MASK; //Turn on LPTMR with default settings //Wait for Timer Compare Flag to be set while((LPTMR0_CSR & LPTMR_CSR_TCF_MASK)==0) { //This may not get proper counter data if the CNR is read at the same time it is incremented printf("Current value of counter register CNR is %d\n",LPTMR0_CNR); } printf("Waited for %d counts\n",compare_value); printf("End of Time Counting Example with Prescale\n"); printf("****************************\n\n"); }
/*---------------------------------------------------------------------------*/ void rtimer_arch_init(void) { #if RTIMER_CONF_USE_LPTMR /* SIM_SCGC5: LPTMR=1 */ SIM_SCGC5 |= SIM_SCGC5_LPTMR_MASK; LPTMR0_CSR = (LPTMR_CSR_TCF_MASK | LPTMR_CSR_TPS(0x00) | LPTMR_CSR_TFC_MASK); /* Clear control register */ LPTMR0_CMR = LPTMR_CMR_COMPARE(LPTMR_CMR_COMPARE_MASK); /* Set up compare register */ LPTMR0_PSR = LPTMR_PSR_PRESCALE(0x00) | LPTMR_PSR_PBYP_MASK | LPTMR_PSR_PCS(0x01); /* Set up prescaler register */ LPTMR0_CSR = (LPTMR_CSR_TPS(0x00) | LPTMR_CSR_TEN_MASK); /* Set up control register */ #else /* SIM_SCGC6: TPM0=1 */ SIM_SCGC6 |= SIM_SCGC6_TPM0_MASK; TPM0_SC = (TPM_SC_CMOD(0x00) | TPM_SC_PS(0x00)); /* Clear status and control register */ TPM0_CNT = TPM_CNT_COUNT(0x00); /* Reset counter register */ TPM0_C1SC = 0x00U; /* Clear channel status and control register */ TPM0_C2SC = 0x00U; /* Clear channel status and control register */ TPM0_C3SC = 0x00U; /* Clear channel status and control register */ TPM0_C4SC = 0x00U; /* Clear channel status and control register */ TPM0_C5SC = 0x00U; /* Clear channel status and control register */ TPM0_MOD = TPM_MOD_MOD(0xFFFF); /* Set up modulo register */ TPM0_C0SC = (TPM_CnSC_CHIE_MASK | TPM_CnSC_MSA_MASK); /* Set up channel status and control register */ TPM0_C0V = TPM_CnV_VAL(0x00); /* Set up channel value register */ TPM0_SC = (TPM_SC_CMOD(0x01) | TPM_SC_PS(0x05)); /* Set up status and control register */ #endif /* RTIMER_CONF_USE_LPTMR */ PRINTF("rtimer_arch_init done\n"); }
/* ===================================================================*/ LDD_TDeviceData* FTM_Init(LDD_TUserData *UserDataPtr) { /* Allocate device structure */ FTM_TDeviceData *DeviceDataPrv; /* {MQXLite RTOS Adapter} Driver memory allocation: Dynamic allocation is simulated by a pointer to the static object */ DeviceDataPrv = &DeviceDataPrv__DEFAULT_RTOS_ALLOC; DeviceDataPrv->UserDataPtr = UserDataPtr; /* Store the RTOS device structure */ /* Interrupt vector(s) allocation */ /* {MQXLite RTOS Adapter} Save old and set new interrupt vector (function handler and ISR parameter) */ /* Note: Exception handler for interrupt is not saved, because it is not modified */ DeviceDataPrv->SavedISRSettings_TUInterrupt.isrData = _int_get_isr_data(LDD_ivIndex_INT_LPTimer); DeviceDataPrv->SavedISRSettings_TUInterrupt.isrFunction = _int_install_isr(LDD_ivIndex_INT_LPTimer, FTM_Interrupt, DeviceDataPrv); /* LPTMR0_CSR: ??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,TCF=1,TIE=0,TPS=0,TPP=0,TFC=0,TMS=0,TEN=0 */ LPTMR0_CSR = (LPTMR_CSR_TCF_MASK | LPTMR_CSR_TPS(0x00)); /* Clear control register */ /* LPTMR0_CMR: ??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,COMPARE=0x1387 */ LPTMR0_CMR = LPTMR_CMR_COMPARE(0x1387); /* Set up compare register */ /* LPTMR0_PSR: ??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,PRESCALE=1,PBYP=0,PCS=0 */ LPTMR0_PSR = (LPTMR_PSR_PRESCALE(0x01) | LPTMR_PSR_PCS(0x00)); /* Set up prescaler register */ /* NVICIP58: PRI58=0x70 */ NVICIP58 = NVIC_IP_PRI58(0x70); /* NVICISER1: SETENA|=0x04000000 */ NVICISER1 |= NVIC_ISER_SETENA(0x04000000); /* LPTMR0_CSR: ??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,TCF=0,TIE=1,TPS=0,TPP=0,TFC=0,TMS=0,TEN=1 */ LPTMR0_CSR = (LPTMR_CSR_TIE_MASK | LPTMR_CSR_TPS(0x00) | LPTMR_CSR_TEN_MASK); /* Set up control register */ /* Registration of the device structure */ PE_LDD_RegisterDeviceStructure(PE_LDD_COMPONENT_FTM_ID,DeviceDataPrv); return ((LDD_TDeviceData *)DeviceDataPrv); /* Return pointer to the device data structure */ }
/*! * brief Ungates the LPTMR clock and configures the peripheral for a basic operation. * * note This API should be called at the beginning of the application using the LPTMR driver. * * param base LPTMR peripheral base address * param config A pointer to the LPTMR configuration structure. */ void LPTMR_Init(LPTMR_Type *base, const lptmr_config_t *config) { assert(config); #if defined(LPTMR_CLOCKS) #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) uint32_t instance = LPTMR_GetInstance(base); /* Ungate the LPTMR clock*/ CLOCK_EnableClock(s_lptmrClocks[instance]); #if defined(LPTMR_PERIPH_CLOCKS) CLOCK_EnableClock(s_lptmrPeriphClocks[instance]); #endif #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */ #endif /* LPTMR_CLOCKS */ /* Configure the timers operation mode and input pin setup */ base->CSR = (LPTMR_CSR_TMS(config->timerMode) | LPTMR_CSR_TFC(config->enableFreeRunning) | LPTMR_CSR_TPP(config->pinPolarity) | LPTMR_CSR_TPS(config->pinSelect)); /* Configure the prescale value and clock source */ base->PSR = (LPTMR_PSR_PRESCALE(config->value) | LPTMR_PSR_PBYP(config->bypassPrescaler) | LPTMR_PSR_PCS(config->prescalerClockSource)); }
/******************************************************************************* * * PROCEDURE NAME: * lptmr_init - * *******************************************************************************/ void lptmr_init(int count, int clock_source) { SIM_SCGC5 |= SIM_SCGC5_LPTMR_MASK; LPTMR0_PSR = ( LPTMR_PSR_PRESCALE(0) // 0000 is div 2 | LPTMR_PSR_PBYP_MASK // LPO feeds directly to LPT | LPTMR_PSR_PCS(clock_source)) ; // use the choice of clock if (clock_source== 0) printf("\n LPTMR Clock source is the MCGIRCLK \n\r"); if (clock_source== 1) printf("\n LPTMR Clock source is the LPOCLK \n\r"); if (clock_source== 2) printf("\n LPTMR Clock source is the ERCLK32 \n\r"); if (clock_source== 3) printf("\n LPTMR Clock source is the OSCERCLK \n\r"); LPTMR0_CMR = LPTMR_CMR_COMPARE(count); //Set compare value LPTMR0_CSR =( LPTMR_CSR_TCF_MASK // Clear any pending interrupt | LPTMR_CSR_TIE_MASK // LPT interrupt enabled | LPTMR_CSR_TPS(0) //TMR pin select |!LPTMR_CSR_TPP_MASK //TMR Pin polarity |!LPTMR_CSR_TFC_MASK // Timer Free running counter is reset whenever TMR counter equals compare |!LPTMR_CSR_TMS_MASK //LPTMR0 as Timer ); LPTMR0_CSR |= LPTMR_CSR_TEN_MASK; //Turn on LPT and start counting }
/*FUNCTION********************************************************************** * * Function Name : LPTMR_HAL_SetPrescalerMode * Description : Set the LPTMR prescaler mode. * *END**************************************************************************/ void LPTMR_HAL_SetPrescalerMode(LPTMR_Type * base, lptmr_prescaler_user_config_t prescaler_config) { uint32_t psr; psr = LPTMR_PSR_PCS(prescaler_config.prescalerClockSelect) | LPTMR_PSR_PBYP(prescaler_config.prescalerBypass) | LPTMR_PSR_PRESCALE(prescaler_config.prescalerValue); LPTMR_WR_PSR(base, psr); }
/*-----------------------------------------------------------*/ void vPortInitTickTimer(void) { #if configUSE_TICKLESS_IDLE == 1 { #if TICK_NOF_BITS==32 xMaximumPossibleSuppressedTicks = 0xffffffffUL/TIMER_COUNTS_FOR_ONE_TICK; /* 32bit timer register */ #elif TICK_NOF_BITS==24 xMaximumPossibleSuppressedTicks = 0xffffffUL/TIMER_COUNTS_FOR_ONE_TICK; /* 24bit timer register */ #elif TICK_NOF_BITS==16 xMaximumPossibleSuppressedTicks = 0xffffUL/TIMER_COUNTS_FOR_ONE_TICK; /* 16bit timer register */ #elif TICK_NOF_BITS==8 xMaximumPossibleSuppressedTicks = 0xffUL/TIMER_COUNTS_FOR_ONE_TICK; /* 8bit timer register */ #else error "unknown configuration!" #endif #if configSYSTICK_USE_LOW_POWER_TIMER ulStoppedTimerCompensation = configSTOPPED_TIMER_COMPENSATION/(configCPU_CLOCK_HZ/configSYSTICK_LOW_POWER_TIMER_CLOCK_HZ); #else ulStoppedTimerCompensation = configSTOPPED_TIMER_COMPENSATION/(configCPU_CLOCK_HZ/configSYSTICK_CLOCK_HZ); #endif } #endif /* configUSE_TICKLESS_IDLE */ #if configSYSTICK_USE_LOW_POWER_TIMER SIM_SCGC5 |= SIM_SCGC5_LPTMR_MASK; /* enable clock: SIM_SCGC5: LPTMR=1 */ /* LPTMR0_CSR: ??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,TCF=1,TIE=0,TPS=0,TPP=0,TFC=0,TMS=0,TEN=0 */ LPTMR0_CSR = (LPTMR_CSR_TCF_MASK | LPTMR_CSR_TPS(0x00)); /* Clear control register */ /* LPTMR0_PSR: ??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,PRESCALE=0,PBYP=1,PCS=1 */ LPTMR0_PSR = LPTMR_PSR_PRESCALE(0x00) | /* prescaler value */ LPTMR_PSR_PBYP_MASK | /* prescaler bypass */ LPTMR_PSR_PCS(0x01); /* Clock source */ /* * PBYP PCS * ERCLK32 1 10 * LPO_1kHz 1 01 * ERCLK 0 00 * IRCLK 1 00 */ *(portNVIC_SYSPRI7) |= portNVIC_LP_TIMER_PRI; /* set priority of low power timer interrupt */ /* NVIC_ISER: SETENA|=0x10000000 */ NVIC_ISER |= NVIC_ISER_SETENA(0x10000000); /* 0xE000E100 <= 0x10000000 */ /* LPTMR0_CSR: ??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,TCF=0,TIE=0,TPS=0,TPP=0,TFC=0,TMS=0,TEN=1 */ LPTMR0_CSR = (LPTMR_CSR_TPS(0x00) | LPTMR_CSR_TEN_MASK); /* Set up control register */ #else /* use normal SysTick Counter */ *(portNVIC_SYSPRI3) |= portNVIC_SYSTICK_PRI; /* set priority of SysTick interrupt */ #endif /* Configure timer to interrupt at the requested rate. */ SET_TICK_DURATION(TIMER_COUNTS_FOR_ONE_TICK-1UL); RESET_TICK_COUNTER_VAL(); ENABLE_TICK_COUNTER(); }
void Lptmr_Init(int count, int clock_source) { _mqx_uint mqx_ret; SIM_SCGC5 |= SIM_SCGC5_LPTMR_MASK; SIM_SOPT1 &= ~SIM_SOPT1_OSC32KSEL_MASK; SIM_SOPT1 |= SIM_SOPT1_OSC32KSEL(2); // ERCLK32 is RTC OSC CLOCK PORTC_PCR1 &= ~PORT_PCR_MUX_MASK; PORTC_PCR1 |= PORT_PCR_MUX(1);//enable ptc1 alt1 functions to select RTC_CLKIN function /********************************************************************************* * On L2K tower board, we use external 32kHz clock instead of 32kHz crystal, so please * don't enable the 32kHz crystal oscillator **********************************************************************************/ /* RTC_CR |= RTC_CR_OSCE_MASK | RTC_CR_CLKO_MASK | RTC_CR_SC8P_MASK ; */ LPTMR0_PSR &= ~LPTMR_PSR_PRESCALE_MASK; LPTMR0_PSR |= LPTMR_PSR_PRESCALE(0); // 0000 is div 2 LPTMR0_PSR |= LPTMR_PSR_PBYP_MASK; // LPO feeds directly to LPT LPTMR0_PSR &= ~LPTMR_PSR_PCS_MASK; LPTMR0_PSR |= LPTMR_PSR_PCS(clock_source); // use the choice of clock if (clock_source== 0) APP_TRACE("\n LPTMR Clock source is the MCGIRCLK \n\r"); if (clock_source== 1) APP_TRACE("\n LPTMR Clock source is the LPOCLK \n\r"); if (clock_source== 2) APP_TRACE("\n LPTMR Clock source is the ERCLK32 \n\r"); if (clock_source== 3) APP_TRACE("\n LPTMR Clock source is the OSCERCLK \n\r"); LPTMR0_CMR = LPTMR_CMR_COMPARE(count); //Set compare value LPTMR0_CSR |=( LPTMR_CSR_TCF_MASK // Clear any pending interrupt | LPTMR_CSR_TIE_MASK // LPT interrupt enabled |!LPTMR_CSR_TPP_MASK //TMR Pin polarity |!LPTMR_CSR_TFC_MASK // Timer Free running counter is reset whenever TMR counter equals compare |!LPTMR_CSR_TMS_MASK //LPTMR0 as Timer ); enable_irq(28) ; _int_install_isr(LDD_ivIndex_INT_LPTimer, lptmr_isr, NULL); mqx_ret = _lwsem_create(&g_lptmr_int_sem, 0); ASSERT_PARAM(MQX_OK == mqx_ret); // // ready for this interrupt. // set_irq_priority(28, 2); }
void LPTMR_Init(LPTMR_Type *base, const lptmr_config_t *config) { assert(config); /* Ungate the LPTMR clock*/ CLOCK_EnableClock(s_lptmrClocks[LPTMR_GetInstance(base)]); /* Configure the timers operation mode and input pin setup */ base->CSR = (LPTMR_CSR_TMS(config->timerMode) | LPTMR_CSR_TFC(config->enableFreeRunning) | LPTMR_CSR_TPP(config->pinPolarity) | LPTMR_CSR_TPS(config->pinSelect)); /* Configure the prescale value and clock source */ base->PSR = (LPTMR_PSR_PRESCALE(config->value) | LPTMR_PSR_PBYP(config->bypassPrescaler) | LPTMR_PSR_PCS(config->prescalerClockSource)); }
static void lptmr_init(void) { uint32_t extosc; /* Clock the timer */ SIM->SCGC5 |= SIM_SCGC5_LPTMR_MASK; /* Reset */ LPTMR0->CSR = 0; #if defined(TARGET_KL43Z) /* Set interrupt handler */ NVIC_SetVector(LPTMR0_IRQn, (uint32_t)lptmr_isr); NVIC_EnableIRQ(LPTMR0_IRQn); MCG->C1 |= MCG_C1_IRCLKEN_MASK; extosc = mcgirc_frequency(); #else /* Set interrupt handler */ NVIC_SetVector(LPTimer_IRQn, (uint32_t)lptmr_isr); NVIC_EnableIRQ(LPTimer_IRQn); /* Clock at (1)MHz -> (1)tick/us */ /* Check if the external oscillator can be divided to 1MHz */ extosc = extosc_frequency(); #endif if (extosc != 0) { //If external oscillator found if (extosc % 1000000u == 0) { //If it is a multiple if 1MHz extosc /= 1000000; if (extosc == 1) { //1MHz, set timerprescaler in bypass mode LPTMR0->PSR = LPTMR_PSR_PCS(3) | LPTMR_PSR_PBYP_MASK; return; } else { //See if we can divide it to 1MHz uint32_t divider = 0; extosc >>= 1; while (1) { if (extosc == 1) { LPTMR0->PSR = LPTMR_PSR_PCS(3) | LPTMR_PSR_PRESCALE(divider); return; } if (extosc % 2 != 0) //If we can't divide by two anymore break; divider++; extosc >>= 1; } } } }
void Init_LPTMR(void) { SIM->SCGC5 |= SIM_SCGC5_LPTMR_MASK; // Configure LPTMR // select 1 kHz LPO clock with prescale factor 0, dividing clock by 2 // resulting in 500 Hz clock LPTMR0->PSR = LPTMR_PSR_PCS(1) | LPTMR_PSR_PRESCALE(0); LPTMR0->CSR = LPTMR_CSR_TIE_MASK; LPTMR0->CMR = 50; // Generate interrupt every 50 clock ticks or 100 ms // Configure NVIC NVIC_SetPriority(LPTimer_IRQn, 128); // 0, 64, 128 or 192 NVIC_ClearPendingIRQ(LPTimer_IRQn); NVIC_EnableIRQ(LPTimer_IRQn); }
/* ===================================================================*/ LDD_TDeviceData* TU1_Init(LDD_TUserData *UserDataPtr) { TU1_TDeviceData *DeviceDataPrv; if (PE_LDD_DeviceDataList[PE_LDD_COMPONENT_TU1_ID] == NULL) { /* Allocate device structure */ /* {Default RTOS Adapter} Driver memory allocation: Dynamic allocation is simulated by a pointer to the static object */ DeviceDataPrv = &DeviceDataPrv__DEFAULT_RTOS_ALLOC; DeviceDataPrv->UserDataPtr = UserDataPtr; /* Store the RTOS device structure */ DeviceDataPrv->InitCntr = 1U; /* First initialization */ } else { /* Memory is already allocated */ DeviceDataPrv = (TU1_TDeviceDataPtr) PE_LDD_DeviceDataList[PE_LDD_COMPONENT_TU1_ID]; DeviceDataPrv->UserDataPtr = UserDataPtr; /* Store the RTOS device structure */ DeviceDataPrv->InitCntr++; /* Increment counter of initialization */ return ((LDD_TDeviceData *)DeviceDataPrv); /* Return pointer to the device data structure */ } /* Interrupt vector(s) allocation */ /* {Default RTOS Adapter} Set interrupt vector: IVT is static, ISR parameter is passed by the global variable */ INT_LPTimer__DEFAULT_RTOS_ISRPARAM = DeviceDataPrv; /* SIM_SCGC5: LPTMR=1 */ SIM_SCGC5 |= SIM_SCGC5_LPTMR_MASK; /* LPTMR0_CSR: ??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,TCF=1,TIE=0,TPS=0,TPP=0,TFC=0,TMS=0,TEN=0 */ LPTMR0_CSR = (LPTMR_CSR_TCF_MASK | LPTMR_CSR_TPS(0x00)); /* Clear control register */ /* LPTMR0_CMR: ??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,COMPARE=0xFFFF */ LPTMR0_CMR = LPTMR_CMR_COMPARE(0xFFFF); /* Set up compare register */ /* LPTMR0_PSR: ??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,PRESCALE=0,PBYP=1,PCS=0 */ LPTMR0_PSR = LPTMR_PSR_PRESCALE(0x00) | LPTMR_PSR_PBYP_MASK | LPTMR_PSR_PCS(0x00); /* Set up prescaler register */ /* NVIC_IPR7: PRI_28=0x80 */ NVIC_IPR7 = (uint32_t)((NVIC_IPR7 & (uint32_t)~(uint32_t)( NVIC_IP_PRI_28(0x7F) )) | (uint32_t)( NVIC_IP_PRI_28(0x80) )); /* NVIC_ISER: SETENA|=0x10000000 */ NVIC_ISER |= NVIC_ISER_SETENA(0x10000000); /* LPTMR0_CSR: ??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,TCF=0,TIE=1,TPS=0,TPP=0,TFC=0,TMS=0,TEN=1 */ LPTMR0_CSR = (LPTMR_CSR_TIE_MASK | LPTMR_CSR_TPS(0x00) | LPTMR_CSR_TEN_MASK); /* Set up control register */ /* Registration of the device structure */ PE_LDD_RegisterDeviceStructure(PE_LDD_COMPONENT_TU1_ID,DeviceDataPrv); return ((LDD_TDeviceData *)DeviceDataPrv); /* Return pointer to the device data structure */ }
/* * External Reference Clock Example(PSC=0x3) * * TWR-K60N512 uses a 50MHz external clock * TWR-K40X256 uses a 8MHz external clock * * Test is pre-scaled to wait for 10 seconds in both cases by adjusting * the compare value. */ void lptmr_external_clk_input() { unsigned int compare_value; printf("\n\n****************************\n"); printf("External Clock Source Example\n"); //Reset LPTMR module lptmr_clear_registers(); /* Turn on external reference clock */ MCG_C2&=~MCG_C2_EREFS_MASK; //allow extal to drive OSC_CR |= OSC_CR_ERCLKEN_MASK; // selects EXTAL to drive XOSCxERCLK //Determine compare value based on which board is being used #if (defined(K60_CLK)) compare_value=7630; //~10 seconds with prescale=0xF and 50MHz clock #else compare_value=1220; //~10 seconds with prescale=0xF and 8MHz clock #endif /* Configure LPTMR */ LPTMR0_CMR=LPTMR_CMR_COMPARE(compare_value); //Set compare value LPTMR0_PSR=LPTMR_PSR_PCS(0x3)|LPTMR_PSR_PRESCALE(0xF); //Use external clock divided by 65536 printf("LPTMR using external clock with PRESCALE=0xF, and compare value=%d (10 seconds)\n",compare_value); printf("Press a key to start counter\n"); in_char(); LPTMR0_CSR|=LPTMR_CSR_TEN_MASK; //Turn on LPT with default settings printf("Counting...\n\n"); //Wait for Timer Compare Flag to be set while((LPTMR0_CSR&LPTMR_CSR_TCF_MASK)==0) { //This may not get proper counter data if the CNR is read at the same time it is incremented //printf("Current value of counter register CNR is %d\n",LPTMR0_CNR); } printf("Timer should have waited for 10 seconds\n"); printf("End of External Clock Example\n"); printf("****************************\n\n"); }
/* ** =================================================================== ** Method : LPTmr1_Init (component Init_LPTMR) ** ** Description : ** This method initializes registers of the LPTMR module ** according to the Peripheral Initialization settings. ** Call this method in user code to initialize the module. By ** default, the method is called by PE automatically; see "Call ** Init method" property of the component for more details. ** Parameters : None ** Returns : Nothing ** =================================================================== */ void LPTmr1_Init(void) { /* SIM_SCGC5: LPTMR=1 */ SIM_SCGC5 |= SIM_SCGC5_LPTMR_MASK; /* LPTMR0_CSR: ??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,TCF=0,TIE=0,TPS=0,TPP=0,TFC=0,TMS=0,TEN=0 */ LPTMR0_CSR = 0x00U; /* LPTMR0_CMR: ??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,COMPARE=0xC8 */ LPTMR0_CMR = LPTMR_CMR_COMPARE(0xC8); /* LPTMR0_CSR: ??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,TCF=1,TIE=0,TPS=0,TPP=0,TFC=0,TMS=0,TEN=0 */ LPTMR0_CSR = LPTMR_CSR_TCF_MASK; /* LPTMR0_PSR: ??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,PRESCALE=7,PBYP=0,PCS=0 */ LPTMR0_PSR = LPTMR_PSR_PRESCALE(0x07); /* LPTMR0_CSR: TCF=0,TEN=1 */ LPTMR0_CSR = (uint32_t)((LPTMR0_CSR & (uint32_t)~(uint32_t)( LPTMR_CSR_TCF_MASK )) | (uint32_t)( LPTMR_CSR_TEN_MASK )); }
/************************************************************************* * 野火嵌入式开发工作室 * * 函数名称:lptmr_counter_init * 功能说明:LPT累加捕捉 * 参数说明:LPT0_ALTn 输入管脚号 ,只能是 LPT0_ALT1、LPT0_ALT2 * count 产生中断的累加计数值 * PrescaleValue 延时滤波 * LPT_CFG 触发方式 * 函数返回:无 * 修改时间:2012-3-14 * 备 注: *************************************************************************/ void lptmr_counter_init(LPT0_ALTn altn,u16 count,u8 PrescaleValue,LPT_CFG cfg) { if(PrescaleValue > 0x0f)PrescaleValue=0x0f; //设置输入管脚 if(altn==LPT0_ALT1) { SIM_SCGC5 |= SIM_SCGC5_PORTA_MASK; //打开 PORTA 时钟 PORTA_PCR19=PORT_PCR_MUX(0x6); //在PTA19上使用 ALT6 } else if(altn==LPT0_ALT2) { SIM_SCGC5 |= SIM_SCGC5_PORTC_MASK; //使能 PORTC 时钟 PORTC_PCR5=PORT_PCR_MUX(0x4); //在PTC5上使用 ALT4 } else //不可能发生事件 { assert_failed(__FILE__, __LINE__); //设置管脚有误? } /* 开启模块时钟 */ SIM_SCGC5|=SIM_SCGC5_LPTIMER_MASK; //使能LPT模块时钟 /* 清状态寄存器 */ LPTMR0_CSR=0x00; //先关了LPT,这样才能设置时钟分频等 /* 设置累加计数值 */ LPTMR_CMR_REG(LPTMR0_BASE_PTR) = LPTMR_CMR_COMPARE(count); //设置比较值 /* 时钟选择 */ LPTMR_PSR_REG(LPTMR0_BASE_PTR) = LPTMR_PSR_PCS(0x1) | LPTMR_PSR_PBYP_MASK | LPTMR_PSR_PRESCALE(PrescaleValue); //使用 LPO clock 且 bypass glitch filter // 开启和配置脉冲滤波器:2^n个时钟上升沿才识别 /* 管脚设置、使能中断 */ LPTMR_CSR_REG(LPTMR0_BASE_PTR) = LPTMR_CSR_TPS(altn)| LPTMR_CSR_TMS_MASK | ( cfg ==LPT_Falling ? LPTMR_CSR_TPP_MASK : 0 ) | LPTMR_CSR_TEN_MASK | LPTMR_CSR_TIE_MASK ; // 选择输入管脚 选择脉冲计数 下降沿 上升沿 使能LPT // TFC = 0,即计数值等于比较值时,计数值复位 enable_irq(LPTMR_irq); //开引脚的IRQ中断 }
/* * 32kHz Input Clock Test (PSC=0x2) * The 32kHz clock (ERCLK32K) can come from two clock sources. * If SOPT1[OSC32KSEL]=1, then it uses 32kHz RTC crystal connected to XTAL32 * This is what the code below tests * If SOPT1[OSC32KSEL]=0, then it uses 32kHz System oscillator, and reguires * that the main system clock be a 32kHz crystal. The tower board does not * support that feature. * * Test is pre-scaled to wait for 8 seconds. */ void lptmr_32khz_input() { unsigned int compare_value=32768; //4 second delay with prescale=1 printf("\n\n****************************\n"); printf("32 Khz Clock Source Example\n"); //Reset LPTMR module lptmr_clear_registers(); /* * Configure to use 32Khz clock from RTC clock */ printf("Test using RTC OSC\n"); SIM_SCGC6|=SIM_SCGC6_RTC_MASK; //Enable RTC registers RTC_CR|=RTC_CR_OSCE_MASK; //Turn on RTC oscillator SIM_SOPT1|=SIM_SOPT1_OSC32KSEL_MASK; //Select RTC OSC as source for ERCLK32K /* Configure LPTMR */ LPTMR0_CMR=LPTMR_CMR_COMPARE(compare_value); //Set compare value LPTMR0_PSR=LPTMR_PSR_PCS(0x2)|LPTMR_PSR_PRESCALE(0x1); //Use 32khz clock (ERCLK32K) and divide source by 4 printf("LPTMR using 32Khz clock with PRESCALE=0x1, and compare value=32768 (4 seconds)\n"); printf("Press a key to start counter\n"); in_char(); LPTMR0_CSR|=LPTMR_CSR_TEN_MASK; //Turn on LPT with default settings printf("Counting...\n\n"); //Wait for Timer Compare Flag to be set while((LPTMR0_CSR&LPTMR_CSR_TCF_MASK)==0) { //This may not get proper counter data if the CNR is read at the same time it is incremented //printf("Current value of counter register CNR is %d\n",LPTMR0_CNR); } printf("4 seconds should have passed\n"); printf("End of 32 Khz Clock Source Example\n"); printf("****************************\n\n"); }
/* * Internal Reference Clock (PSC=0x0) * The Internal Reference Clock can come from two clock sources. * If MCG_C2[IRCS]=0, then uses slow internal clock (32kHz) * If MCG_C2[IRCS]=1, then uses fast internal clock (2Mhz) * * This example uses fast internal clock. It is pre-scaled to wait for 4 seconds. * Because of trim values, it may be slightly faster or slower than this. */ void lptmr_internal_ref_input() { unsigned int compare_value=15625; //4 seconds with prescale=8 and 2Mhz fast clock printf("\n\n****************************\n"); printf("Internal Reference Clock Example\n"); //Reset LPTMR module lptmr_clear_registers(); /* Ensure Internal Reference Clock is Enabled */ MCG_C1|=MCG_C1_IRCLKEN_MASK; //Enable fast internal ref clock by setting MCG_C2[IRCS]=1 //If wanted to use 32Khz slow mode, set MCG_C2[IRCS]=0 instead MCG_C2|=MCG_C2_IRCS_MASK; /* Configure LPTMR */ LPTMR0_CMR=LPTMR_CMR_COMPARE(compare_value); //Set compare value LPTMR0_PSR=LPTMR_PSR_PCS(0x0)|LPTMR_PSR_PRESCALE(0x8); //Use internal clock prescaled by 512 printf("LPTMR using fast internal ref clock with PRESCALE=0x8, and compare value=15625 (4 seconds)\n"); printf("Press a key to start counter\n"); in_char(); LPTMR0_CSR|=LPTMR_CSR_TEN_MASK; //Turn on LPT with default settings printf("Counting...\n\n"); //Wait for Timer Compare Flag to be set while((LPTMR0_CSR&LPTMR_CSR_TCF_MASK)==0) { //This may not get proper counter data if the CNR is read at the same time it is incremented //printf("Current value of counter register CNR is %d\n",LPTMR0_CNR); } printf("4 seconds should have passed\n"); printf("End of Internal reference Clock Source Example\n"); printf("****************************\n\n"); }
/** * @brief Compute the LPTMR prescaler setting, see reference manual for details */ static inline int32_t _lptmr_compute_prescaler(uint8_t dev, uint32_t freq) { uint32_t prescale = 0; if ((freq > lptmr_config[dev].base_freq) || (freq == 0)) { /* Frequency out of range */ return -1; } while (freq < lptmr_config[dev].base_freq){ ++prescale; freq <<= 1; } if (freq != lptmr_config[dev].base_freq) { /* freq was not a power of two division of base_freq */ return -2; } if (prescale == 0) { /* Prescaler bypass enabled */ return LPTMR_PSR_PBYP_MASK; } /* LPTMR_PSR_PRESCALE == 0 yields base_freq / 2, * LPTMR_PSR_PRESCALE == 1 yields base_freq / 4 etc.. */ return LPTMR_PSR_PRESCALE(prescale - 1); }
/** * @brief lptmr 定时器初始化 * * @param clock 时钟选择 * * @return E_OK 初始化成功 * @return E_INIT 初始化失败 * * @see lptmr_registers_clear() * @note 在这个定时器中,由于产生不了小于35.6ms的基准定时,所以统一选择基准为50ms的定时。 * 在移植过程中应该相应调整COMPARE寄存器和PSR寄存器中的预分频系数。 */ ER lptmr_timer_init(uint32_t clock) { switch (clock) { case LPTMR_INTERNAL_CLOCK: lptmr_registers_clear(); /* 把LPTMR寄存器清零 */ SIM_SCGC5 |= SIM_SCGC5_LPTIMER_MASK; /* 使能LPT模块时钟 */ MCG_C1 |= MCG_C1_IRCLKEN_MASK; /* 使能内部参考时钟 */ MCG_C2 |= MCG_C2_IRCS_MASK; /* MCG_C2[IRCS]=1,使能快速内部参考时钟(2MHz) */ /** * 配置 LPTMR参数 */ LPTMR0_CMR = LPTMR_CMR_COMPARE(LPTMR_TIMER_COMPARE_INTERNAL); /* 设置比较寄存器值 */ LPTMR0_PSR = LPTMR_PSR_PCS(LPTMR_INTERNAL_CLOCK) |LPTMR_PSR_PRESCALE(LPTMR_TIMER_PRESCALE8); /* 使用内部时钟,系数预分频为8*/ LPTMR0_CSR |= LPTMR_CSR_TEN_MASK; /* 开启LPT模块设置*/ break; case LPTMR_LPO_CLOCK: lptmr_registers_clear(); /* 把LPTMR寄存器清零 */ SIM_SCGC5 |= SIM_SCGC5_LPTIMER_MASK; /*使能LPT模块时钟*/ /** * 配置 LPTMR */ LPTMR0_CMR = LPTMR_CMR_COMPARE(LPTMR_TIMER_COMPARE_LPO); /*设置比较寄存器值 */ LPTMR0_PSR = LPTMR_PSR_PCS(LPTMR_LPO_CLOCK) | LPTMR_PSR_PBYP_MASK; /*设置PBYP为1,计数器一次一次累加*/ LPTMR0_CSR |= LPTMR_CSR_TEN_MASK; /*开启LPT模块设置*/ break; default: return E_OBJ; /*如果初始化失败*/ } return E_OK; /*如果初始化成功*/ }
return; } if (extosc % 2 != 0) //If we can't divide by two anymore break; divider++; extosc >>= 1; } } } } #if defined(TARGET_KL43Z) //No suitable actual IRC oscillator clock -> Set it to (8MHz / divider) MCG->SC &= ~MCG_SC_FCRDIV_MASK; uint32_t temp = ~MCG->MC; MCG->MC &= temp & MCG_MC_LIRC_DIV2_MASK; LPTMR0->PSR = LPTMR_PSR_PCS(0) | LPTMR_PSR_PRESCALE(2); #else //No suitable external oscillator clock -> Use fast internal oscillator (4MHz / divider) MCG->C1 |= MCG_C1_IRCLKEN_MASK; MCG->C2 |= MCG_C2_IRCS_MASK; LPTMR0->PSR = LPTMR_PSR_PCS(0); switch (MCG->SC & MCG_SC_FCRDIV_MASK) { case MCG_SC_FCRDIV(0): //4MHz LPTMR0->PSR |= LPTMR_PSR_PRESCALE(1); break; case MCG_SC_FCRDIV(1): //2MHz LPTMR0->PSR |= LPTMR_PSR_PRESCALE(0); break; default: //1MHz or anything else, in which case we put it on 1MHz MCG->SC &= ~MCG_SC_FCRDIV_MASK; MCG->SC |= MCG_SC_FCRDIV(2);
void WakeUp::set_ms(uint32_t ms) { /* Clock the timer */ SIM->SCGC5 |= 0x1u; //Check if it is running, in that case, store current values remainder_count = 0; if (NVIC_GetVector(LPTimer_IRQn) != (uint32_t)WakeUp::irq_handler) { oldvector = NVIC_GetVector(LPTimer_IRQn); oldPSR = LPTMR0->PSR; if (LPTMR0->CSR & LPTMR_CSR_TIE_MASK) { //Write first to sync value LPTMR0->CNR = 0; uint16_t countval = LPTMR0->CNR; if (countval < LPTMR0->CMR) remainder_count = countval - LPTMR0->CMR; } } LPTMR0->CSR = 0; if (ms != 0) { /* Set interrupt handler */ NVIC_SetVector(LPTimer_IRQn, (uint32_t)WakeUp::irq_handler); NVIC_EnableIRQ(LPTimer_IRQn); uint32_t counts; //Set clock if (is32kXtal()) { SIM->SOPT1 &= ~SIM_SOPT1_OSC32KSEL_MASK; //Put RTC/LPTMR on 32kHz external. #ifdef OSC0 OSC0->CR |= OSC_CR_EREFSTEN_MASK; #else OSC->CR |= OSC_CR_EREFSTEN_MASK; #endif LPTMR0->PSR = LPTMR_PSR_PCS(2); counts = (uint32_t)((float)ms * 32.768f); } else { //Clock from the 1kHz LPO LPTMR0->PSR = LPTMR_PSR_PCS(1); counts = (uint32_t)((float)ms * cycles_per_ms); } //If no prescaler is needed if (counts <= 0xFFFF) LPTMR0->PSR |= LPTMR_PSR_PBYP_MASK; else { //Otherwise increase prescaler until it fits counts >>= 1; uint32_t prescaler = 0; while (counts > 0xFFFF) { counts >>= 1; prescaler++; } LPTMR0->PSR |= LPTMR_PSR_PRESCALE(prescaler); } LPTMR0->CMR = counts; LPTMR0->CSR = LPTMR_CSR_TIE_MASK; LPTMR0->CSR |= LPTMR_CSR_TEN_MASK; } else {