void pwmout_init(pwmout_t* obj, PinName pin) { // determine the channel PWMName pwm = (PWMName)pinmap_peripheral(pin, PinMap_PWM); if (pwm == (PWMName)NC) error("PwmOut pin mapping failed"); unsigned int port = (unsigned int)pin >> PORT_SHIFT; unsigned int ftm_n = (pwm >> TPM_SHIFT); unsigned int ch_n = (pwm & 0xFF); SIM->SCGC5 |= 1 << (SIM_SCGC5_PORTA_SHIFT + port); SIM->SCGC6 |= 1 << (SIM_SCGC6_FTM0_SHIFT + ftm_n); FTM_Type *ftm = (FTM_Type *)(FTM0_BASE + 0x1000 * ftm_n); ftm->MODE |= FTM_MODE_WPDIS_MASK; //write protection disabled ftm->CONF |= FTM_CONF_BDMMODE(3); ftm->SC = FTM_SC_CLKS(1) | FTM_SC_PS(6); // (48)MHz / 64 = (0.75)MHz ftm->CONTROLS[ch_n].CnSC = (FTM_CnSC_MSB_MASK | FTM_CnSC_ELSB_MASK); /* No Interrupts; High True pulses on Edge Aligned PWM */ ftm->PWMLOAD |= FTM_PWMLOAD_LDOK_MASK; //loading updated values enabled //ftm->SYNCONF |= FTM_SYNCONF_SWRSTCNT_MASK; ftm->MODE |= FTM_MODE_INIT_MASK; obj->CnV = &ftm->CONTROLS[ch_n].CnV; obj->MOD = &ftm->MOD; obj->CNT = &ftm->CNT; obj->SYNC = &ftm->SYNC; // 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); }
/* * LPLD_FTM_IC_Init * FTM模块输入捕获模式初始化,内部调用 */ static uint8 LPLD_FTM_IC_Init(FTM_InitTypeDef ftm_init_structure) { uint8 i; uint8 ps = ftm_init_structure.FTM_ClkDiv; FTM_ISR_CALLBACK isr_func = ftm_init_structure.FTM_Isr; FTM_MemMapPtr ftmx = ftm_init_structure.FTM_Ftmx; //参数检查 //ASSERT( ps <= 7); //时钟分频系数 if (ps > 7) return 0; ftmx->CONF=FTM_CONF_BDMMODE(0x3); ftmx->SC = 0; ftmx->CNT = 0; ftmx->CNTIN = 0; ftmx->MOD = 0; ftmx->QDCTRL = (~FTM_QDCTRL_QUADEN_MASK); //关闭正交解码 ftmx->FILTER = 0x00; //关过虑器 // 配置FTM控制寄存器 // 将FTM Counter配置成Free Counter // 禁用中断, 加计数模式, 时钟源:System clock(Bus Clk), 分频系数:PS // 假设SysClk = 50MHz, SC_PS=3, FTM Clk = 50MHz/2^3 = 6.25MHz ftmx->SC |= FTM_SC_CLKS(1)|FTM_SC_PS(ps); //ftmx->SC |= FTM_SC_TOIE_MASK; //使能计数溢出中断 ftmx->SC &= (~FTM_SC_CPWMS_MASK); //FTM加计数 //设置中断函数入口地址并开启中断 if(isr_func!=NULL) { if(ftmx == FTM0) i=0; else if(ftmx == FTM1) i=1; else if(ftmx == FTM2) i=2; else if (ftmx == FTM3) i = 3; else return 0; FTM_ISR[i] = isr_func; } return 1; }
void FTM_init (FTM_MemMapPtr base) { // Habilito el pin PTC1 como salida del canal 0 PORTC_PCR1 = (PORT_PCR_ISF_MASK | PORT_PCR_MUX(0x04)); PORTB_PCR18 = (PORT_PCR_ISF_MASK | PORT_PCR_MUX(0x03)); // Habilito la llave general de las interrupciones //NVICISER1 |= NVIC_ISER_SETENA(0x0400); // Habilito el clock gating SIM_SCGC6 |= SIM_SCGC6_FTM0_MASK; SIM_SCGC6 |= SIM_SCGC6_FTM2_MASK; // Deshabilito la proteccion de escritura FTM_MODE_REG(base) = FTM_MODE_WPDIS_MASK; // Apago los flag de interrupciones FTM_STATUS_REG(base) = (FTM0_STATUS & 0x00); // Deshabilito los clocks y borro la configuracion FTM_SC_REG(base) = 0x00; // Configuro el canal 0 como nada FTM_CnSC_REG(base,0) = 0x00; // Configuro la salida inicial en alto (los LEDs son activo-bajo) FTM_MODE_REG(base) = FTM_MODE_INIT_MASK; // Configuro el PWM a duty 25% y reinicio el contador FTM_CnV_REG(base,0) = 0x0000; FTM_MOD_REG(base) = 0x0000; FTM_CNTIN_REG(base) = 0x0000; FTM_CNT_REG(base) = 0x0000; FTM_PWMLOAD_REG(base) = (FTM_PWMLOAD_LDOK_MASK | FTM_PWMLOAD_CH0SEL_MASK); // Habilito las interrupciones y los clocks, y configuro el prescaler FTM_SC_REG(base) = (FTM_SC_TOIE_MASK | FTM_SC_CLKS(0x01) | FTM_SC_PS(0x0F)); // Habilito los contadores del modulo FTM_CONF_REG(base) = FTM_CONF_BDMMODE(0x03); }
void pwmout_init(pwmout_t* obj, PinName pin) { // determine the channel PWMName pwm = (PWMName)pinmap_peripheral(pin, PinMap_PWM); if (pwm == (PWMName)NC) error("PwmOut pin mapping failed"); uint32_t clkdiv = 0; float clkval = SystemCoreClock / 1000000.0f; while (clkval > 1) { clkdiv++; clkval /= 2.0; if (clkdiv == 7) break; } pwm_clock = clkval; unsigned int port = (unsigned int)pin >> PORT_SHIFT; unsigned int ftm_n = (pwm >> TPM_SHIFT); unsigned int ch_n = (pwm & 0xFF); SIM->SCGC5 |= 1 << (SIM_SCGC5_PORTA_SHIFT + port); SIM->SCGC6 |= 1 << (SIM_SCGC6_FTM0_SHIFT + ftm_n); FTM_Type *ftm = (FTM_Type *)(FTM0_BASE + 0x1000 * ftm_n); ftm->CONF |= FTM_CONF_BDMMODE(3); ftm->SC = FTM_SC_CLKS(1) | FTM_SC_PS(clkdiv); // (clock)MHz / clkdiv ~= (0.75)MHz ftm->CONTROLS[ch_n].CnSC = (FTM_CnSC_MSB_MASK | FTM_CnSC_ELSB_MASK); /* No Interrupts; High True pulses on Edge Aligned PWM */ obj->CnV = &ftm->CONTROLS[ch_n].CnV; obj->MOD = &ftm->MOD; obj->CNT = &ftm->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); }
status_t FTM_Init(FTM_Type *base, const ftm_config_t *config) { assert(config); uint32_t reg; if (!(config->pwmSyncMode & (FTM_SYNC_TRIG0_MASK | FTM_SYNC_TRIG1_MASK | FTM_SYNC_TRIG2_MASK | FTM_SYNC_SWSYNC_MASK))) { /* Invalid PWM sync mode */ return kStatus_Fail; } /* Ungate the FTM clock*/ CLOCK_EnableClock(s_ftmClocks[FTM_GetInstance(base)]); /* Configure the fault mode, enable FTM mode and disable write protection */ base->MODE = FTM_MODE_FAULTM(config->faultMode) | FTM_MODE_FTMEN_MASK | FTM_MODE_WPDIS_MASK; /* Configure the update mechanism for buffered registers */ FTM_SetPwmSync(base, config->pwmSyncMode); if (config->reloadPoints) { /* Setup intermediate register reload points */ FTM_SetReloadPoints(base, config->reloadPoints); } /* Set the clock prescale factor */ base->SC = FTM_SC_PS(config->prescale); /* Setup the counter operation */ base->CONF = (FTM_CONF_BDMMODE(config->bdmMode) | FTM_CONF_GTBEEN(config->useGlobalTimeBase)); /* Initial state of channel output */ base->OUTINIT = config->chnlInitState; /* Channel polarity */ base->POL = config->chnlPolarity; /* Set the external trigger sources */ base->EXTTRIG = config->extTriggers; #if defined(FSL_FEATURE_FTM_HAS_RELOAD_INITIALIZATION_TRIGGER) && (FSL_FEATURE_FTM_HAS_RELOAD_INITIALIZATION_TRIGGER) if (config->extTriggers & kFTM_ReloadInitTrigger) { base->CONF |= FTM_CONF_ITRIGR_MASK; } else { base->CONF &= ~FTM_CONF_ITRIGR_MASK; } #endif /* FSL_FEATURE_FTM_HAS_RELOAD_INITIALIZATION_TRIGGER */ /* FTM deadtime insertion control */ base->DEADTIME = (FTM_DEADTIME_DTPS(config->deadTimePrescale) | FTM_DEADTIME_DTVAL(config->deadTimeValue)); /* FTM fault filter value */ reg = base->FLTCTRL; reg &= ~FTM_FLTCTRL_FFVAL_MASK; reg |= FTM_FLTCTRL_FFVAL(config->faultFilterValue); base->FLTCTRL = reg; return kStatus_Success; }