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
	}
예제 #2
0
/*---------------------------------------------------------------------------*/
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");
}
예제 #3
0
파일: TU1.c 프로젝트: Chruit90/PREN
/* ===================================================================*/
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 */
}
예제 #4
0
파일: fsl_tpm.c 프로젝트: Archcady/mbed-os
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;
    }
}
예제 #5
0
파일: main.c 프로젝트: Imajie/ARM
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
}
예제 #6
0
파일: tpm.c 프로젝트: decyborg/nerf_trigger
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;
}
예제 #7
0
파일: Servo.c 프로젝트: brentnd/Freesnail
/* 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);	
}
예제 #9
0
파일: pwmout_api.c 프로젝트: Illuminux/mbed
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);
}
예제 #10
0
파일: TU2.c 프로젝트: Judahh/M0PlusFreeRTOS
/* ===================================================================*/
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 */
}
예제 #11
0
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);
                              
}
예제 #12
0
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);
}
예제 #13
0
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);
}
예제 #14
0
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);
	}
}
예제 #15
0
파일: TU2.c 프로젝트: francodemare/RoboTito
/* ===================================================================*/
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);
}
예제 #17
0
파일: tpm.c 프로젝트: decyborg/nerf_trigger
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;
}
예제 #18
0
/*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);
  
}
예제 #19
0
파일: tpm.c 프로젝트: jifwin/int_dom
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
}
예제 #20
0
파일: tpm.c 프로젝트: zwzmzd/kl02z
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); 
    
}
예제 #21
0
파일: Echo.c 프로젝트: Cheburashek/AUTOauto
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
										 
}
예제 #22
0
파일: timer.c 프로젝트: dozencrows/KiMony
    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);
예제 #23
0
파일: smt160_kl25.c 프로젝트: jdolinay/ucp
/** 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;

}
예제 #24
0
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

}