void Init_RGB_LEDs(void) { SIM->SCGC5 |= SIM_SCGC5_PORTB_MASK | SIM_SCGC5_PORTD_MASK; SIM->SCGC6 |= SIM_SCGC6_TPM0_MASK | SIM_SCGC6_TPM2_MASK; SIM->SOPT2 |= SIM_SOPT2_TPMSRC(2); PORTB->PCR[18] &= ~PORT_PCR_MUX_MASK; PORTB->PCR[18] |= PORT_PCR_MUX(3); // TPM2_CH0 enable on PTB18 PORTB->PCR[19] &= ~PORT_PCR_MUX_MASK; PORTB->PCR[19] |= PORT_PCR_MUX(3); // TPM2_CH1 enable on PTB19 PORTD->PCR[1] &= ~PORT_PCR_MUX_MASK; PORTD->PCR[1] |= PORT_PCR_MUX(4); // TPM0_CH1 enable on PTD1 TPM0->MOD = TPM_MODULE; // 0x0063 / 25MHz = 4uS PWM period TPM0->CONTROLS[1].CnSC = TPM_Cn_MODE; // No Interrupts; High True pulses on Edge Aligned PWM TPM0->CONTROLS[1].CnV = TPM_INIT_VAL; // set to initial duty cycle TPM2->MOD = TPM_MODULE; // 0x0063 / 25MHz = 4uS PWM period */ TPM2->CONTROLS[0].CnSC = TPM_Cn_MODE; // No Interrupts; High True pulses on Edge Aligned PWM TPM2->CONTROLS[0].CnV = TPM_INIT_VAL; // set to initial duty cycle TPM2->CONTROLS[1].CnSC = TPM_Cn_MODE; // No Interrupts; High True pulses on Edge Aligned PWM TPM2->CONTROLS[1].CnV = TPM_INIT_VAL; // set to initial duty cycle TPM2->SC = TPM_SC_CMOD(1) | TPM_SC_PS(0); // Edge Aligned PWM running from BUSCLK TPM0->SC = TPM_SC_CMOD(1) | TPM_SC_PS(0); // Edge Aligned PWM running from BUSCLK }
/*---------------------------------------------------------------------------*/ 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* TU1_Init(LDD_TUserData *UserDataPtr) { TU1_TDeviceData *DeviceDataPrv; if (PE_LDD_DeviceDataList[PE_LDD_COMPONENT_TU1_ID] == NULL) { /* Allocate device structure */ /* {FreeRTOS 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 */ } /* SIM_SCGC6: TPM1=1 */ SIM_SCGC6 |= SIM_SCGC6_TPM1_MASK; /* TPM1_SC: ??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,DMA=0,TOF=0,TOIE=0,CPWMS=0,CMOD=0,PS=0 */ TPM1_SC = (TPM_SC_CMOD(0x00) | TPM_SC_PS(0x00)); /* Clear status and control register */ /* TPM1_CNT: ??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,COUNT=0 */ TPM1_CNT = TPM_CNT_COUNT(0x00); /* Reset counter register */ /* TPM1_C0SC: ??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,CHF=0,CHIE=0,MSB=0,MSA=0,ELSB=0,ELSA=0,??=0,DMA=0 */ TPM1_C0SC = 0x00U; /* Clear channel status and control register */ /* TPM1_C1SC: ??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,CHF=0,CHIE=0,MSB=0,MSA=0,ELSB=0,ELSA=0,??=0,DMA=0 */ TPM1_C1SC = 0x00U; /* Clear channel status and control register */ /* TPM1_MOD: ??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,MOD=0xCCCC */ TPM1_MOD = TPM_MOD_MOD(0xCCCC); /* Set up modulo register */ /* TPM1_C1SC: ??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,CHF=0,CHIE=0,MSB=1,MSA=0,ELSB=1,ELSA=1,??=0,DMA=0 */ TPM1_C1SC = (TPM_CnSC_MSB_MASK | TPM_CnSC_ELSB_MASK | TPM_CnSC_ELSA_MASK); /* Set up channel status and control register */ /* TPM1_C1V: ??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,VAL=0x0F5C */ TPM1_C1V = TPM_CnV_VAL(0x0F5C); /* Set up channel value register */ /* PORTA_PCR13: ISF=0,MUX=3 */ PORTA_PCR13 = (uint32_t)((PORTA_PCR13 & (uint32_t)~(uint32_t)( PORT_PCR_ISF_MASK | PORT_PCR_MUX(0x04) )) | (uint32_t)( PORT_PCR_MUX(0x03) )); DeviceDataPrv->Source = TPM_PDD_SYSTEM; /* Store clock source */ /* TPM1_SC: ??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,DMA=0,TOF=0,TOIE=0,CPWMS=0,CMOD=1,PS=3 */ TPM1_SC = (TPM_SC_CMOD(0x01) | TPM_SC_PS(0x03)); /* Set up status and 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 */ }
void TPM_Init(TPM_Type *base, const tpm_config_t *config) { assert(config); /* Enable the module clock */ CLOCK_EnableClock(s_tpmClocks[TPM_GetInstance(base)]); #if defined(FSL_FEATURE_TPM_HAS_GLOBAL) && FSL_FEATURE_TPM_HAS_GLOBAL /* TPM reset is available on certain SoC's */ TPM_Reset(base); #endif /* Set the clock prescale factor */ base->SC = TPM_SC_PS(config->prescale); /* Setup the counter operation */ base->CONF = TPM_CONF_DOZEEN(config->enableDoze) | TPM_CONF_GTBEEN(config->useGlobalTimeBase) | TPM_CONF_CROT(config->enableReloadOnTrigger) | TPM_CONF_CSOT(config->enableStartOnTrigger) | TPM_CONF_CSOO(config->enableStopOnOverflow) | #if defined(FSL_FEATURE_TPM_HAS_PAUSE_COUNTER_ON_TRIGGER) && FSL_FEATURE_TPM_HAS_PAUSE_COUNTER_ON_TRIGGER TPM_CONF_CPOT(config->enablePauseOnTrigger) | #endif #if defined(FSL_FEATURE_TPM_HAS_EXTERNAL_TRIGGER_SELECTION) && FSL_FEATURE_TPM_HAS_EXTERNAL_TRIGGER_SELECTION TPM_CONF_TRGSRC(config->triggerSource) | #endif TPM_CONF_TRGSEL(config->triggerSelect); if (config->enableDebugMode) { base->CONF |= TPM_CONF_DBGMODE_MASK; } else { base->CONF &= ~TPM_CONF_DBGMODE_MASK; } }
void init_PWM(void) { // setup timer for PWM // set module clock to FLL SIM_SOPT2 |= SIM_SOPT2_TPMSRC(1); // turn on TPM clock SIM_SCGC6 |= SIM_SCGC6_TPM0_MASK; // turn off module clock TPM0_SC &= ~(TPM_SC_CMOD_MASK); // wait for counter to turn off while( TPM0_SC & TPM_SC_CMOD_MASK ); // set MSB, set ELSB TPM0_C0SC = (TPM_CnSC_MSB_MASK | TPM_CnSC_ELSB_MASK); // Set the PWM period TPM0_MOD = 1000; // Set the initial value TPM0_C0V = 500; // Clear the counter TPM0_CNT = 0; // counter increments on TPM clock, PreScale = /1 TPM0_SC = (TPM_SC_CMOD(1) | TPM_SC_PS(0)); SIM_SCGC5 |= SIM_SCGC5_PORTC_MASK; PORTC_PCR1 = PORT_PCR_MUX(4); // Set PTC1 to TPM0_CH0 }
int TPM_init_IC(TPM_MemMapPtr TPMx, int clock_source, int modulo, int clock_mode, int ps) { int val = 1; int i; if(TPMx == TPM0_BASE_PTR) SIM_SCGC6 |= SIM_SCGC6_TPM0_MASK; else if(TPMx == TPM1_BASE_PTR) SIM_SCGC6 |= SIM_SCGC6_TPM1_MASK; else SIM_SCGC6 |= SIM_SCGC6_TPM2_MASK; SIM_SOPT2 |= SIM_SOPT2_TPMSRC(clock_source); TPM_MOD_REG(TPMx) = modulo; TPM_SC_REG(TPMx) = TPM_SC_TOIE_MASK | TPM_SC_CMOD(clock_mode) | TPM_SC_PS(ps); i= ps; while(i--) { val += val; } val=(mcg_clk_hz/2)/val; return val; }
/* Initialize the turning servo with the TPM module. * Sets up the timer clock and aligns servo to center */ void InitServo() { SIM_SOPT2 |= SIM_SOPT2_PLLFLLSEL_MASK; SIM_SOPT2 &= ~(SIM_SOPT2_TPMSRC_MASK); SIM_SOPT2 |= SIM_SOPT2_TPMSRC(1); SIM_SCGC6 |= SIM_SCGC6_TPM1_MASK; TPM1_SC = 0; TPM1_CONF = 0; TPM1_SC = TPM_SC_PS(SERVO_CLK_PRESCALE); TPM1_SC |= TPM_SC_TOIE_MASK; TPM1_MOD = SERVO_CLK / (1 << (SERVO_CLK_PRESCALE + 1)) / SERVO_FREQ; TPM1_C0SC = TPM_CnSC_MSB_MASK | TPM_CnSC_ELSB_MASK; TPM1_C1SC = TPM_CnSC_MSB_MASK | TPM_CnSC_ELSB_MASK; SetServo(0.0); TPM1_SC |= TPM_SC_CMOD(1); enable_irq(INT_TPM1 - 16); PORTB_PCR0 = PORT_PCR_MUX(3); }
void Init_TPM(uint32_t period_ms) { //turn on clock to TPM SIM->SCGC6 |= SIM_SCGC6_TPM0_MASK; //set clock source for tpm to be TPM Source 3 which is MCGIR (32 kHz) SIM->SOPT2 |= SIM_SOPT2_TPMSRC(3); // disable TPM TPM0->SC = 0; //set TPM to count up and divide by 32 with prescaler and use clock mode // will count at 1 kHz TPM0->SC = (TPM_SC_PS(5)); //load the counter and mod. Note: 16-bit counter, not 32-bit TPM0->MOD = TPM_MOD_MOD(period_ms); TPM0->SC |= TPM_SC_TOIE_MASK; // Configure NVIC NVIC_SetPriority(TPM0_IRQn, 128); // 0, 64, 128 or 192 NVIC_ClearPendingIRQ(TPM0_IRQn); NVIC_EnableIRQ(TPM0_IRQn); }
void pwmout_init(pwmout_t* obj, PinName pin) { // determine the channel PWMName pwm = (PWMName)pinmap_peripheral(pin, PinMap_PWM); if (pwm == (uint32_t)NC) { error("PwmOut pin mapping failed"); } unsigned int port = (unsigned int)pin >> PORT_SHIFT; unsigned int tpm_n = (pwm >> TPM_SHIFT); unsigned int ch_n = (pwm & 0xFF); SIM->SCGC5 |= 1 << (SIM_SCGC5_PORTA_SHIFT + port); SIM->SCGC6 |= 1 << (SIM_SCGC6_TPM0_SHIFT + tpm_n); SIM->SOPT2 |= SIM_SOPT2_TPMSRC(1); // Clock source: MCGFLLCLK or MCGPLLCLK TPM_Type *tpm = (TPM_Type *)(TPM0_BASE + 0x1000 * tpm_n); tpm->SC = TPM_SC_CMOD(1) | TPM_SC_PS(6); // (48)MHz / 64 = (0.75)MHz tpm->CONTROLS[ch_n].CnSC = (TPM_CnSC_MSB_MASK | TPM_CnSC_ELSB_MASK); // No Interrupts; High True pulses on Edge Aligned PWM obj->CnV = &tpm->CONTROLS[ch_n].CnV; obj->MOD = &tpm->MOD; obj->CNT = &tpm->CNT; // default to 20ms: standard for servos, and fine for e.g. brightness control pwmout_period_ms(obj, 20); pwmout_write(obj, 0); // Wire pinout pinmap_pinout(pin, PinMap_PWM); }
/* ===================================================================*/ LDD_TDeviceData* TU2_Init(LDD_TUserData *UserDataPtr) { /* Allocate device structure */ TU2_TDeviceData *DeviceDataPrv; /* {FreeRTOS 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 */ /* {FreeRTOS RTOS Adapter} Set interrupt vector: IVT is static, ISR parameter is passed by the global variable */ INT_TPM1__BAREBOARD_RTOS_ISRPARAM = DeviceDataPrv; /* SIM_SCGC6: TPM1=1 */ SIM_SCGC6 |= SIM_SCGC6_TPM1_MASK; /* TPM1_SC: ??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,DMA=0,TOF=0,TOIE=0,CPWMS=0,CMOD=0,PS=0 */ TPM1_SC = (TPM_SC_CMOD(0x00) | TPM_SC_PS(0x00)); /* Clear status and control register */ /* TPM1_CNT: ??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,COUNT=0 */ TPM1_CNT = TPM_CNT_COUNT(0x00); /* Reset counter register */ /* TPM1_C0SC: ??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,CHF=0,CHIE=0,MSB=0,MSA=0,ELSB=0,ELSA=0,??=0,DMA=0 */ TPM1_C0SC = 0x00U; /* Clear channel status and control register */ /* TPM1_C1SC: ??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,CHF=0,CHIE=0,MSB=0,MSA=0,ELSB=0,ELSA=0,??=0,DMA=0 */ TPM1_C1SC = 0x00U; /* Clear channel status and control register */ /* TPM1_MOD: ??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,MOD=0xFFFF */ TPM1_MOD = TPM_MOD_MOD(0xFFFF); /* Set up modulo register */ /* TPM1_C1SC: ??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,CHF=0,CHIE=1,MSB=0,MSA=0,ELSB=1,ELSA=1,??=0,DMA=0 */ TPM1_C1SC = (TPM_CnSC_CHIE_MASK | TPM_CnSC_ELSB_MASK | TPM_CnSC_ELSA_MASK); /* Set up channel status and control register */ /* PORTA_PCR13: ISF=0,MUX=3 */ PORTA_PCR13 = (uint32_t)((PORTA_PCR13 & (uint32_t)~(uint32_t)( PORT_PCR_ISF_MASK | PORT_PCR_MUX(0x04) )) | (uint32_t)( PORT_PCR_MUX(0x03) )); DeviceDataPrv->EnEvents = 0x0101U; /* Enable selected events */ /* NVIC_IPR4: PRI_18=0x80 */ NVIC_IPR4 = (uint32_t)((NVIC_IPR4 & (uint32_t)~(uint32_t)( NVIC_IP_PRI_18(0x7F) )) | (uint32_t)( NVIC_IP_PRI_18(0x80) )); /* NVIC_ISER: SETENA|=0x00040000 */ NVIC_ISER |= NVIC_ISER_SETENA(0x00040000); /* TPM1_SC: ??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,DMA=0,TOF=0,TOIE=1,CPWMS=0,CMOD=1,PS=4 */ TPM1_SC = (TPM_SC_TOIE_MASK | TPM_SC_CMOD(0x01) | TPM_SC_PS(0x04)); /* Set up status and control register */ /* Registration of the device structure */ PE_LDD_RegisterDeviceStructure(PE_LDD_COMPONENT_TU2_ID,DeviceDataPrv); return ((LDD_TDeviceData *)DeviceDataPrv); /* Return pointer to the device data structure */ }
void TFC_InitServos() { //Clock Setup for the TPM requires a couple steps. //1st, set the clock mux //See Page 124 of f the KL25 Sub-Family Reference Manual, Rev. 3, September 2012 SIM_SOPT2 |= SIM_SOPT2_PLLFLLSEL_MASK;// We Want MCGPLLCLK/2 (See Page 196 of the KL25 Sub-Family Reference Manual, Rev. 3, September 2012) SIM_SOPT2 &= ~(SIM_SOPT2_TPMSRC_MASK); SIM_SOPT2 |= SIM_SOPT2_TPMSRC(1); //We want the MCGPLLCLK/2 (See Page 196 of the KL25 Sub-Family Reference Manual, Rev. 3, September 2012) //Enable the Clock to the FTM1 Module //See Page 207 of f the KL25 Sub-Family Reference Manual, Rev. 3, September 2012 SIM_SCGC6 |= SIM_SCGC6_TPM1_MASK; //The TPM Module has Clock. Now set up the peripheral //Blow away the control registers to ensure that the counter is not running TPM1_SC = 0; TPM1_CONF = 0; //While the counter is disabled we can setup the prescaler TPM1_SC = TPM_SC_PS(FTM1_CLK_PRESCALE); TPM1_SC |= TPM_SC_TOIE_MASK; //Enable Interrupts for the Timer Overflow //Setup the mod register to get the correct PWM Period TPM1_MOD = FTM1_CLOCK/(1<<(FTM1_CLK_PRESCALE+1))/FTM1_OVERFLOW_FREQUENCY; //Setup Channels 0 and 1 TPM1_C0SC = TPM_CnSC_MSB_MASK | TPM_CnSC_ELSB_MASK; TPM1_C1SC = TPM_CnSC_MSB_MASK | TPM_CnSC_ELSB_MASK; //Enable the Counter //Set the Default duty cycle to servo neutral TFC_SetServo(0, 0.0); TFC_SetServo(1, 0.0); //Enable the TPM COunter TPM1_SC |= TPM_SC_CMOD(1); //Enable TPM1 IRQ on the NVIC enable_irq (INT_TPM1-16); //Enable the FTM functions on the the port PORTB_PCR0 = PORT_PCR_MUX(3); PORTB_PCR1 = PORT_PCR_MUX(3); }
void pwmout_init(pwmout_t* obj, PinName pin) { // determine the channel PWMName pwm = (PWMName)pinmap_peripheral(pin, PinMap_PWM); MBED_ASSERT(pwm != (PWMName)NC); uint32_t clkdiv = 0; float clkval; #if defined(TARGET_KL43Z) if (mcgirc_frequency()) { SIM->SOPT2 |= SIM_SOPT2_TPMSRC(3); // Clock source: MCGIRCLK clkval = mcgirc_frequency() / 1000000.0f; } else { SIM->SOPT2 |= SIM_SOPT2_TPMSRC(1); // Clock source: IRC48M clkval = CPU_INT_IRC_CLK_HZ / 1000000.0f; } #else if (mcgpllfll_frequency()) { SIM->SOPT2 |= SIM_SOPT2_TPMSRC(1); // Clock source: MCGFLLCLK or MCGPLLCLK clkval = mcgpllfll_frequency() / 1000000.0f; } else { SIM->SOPT2 |= SIM_SOPT2_TPMSRC(2); // Clock source: ExtOsc clkval = extosc_frequency() / 1000000.0f; } #endif while (clkval > 1) { clkdiv++; clkval /= 2.0; if (clkdiv == 7) break; } pwm_clock = clkval; unsigned int port = (unsigned int)pin >> PORT_SHIFT; unsigned int tpm_n = (pwm >> TPM_SHIFT); unsigned int ch_n = (pwm & 0xFF); SIM->SCGC5 |= 1 << (SIM_SCGC5_PORTA_SHIFT + port); SIM->SCGC6 |= 1 << (SIM_SCGC6_TPM0_SHIFT + tpm_n); TPM_Type *tpm = (TPM_Type *)(TPM0_BASE + 0x1000 * tpm_n); tpm->SC = TPM_SC_CMOD(1) | TPM_SC_PS(clkdiv); // (clock)MHz / clkdiv ~= (0.75)MHz tpm->CONTROLS[ch_n].CnSC = (TPM_CnSC_MSB_MASK | TPM_CnSC_ELSB_MASK); /* No Interrupts; High True pulses on Edge Aligned PWM */ obj->CnV = &tpm->CONTROLS[ch_n].CnV; obj->MOD = &tpm->MOD; obj->CNT = &tpm->CNT; // default to 20ms: standard for servos, and fine for e.g. brightness control pwmout_period_ms(obj, 20); pwmout_write (obj, 0); // Wire pinout pinmap_pinout(pin, PinMap_PWM); }
void TFC_InitMotorPWM() { //Clock Setup for the TPM requires a couple steps. //1st, set the clock mux //See Page 124 of f the KL25 Sub-Family Reference Manual, Rev. 3, September 2012 SIM_SOPT2 |= SIM_SOPT2_PLLFLLSEL_MASK;// We Want MCGPLLCLK/2 (See Page 196 of the KL25 Sub-Family Reference Manual, Rev. 3, September 2012) SIM_SOPT2 &= ~(SIM_SOPT2_TPMSRC_MASK); SIM_SOPT2 |= SIM_SOPT2_TPMSRC(1); //We want the MCGPLLCLK/2 (See Page 196 of the KL25 Sub-Family Reference Manual, Rev. 3, September 2012) //Enable the Clock to the FTM0 Module //See Page 207 of f the KL25 Sub-Family Reference Manual, Rev. 3, September 2012 SIM_SCGC6 |= SIM_SCGC6_TPM0_MASK; //The TPM Module has Clock. Now set up the peripheral //Blow away the control registers to ensure that the counter is not running TPM0_SC = 0; TPM0_CONF = 0; //Set TPM module to continue in debug mode TPM0_CONF |= 0x00000060; //While the counter is disabled we can setup the prescaler TPM0_SC = TPM_SC_PS(FTM0_CLK_PRESCALE); //Setup the mod register to get the correct PWM Period TPM0_MOD = FTM0_CLOCK/(1<<FTM0_CLK_PRESCALE)/FTM0_OVERFLOW_FREQUENCY; //Setup Channels 0,1,2,3 TPM0_C0SC = TPM_CnSC_MSB_MASK | TPM_CnSC_ELSB_MASK; TPM0_C1SC = TPM_CnSC_MSB_MASK | TPM_CnSC_ELSB_MASK; TPM0_C2SC = TPM_CnSC_MSB_MASK | TPM_CnSC_ELSB_MASK; TPM0_C3SC = TPM_CnSC_MSB_MASK | TPM_CnSC_ELSB_MASK; //Enable the Counter //Set the Default duty cycle to 50% duty cycle TFC_SetMotorPWM(0.0,0.0); //Enable the TPM Counter TPM0_SC |= TPM_SC_CMOD(1); //Enable the FTM functions on the the port PORTC_PCR1 = PORT_PCR_MUX(4); PORTC_PCR2 = PORT_PCR_MUX(4); PORTC_PCR3 = PORT_PCR_MUX(4); PORTC_PCR4 = PORT_PCR_MUX(4); }
void TPM_vfnStartTimer(uint8_t bTPMToEnable, uint8_t bTPMPrescaler) { uint32_t * pdwTPM_SCRegister; if(bTPMToEnable < MAX_TPM) { pdwTPM_SCRegister = (uint32_t*)TPM_gapdwRegisters[bTPMToEnable][TPM_SC]; /* Enable module with internal CLK and */ *pdwTPM_SCRegister = TPM_SC_CMOD(0x01)|TPM_SC_PS(bTPMPrescaler); } }
/* ===================================================================*/ LDD_TDeviceData* TU2_Init(LDD_TUserData *UserDataPtr) { TU2_TDeviceData *DeviceDataPrv; if (PE_LDD_DeviceDataList[PE_LDD_COMPONENT_TU2_ID] == NULL) { /* Allocate device structure */ /* {FreeRTOS RTOS Adapter} Driver memory allocation: RTOS function call is defined by FreeRTOS RTOS Adapter property */ DeviceDataPrv = (TU2_TDeviceData *)pvPortMalloc(sizeof(TU2_TDeviceData)); #if FreeRTOS_CHECK_MEMORY_ALLOCATION_ERRORS if (DeviceDataPrv == NULL) { return (NULL); } #endif DeviceDataPrv->UserDataPtr = UserDataPtr; /* Store the RTOS device structure */ DeviceDataPrv->InitCntr = 1U; /* First initialization */ } else { /* Memory is already allocated */ DeviceDataPrv = (TU2_TDeviceDataPtr) PE_LDD_DeviceDataList[PE_LDD_COMPONENT_TU2_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 */ } /* SIM_SCGC6: TPM1=1 */ SIM_SCGC6 |= SIM_SCGC6_TPM1_MASK; /* TPM1_SC: ??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,DMA=0,TOF=0,TOIE=0,CPWMS=0,CMOD=0,PS=0 */ TPM1_SC = (TPM_SC_CMOD(0x00) | TPM_SC_PS(0x00)); /* Clear status and control register */ /* TPM1_CNT: ??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,COUNT=0 */ TPM1_CNT = TPM_CNT_COUNT(0x00); /* Reset counter register */ /* TPM1_C0SC: ??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,CHF=0,CHIE=0,MSB=0,MSA=0,ELSB=0,ELSA=0,??=0,DMA=0 */ TPM1_C0SC = 0x00U; /* Clear channel status and control register */ /* TPM1_C1SC: ??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,CHF=0,CHIE=0,MSB=0,MSA=0,ELSB=0,ELSA=0,??=0,DMA=0 */ TPM1_C1SC = 0x00U; /* Clear channel status and control register */ /* TPM1_MOD: ??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,MOD=0x02B3 */ TPM1_MOD = TPM_MOD_MOD(0x02B3); /* Set up modulo register */ /* TPM1_C0SC: ??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,CHF=0,CHIE=0,MSB=1,MSA=0,ELSB=1,ELSA=1,??=0,DMA=0 */ TPM1_C0SC = (TPM_CnSC_MSB_MASK | TPM_CnSC_ELSB_MASK | TPM_CnSC_ELSA_MASK); /* Set up channel status and control register */ /* TPM1_C0V: ??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,??=0,VAL=0 */ TPM1_C0V = TPM_CnV_VAL(0x00); /* Set up channel value register */ /* PORTE_PCR20: ISF=0,MUX=3 */ PORTE_PCR20 = (uint32_t)((PORTE_PCR20 & (uint32_t)~(uint32_t)( PORT_PCR_ISF_MASK | PORT_PCR_MUX(0x04) )) | (uint32_t)( PORT_PCR_MUX(0x03) )); DeviceDataPrv->Source = TPM_PDD_SYSTEM; /* Store clock source */ /* Registration of the device structure */ PE_LDD_RegisterDeviceStructure(PE_LDD_COMPONENT_TU2_ID,DeviceDataPrv); return ((LDD_TDeviceData *)DeviceDataPrv); /* Return pointer to the device data structure */ }
void Timer_TPM::__init_timer() { //Set TPM clocks SIM->SOPT2 |= SIM_SOPT2_TPMSRC(1); //Set TPM global clock source: MCGFLLCLK SIM->SCGC6 |= SIM_SCGC6_TPM0_MASK; //Enable TPM block (clock gating) TPM0->SC = 0; //Reset TPM //Configure TPM prescaler TPM0->SC = TPM_SC_PS(0); //Prescaler set to 1 TPM0->CNT = 0; //Set the count register //Set interrupt handler NVIC_SetVector(TPM0_IRQn, (uint32_t) __tpm_isr_wrapper); NVIC_EnableIRQ(TPM0_IRQn); }
void TPM_init_PWM(TPM_MemMapPtr TPMx, int clock_source, int module, int clock_mode, int ps, int counting_mode) { if(TPMx == TPM0_BASE_PTR) SIM_SCGC6 |= SIM_SCGC6_TPM0_MASK; else if(TPMx == TPM1_BASE_PTR) SIM_SCGC6 |= SIM_SCGC6_TPM1_MASK; else SIM_SCGC6 |= SIM_SCGC6_TPM2_MASK; SIM_SOPT2 |= SIM_SOPT2_TPMSRC(clock_source); TPM_MOD_REG(TPMx) = module; TPM_SC_REG(TPMx) |= TPM_SC_CMOD(clock_mode) | TPM_SC_PS(ps); if(counting_mode) TPM_SC_REG(TPMx) |= TPM_SC_CPWMS_MASK; }
/*configures TPM0_CH3 green LED to be PWM controlled*/ void tpm_init(void) { SIM_SCGC6 |= SIM_SCGC6_TPM0_MASK; //enable TPM clock gate SIM_SOPT2 |= SIM_SOPT2_TPMSRC(1) | SIM_SOPT2_PLLFLLSEL_MASK; //select PLL as clock source of TPM0_MOD = 1000; #ifdef FRDM_REVA TPM0_C3SC = TPM_CnSC_MSB_MASK |TPM_CnSC_ELSB_MASK; //PWM edge aligned TPM0_C3V = 500; #else TPM0_C5SC = TPM_CnSC_MSB_MASK |TPM_CnSC_ELSB_MASK; //PWM edge aligned TPM0_C5V = 500; #endif TPM0_SC |= TPM_SC_PS(0) | TPM_SC_CMOD(1); }
void tpm_init(void){ PORTD->PCR[5] = PORT_PCR_MUX(4); //TPM0_CH5 PORTE->PCR[29] = PORT_PCR_MUX(3); //TPM0_CH2 SIM->SCGC6 |= SIM_SCGC6_TPM0_MASK; //dolaczenie sygnalu taktujacego do modulu TMP SIM->SCGC5 |= (SIM_SCGC5_PORTD_MASK | SIM_SCGC5_PORTE_MASK); //dolaczenie sygnalu taktujacego do portu D i E, zrobione tez w leds initializze SIM->SOPT2 |= SIM_SOPT2_TPMSRC(1); // MCGFLLCLK clock or MCGPLLCLK/2 SIM->SOPT2 |= SIM_SOPT2_PLLFLLSEL_MASK; //MCGPLLCLK clock with fixed divide by two TPM0->MOD = TPM_MOD_MOD(4095); TPM0->CNT |= TPM_CNT_COUNT_SHIFT; //reset counter //edge aligned pwm TPM0->CONTROLS[2].CnSC |= TPM_CnSC_MSB_MASK | TPM_CnSC_ELSB_MASK; //high true pulses TPM0->CONTROLS[5].CnSC |= TPM_CnSC_MSB_MASK | TPM_CnSC_ELSB_MASK | TPM_CnSC_ELSA_MASK; //low true pulses //edge aligned pwm end //center aligned PWM /* TPM0->CONTROLS[2].CnSC |= TPM_CnSC_MSB_MASK | TPM_CnSC_ELSB_MASK; //high-true pulses TPM0->CONTROLS[5].CnSC |= TPM_CnSC_MSB_MASK | TPM_CnSC_ELSA_MASK; //low true pulses */ //center aligned PWM end TPM0->CONTROLS[2].CnV = TPM_CnV_VAL(0); //poczatkowa wartosc wspolczyynika wypelninia TPM0->CONTROLS[5].CnV = TPM_CnV_VAL(0); //poczatkowa wartosc wspolczyynika wypelninia TPM0->SC = TPM_SC_PS(0x07) | TPM_SC_CPWMS_MASK | TPM_SC_CMOD(0x01); //divide by 128 !! //upcounting //increment every counter clock }
static void _TPM_InitBasic(uint32_t instance, uint32_t modulo, TPM_ClockDiv_Type ps) { /* enable clock gate */ *(uint32_t*)SIM_TPMClockGateTable[instance].addr |= SIM_TPMClockGateTable[instance].mask; /* disable FTM, we must set CLKS(0) before config FTM! */ TPM_InstanceTable[instance]->SC = 0; /* set CNT and CNTIN */ TPM_InstanceTable[instance]->CNT = 0; /* set modulo */ TPM_InstanceTable[instance]->MOD = modulo; /* set FTM clock to system clock */ SIM->SOPT2 &= ~SIM_SOPT2_TPMSRC_MASK; SIM->SOPT2 |= SIM_SOPT2_TPMSRC(1); /* set ps, this must be done after set modulo */ TPM_InstanceTable[instance]->SC &= ~TPM_SC_PS_MASK; TPM_InstanceTable[instance]->SC |= TPM_SC_PS(ps); }
void Echo_init(void){ // PORTE 20 CONFIG (TPM1 Channel 0) SIM->SCGC5 |= SIM_SCGC5_PORTE_MASK; PORTE->PCR[ECHO_PIN] |= PORT_PCR_MUX(0x03); //*************************************************************** // TPM1 CONFIG SIM->SOPT2 |= SIM_SOPT2_TPMSRC(3); // MCGIRC MCG->C1 |= MCG_C1_IRCLKEN_MASK; // MCGIRCLK active. MCG->C2 |= MCG_C2_IRCS_MASK; // External FAST (4MHz) reference clock is selected. SIM->SCGC6 |= SIM_SCGC6_TPM1_MASK; TPM1->SC |= TPM_SC_PS(1) // Divide by 2 (1MHz) | TPM_SC_CMOD(0x01); // Enabling TPM1 NVIC_ClearPendingIRQ(TPM1_IRQn); NVIC_EnableIRQ(TPM1_IRQn); NVIC_SetPriority(TPM1_IRQn, 1); TPM1->CONTROLS[0].CnSC |= TPM_CnSC_ELSA_MASK // Input capture -> every edge | TPM_CnSC_ELSB_MASK | TPM_CnSC_CHIE_MASK; // Channel int. enabled }
interruptRegisterTPMIRQHandler(timerTPMIRQHandler, 0); interruptRegisterTPMIRQHandler(timerTPMIRQHandler, 1); interruptRegisterTPMIRQHandler(timerTPMIRQHandler, 2); } void tpmEnableTimer(int timerIndex) { SIM_SCGC6 |= tpmGateFlags[timerIndex]; NVIC_EnableIRQ(TPM0_IRQn + timerIndex); } void tpmStartTimer(int timerIndex, uint32_t periodClocks, uint32_t prescaleShift) { tpmPtrs[timerIndex]->MOD = (periodClocks >> (prescaleShift & TPM_SC_PS_MASK)) - 1; tpmPtrs[timerIndex]->CNT = 0; tpmPtrs[timerIndex]->SC = TPM_SC_TOIE_MASK | TPM_SC_TOF_MASK | TPM_SC_PS(prescaleShift); tpmPtrs[timerIndex]->CONF = 0; tpmCounter[timerIndex] = 0; tpmPtrs[timerIndex]->SC |= TPM_SC_CMOD(1); } void tpmOneShotTimer(int timerIndex, uint32_t periodClocks, uint32_t prescaleShift) { SIM_SCGC6 |= tpmGateFlags[timerIndex]; tpmPtrs[timerIndex]->MOD = (periodClocks >> (prescaleShift & TPM_SC_PS_MASK)) - 1; tpmPtrs[timerIndex]->CNT = 0; tpmPtrs[timerIndex]->SC = TPM_SC_TOIE_MASK | TPM_SC_TOF_MASK | TPM_SC_PS(prescaleShift); tpmPtrs[timerIndex]->CONF = TPM_CONF_CSOO_MASK; tpmCounter[timerIndex] = 0; NVIC_EnableIRQ(TPM0_IRQn + timerIndex); tpmPtrs[timerIndex]->SC |= TPM_SC_CMOD(1);
/** init the timer TPM1 for measuring temperature using input capture * */ void smt160_init() { int prio = 2; // priorita interruptu; 0 az 3, 0 = max /* Initialize our global variables */ gsmt_start = 0; gsmt_pulse = 0; gsmt_period = 0; gsmt_tmp_pulse = 0; gsmt_pulses = 0; gsmt_period_sum = 0; gsmt_sumcnt = 0; /* Enable Port A clock (pins used for input capture) */ SIM_SCGC5 |= SIM_SCGC5_PORTA_MASK; /* enable input pins for TPM1 channels 0 and 1 The timer channel is Alt 3 function of the pins */ PORTA_PCR12 = PORT_PCR_MUX(3); /* PTA12 = channel 0 for TPM1 */ PORTA_PCR13 = PORT_PCR_MUX(1); /* using PTA13 as GPIO for deciding falling/rising */ GPIOA_PDDR &= ~(1 << SMT160_INPUT_PIN_NO); /* set PTA13 to input mode */ /* Enable clock for timer TMP1 */ SIM_SCGC6 |= SIM_SCGC6_TPM1_MASK; /* and clock source */ SIM_SOPT2 |= SIM_SOPT2_TPMSRC(1); // select the PLLFLLCLK as TPM clock source /* Set timer to input capture mode etc. */ TPM1_SC = TPM_SC_CMOD(1) | TPM_SC_PS(0); //0x08; // CMOD = 01, prescaler = 1 /* test TOF interrupt TPM1_SC |= TPM_SC_TOIE_MASK; TPM1_MOD = 10000; */ #if 0 // Input capture config // Version with 2 input pins used: channel 0 detects pulses, channel 1 // detects period. TPM1_C0SC = 0; /* clear any pending interrupt and set all values to default */ TPM1_C0SC |= TPM_CnSC_ELSA_MASK | TPM_CnSC_ELSB_MASK; /* input capture on falling and rising edges */ TPM1_C0SC |= TPM_CnSC_CHIE_MASK; /* enable channel interrupt */ TPM1_C1SC = 0; /* clear any pending interrupt and set all values to default */ TPM1_C1SC |= TPM_CnSC_ELSA_MASK; /* input capture on rising edges only */ TPM1_C1SC |= TPM_CnSC_CHIE_MASK; /* enable channel interrupt */ #endif // Input capture config // Version with 1 pin used; wait for rising edge TPM1_C0SC = 0; /* clear any pending interrupt and set all values to default */ /* input capture on rising and falling edge + enable channel interrupt */ TPM1_C0SC |= TPM_CnSC_ELSA_MASK | TPM_CnSC_ELSB_MASK | TPM_CnSC_CHIE_MASK; // Enable the interrupt // Note: sample code package provides function for this in arm_cm0.c; (enable_irq(interrupt);) // CMSIS compatible environment should implement NVIC_EnableIRQ((IRQn_Type)interrupt); // In NVIC there are 32-bit registers where each bit corresponds to 1 interrupt // The number of the interrupt used in NVIC is "non-core" int number, which is the // absolute number - 16. (there are 16 core interrupts which are not controlled by NVIC) // ICPR register = clear pending flag (writing 1 clears pending interrupt) // ISER register = enable interrupt by writing 1 to its bit NVIC_ICPR |= (1 << (INT_TPM1 - 16) ); // clear possibly pending interrupt NVIC_ISER |= (1 << (INT_TPM1 - 16) ); // enable the interrupt // Set priority for the interrupt // Bit field starting location = 8 * (IRQ mod 4) + 6 = // Zde IRQ = 18 (cislo TPM1 int v MKL25Z4.h - 16) // start = 8 * 18 mod 4 + 6 = 8 * 2 + 6 = 22 NVIC_IPR4 = ((prio & 0x03) << 22); EnableInterrupts; }
void setupTPM() { /******* FIRST: Setup TPM Clocks **********/ /* LED Timers: slow enough to be seen by the human eye, fast * enough to be a seamless fade --> 200Hz frequency (200 ticks/sec) * * Accomplished by dividing the fast 4 MHz clock by 128 by setting * the prescaler bits to 7 [DIVIDE_BY_128] and further divide it by * 155 setting the modulus register to 154 [DIVIDE_TO_200HZ] * * 4 MHz / 128 / 155 = ~200Hz (201.61Hz) */ // TPM0: Used to toggle blue LED TPM0_BASE_PTR->SC = TPM_SC_CMOD(1) | TPM_SC_PS(DIVIDE_BY_128); TPM0_BASE_PTR->MOD = DIVIDE_TO_200HZ; // TPM2: Used to toggle green/red LEDs TPM2_BASE_PTR->SC = TPM_SC_CMOD(1) | TPM_SC_PS(DIVIDE_BY_128); TPM2_BASE_PTR->MOD = DIVIDE_TO_200HZ; /* * Profiling timer: required to have 10us period -> 100 kHz * Accomplished by dividing the fast 4 MHz clock by 8 by setting * the prescaler bits to 3 [DIVIDE_BY_8] and further divide it by * 5 setting the modulus register to 4 [DIVIDE_TO_10kHZ] * * 4 MHz / 8 / 5 = 100 kHz */ // TPM1: Used to profile functions TPM1_BASE_PTR->SC = TPM_SC_CMOD(1) | TPM_SC_PS(DIVIDE_BY_8); TPM1_BASE_PTR->MOD = DIVIDE_TO_10kHZ; /* PORTB clock is enabled by writing to the SGC5 register. Turn on clock gating to PortB * module (red and green LEDs) and PortD module (blue LED) */ SIM_BASE_PTR->SCGC5 |= SIM_SCGC5_PORTB_MASK| SIM_SCGC5_PORTD_MASK; /******* SECOND: Setup TPM in PWM Mode **********/ /* * Configure the timer in the PWM mode to manually change the value of the PTB18/19 [red/blue] pins * The PTB18 and PTB19 pins are multiplexed with channel 0 of the TPM2 module. Switch the pins to * be the TPM outputs instead of normal GPIO pins by writing the PCR register. */ PORTB_BASE_PTR->PCR[RED_PIN] = PORTB_BASE_PTR->PCR[GREEN_PIN] = PORT_PCR_MUX(TPM_OUTPUT_SELECTION); /* * Do the same for PTD1 [blue] pin */ PORTD_PCR1 = PORT_PCR_MUX(4); // TPM0_CH1 enable on PTD1 (blue) PTB_BASE_PTR->PDDR = 1 << RED_PIN; // Configure Red Pin to be output /* * Configure TPM0/TPM2 to run in the PWM mode and generate short impulses (1/8 of the timer period) * */ TPM2_BASE_PTR->CONTROLS[RED_LED].CnSC = TPM_CnSC_MSB_MASK | TPM_CnSC_ELSA_MASK; TPM2_BASE_PTR->CONTROLS[GREEN_LED].CnSC = TPM_CnSC_MSB_MASK | TPM_CnSC_ELSA_MASK; TPM0_BASE_PTR->CONTROLS[BLUE_LED].CnSC = TPM_CnSC_MSB_MASK | TPM_CnSC_ELSA_MASK; /******* THIRD : Set default LED values = Off initially **********/ TPM2_BASE_PTR->CONTROLS[RED_LED].CnV = 0x0; TPM2_BASE_PTR->CONTROLS[GREEN_LED].CnV = 0x0; TPM0_BASE_PTR->CONTROLS[BLUE_LED].CnV = 0x0; /******* LAST : Enable interrupts **********/ NVIC_EnableIRQ(TPM0_IRQn); // Use TPM1 for profiler timer NVIC_EnableIRQ(TPM1_IRQn); // Use TPM1 for profiler timer }