/* * Initializes i2c clock for the required speed */ static cy_en_sysclk_status_t i2c_init_clock(i2c_obj_t *obj, uint32_t speed) { I2cDividerInfo *p_div = NULL; cy_en_sysclk_status_t status = CY_SYSCLK_INVALID_STATE; I2cDividerType divider = select_divider(speed); if (divider == I2C_INVALID_DIVIDER) { error("I2C: required speed/frequency is out of valid range."); } if (allocate_divider(divider) < 0) { error("I2C: cannot allocate clock divider."); } obj->divider = divider; p_div = &i2c_dividers[divider]; status = Cy_SysClk_PeriphAssignDivider(obj->clock, p_div->div_type, p_div->div_num); if (status != CY_SYSCLK_SUCCESS) { error("I2C: cannot assign clock divider."); } /* Set desired speed/frequency */ obj->actual_speed = Cy_SCB_I2C_SetDataRate(obj->base, speed, p_div->clk_frequency); return (obj->actual_speed != 0) ? CY_SYSCLK_SUCCESS : CY_SYSCLK_BAD_PARAM; }
/* * 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; }