Skip to content

Conversation

jnohlgard
Copy link
Member

Contribution description

Update the Kinetis I2C driver for the new API

Needs some more testing

Issues/PRs references

#6577

@jnohlgard jnohlgard added Platform: ARM Platform: This PR/issue effects ARM-based platforms State: WIP State: The PR is still work-in-progress and its code is not in its final presentable form yet Area: drivers Area: Device drivers TF: I2C Marks issues and PRs related to the work of the I²C rework task force labels Jun 1, 2018
};

static const i2c_conf_t i2c_config[I2C_NUMOF] = I2C_CONFIG;
Copy link
Contributor

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 ?

Copy link
Member Author

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.

Copy link
Contributor

@aabadie aabadie Jun 1, 2018

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).

Copy link
Member Author

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

@jnohlgard jnohlgard force-pushed the pr/kinetis-i2c branch 4 times, most recently from 241b1ed to d244646 Compare June 1, 2018 22:48
@jnohlgard
Copy link
Member Author

Cherry picked in #8933 #8814 #8930 to avoid rebase problems later

@jnohlgard jnohlgard added the CI: needs squashing Commits in this PR need to be squashed; If set, CI systems will mark this PR as unmergable label Jun 1, 2018
@jnohlgard
Copy link
Member Author

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.

Copy link
Member

@dylad dylad left a 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
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this related ?

Copy link
Member Author

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.

while (!(dev->S & I2C_S_IICIF_MASK));

dev->S = I2C_S_IICIF_MASK;
I2C_Type *i2c = i2c_config[dev].i2c;
Copy link
Member

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;
}

Copy link
Member

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 ?

Copy link
Member Author

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)

Copy link
Member

@dylad dylad Jun 8, 2018

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 ?

Copy link
Member Author

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.

Copy link
Member

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 ?

Copy link
Member Author

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

@jnohlgard
Copy link
Member Author

Were you able to test it with some devices ?

I have tested it with the fxos8700 driver with the updates in #9268

@jnohlgard
Copy link
Member Author

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..

@jnohlgard
Copy link
Member Author

Added some asserts for enabling interrupts and a check to ensure that data != NULL when len > 0

@dylad
Copy link
Member

dylad commented Jun 11, 2018

@gebart I tend to ACK this PR but I have no hardware to test it :(
Do you know if someone have the required hardware for testing ?

@jnohlgard
Copy link
Member Author

I have Mulle and frdm boards, and I know that there are some kinetis boards among the FU Berlin people

@dylad
Copy link
Member

dylad commented Jun 11, 2018

I guess I'll resend an email on the devel mailing to require some help for testing

@MichelRottleuthner
Copy link
Contributor

Just tested this with pba-d-01-kw2x and the already merged srf08 driver. Works fine

Copy link
Member

@dylad dylad left a 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.

Copy link
Member

@smlng smlng left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tested with several sensor drivers on board pba-d-01-kw2x works like charm see #9455 and #9457. Please squash and then lets do this!

Joakim Nohlgård added 5 commits June 29, 2018 09:00
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
#if I2C_3_EN
[I2C_3] = MUTEX_INIT
#endif
#define THREAD_FLAG_KINETIS_I2C (1u << 8)
Copy link
Member Author

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

Copy link
Member Author

@jnohlgard jnohlgard left a 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.

@dylad dylad removed CI: needs squashing Commits in this PR need to be squashed; If set, CI systems will mark this PR as unmergable State: WIP State: The PR is still work-in-progress and its code is not in its final presentable form yet labels Jun 29, 2018
@dylad
Copy link
Member

dylad commented Jun 29, 2018

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);
Copy link
Member Author

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.

Copy link
Member

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 :)

@dylad
Copy link
Member

dylad commented Jun 29, 2018

Here we go ! thanks @gebart for your work !

@dylad dylad merged commit 2e06e99 into RIOT-OS:new_i2c_if Jun 29, 2018
@jnohlgard jnohlgard deleted the pr/kinetis-i2c branch June 30, 2018 12:06
basilfx pushed a commit to basilfx/RIOT that referenced this pull request Jul 10, 2018
kinetis: Update i2c driver to new API
dylad added a commit to dylad/RIOT that referenced this pull request Jul 10, 2018
kinetis: Update i2c driver to new API
dylad added a commit that referenced this pull request Jul 11, 2018
kinetis: Update i2c driver to new API
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Area: drivers Area: Device drivers Platform: ARM Platform: This PR/issue effects ARM-based platforms TF: I2C Marks issues and PRs related to the work of the I²C rework task force
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants