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);
}
Exemplo n.º 2
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);
}
Exemplo n.º 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");
    
    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);
}
Exemplo n.º 4
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);
}
Exemplo n.º 5
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);
}
Exemplo n.º 6
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);
    
}
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);
}
Exemplo n.º 8
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);
}
Exemplo n.º 9
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);
}
Exemplo n.º 10
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);
}
Exemplo n.º 11
0
void pwmout_init(pwmout_t *obj, PinName pin)
{
    // Determine the pwm channel
    PWMName pwm = (PWMName)pinmap_peripheral(pin, PinMap_PWM);
    //Assert input is valid
    MBED_ASSERT(pwm != (PWMName)NC);
    switch (pwm) {
        case PWM_0:
            obj->channel = TSB_TB2;
            break;
        case PWM_1:
            obj->channel = TSB_TB3;
            break;
        case PWM_2:
            obj->channel = TSB_TB4;
            break;
        case PWM_3:
            obj->channel = TSB_TB5;
            break;
        case PWM_4:
            obj->channel = TSB_TB6;
            break;
        case PWM_5:
            obj->channel = TSB_TB7;
            break;
        default:
            obj->channel = NULL;
            break;
    }
    CG_SetFcPeriphA((0x01U << (15U + pwm)), ENABLE);
    TMRB_SetIdleMode(TSB_TB0, DISABLE);
    // Set pin function as PWM
    pinmap_pinout(pin, PinMap_PWM);
    // Default to 20ms, 0% duty cycle
    pwmout_period_ms(obj, 20);
}
Exemplo n.º 12
0
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);
}
Exemplo n.º 13
0
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;
    }
    
    // Unified 32-bit counter, autolimit
    pwm->CONFIG |= ((0x3 << 17) | 0x01);
    
    // halt and clear the counter
    pwm->CTRL |= (1 << 2) | (1 << 3);
    
    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;

    // default to 20ms: standard for servos, and fine for e.g. brightness control
    pwmout_period_ms(obj, 20);
    pwmout_write    (obj, 0);
}
Exemplo n.º 14
0
void pwmout_init(pwmout_t* obj, PinName pin) {
    // determine the SPI to use
    PWMName pwm_mapped = (PWMName)pinmap_peripheral(pin, PinMap_PWM);
    if (pwm_mapped == (PWMName)NC) {
        error("PwmOut pin mapping failed");
    }
    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;

    // Enable the SCT clock
    LPC_SYSCON->SYSAHBCLKCTRL |= (1UL << 31);

    // Clear peripheral reset the SCT:
    LPC_SYSCON->PRESETCTRL |=  (1 << (obj->pwm_ch + 9));
    pinmap_pinout(pin, PinMap_PWM);
    LPC_SCT0_Type* pwm = obj->pwm;

    // 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);

    switch(pwm_mapped) {
    case SCT0_0:
    case SCT1_0:
        pwm->OUT0_SET = (1 << 0); // event 0
        pwm->OUT0_CLR = (1 << 1); // event 1
        break;
    case SCT0_1:
    case SCT1_1:
        pwm->OUT1_SET = (1 << 0); // event 0
        pwm->OUT1_CLR = (1 << 1); // event 1
        break;
    case SCT0_2:
    case SCT1_2:
        pwm->OUT2_SET = (1 << 0); // event 0
        pwm->OUT2_CLR = (1 << 1); // event 1
        break;
    case SCT0_3:
    case SCT1_3:
        pwm->OUT3_SET = (1 << 0); // event 0
        pwm->OUT3_CLR = (1 << 1); // event 1
        break;
    default:
        break;
    }
    // Event 0 : MATCH and MATCHSEL=0
    pwm->EV0_CTRL  = (1 << 12);
    pwm->EV0_STATE = 0xFFFFFFFF;
    // Event 1 : MATCH and MATCHSEL=1
    pwm->EV1_CTRL  = (1 << 12) | (1 << 0);
    pwm->EV1_STATE = 0xFFFFFFFF;

    // Match reload register
    pwm->MATCHREL0 = 20000; // 20ms
    pwm->MATCHREL1 = (pwm->MATCHREL0 / 4); // 50% duty

    // 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);
}
Exemplo n.º 15
0
// Any Port pin may be used for PWM.
// Max number of PWM outputs is 4
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 Output");
    }

    sct_used |= (1 << sct_n);

    obj->pwm =  (LPC_SCT_TypeDef*)LPC_SCT;
    obj->pwm_ch = sct_n;

    LPC_SCT_TypeDef* pwm = obj->pwm;

    // Init SCT on first use
    if (! sct_inited) {
      sct_inited = 1;

      // Enable the SCT clock
      LPC_SYSCON->SYSAHBCLKCTRL |= (1 << 8);

      // Clear peripheral reset the SCT:
      LPC_SYSCON->PRESETCTRL |=  (1 << 8);

      // Two 16-bit counters, autolimit (ie reset on Match_0)
      //pwm->CONFIG &= ~(0x1);
      //pwm->CONFIG |= (1 << 17);
      pwm->CONFIG |= ((0x3 << 17) | 0x01);

      // halt and clear the counter
      pwm->CTRL_U |= (1 << 2) | (1 << 3);

      // System Clock (30 Mhz) -> Prescaler -> us_ticker (1 MHz)
      pwm->CTRL_U &= ~(0x7F << 5);
      pwm->CTRL_U |= (((SystemCoreClock/1000000 - 1) & 0x7F) << 5);

      pwm->EVENT[0].CTRL  = (1 << 12) | 0;                     // Event_0 on Match_0
      pwm->EVENT[0].STATE = 0xFFFFFFFF;                        // All states
    
      // unhalt the counter:
      //    - clearing bit 2 of the CTRL register
      pwm->CTRL_U &= ~(1 << 2);
      
      // Not using IRQs 
      //NVIC_SetVector(PWM_IRQn, (uint32_t)pwm_irq_handler);
      //NVIC_EnableIRQ(PWM_IRQn);    
    }

    // LPC81x has only one SCT and 4 Outputs
    // LPC82x has only one SCT and 6 Outputs
    // LPC1549 has 4 SCTs and 16 Outputs    
    switch(sct_n) {
        case 0:
            // SCTx_OUT0
            LPC_SWM->PINASSIGN[6] &= ~0xFF000000;
            LPC_SWM->PINASSIGN[6] |= (pin << 24);
            break;
        case 1:
            // SCTx_OUT1
            LPC_SWM->PINASSIGN[7] &= ~0x000000FF;
            LPC_SWM->PINASSIGN[7] |= (pin);
            break;
        case 2:
            // SCTx_OUT2
            LPC_SWM->PINASSIGN[7] &= ~0x0000FF00;
            LPC_SWM->PINASSIGN[7] |= (pin << 8);
            break;
        case 3:
            // SCTx_OUT3
            LPC_SWM->PINASSIGN[7] &= ~0x00FF0000;
            LPC_SWM->PINASSIGN[7] |= (pin << 16);
            break;
        default:
            break;
    }

    pwm->EVENT[sct_n + 1].CTRL  = (1 << 12) | (sct_n + 1);  // Event_n on Match_n
    pwm->EVENT[sct_n + 1].STATE = 0xFFFFFFFF;               // All states

    pwm->OUT[sct_n].SET = (1 << 0);                         // All PWM channels are SET on Event_0
    pwm->OUT[sct_n].CLR = (1 << (sct_n + 1));               // PWM ch is CLRed on Event_(ch+1)
   
    // default to 20ms: standard for servos, and fine for e.g. brightness control
    pwmout_period_ms(obj, 20);   // 20ms period
    pwmout_write    (obj, 0.0);  //  0ms pulsewidth, dutycycle 0
}