-
Notifications
You must be signed in to change notification settings - Fork 2.1k
kinetis: Update i2c driver to new API #9262
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
cpu/kinetis/periph/i2c.c
Outdated
}; | ||
|
||
static const i2c_conf_t i2c_config[I2C_NUMOF] = I2C_CONFIG; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok but then it's not consistent with the other configuration arrays (UART, SPI, PWM, ADC, etc).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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_pwm | ||
FEATURES_PROVIDED += periph_rtc | ||
FEATURES_PROVIDED += periph_rtt |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this related ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I had to pull in some upstream merged PRs to avoid problems rebasing later.
cpu/kinetis/periph/i2c.c
Outdated
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you add a guard here please ?
if (len == 0 || data == NULL) {
return -EINVAL;
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you also return in case of unsupported features ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ACK.
Thanks for testing @MichelRottleuthner
Please squash so we can merge this one.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Changed the thread flag usage to avoid dependency on PR #9284. Immediately squashed after a search+replace of the thread flag constant in i2c.c.
Tested on frdm-kw41z with fxos8700 driver.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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