Exemplo n.º 1
0
/*
 * Initializes spi clock for the required speed
 */
static cy_en_sysclk_status_t spi_init_clock(spi_obj_t *obj, uint32_t frequency)
{
    cy_en_sysclk_status_t status = CY_SYSCLK_INVALID_STATE;
    uint32_t div_value;

    if (obj->div_num == CY_INVALID_DIVIDER) {
        if (allocate_divider(obj) < 0) {
            error("spi: cannot allocate clock divider.");
            return CY_SYSCLK_INVALID_STATE;
        }
    }

    // Set up proper frequency; round up the divider so the frequency is not higher than specified.
    div_value = (CY_CLK_PERICLK_FREQ_HZ + frequency *(SPI_OVERSAMPLE - 1)) / frequency / SPI_OVERSAMPLE;
    obj->clk_frequency = CY_CLK_PERICLK_FREQ_HZ / div_value / SPI_OVERSAMPLE;
    Cy_SysClk_PeriphDisableDivider(obj->div_type, obj->div_num);
    if (Cy_SysClk_PeriphSetDivider(obj->div_type, obj->div_num, div_value) != CY_SYSCLK_SUCCESS) {
        obj->div_num = CY_INVALID_DIVIDER;
    }
    Cy_SysClk_PeriphEnableDivider(obj->div_type, obj->div_num);

    if (obj->div_num != CY_INVALID_DIVIDER) {
        status = Cy_SysClk_PeriphAssignDivider(obj->clock, obj->div_type, obj->div_num);
        if (status != CY_SYSCLK_SUCCESS) {
            error("spi: cannot assign clock divider.");
            return status;
        }
    }
    return CY_SYSCLK_SUCCESS;
}
Exemplo n.º 2
0
static int allocate_divider(I2cDividerType divider)
{
    I2cDividerInfo *p_div = &i2c_dividers[divider];

    if (p_div->div_num == CY_INVALID_DIVIDER) {
        p_div->div_num = cy_clk_allocate_divider(CY_SYSCLK_DIV_8_BIT);
        if (p_div->div_num != CY_INVALID_DIVIDER) {
            p_div->div_type = CY_SYSCLK_DIV_8_BIT;
        } else {
            p_div->div_num = cy_clk_allocate_divider(CY_SYSCLK_DIV_16_BIT);
            if (p_div->div_num != CY_INVALID_DIVIDER) {
                p_div->div_type = CY_SYSCLK_DIV_16_BIT;
            }
        }
    }

    if (p_div->div_num != CY_INVALID_DIVIDER) {
        // Set up proper frequency;
        uint32_t div_value = cy_PeriClkFreqHz / p_div->clk_frequency;
        p_div->clk_frequency = cy_PeriClkFreqHz / div_value;
        if (Cy_SysClk_PeriphSetDivider(p_div->div_type, p_div->div_num, div_value) == CY_SYSCLK_SUCCESS) {
            Cy_SysClk_PeriphEnableDivider(p_div->div_type, p_div->div_num);
        } else {
            p_div->div_num = CY_INVALID_DIVIDER;
        }
    }

    return (p_div->div_num == CY_INVALID_DIVIDER) ? -1 : 0;
}
Exemplo n.º 3
0
void pwmout_init(pwmout_t *obj, PinName pin)
{
    uint32_t    pwm_cnt = 0;
    uint32_t    pwm_function = 0;
    uint32_t    abs_cnt_num = 0;

    MBED_ASSERT(obj);
    MBED_ASSERT(pin != (PinName)NC);
    // Allocate and setup clock.
    if (pwm_clock_divider == CY_INVALID_DIVIDER) {
        pwm_clock_divider = cy_clk_allocate_divider(CY_SYSCLK_DIV_8_BIT);
        if (pwm_clock_divider == CY_INVALID_DIVIDER) {
            error("PWM clock divider allocation failed.");
            return;
        }
        Cy_SysClk_PeriphSetDivider(CY_SYSCLK_DIV_8_BIT,
                                   pwm_clock_divider,
                                   (CY_CLK_PERICLK_FREQ_HZ / PWMOUT_BASE_CLOCK_HZ) - 1);
        Cy_SysClk_PeriphEnableDivider(CY_SYSCLK_DIV_8_BIT, pwm_clock_divider);
    }

    pwm_cnt = pinmap_peripheral(pin, PinMap_PWM_OUT);
    if (pwm_cnt != (uint32_t)NC) {
        if (cy_reserve_io_pin(pin)) {
            error("PWMOUT pin reservation conflict.");
        }
        obj->base = (TCPWM_Type*)CY_PERIPHERAL_BASE(pwm_cnt);
        obj->pin = pin;
        if (obj->base == TCPWM0) {
            obj->counter_id = ((PWMName)pwm_cnt - PWM_32b_0) / (PWM_32b_1 - PWM_32b_0);
            abs_cnt_num = obj->counter_id;
        } else {
            // TCPWM1 is used.
            obj->counter_id = ((PWMName)pwm_cnt - PWM_16b_0) / (PWM_16b_1 - PWM_16b_0);
            abs_cnt_num = obj->counter_id + 8;
        }
        if (cy_reserve_tcpwm(abs_cnt_num)) {
            error("PWMOUT Timer/Counter reservation conflict.");
        }

        // Configure clock.
        pwm_function = pinmap_function(pin, PinMap_PWM_OUT);
        obj->clock = CY_PIN_CLOCK(pwm_function);
        Cy_SysClk_PeriphAssignDivider(obj->clock, CY_SYSCLK_DIV_8_BIT, pwm_clock_divider);
        Cy_TCPWM_PWM_Init(obj->base, obj->counter_id, &pwm_config);
        pin_function(pin, pwm_function);
        // These will be properly configured later on.
        obj->period = 0;
        obj->pulse_width = 0;
        obj->prescaler = 0;
#if DEVICE_SLEEP && DEVICE_LPTICKER
        obj->pm_callback_handler.callback = pwm_pm_callback;
        obj->pm_callback_handler.type = CY_SYSPM_DEEPSLEEP;
        obj->pm_callback_handler.skipMode = 0;
        obj->pm_callback_handler.callbackParams = &obj->pm_callback_params;
        obj->pm_callback_params.base = obj->base;
        obj->pm_callback_params.context = obj;
        if (!Cy_SysPm_RegisterCallback(&obj->pm_callback_handler)) {
            error("PM callback registration failed!");
        }
#endif // DEVICE_SLEEP && DEVICE_LPTICKER

    } else {
        error("PWM OUT pinout mismatch.");
    }
}