Skip to content

cpu: efm32: adapt to new I2C interface#9208

Merged
dylad merged 2 commits intoRIOT-OS:new_i2c_iffrom
basilfx:feature/efm32_new_i2c
Jul 10, 2018
Merged

cpu: efm32: adapt to new I2C interface#9208
dylad merged 2 commits intoRIOT-OS:new_i2c_iffrom
basilfx:feature/efm32_new_i2c

Conversation

@basilfx
Copy link
Copy Markdown
Member

@basilfx basilfx commented May 27, 2018

Contribution description

This PR updates the EFM32 port to work with the new I2C peripheral interface. I've tested this on the SLTB001A (which has Si7021, BMP280 + I2C power controller), SLSTK3401a (Si7021) and STK3600 (for #9207).

I don't have 10-bit I2C device, nor have I access to something to test 16 bit registers.

Issues/PRs references

#6577, depends on #9205 and #9206 (or #8383).

@basilfx basilfx requested a review from kYc0o May 27, 2018 21:21
@basilfx basilfx added the TF: I2C Marks issues and PRs related to the work of the I²C rework task force label May 27, 2018
Copy link
Copy Markdown
Contributor

@aabadie aabadie left a comment

Choose a reason for hiding this comment

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

Now there's a common implementation is drivers/periph_common/i2c.c where default i2c_read_byte, i2c_write_byte, i2c_read_reg, i2c_write_reg, i2c_read_regs and i2c_write_regs/ are already available it the CPU implementation can work with them.
In short, if the CPU supports it, it can only provide i2c_read_bytes and i2c_write_bytes function and reuse the others from the driver.

See #9202 and #9198 as examples.

}

int i2c_read_reg(i2c_t dev, uint8_t address, uint8_t reg, void *data)
int i2c_read_reg(i2c_t dev, uint16_t address, uint16_t reg, void *data, uint8_t flags)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

i2c_read_reg and i2c_write_reg are now provided by the common driver in drivers/periph_common. Just define PERIPH_I2C_NEED_READ_REG and PERIPH_I2C_NEED_WRITE_REG in the periph_cpu.h file of your CPU type.
For example in #9202, I added the following in cpu/stm32_common/periph_cpu_common.h:

/**
 * @name    Use the shared I2C functions
 * @{
 */
/** Use read regs function from periph common */
#define PERIPH_I2C_NEED_READ_REG
/** Use write regs function from periph common */
#define PERIPH_I2C_NEED_WRITE_REG
/** @} */

Other defines exist for PERIPH_I2C_NEED_READ_REGS and PERIPH_I2C_NEED_WRITE_REGS if your CPU driver implementation works with them.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

@aabadie I don't want to use the common implementations, because I then have to use the optional I2C flags, which I cannot use with emlib. Emlib has its own way to provide I2C_START and I2C_STOP.

Copy link
Copy Markdown
Contributor

@aabadie aabadie May 28, 2018

Choose a reason for hiding this comment

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

I see. Why not converting RIOT common flags to emlib ones (using a switch) ? This way you can get rid of these functions.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

I can see if that works, but it would require me to briefly patch em_i2c.c (which I don't mind, since Gecko-SDK is already prepared for RIOT-OS).

}

int i2c_write_byte(i2c_t dev, uint8_t address, uint8_t data)
int i2c_write_byte(i2c_t dev, uint16_t address, uint8_t data, uint8_t flags)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

You don't need this function, it's already provided by the common i2c driver (in drivers/periph_common/)

}

int i2c_read_byte(i2c_t dev, uint8_t address, void *data)
int i2c_read_byte(i2c_t dev, uint16_t address, void *data, uint8_t flags)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

You also don't need this function

PKG_NAME=gecko_sdk
PKG_URL=https://github.com/basilfx/RIOT-gecko-sdk
PKG_VERSION=d381e526d68a2d0c951f37040c1c2e168ac66cd6
PKG_VERSION=a5e7be18ef3d7947ab6f04f9cd74f8808da7aece
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Why do you need to update ?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

It includes an update for the I2C driver.

/* transfer finished, interpret the result */
switch (i2c_progress[dev]) {
case i2cTransferDone:
return I2C_ACK;
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

We were wondering last week if it's better to return I2C_ACK when everything is fine or the number of bytes written on the bus.
What do you think ?

Copy link
Copy Markdown
Member Author

@basilfx basilfx May 28, 2018

Choose a reason for hiding this comment

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

I don't think it really matters. I2C_ACK would imply all bytes are transferred (in either direction), otherwise you would receive a different error (e.g. bus arbitration lost, NACK).

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I agree but we need to get a consensus here so all CPUs will behave in the same way :)

Copy link
Copy Markdown
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.

@basilfx The I2C API now uses errno as return code. You can have a look to drivers/include/periph/i2c.h for the details. But the previous I2C_ACK and so has been removed so some changes are required.

@dylad
Copy link
Copy Markdown
Member

