kinetis: Update i2c driver to new API#9262
Conversation
cpu/kinetis/periph/i2c.c
Outdated
| 1280, 1536, 1792, 2048, 2304, 2560, 3072, 3840, /* 0x38 ~ 0x3f */ | ||
| }; | ||
|
|
||
| static const i2c_conf_t i2c_config[I2C_NUMOF] = I2C_CONFIG; |
There was a problem hiding this comment.
Why not directly defining this array of structs in the board periph_conf (like stm32, sam0, etc) instead of using the I2C_CONFIG macro ?
There was a problem hiding this comment.
I wanted to avoid unintentionally instancing this local array inside any other files, so I decided to put it as a define instead.
There was a problem hiding this comment.
Ok but then it's not consistent with the other configuration arrays (UART, SPI, PWM, ADC, etc).
There was a problem hiding this comment.
alright, will change this for now
241b1ed to
d244646
Compare
|
Refactored to use IRQs when transferring the actual data bytes. This method lets the CPU perform other tasks while waiting for a slow I2C slave. |
dylad
left a comment
There was a problem hiding this comment.
I have zero knowledge of this MCU but overall looks good. Just a few things could be change.
Were you able to test it with some devices ?
| FEATURES_PROVIDED += periph_gpio | ||
| FEATURES_PROVIDED += periph_pwm | ||
| FEATURES_PROVIDED += periph_rtc | ||
| FEATURES_PROVIDED += periph_rtt |
There was a problem hiding this comment.
I had to pull in some upstream merged PRs to avoid problems rebasing later.
| while (!(dev->S & I2C_S_IICIF_MASK)); | ||
|
|
||
| dev->S = I2C_S_IICIF_MASK; | ||
| I2C_Type *i2c = i2c_config[dev].i2c; |
There was a problem hiding this comment.
Could you add a guard here please ?
if (len == 0 || data == NULL) {
return -EINVAL;
}
There was a problem hiding this comment.
Could you also return in case of unsupported features ?
There was a problem hiding this comment.
len == 0 is not an error, it can be used to send a start condition or stop condition, depending on flags.
I don't think there are any unsupported flags here (other than REG16, which I think we can just ignore in the _bytes functions)
There was a problem hiding this comment.
it can be used to send a start condition or stop condition, depending on flags
I never thought of it but is this really useful for the user ? I mean, we're suppose to read or write on the bus so why just sending a start out of the blue ?
There was a problem hiding this comment.
The hih6130 is one weird device which uses empty writes to trigger measurements. The user sends a start condition for writing followed by a stop condition, so zero data bytes. Then when reading the device will return the most recent measurement.
There was a problem hiding this comment.
The hih6130 is one weird device which uses empty writes to trigger measurements
Indeed, I'll look at this one. Is this even I2C/TWI compliant ?
There was a problem hiding this comment.
Dunno, but it's a device that we have a driver for
I have tested it with the fxos8700 driver with the updates in #9268 |
|
It would be a good idea to test with the hih6130 as well because of the null write behaviour, but I don't remember where I put my breakout board for that sensor.. |
|
Added some asserts for enabling interrupts and a check to ensure that data != NULL when len > 0 |
|
@gebart I tend to ACK this PR but I have no hardware to test it :( |
|
I have Mulle and frdm boards, and I know that there are some kinetis boards among the FU Berlin people |
|
I guess I'll resend an email on the devel mailing to require some help for testing |
|
Just tested this with pba-d-01-kw2x and the already merged srf08 driver. Works fine |
dylad
left a comment
There was a problem hiding this comment.
ACK.
Thanks for testing @MichelRottleuthner
Please squash so we can merge this one.
Uses timer freerunning counter mode (TFC) and updating an internal reference point instead of relying on RTT for reference time. The target accuracy has been greatly improved for all test cases in bench_periph_timer
5b99c11 to
8be0cd4
Compare
8be0cd4 to
df199b5
Compare
| #if I2C_3_EN | ||
| [I2C_3] = MUTEX_INIT | ||
| #endif | ||
| #define THREAD_FLAG_KINETIS_I2C (1u << 8) |
There was a problem hiding this comment.
Added this to avoid dependency on contested PR #9284. We can update the driver later if a consensus is reached regarding the reserved thread flags
|
Just re-trigger Travis and we're good to go. |
| ++dummy; | ||
| /* Wait until the ISR signals back */ | ||
| TRACE("i2c: read C1=%02x S=%02x\n", (unsigned)i2c->C1, (unsigned)i2c->S); | ||
| thread_flags_t tflg = thread_flags_wait_any(THREAD_FLAG_KINETIS_I2C | THREAD_FLAG_TIMEOUT); |
There was a problem hiding this comment.
We are checking for the TIMEOUT thread flag, but there is not yet anything setting it in the driver. I left this thread flag check here to make it simple in the future to add a timeout, but I did not yet find a satisfying solution which does not add extra dependencies to the driver. This part of the code can still be used if a user wants to eliminate the possibility of a bus hang blocking the application, they can use xtimer to provide a timer which sets the timeout flag.
There was a problem hiding this comment.
I'm fine with this, switching thread while waiting here is an excellent idea and IMHO we should do it for every MCU/drivers :)
|
Here we go ! thanks @gebart for your work ! |
kinetis: Update i2c driver to new API
kinetis: Update i2c driver to new API
kinetis: Update i2c driver to new API
Contribution description
Update the Kinetis I2C driver for the new API
Needs some more testing
Issues/PRs references
#6577