/* * 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; }
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; }
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."); } }