Skip to content
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

tests/periph_i2c: Update to new I2C API #9168

Merged
merged 2 commits into from
Jun 14, 2018

Conversation

MrKevinWeiss
Copy link
Contributor

@MrKevinWeiss MrKevinWeiss commented May 23, 2018

Updated test for command shell interface to new i2c api. Added some features and simplified a bit.

Contribution description

-update to new api
-standardize variable names
-add new commands to match api closer
-remove i2c clock speed functionality

Issues/PRs references

Issue #6577
Involves PR #9162, #6576, #9257

@dylad dylad added the TF: I2C Marks issues and PRs related to the work of the I²C rework task force label May 23, 2018
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.

Nice job ! just a few mistakes.


if (speed < 0 || speed > 4) {
puts("Error: Speed value not in range (0 - 4)");
res = i2c_init(dev);
Copy link
Member

Choose a reason for hiding this comment

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

i2c_init must not be call there. It only belongs to drivers/periph_common/init.c

puts("Error: Init: Given device not available");
return 1;
}
else if (res == 0){
Copy link
Member

Choose a reason for hiding this comment

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

space before curly brace

@MrKevinWeiss
Copy link
Contributor Author

I will wait for all changes to the api before fixing things

@MrKevinWeiss MrKevinWeiss self-assigned this May 28, 2018
@MrKevinWeiss
Copy link
Contributor Author

@dylad I tested with #9198 and it seems to function, can we merge?

@dylad
Copy link
Member

dylad commented May 28, 2018

Let me (or someone else ) test it first and give an ACK.
Plus I would like to test on two different CPUs to validate this.

@aabadie aabadie added the Area: tests Area: tests and testing framework label Jun 3, 2018
@MrKevinWeiss
Copy link
Contributor Author

@dylad So it is a bit heavy but should support most all API and have a few nice features for later. Eventually I will do a minimal shell (binary based) but for now this should do. Once everything is up to date and merged it would be nice to make buildtest and see if memory issues occur on any board (right now they all fail because the API isn't fully ported). Here is it in working with the samr21 (ie, the API is working).

return 1;
}

int cmd_i2c_acquire(int argc, char **argv) {
Copy link
Member

Choose a reason for hiding this comment

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

I don't think we should use this here. acquire and release functions are supposed to be handled by the driver not the user. In the current case, if the user use cmd_i2c_acquire, it will block the I2C.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yup I know, I think if it is in the API it should be tested (the fact that it blocks shouldn't be a problem for the test since I should be able to expect timeout and provide resets). If you don't wish to have this tested in the automated test we can remove it but I think since it is exposed to the user it should be tests. Also some clarification on it's expected behavior would be nice (ie is it required to acquire before use? Can we release twice without getting an error?)

Copy link
Member

Choose a reason for hiding this comment

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

You're right I mess up things sorry. acquire doesn't belong to CPU driver but device driver so we must be able to test the acquire/release function.
You can leave it as it.

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.

first review round.

printf("Error: ETIMEDOUT [%d]\n", -res);
return 1;
}
else if (res == I2C_ACK) {
Copy link
Member

Choose a reason for hiding this comment

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

From the code below, this will never be used but is handled in the function with specific success output.
Meaning: this could be removed, or not?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'd like to leave it in, just in case somebody does something in the future it won't say unknown error since nothing specifies that one must handle the ACK first.

Copy link
Member

Choose a reason for hiding this comment

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

fine with me


int print_i2c_error(int res) {
if (res == -EOPNOTSUPP) {
printf("Error: EOPNOTSUPP [%d]\n", -res);
Copy link
Member

Choose a reason for hiding this comment

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

here and below: does it make sense to print the number, too? IMHO simply using puts("Error: EOPNOTSUPP!"); should be fine and enough.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The number is more there if the python (or any other) interface wants to use it, since it is a standard errno it may be easy just to feed it into a standard decoding function and get more info (I also don't think it adds too much bloat).

int dev, speed, res;
int check_dev(void) {
if (i2c_dev < 0) {
puts("Error: no I2C device was initialized");
Copy link
Member

Choose a reason for hiding this comment

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

there is ENODEV which you could use here and print similarly to the other errors? See print_i2c_error, too

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yup, nice catch, will do! [TODO]

dev = atoi(argv[1]);
speed = atoi(argv[2]);
if (dev < 0 || dev >= (int)I2C_NUMOF) {
Copy link
Member

Choose a reason for hiding this comment

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

minor nit, but this can be simplified to:

if (dev < 0 || dev >= (int)I2C_NUMOF) {
    puts("Error: Given device not available");
    i2c_dev = -1;
    return 1;
}
printf("Success: i2c_%i successfully assigned as master\n", dev);
i2c_dev = dev;
return 0;

omitting the else branch because of the return in the if part and also the final return 1 would've never been reached, too.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yup, will do. [TODO]

return 1;
}

if (argc != 1) {
Copy link
Member

Choose a reason for hiding this comment

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

why bother? You don't expect nor use arguments, so (IMHO) no need to check the number.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

OK, I a bit think an exact structure should be enforced but I will change it anyways. [TODO]

res = i2c_init_master(dev, map_speed[speed]);
if (res == -1) {
puts("Error: Init: Given device not available");
if (argc != 1) {
Copy link
Member

Choose a reason for hiding this comment

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

dito, see above

Copy link
Contributor Author

Choose a reason for hiding this comment

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

[TODO]



if (res == I2C_ACK) {
printf("Success: i2c_%i successfully read 1 byte from reg 0x%02x: [",
Copy link
Member

Choose a reason for hiding this comment

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

why not having one printf only, instead of 2 + puts?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yup, legacy stuff. [TODO]

res = i2c_read_byte(i2c_dev, addr, &data, flags);

if (res == I2C_ACK) {
printf("Success: i2c_%i successfully read 1 byte: [", i2c_dev);
Copy link
Member

Choose a reason for hiding this comment

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

nit picky: omit successfully because its already a Success 😉

applies to other output above and below, too.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yup legacy, will do. [TODO] x3

}

if (res == I2C_ACK) {
printf("Success: i2c_%i successfully read %i bytes from reg 0x%02x: [",
Copy link
Member

Choose a reason for hiding this comment

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

IMHO its a bit confusing, that the user puts in the address of a register in decimal and its printed in HEX here, or not? At least from what I found atoi expects numbers of base 10, but you could use strtol with base 16 instead.

Copy link
Member

Choose a reason for hiding this comment

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

and btw. maybe this printing could be a helper function? Something like:

static inline print_i2c_read(i2c_t dev, uint16_t *reg, uint8_t *buf, size_t len)
{
    assert ((dev > 0) && (len > 0));
    printf("Success: i2c_%i read %i byte(s) ", dev, len);
    if (reg != Null) {
        printf("from reg 0x%02x ", reg);
    }
    printf(": [ ");
    for (unsigned i = 0; i < len; i++) {
        printf("0x%02x ", data[i]);
    }
    puts("]");
}

and then be use in i2c_read_reg(s)/byte(s)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I may just do strtol (legacy used atoi), I know lots of times I like seeing the hex numbers (since most data sheets support that). With the interface it gets abstracted out though. Either way I'll improve somehow. [TODO]

int res;
uint8_t addr;
int length = argc - 2;
uint8_t reg;
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 enough, because the API uses uint16_t, or not?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yup, legacy stuff [TODO]


dev = atoi(argv[1]);
speed = atoi(argv[2]);
static inline int get_num(char *str) {
Copy link
Contributor

Choose a reason for hiding this comment

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

Please put function opening curly on a new line

{
(void)argv;
if (argc != 1) {
puts("Error: Aquire: Invalid number of arguments!");
Copy link
Contributor

Choose a reason for hiding this comment

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

Typo: acquire

int print_i2c_error(int res)
{

int check_dev(void) {
Copy link
Contributor

Choose a reason for hiding this comment

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

More curlies that should go on a new line

@tcschmidt
Copy link
Member

@smlng @MrKevinWeiss can we resolve the controversial change request?

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.

@MrKevinWeiss: @keestux is right. Can you fix this, i.e. opening braces of function should be on a separate line (on their own). Otherwise the code looks good and ready to merge - but I would rather leave this to @dylad or @aabadie, who seem to manage the I2C rework

@dylad
Copy link
Member

dylad commented Jun 13, 2018

If @smlng thinks this PR is good to go after the final comment is adressed then I guess we can go :)

@MrKevinWeiss MrKevinWeiss added State: waiting for other PR State: The PR requires another PR to be merged first and removed State: waiting for other PR State: The PR requires another PR to be merged first labels Jun 13, 2018
static inline void print_i2c_read(i2c_t dev, uint16_t *reg, uint8_t *buf,
size_t len)
{
printf("Success: i2c_%i read %i byte(s) ", dev, len);
Copy link
Member

Choose a reason for hiding this comment

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

travis complains here, should printf("Success: i2c_%i read %i byte(s) ", dev, (int)len); for instance.

Copy link
Member

Choose a reason for hiding this comment

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

casting length from size_t to int is the easiest, I guess.

Copy link
Member

Choose a reason for hiding this comment

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

@MrKevinWeiss can you fix this small issue before merge, because it will hit us anyway when this branch will be merged back into master.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

oops missed that, sure!

@smlng
Copy link
Member

smlng commented Jun 13, 2018

@dylad apart from the minor issue travis reports, this is good to go. And @MrKevinWeiss would be happy to get this done (over with 😬) and work on refining the test scripts eventually making I2C testing easier for everyone, that is: no need to merge different PRs together to run tests.

@dylad
Copy link
Member

dylad commented Jun 13, 2018

@smlng I'm not an expert in testing/CI and so, but this looks OK to me. If all comments + Travis are addressed, we can click on the big green button :)

puts("Error: Speed value not in range (0 - 4)");
(void)argv;
(void)argc;
if (check_dev() == 1){
Copy link
Contributor

Choose a reason for hiding this comment

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

space before curly (there are more like these)

puts("]");
return 0;

switch (GET_I2C_CLK_SPD(i2c_dev)) {
Copy link
Contributor

Choose a reason for hiding this comment

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

The indenting of this switch/case statement is somewhat unusual. The Coding Convention does not say anything specific about it, but I like to see an extra indentation for the statements besides the "case".

switch (GET_I2C_CLK_SPD(i2c_dev)) {
    case case I2C_SPEED_LOW:
        printf("Success: i2...");
        break;
    case I2C_SPEED_NORMAL:

}
printf("0x%02x", buf[i]);
}
puts("]");
Copy link
Contributor

Choose a reason for hiding this comment

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

Why the mix of puts and printf?
Personally I prefer to see just printf's, for consistency.

}
printf(": [");
for (int i = 0; i < len; i++) {
if (i != 0){
Copy link
Contributor

Choose a reason for hiding this comment

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

space before curly


int cmd_init_master(int argc, char **argv)
static inline int get_num(char *str)
Copy link
Contributor

Choose a reason for hiding this comment

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

I'd like to see "const char *" for the argument

@dylad
Copy link
Member

dylad commented Jun 14, 2018

If everything is addressed, I think you can squash.

@MrKevinWeiss MrKevinWeiss force-pushed the n/pr/tests/periph_i2c branch from 468d8e3 to 067bff4 Compare June 14, 2018 07:54
@MrKevinWeiss MrKevinWeiss force-pushed the n/pr/tests/periph_i2c branch from 067bff4 to 0beaf30 Compare June 14, 2018 08:00
@smlng
Copy link
Member

smlng commented Jun 14, 2018

@dylad we squashed it, you wanna hit merge?

@dylad
Copy link
Member

dylad commented Jun 14, 2018

Here we go !
Good job guys !

@dylad dylad merged commit a2ee6ea into RIOT-OS:new_i2c_if Jun 14, 2018
basilfx pushed a commit to basilfx/RIOT that referenced this pull request Jul 10, 2018
dylad added a commit to dylad/RIOT that referenced this pull request Jul 10, 2018
@MrKevinWeiss MrKevinWeiss deleted the n/pr/tests/periph_i2c branch July 11, 2018 08:06
dylad added a commit that referenced this pull request Jul 11, 2018
tests/periph_i2c: Update to new I2C API
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Area: tests Area: tests and testing framework 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.

6 participants