@@ -107,6 +107,10 @@ void i2c_init(i2c_t *obj, PinName sda, PinName scl)
107107 I2CName i2c_scl = (I2CName ) pinmap_peripheral (scl , PinMap_I2C_SCL );
108108 obj -> i2c .i2c = (I2C_TypeDef * ) pinmap_merge (i2c_sda , i2c_scl );
109109 MBED_ASSERT (((int ) obj -> i2c .i2c ) != NC );
110+
111+ /* You need both SDA and SCL for I2C, so configuring one of them to NC is illegal */
112+ MBED_ASSERT ((uint32_t )sda != (uint32_t )NC );
113+ MBED_ASSERT ((uint32_t )scl != (uint32_t )NC );
110114
111115 /* Enable clock for the peripheral */
112116 CMU_ClockEnable (i2c_get_clock (obj ), true);
@@ -132,6 +136,8 @@ void i2c_init(i2c_t *obj, PinName sda, PinName scl)
132136#endif
133137
134138 /* Set up the pins for I2C use */
139+ /* Note: Set up pins in higher drive strength to reduce slew rate */
140+ /* Though this requires user knowledge, since drive strength is controlled per port, not pin */
135141 pin_mode (scl , WiredAndPullUp );
136142 pin_mode (sda , WiredAndPullUp );
137143
@@ -192,7 +198,23 @@ void i2c_frequency(i2c_t *obj, int hz)
192198{
193199 /* Set frequency. As the second argument is 0,
194200 * HFPER clock frequency is used as reference freq */
195- I2C_BusFreqSet (obj -> i2c .i2c , REFERENCE_FREQUENCY , hz , i2cClockHLRStandard );
201+ if (hz <= 0 ) return ;
202+ /* In I2C Normal mode (50% duty), we can go up to 100kHz */
203+ if (hz <= 100000 ) {
204+ I2C_BusFreqSet (obj -> i2c .i2c , REFERENCE_FREQUENCY , hz , i2cClockHLRStandard );
205+ }
206+ /* In I2C Fast mode (6:3 ratio), we can go up to 400kHz */
207+ else if (hz <= 400000 ) {
208+ I2C_BusFreqSet (obj -> i2c .i2c , REFERENCE_FREQUENCY , hz , i2cClockHLRAsymetric );
209+ }
210+ /* In I2C Fast+ mode (11:6 ratio), we can go up to 1 MHz */
211+ else if (hz <= 1000000 ) {
212+ I2C_BusFreqSet (obj -> i2c .i2c , REFERENCE_FREQUENCY , hz , i2cClockHLRFast );
213+ }
214+ /* Cap requested frequency at 1MHz */
215+ else {
216+ I2C_BusFreqSet (obj -> i2c .i2c , REFERENCE_FREQUENCY , 1000000 , i2cClockHLRFast );
217+ }
196218}
197219
198220/* Creates a start condition on the I2C bus */
@@ -352,11 +374,15 @@ int block_and_wait_for_ack(I2C_TypeDef *i2c)
352374void i2c_slave_mode (i2c_t * obj , int enable_slave )
353375{
354376 if (enable_slave ) {
377+ /* Reference manual note: DIV must be set to 1 during slave operation */
378+ obj -> i2c .i2c -> CLKDIV = 1 ;
355379 obj -> i2c .i2c -> CTRL |= _I2C_CTRL_SLAVE_MASK ;
356380 obj -> i2c .i2c -> CTRL |= _I2C_CTRL_AUTOACK_MASK ; //Slave implementation assumes auto acking
357381 } else {
358382 obj -> i2c .i2c -> CTRL &= ~_I2C_CTRL_SLAVE_MASK ;
359383 obj -> i2c .i2c -> CTRL &= ~_I2C_CTRL_AUTOACK_MASK ; //Master implementation ACKs manually
384+ /* function is only called with enable_slave = false through i2c_init(..), so frequency is
385+ already guaranteed to be set */
360386 }
361387}
362388
0 commit comments