示例#1
0
void pwmout_period_us(pwmout_t* obj, int us)
{
    TimHandle.Instance = (TIM_TypeDef *)(obj->pwm);

    float dc = pwmout_read(obj);

    __HAL_TIM_DISABLE(&TimHandle);

    TimHandle.Init.Period        = us - 1;
    TimHandle.Init.Prescaler     = (uint16_t)(SystemCoreClock / 1000000) - 1; // 1 us tick
    TimHandle.Init.ClockDivision = 0;
    TimHandle.Init.CounterMode   = TIM_COUNTERMODE_UP;

    if (HAL_TIM_PWM_Init(&TimHandle) != HAL_OK) {
        error("Cannot initialize PWM");
    }

    // Set duty cycle again
    pwmout_write(obj, dc);

    // Save for future use
    obj->period = us;

    __HAL_TIM_ENABLE(&TimHandle);
}
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");
    
    obj->pwm = pwm;
    obj->MR = PWM_MATCH[pwm];
    
    // ensure the power is on
    LPC_SC->PCONP |= 1 << 6;
    
    // ensure clock to /4
    LPC_SC->PCLKSEL0 &= ~(0x3 << 12);     // pclk = /4
    LPC_PWM1->PR = 0;                     // no pre-scale
    
    // ensure single PWM mode
    LPC_PWM1->MCR = 1 << 1; // reset TC on match 0
    
    // enable the specific PWM output
    LPC_PWM1->PCR |= 1 << (8 + pwm);
    
    pwm_clock_mhz = SystemCoreClock / 4000000;
    
    // 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);
}
示例#3
0
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);
}
示例#4
0
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");
    
    obj->pwm = pwm;
    
    // Timer registers
    timer_mr tid = pwm_timer_map[pwm];
    LPC_TMR_TypeDef *timer = Timers[tid.timer];
    
    // Disable timer
    timer->TCR = 0;
    
    // Power the correspondent timer
    LPC_SYSCON->SYSAHBCLKCTRL |= 1 << (tid.timer + 7);
    
    /* Enable PWM function */
    timer->PWMC = (1 << 3)|(1 << 2)|(1 << 1)|(1 << 0);
    
    /* Reset Functionality on MR3 controlling the PWM period */
    timer->MCR = 1 << 10;
    
    pwm_clock_mhz = SystemCoreClock / 1000000;
    
    // 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);
}
示例#5
0
void pwmout_period_us(pwmout_t* obj, int us)
{
    TimHandle.Instance = (TIM_TypeDef *)(obj->pwm);

    float dc = pwmout_read(obj);

    __HAL_TIM_DISABLE(&TimHandle);

    // Update the SystemCoreClock variable
    SystemCoreClockUpdate();

    TimHandle.Init.Period        = us - 1;
    TimHandle.Init.Prescaler     = (uint16_t)(SystemCoreClock / 1000000) - 1; // 1 µs tick
    TimHandle.Init.ClockDivision = 0;
    TimHandle.Init.CounterMode   = TIM_COUNTERMODE_UP;
    HAL_TIM_PWM_Init(&TimHandle);

    // Set duty cycle again
    pwmout_write(obj, dc);

    // Save for future use
    obj->period = us;

    __HAL_TIM_ENABLE(&TimHandle);
}
示例#6
0
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);
}
示例#7
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);

    // power on
    CPGSTBCR3 &= ~(1<<0);

    obj->pwm = pwm;
    if (((uint32_t)PORT[obj->pwm] & 0x00000010) != 0) {
        obj->ch  = 2;
        PWMPWPR_2_BYTE_L = 0x00;
    } else {
        obj->ch  = 1;
        PWMPWPR_1_BYTE_L = 0x00;
    }

    // Wire pinout
    pinmap_pinout(pin, PinMap_PWM);

    // default to 491us: standard for servos, and fine for e.g. brightness control
    pwmout_write(obj, 0);
    if ((obj->ch == 2) && (init_period_ch2 == 0)) {
        pwmout_period_us(obj, 491);
        init_period_ch2 = 1;
    }
    if ((obj->ch == 1) && (init_period_ch1 == 0)) {
        pwmout_period_us(obj, 491);
        init_period_ch1 = 1;
    }
}
示例#8
0
void pwmout_period_us(pwmout_t* obj, int us) 
{
    float dc = pwmout_read(obj);

    obj->period = us;
    // Set duty cycle again
    pwmout_write(obj, dc);
}
示例#9
0
文件: pwmout_api.c 项目: sg-/mbed-os
void pwmout_pulsewidth_us(pwmout_t *obj, int us)
{
    float seconds = 0;
    float value = 0;

    seconds = (float)(us / 1000000.0f);
    value = (((seconds / obj->period) * 100.0f) / 100.0f);
    pwmout_write(obj, value);
}
示例#10
0
void AmebaServo::writeMicroseconds(int value)
{
    if (value < min) value = min;
    if (value > max) value = max;

    currentWidth = 180 * (value - min) / (max - min);

    pwmout_write( (pwmout_t *)gpio_pin_struct[servoPin], value * 1.0 / 20000);
}
示例#11
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);
}
示例#12
0
文件: pwmout_api.c 项目: sg-/mbed-os
void pwmout_free(pwmout_t *obj)
{
    // Stops and clear count operation
    TMRB_SetRunState(obj->channel, TMRB_STOP);
    pwmout_write(obj,0);
    obj->pin = NC;
    obj->channel = NULL;
    obj->trailing_timing = 0;
    obj->leading_timing = 0;
    obj->divisor = 0;
}
示例#13
0
文件: pwmout_api.c 项目: sg-/mbed-os
void pwmout_free(pwmout_t *obj)
{
    // Stops and clear count operation
    TMRB_SetRunState(obj->channel, TMRB_STOP);
    pwmout_write(obj,0);
    obj->channel = NULL;
    obj->trailing_timing = 0;
    obj->leading_timing = 0;
    obj->divisor = 0;
    TMRB_SetIdleMode(TSB_TB0, ENABLE);
}
示例#14
0
文件: pwmout_api.c 项目: sg-/mbed-os
void pwmout_pulsewidth_us(pwmout_t *obj, int us)
{
    float seconds = 0;
    float value = 0;

    MBED_ASSERT(obj->channel != NULL);

    seconds = (float)(us / 1000000.0f);
    value = (((seconds / obj->period) * 100.0f) / 100.0f);
    pwmout_write(obj, value);
}
示例#15
0
void pwmout_pulsewidth_us(pwmout_t* obj, int us) {
    float value = 0;

    if (obj->ch == 2) {
        if (period_ch2 != 0) {
            value = (float)us / (float)period_ch2;
        }
    } else {
        if (period_ch1 != 0) {
            value = (float)us / (float)period_ch1;
        }
    }

    pwmout_write(obj, value);
}
示例#16
0
//int main_app(IN u16 argc, IN u8 *argv[])
void main(void)
{
    int i;
    
    for (i=0; i<4; i++) {
        pwmout_init(&pwm_led[i], pwm_led_pin[i]);
        pwmout_period_us(&pwm_led[i], PWM_PERIOD);
    }

    while (1) {
#if USE_FLOAT
        for (i=0; i<4; i++) {
            pwmout_write(&pwm_led[i], pwms[i]);

            pwms[i] += steps[i];
            if (pwms[i] >= 1.0) {
                steps[i] = -PWM_STEP;
                pwms[i] = 1.0;
            }

            if (pwms[i] <= 0.0) {
                steps[i] = PWM_STEP;
                pwms[i] = 0.0;
            }
        }
#else        
        for (i=0; i<4; i++) {
            pwmout_pulsewidth_us(&pwm_led[i], pwms[i]);

            pwms[i] += steps[i];
            if (pwms[i] >= PWM_PERIOD) {
                steps[i] = -PWM_STEP;
                pwms[i] = PWM_PERIOD;
            }

            if (pwms[i] <= 0) {
                steps[i] = PWM_STEP;
                pwms[i] = 0;
            }
        }
#endif        
//        wait_ms(20);
//        RtlMsleepOS(25);
		pwm_delay();
    }
}
示例#17
0
void pwmout_period_us(pwmout_t* obj, int us)
{
    TimHandle.Instance = (TIM_TypeDef *)(obj->pwm);

    float dc = pwmout_read(obj);

    __HAL_TIM_DISABLE(&TimHandle);

    SystemCoreClockUpdate();

    /* To make it simple, we use to possible prescaler values which lead to:
     * pwm unit = 1us, period/pulse can be from 1us to 65535us
     * or
     * pwm unit = 500us, period/pulse can be from 500us to ~32.76sec
     * Be careful that all the channels of a PWM shares the same prescaler
     */
    if (us >  0xFFFF) {
        obj->prescaler = 500;
    } else {
        obj->prescaler = 1;
    }
    TimHandle.Init.Prescaler     = ((SystemCoreClock / 1000000) * obj->prescaler) - 1;

    if (TimHandle.Init.Prescaler > 0xFFFF)
        error("PWM: out of range prescaler");

    TimHandle.Init.Period        = (us - 1) / obj->prescaler;
    if (TimHandle.Init.Period > 0xFFFF)
        error("PWM: out of range period");

    TimHandle.Init.ClockDivision = 0;
    TimHandle.Init.CounterMode   = TIM_COUNTERMODE_UP;

    if (HAL_TIM_PWM_Init(&TimHandle) != HAL_OK) {
        error("Cannot initialize PWM\n");
    }

    // Save for future use
    obj->period = us;

    // Set duty cycle again
    pwmout_write(obj, dc);

    __HAL_TIM_ENABLE(&TimHandle);
}
示例#18
0
void pwmout_init(pwmout_t* obj, PinName pin) {
    // determine the channel
    uint8_t pwmOutSuccess = 0;
    PWMName pwm = (PWMName)pinmap_peripheral(pin, PinMap_PWM);

    MBED_ASSERT(pwm != (PWMName)NC);

        
    if(PWM_taken[(uint8_t)pwm]){
        for(uint8_t i = 1; !pwmOutSuccess && (i<NO_PWMS) ;i++){
            if(!PWM_taken[i]){
                pwm           = (PWMName)i;
                PWM_taken[i]  = 1;
                pwmOutSuccess = 1;
            }
        }
    }
    else{
        pwmOutSuccess           = 1;
        PWM_taken[(uint8_t)pwm] = 1;
    }
    
    if(!pwmOutSuccess){
        error("PwmOut pin mapping failed. All available PWM channels are in use.");
    }
    
    obj->pwm = pwm;
    obj->pin = pin;
    
    gpiote_init(pin,(uint8_t)pwm);
    ppi_init((uint8_t)pwm);
    
    if(pwm == 0){
        NRF_POWER->TASKS_CONSTLAT = 1;
    }
    
    timer_init((uint8_t)pwm);
    
    //default to 20ms: standard for servos, and fine for e.g. brightness control
    pwmout_period_ms(obj, 20);
    pwmout_write    (obj, 0);
    
}
示例#19
0
void pwmout_period_us(pwmout_t* obj, int us) {
    TIM_TypeDef *tim = (TIM_TypeDef *)(obj->pwm);
    TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure;
    float dc = pwmout_read(obj);

    TIM_Cmd(tim, DISABLE);

    obj->period = us;

    TIM_TimeBaseStructure.TIM_Period        = obj->period - 1;
    TIM_TimeBaseStructure.TIM_Prescaler     = (uint16_t)(SystemCoreClock / 1000000) - 1; // 1 µs tick
    TIM_TimeBaseStructure.TIM_ClockDivision = 0;
    TIM_TimeBaseStructure.TIM_CounterMode   = TIM_CounterMode_Up;
    TIM_TimeBaseInit(tim, &TIM_TimeBaseStructure);

    // Set duty cycle again
    pwmout_write(obj, dc);

    TIM_ARRPreloadConfig(tim, ENABLE);
    TIM_Cmd(tim, ENABLE);
}
示例#20
0
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);
}
示例#21
0
void pwmout_init(pwmout_t* obj, PinName pin) {
    PWMName pwm = (PWMName)pinmap_peripheral(pin, PinMap_PWM);
    if (pwm == (PWMName)NC) {
        error("PwmOut pin mapping failed");
    }
    obj->pwm_name = pwm;

    uint32_t pwm_base_clock;
    clock_manager_get_frequency(kBusClock, &pwm_base_clock);
    float clkval = (float)pwm_base_clock / 1000000.0f;
    uint32_t clkdiv = 0;
    while (clkval > 1) {
        clkdiv++;
        clkval /= 2.0f;
        if (clkdiv == 7) {
            break;
        }
    }

    pwm_clock_mhz = clkval;
    uint32_t channel = pwm & 0xF;
    uint32_t instance = pwm >> TPM_SHIFT;
    clock_manager_set_gate(kClockModuleFTM, instance, true);
    ftm_hal_set_tof_frequency(instance, 3);
    ftm_hal_set_clock_source(instance, kClock_source_FTM_SystemClk);
    ftm_hal_set_clock_ps(instance, (ftm_clock_ps_t)clkdiv);
    ftm_hal_set_counter_init_val(instance, 0);
    // default to 20ms: standard for servos, and fine for e.g. brightness control
    pwmout_period_ms(obj, 20);
    pwmout_write    (obj, 0);
    ftm_config_t config = {
        .mode = kFtmEdgeAlignedPWM,
        .channel = channel,
        .edge_mode = {.ftm_pwm_edge_mode = kFtmHighTrue}
    };
    ftm_hal_enable_pwm_mode(instance, &config);

    // Wire pinout
    pinmap_pinout(pin, PinMap_PWM);
}
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");
    
    obj->channel = pwm;
    obj->pwm = LPC_PWM0;
    
    if (obj->channel > 6) { // PWM1 is used if pwm > 6
      obj->channel -= 6;
      obj->pwm = LPC_PWM1;
    }
    
    obj->MR = (__IO uint32_t *)((uint32_t)obj->pwm + PWM_mr_offset[obj->channel]);
    
    // ensure the power is on
    if (obj->pwm == LPC_PWM0) {
        LPC_SC->PCONP |= 1 << 5;
    } else {
        LPC_SC->PCONP |= 1 << 6;
    }
    
    obj->pwm->PR = 0;                     // no pre-scale
    
    // ensure single PWM mode
    obj->pwm->MCR = 1 << 1; // reset TC on match 0
    
    // enable the specific PWM output
    obj->pwm->PCR |= 1 << (8 + obj->channel);
    
    pwm_clock_mhz = PeripheralClock / 1000000;
    
    // 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);
}
示例#23
0
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");
    
    obj->pwm = pwm;
    
    // Timer registers
    timer_mr tid = pwm_timer_map[pwm];
    LPC_TMR_TypeDef *timer = Timers[tid.timer];
    
    // Disable timer
    timer->TCR = 0;
    
    // Power the correspondent timer
    LPC_SYSCON->SYSAHBCLKCTRL |= 1 << (tid.timer + 7);
    
    /* Enable PWM function */
    timer->PWMC = (1 << 3)|(1 << 2)|(1 << 1)|(1 << 0);
    
    /* Reset Functionality on MR3 controlling the PWM period */
    timer->MCR = 1 << 10;
    
    if (timer == LPC_TMR16B0 || timer == LPC_TMR16B1) {
    /* Set 16-bit timer prescaler to avoid timer expire for default 20ms */
    /* This can be also modified by user application, but the prescaler value */
    /* might be trade-off to timer accuracy */
        timer->PR = 30;
    }

    // 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);
}
示例#24
0
void pwmout_free(pwmout_t* obj) {
    pwmout_write(obj, 0);
}
示例#25
0
// Set the PWM period, keeping the duty cycle the same.
void pwmout_period_us(pwmout_t* obj, int us) {
    float dc = pwmout_read(obj);
    *obj->MOD = PWM_CLOCK_MHZ * us;
    pwmout_write(obj, dc);
}
示例#26
0
void pwmout_period_us(pwmout_t* obj, int us)
{
    TimHandle.Instance = (TIM_TypeDef *)(obj->pwm);
    RCC_ClkInitTypeDef RCC_ClkInitStruct;
    uint32_t PclkFreq;
    uint32_t APBxCLKDivider;
    float dc = pwmout_read(obj);

    __HAL_TIM_DISABLE(&TimHandle);

    // Get clock configuration
    // Note: PclkFreq contains here the Latency (not used after)
    HAL_RCC_GetClockConfig(&RCC_ClkInitStruct, &PclkFreq);

    // Get the PCLK and APBCLK divider related to the timer
    switch (obj->pwm) {

    // APB1 clock
    case PWM_2:
    case PWM_3:
    case PWM_4:
    case PWM_5:
    case PWM_12:
    case PWM_13:
    case PWM_14:
        PclkFreq = HAL_RCC_GetPCLK1Freq();
        APBxCLKDivider = RCC_ClkInitStruct.APB1CLKDivider;
        break;

    // APB2 clock
    case PWM_1:
    case PWM_8:
    case PWM_9:
    case PWM_10:
    case PWM_11:
        PclkFreq = HAL_RCC_GetPCLK2Freq();
        APBxCLKDivider = RCC_ClkInitStruct.APB2CLKDivider;
        break;
    default:
        return;
    }

    /* To make it simple, we use to possible prescaler values which lead to:
      * pwm unit = 1us, period/pulse can be from 1us to 65535us
      * or
      * pwm unit = 500us, period/pulse can be from 500us to ~32.76sec
      * Be careful that all the channels of a PWM shares the same prescaler
      */
    if (us >  0xFFFF) {
        obj->prescaler = 500;
    } else {
        obj->prescaler = 1;
    }

    // TIMxCLK = PCLKx when the APB prescaler = 1 else TIMxCLK = 2 * PCLKx
    if (APBxCLKDivider == RCC_HCLK_DIV1)
        TimHandle.Init.Prescaler   = (uint16_t)(((PclkFreq) / 1000000) * obj->prescaler) - 1; // 1 us tick
    else
        TimHandle.Init.Prescaler   = (uint16_t)(((PclkFreq * 2) / 1000000) * obj->prescaler) - 1; // 1 us tick

    if (TimHandle.Init.Prescaler > 0xFFFF)
        error("PWM: out of range prescaler");

    TimHandle.Init.Period        = (us - 1) / obj->prescaler;
    if (TimHandle.Init.Period > 0xFFFF)
        error("PWM: out of range period");

    TimHandle.Init.ClockDivision = 0;
    TimHandle.Init.CounterMode   = TIM_COUNTERMODE_UP;

    if (HAL_TIM_PWM_Init(&TimHandle) != HAL_OK) {
        error("Cannot initialize PWM\n");
    }

    // Save for future use
    obj->period = us;

    // Set duty cycle again
    pwmout_write(obj, dc);

    __HAL_TIM_ENABLE(&TimHandle);
}
示例#27
0
void pwmout_pulsewidth_us(pwmout_t* obj, int us)
{
    float value = (float)us / (float)obj->period;
    pwmout_write(obj, value);
}
示例#28
0
文件: pwmout_api.c 项目: AsamQi/mbed
// Set the PWM period, keeping the duty cycle the same.
void pwmout_period_us(pwmout_t* obj, int us) {
    float dc = pwmout_read(obj);
    *obj->MOD = (uint32_t)(pwm_clock * (float)us) - 1;
    pwmout_write(obj, dc);
}
示例#29
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);

    if (pwm >= MTU2_PWM_OFFSET) {
        /* PWM by MTU2 */
        int tmp_pwm;
        
        // power on
        CPGSTBCR3 &= ~(CPG_STBCR3_BIT_MSTP33);
        
        obj->pwm = pwm;
        tmp_pwm = (int)(obj->pwm - MTU2_PWM_OFFSET);
        if (((uint32_t)MTU2_PORT[tmp_pwm] & 0x00000040) == 0x00000040) {
            obj->ch  = 4;
            MTU2TOER |= 0x36;
        } else if (((uint32_t)MTU2_PORT[tmp_pwm] & 0x00000030) == 0x00000030) {
            obj->ch  = 3;
            MTU2TOER |= 0x09;
        } else if (((uint32_t)MTU2_PORT[tmp_pwm] & 0x00000020) == 0x00000020) {
            obj->ch  = 2;
        } else if (((uint32_t)MTU2_PORT[tmp_pwm] & 0x00000010) == 0x00000010) {
            obj->ch  = 1;
        } else {
            obj->ch  = 0;
        }
        // Wire pinout
        pinmap_pinout(pin, PinMap_PWM);

        int bitmask = 1 << (pin  & 0xf);

        *PMSR(PINGROUP(pin)) = (bitmask << 16) | 0;

        // default duty 0.0f
        pwmout_write(obj, 0);
        if (init_mtu2_period_ch[obj->ch] == 0) {
            // default period 1ms
            pwmout_period_us(obj, 1000);
            init_mtu2_period_ch[obj->ch] = 1;
        }
    } else {
        /* PWM */
        // power on
        CPGSTBCR3 &= ~(CPG_STBCR3_BIT_MSTP30);

        obj->pwm = pwm;
        if (((uint32_t)PORT[obj->pwm] & 0x00000010) == 0x00000010) {
            obj->ch  = 2;
            PWMPWPR_2_BYTE_L = 0x00;
        } else {
            obj->ch  = 1;
            PWMPWPR_1_BYTE_L = 0x00;
        }

        // Wire pinout
        pinmap_pinout(pin, PinMap_PWM);

        // default to 491us: standard for servos, and fine for e.g. brightness control
        pwmout_write(obj, 0);
        if ((obj->ch == 2) && (init_period_ch2 == 0)) {
            pwmout_period_us(obj, 491);
            init_period_ch2 = 1;
        }
        if ((obj->ch == 1) && (init_period_ch1 == 0)) {
            pwmout_period_us(obj, 491);
            init_period_ch1 = 1;
        }
    }
}
示例#30
0
文件: pwmout_api.c 项目: AsamQi/mbed
void pwmout_init(pwmout_t* obj, PinName pin) {
    MBED_ASSERT(pin != (uint32_t)NC);

    int sct_n = get_available_sct();
    if (sct_n == -1) {
        error("No available SCT");
    }
    
    sct_used |= (1 << sct_n);
    obj->pwm =  SCTs[sct_n];
    obj->pwm_ch = sct_n;

    LPC_SCT0_Type* pwm = obj->pwm;

    // Enable the SCT clock
    LPC_SYSCON->SYSAHBCLKCTRL1 |= (1 << (obj->pwm_ch + 2));

    // Clear peripheral reset the SCT:
    LPC_SYSCON->PRESETCTRL1 |=  (1 << (obj->pwm_ch + 2));
    LPC_SYSCON->PRESETCTRL1 &= ~(1 << (obj->pwm_ch + 2));
    
    switch(obj->pwm_ch) {
    	case 0:
            // SCT0_OUT0
            LPC_SWM->PINASSIGN[7] &= ~0x0000FF00;
            LPC_SWM->PINASSIGN[7] |= (pin << 8);
    		break;
    	case 1:
            // SCT1_OUT0
            LPC_SWM->PINASSIGN[8] &= ~0x000000FF;
            LPC_SWM->PINASSIGN[8] |= (pin);
    		break;
    	case 2:
            // SCT2_OUT0
            LPC_SWM->PINASSIGN[8] &= ~0xFF000000;
            LPC_SWM->PINASSIGN[8] |= (pin << 24);
    		break;
    	case 3:
            // SCT3_OUT0
            LPC_SWM->PINASSIGN[9] &= ~0x00FF0000;
            LPC_SWM->PINASSIGN[9] |= (pin << 16);
    		break;
    	default:
    		break;
    }
    
    // Two 16-bit counters, autolimit
    pwm->CONFIG &= ~(0x1);
    pwm->CONFIG |= (1 << 17);
    
    // halt and clear the counter
    pwm->CTRL |= (1 << 2) | (1 << 3);
    
    // System Clock -> us_ticker (1)MHz
    pwm->CTRL &= ~(0x7F << 5);
    pwm->CTRL |= (((SystemCoreClock/1000000 - 1) & 0x7F) << 5);
    
    // Match reload register
    pwm->MATCHREL0 = 20000; // 20ms
    pwm->MATCHREL1 = (pwm->MATCHREL0 / 4); // 50% duty
    
    pwm->OUT0_SET = (1 << 0); // event 0
    pwm->OUT0_CLR = (1 << 1); // event 1

	pwm->EV0_CTRL  = (1 << 12);
	pwm->EV0_STATE = 0xFFFFFFFF;
	pwm->EV1_CTRL  = (1 << 12) | (1 << 0);
	pwm->EV1_STATE = 0xFFFFFFFF;

    // unhalt the counter:
    //    - clearing bit 2 of the CTRL register
    pwm->CTRL &= ~(1 << 2);

    // default to 20ms: standard for servos, and fine for e.g. brightness control
    pwmout_period_ms(obj, 20);
    pwmout_write    (obj, 0);
}