I think I have a fix for this. The F[MULT] bits are set in the i2c_frequency() function in mbed-src/vendor/Freescale/KL25Z/hal/i2c_api.c. A minimal patch is:
<<verbatim>>
--- i2c_api.c 2013-07-11 02:05:47.306427939 +1000
+++ i2c_api.c.new 2013-07-11 02:08:55.737406031 +1000
@@ -198,7 +198,9 @@
// we look for the values that minimize the error
// test all the MULT values
- for (i = 1; i < 5; i*=2) {
+ // ERRATA e6070: We require MULT = 0, otherwise repeated start doesn't work.
+ // for (i = 1; i < 5; i*=2) {
+ i = 1; {
for (j = 0; j < 0x40; j++) {
ref = PCLK / (i*ICR[j]);
error = (ref > hz) ? ref - hz : hz - ref;
<</verbatim>>
That is, instead of testing all possible multipliers 1,2,4, only allow the multiplier to be 1 (corresponding to MULT=0). This appears to work OK.
Another improvement to this function would be to return the actual bus frequency that was chosen, or provide another function to calculate the current bus frequency.
Elsewhere on the forums /questions/802/Problem-with-I2C-read-commands/, someone pointed out a problem with the FRDM I2C implementation, and problems when the clock rate is > 100KHz. In a blog post MCU on Eclipse it was identified as a hardware bug where I2C only works correctly when the clock prescaler is set to 1.
There is also an errata on the freescale website, http://cache.freescale.com/files/microcontrollers/doc/errata/KINETIS_L_2N97F.pdf?fpsp=1 :
Quote:
e6070:I2C: Repeat start cannot be generated if the I2Cx_F[MULT] field is set to a non-zero value
Errata type: Errata
Description: If the I2Cx_F[MULT] field is written with a non-zero value, then a repeat start cannot be generated
Workaround: There are two possible workarounds:
1) Configure I2Cx_F[MULT] to zero if a repeat start has to be generated.
2) Temporarily set I2Cx_F [MULT] to zero immediately before setting the Repeat START bit in the I2C C1 register (I2Cx_C1[RSTA]=1) and restore the I2Cx_F [MULT] field to the original value after the repeated start has occurred
Is it possible to get a workaround into the MBED library? If I understand mcuoneclipse correctly, it is possible to achieve I2C clock rates by other methods, leaving the prescaler set to 1.