dylad commented Jun 13, 2018

@basilfx Any progress on this ?

@dylad
Copy link
Copy Markdown
Member

dylad commented Jul 3, 2018

ping @basilfx

@basilfx
Copy link
Copy Markdown
Member Author

basilfx commented Jul 3, 2018

@dylad Sorry, I haven't found the time to fix this yet.

@dylad
Copy link
Copy Markdown
Member

dylad commented Jul 3, 2018

@basilfx no problem, do you think you can fix it before the new release ?

Copy link
Copy Markdown
Contributor

@aabadie aabadie left a comment

Choose a reason for hiding this comment

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

@basilfx, this PR is the last one remaining to have all CPUs drivers adapted. It would be great to have it merged soon.
Do you think you'll have time to work on it before mid-july (and even before, so we can test the whole feature branch) ?

}

int i2c_init_master(i2c_t dev, i2c_speed_t speed)
int i2c_init(i2c_t dev)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Should be void i2c_init(i2c_t dev), according to the new i2c api

assert(I2C_NUMOF <= (sizeof(i2c_lock) / sizeof(i2c_lock[0])));

/* check if device is valid */
if (dev >= I2C_NUMOF) {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

There's a consensus on using assert:

assert(dev < I2C_NUMOF);

@dylad
Copy link
Copy Markdown
Member

dylad commented Jul 4, 2018

I talked with @basilfx on IRC. He'll try to adapt the EFM32 this week-end if he find some time.
We're almost done !

* @brief Start and track an I2C transfer.
*/
static void _transfer(i2c_t dev, I2C_TransferSeq_TypeDef *transfer)
int _transfer(i2c_t dev, I2C_TransferSeq_TypeDef *transfer)
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This function should remain static or maybe even become static inline, otherwise it's exposed publicly.

@basilfx basilfx force-pushed the feature/efm32_new_i2c branch 2 times, most recently from 5c4ea66 to f12267a Compare July 9, 2018 19:21
@basilfx
Copy link
Copy Markdown
Member Author

basilfx commented Jul 9, 2018

I have fixed all the comments. Sorry for the delay, as I have been very busy with other things. I also thought it would be more work, but I opted for not supporting I2C_NOSTART/I2C_NOSTOP instead.

This version won't compile, because it depends on current master, which updates pkg/gecko-sdk for a change I need. Once new_i2c_if gets rebased, it should work, in the mean time, simply change the hash in pkg/gecko-sdk/Makefile to a5e7be18ef3d7947ab6f04f9cd74f8808da7aece. This was a commit I added in here, but I removed it. You may have to remove your bin/ directory (git-cache issue?).

I tested STK3600 with U8g2, SLTB001A with Si7021 and BMP280 and the SLSTK3401a with Si7021.

Copy link
Copy Markdown
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.

when compiling I get the following error on macOS:

/RIOT/cpu/efm32/periph/i2c.c:86:14: error: 'i2cTransferAddrNack' undeclared (first use in this function); did you mean 'i2cTransferNack'?
         case i2cTransferAddrNack:
              ^~~~~~~~~~~~~~~~~~~
              i2cTransferNack
/RIOT/cpu/efm32/periph/i2c.c:86:14: note: each undeclared identifier is reported only once for each function it appears in

@basilfx
Copy link
Copy Markdown
Member Author

basilfx commented Jul 10, 2018

@smlng Please see my comment :-)

@smlng
Copy link
Copy Markdown
Member

smlng commented Jul 10, 2018

oops ... but yes with the new commit its works.

@dylad
Copy link
Copy Markdown
Member

dylad commented Jul 10, 2018

@aabadie are you happy with the changes ?

@smlng
Copy link
Copy Markdown
Member

smlng commented Jul 10, 2018

well then please squash to make travis happy

@basilfx basilfx force-pushed the feature/efm32_new_i2c branch from f12267a to 10339e2 Compare July 10, 2018 12:14
@basilfx
Copy link
Copy Markdown
Member Author

basilfx commented Jul 10, 2018

Travis is Happy!

@smlng
Copy link
Copy Markdown
Member

smlng commented Jul 10, 2018

I trust @basilfx to have this tested well enough to get it merged, @dylad any objections?

@smlng
Copy link
Copy Markdown
Member

smlng commented Jul 10, 2018

and ping @aabadie, let's get over with this.

@dylad
Copy link
Copy Markdown
Member

dylad commented Jul 10, 2018

we can merge this one as soon as @aabadie dismiss his review if he think his comments were addressed !

@dylad
Copy link
Copy Markdown
Member

dylad commented Jul 10, 2018

Here we go ! thanks @basilfx !

@dylad dylad merged commit 912440e into RIOT-OS:new_i2c_if Jul 10, 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
dylad added a commit that referenced this pull request Jul 11, 2018
cpu: efm32: adapt to new I2C interface
@basilfx basilfx deleted the feature/efm32_new_i2c branch July 21, 2019 22:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

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.

4 participants