Commit 310e78e6 authored by chuck todd's avatar chuck todd Committed by Me No Dev

Support CPU frequency changes (#2222)

The I2C hardware has limitations on min and max bus frequency directly related to CPU frequency, bus speed cannot be greater than 1/100 CPU clock, nor less than CPU clock / 8192.
parent c827bb41
...@@ -1604,19 +1604,35 @@ i2c_err_t i2cRead(i2c_t * i2c, uint16_t address, uint8_t* buff, uint16_t size, b ...@@ -1604,19 +1604,35 @@ i2c_err_t i2cRead(i2c_t * i2c, uint16_t address, uint8_t* buff, uint16_t size, b
return last_error; return last_error;
} }
#define MIN_I2C_CLKS 100
i2c_err_t i2cSetFrequency(i2c_t * i2c, uint32_t clk_speed) i2c_err_t i2cSetFrequency(i2c_t * i2c, uint32_t clk_speed)
{ {
if(i2c == NULL) { if(i2c == NULL) {
return I2C_ERROR_DEV; return I2C_ERROR_DEV;
} }
I2C_FIFO_CONF_t f; uint32_t apb = getApbFrequency();
uint32_t period = (apb/clk_speed) / 2;
if((apb/8192 > clk_speed)||(apb/MIN_I2C_CLKS < clk_speed)){ //out of bounds
log_w("i2c freq(%d) out of bounds.vs APB Clock(%d), min=%d, max=%d",clk_speed,apb,(apb/8192),(apb/MIN_I2C_CLKS));
}
if(period < (MIN_I2C_CLKS/2) ){
period = (MIN_I2C_CLKS/2);
clk_speed = apb/(period*2);
log_w("APB Freq too slow, Reducing i2c Freq to %d Hz",clk_speed);
} else if ( period> 4095) {
period = 4095;
clk_speed = apb/(period*2);
log_w("APB Freq too fast, Increasing i2c Freq to %d Hz",clk_speed);
}
uint32_t period = (getApbFrequency()/clk_speed) / 2;
uint32_t halfPeriod = period/2; uint32_t halfPeriod = period/2;
uint32_t quarterPeriod = period/4; uint32_t quarterPeriod = period/4;
I2C_MUTEX_LOCK(); I2C_MUTEX_LOCK();
I2C_FIFO_CONF_t f;
// Adjust Fifo thresholds based on frequency // Adjust Fifo thresholds based on frequency
f.val = i2c->dev->fifo_conf.val; f.val = i2c->dev->fifo_conf.val;
uint32_t a = (clk_speed / 50000L )+1; uint32_t a = (clk_speed / 50000L )+1;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment