@@ -107,6 +107,10 @@ void i2c_init(i2c_t *obj, PinName sda, PinName scl)
107
107
I2CName i2c_scl = (I2CName ) pinmap_peripheral (scl , PinMap_I2C_SCL );
108
108
obj -> i2c .i2c = (I2C_TypeDef * ) pinmap_merge (i2c_sda , i2c_scl );
109
109
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 );
110
114
111
115
/* Enable clock for the peripheral */
112
116
CMU_ClockEnable (i2c_get_clock (obj ), true);
@@ -132,6 +136,8 @@ void i2c_init(i2c_t *obj, PinName sda, PinName scl)
132
136
#endif
133
137
134
138
/* 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 */
135
141
pin_mode (scl , WiredAndPullUp );
136
142
pin_mode (sda , WiredAndPullUp );
137
143
@@ -192,7 +198,23 @@ void i2c_frequency(i2c_t *obj, int hz)
192
198
{
193
199
/* Set frequency. As the second argument is 0,
194
200
* 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
+ }
196
218
}
197
219
198
220
/* Creates a start condition on the I2C bus */
@@ -352,11 +374,15 @@ int block_and_wait_for_ack(I2C_TypeDef *i2c)
352
374
void i2c_slave_mode (i2c_t * obj , int enable_slave )
353
375
{
354
376
if (enable_slave ) {
377
+ /* Reference manual note: DIV must be set to 1 during slave operation */
378
+ obj -> i2c .i2c -> CLKDIV = 1 ;
355
379
obj -> i2c .i2c -> CTRL |= _I2C_CTRL_SLAVE_MASK ;
356
380
obj -> i2c .i2c -> CTRL |= _I2C_CTRL_AUTOACK_MASK ; //Slave implementation assumes auto acking
357
381
} else {
358
382
obj -> i2c .i2c -> CTRL &= ~_I2C_CTRL_SLAVE_MASK ;
359
383
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 */
360
386
}
361
387
}
362
388
0 commit comments