/ * @brief * Set I2C bus frequency. * * @details * The bus frequency is only of relevance when acting as a master. The bus * frequency should not be set higher than the max frequency accepted by the * slowest device on the bus. * * Notice that due to asymmetric requirements on low and high I2C clock * cycles by the I2C specification, the actual max frequency allowed in order
| 207 | * fast+ modes. |
| 208 | ******************************************************************************/ |
| 209 | void I2C_BusFreqSet(I2C_TypeDef *i2c, |
| 210 | uint32_t refFreq, |
| 211 | uint32_t freq, |
| 212 | I2C_ClockHLR_TypeDef type) |
| 213 | { |
| 214 | uint32_t n; |
| 215 | uint32_t div; |
| 216 | |
| 217 | /* Unused parameter */ |
| 218 | (void)type; |
| 219 | |
| 220 | /* Avoid divide by 0 */ |
| 221 | EFM_ASSERT(freq); |
| 222 | if (!freq) |
| 223 | { |
| 224 | return; |
| 225 | } |
| 226 | |
| 227 | /* Frequency is given by fSCL = fHFPERCLK/((Nlow + Nhigh)(DIV + 1) + 4), thus */ |
| 228 | /* DIV = ((fHFPERCLK - 4fSCL)/((Nlow + Nhigh)fSCL)) - 1 */ |
| 229 | |
| 230 | if (!refFreq) |
| 231 | { |
| 232 | refFreq = CMU_ClockFreqGet(cmuClock_HFPER); |
| 233 | } |
| 234 | n = (uint32_t)(i2cNSum[(i2c->CTRL & _I2C_CTRL_CLHR_MASK) >> _I2C_CTRL_CLHR_SHIFT]); |
| 235 | |
| 236 | div = (refFreq - (4 * freq)) / (n * freq); |
| 237 | EFM_ASSERT(div); |
| 238 | if (div) |
| 239 | { |
| 240 | div--; |
| 241 | } |
| 242 | |
| 243 | /* Clock divisor must be at least 1 in slave mode according to reference */ |
| 244 | /* manual (in which case there is normally no need to set bus frequency). */ |
| 245 | if ((i2c->CTRL & I2C_CTRL_SLAVE) && !div) |
| 246 | { |
| 247 | div = 1; |
| 248 | } |
| 249 | |
| 250 | EFM_ASSERT(div <= _I2C_CLKDIV_DIV_MASK); |
| 251 | i2c->CLKDIV = div; |
| 252 | } |
| 253 | |
| 254 | |
| 255 | /***************************************************************************//** |
no test coverage detected