added prescaler for 16 bit pwm in LPC1347 target
Fork of mbed-dev by
Diff: targets/hal/TARGET_Silicon_Labs/TARGET_EFM32/i2c_api.c
- Revision:
- 52:4ce9155acc4d
- Parent:
- 50:a417edff4437
- Child:
- 144:ef7eb2e8f9f7
diff -r 2dcb841baa4f -r 4ce9155acc4d targets/hal/TARGET_Silicon_Labs/TARGET_EFM32/i2c_api.c --- a/targets/hal/TARGET_Silicon_Labs/TARGET_EFM32/i2c_api.c Fri Jan 15 08:00:11 2016 +0000 +++ b/targets/hal/TARGET_Silicon_Labs/TARGET_EFM32/i2c_api.c Fri Jan 15 13:15:11 2016 +0000 @@ -107,6 +107,10 @@ I2CName i2c_scl = (I2CName) pinmap_peripheral(scl, PinMap_I2C_SCL); obj->i2c.i2c = (I2C_TypeDef*) pinmap_merge(i2c_sda, i2c_scl); MBED_ASSERT(((int) obj->i2c.i2c) != NC); + + /* You need both SDA and SCL for I2C, so configuring one of them to NC is illegal */ + MBED_ASSERT((uint32_t)sda != (uint32_t)NC); + MBED_ASSERT((uint32_t)scl != (uint32_t)NC); /* Enable clock for the peripheral */ CMU_ClockEnable(i2c_get_clock(obj), true); @@ -132,6 +136,8 @@ #endif /* Set up the pins for I2C use */ + /* Note: Set up pins in higher drive strength to reduce slew rate */ + /* Though this requires user knowledge, since drive strength is controlled per port, not pin */ pin_mode(scl, WiredAndPullUp); pin_mode(sda, WiredAndPullUp); @@ -192,7 +198,23 @@ { /* Set frequency. As the second argument is 0, * HFPER clock frequency is used as reference freq */ - I2C_BusFreqSet(obj->i2c.i2c, REFERENCE_FREQUENCY, hz, i2cClockHLRStandard); + if (hz <= 0) return; + /* In I2C Normal mode (50% duty), we can go up to 100kHz */ + if (hz <= 100000) { + I2C_BusFreqSet(obj->i2c.i2c, REFERENCE_FREQUENCY, hz, i2cClockHLRStandard); + } + /* In I2C Fast mode (6:3 ratio), we can go up to 400kHz */ + else if (hz <= 400000) { + I2C_BusFreqSet(obj->i2c.i2c, REFERENCE_FREQUENCY, hz, i2cClockHLRAsymetric); + } + /* In I2C Fast+ mode (11:6 ratio), we can go up to 1 MHz */ + else if (hz <= 1000000) { + I2C_BusFreqSet(obj->i2c.i2c, REFERENCE_FREQUENCY, hz, i2cClockHLRFast); + } + /* Cap requested frequency at 1MHz */ + else { + I2C_BusFreqSet(obj->i2c.i2c, REFERENCE_FREQUENCY, 1000000, i2cClockHLRFast); + } } /* Creates a start condition on the I2C bus */ @@ -352,11 +374,15 @@ void i2c_slave_mode(i2c_t *obj, int enable_slave) { if(enable_slave) { + /* Reference manual note: DIV must be set to 1 during slave operation */ + obj->i2c.i2c->CLKDIV = 1; obj->i2c.i2c->CTRL |= _I2C_CTRL_SLAVE_MASK; obj->i2c.i2c->CTRL |= _I2C_CTRL_AUTOACK_MASK; //Slave implementation assumes auto acking } else { obj->i2c.i2c->CTRL &= ~_I2C_CTRL_SLAVE_MASK; obj->i2c.i2c->CTRL &= ~_I2C_CTRL_AUTOACK_MASK; //Master implementation ACKs manually + /* function is only called with enable_slave = false through i2c_init(..), so frequency is + already guaranteed to be set */ } }