Conversation
lebrush
left a comment
There was a problem hiding this comment.
Codewise looks sensitive except some quirks I've commented. Please note that in public API methods you should test if the value of "bus" is sensitive (< NUMOF).
I unassign myself as I can't test or qualify this PR regarding functionality since I've very few knowledge of samd platforms and no board to test it.
cpu/sam0_common/periph/i2c.c
Outdated
|
|
||
| /* guard file in case no I2C device is defined */ | ||
| #if I2C_NUMOF | ||
| #ifdef I2C_NUMOF |
There was a problem hiding this comment.
if it's defined as 0 line 62 will fail to compile, but it's still a valid value, meaning disabled.
There was a problem hiding this comment.
This issue can also be applied on sam0 UART. (maybe somewhere else too ?)
What should I do ?
There was a problem hiding this comment.
You are right, there's currently a mixture of #if and #ifdefs. It should be addressed by the build system in the future anway. So by now, whatever it's Ok
There was a problem hiding this comment.
Yes, I was thinking of opening an issue for this point to have community's opinion as some driver use #if xxx_NUMOF and others #ifdef xxx_NUMOF. I'll do it later today.
| /* Reset I2C */ | ||
| I2CSercom->CTRLA.reg = SERCOM_I2CS_CTRLA_SWRST; | ||
| while (I2CSercom->SYNCBUSY.reg & SERCOM_I2CM_SYNCBUSY_MASK) {} | ||
| dev(bus)->CTRLA.reg = SERCOM_I2CM_CTRLA_SWRST; |
There was a problem hiding this comment.
This was i2cs and now i2cm. Expected?
There was a problem hiding this comment.
Yes.
I2C Sercom can be either master or slave. I2CS bit resets all registers related to slave mode which is not our case (as our aim is to reset our master I2C here). This must be an unspotted mistake from previous driver.
| return i2c_config[bus].dev; | ||
| } | ||
|
|
||
| int i2c_init_master(i2c_t bus, i2c_speed_t speed) |
There was a problem hiding this comment.
Bus should be tested against NUMOF.
| /* Find and set baudrate. Read speed configuration. Set transfer | ||
| * speed: SERCOM_I2CM_CTRLA_SPEED(0): Standard-mode (Sm) up to 100 | ||
| * kHz and Fast-mode (Fm) up to 400 kHz */ | ||
| switch (speed) { |
There was a problem hiding this comment.
Idea: This could be refactored if the I2C speed enum contains the values which create tmp_baud
There was a problem hiding this comment.
Hum, I understand what you mean. But the calculation requires to know both CORE_CLOCK and the I2C desired speed. I don't think the user must rewrite those values if he changes CORE_CLOCK.
Maybe others maintainers have some ideas ?
There was a problem hiding this comment.
I meant the following: you can redefine the i2c_speed_t in periph_cpu_common.h as
typedef enum {
I2C_SPEED_NORMAL = 100000,
I2C_SPEED_FAST = 400000,
...
} i2c_speed_t;Then you can skip the switch:
tmp_baud = (int32_t)(((CLOCK_CORECLOCK + (2 * (speed)) - 1) / (2 * (speed))) - 5);
if (tmp_baud < 255 && tmp_baud > 0) {
dev(bus)->CTRLA.reg |= SERCOM_I2CM_CTRLA_SPEED(0);
dev(bus)->BAUD.reg = SERCOM_I2CM_BAUD_BAUD(tmp_baud);
}But now I relised that the high speed has different values (2 instead of 0 and HSBAD instead of BAUD), so I'm not sure it makes sense.
cpu/sam0_common/periph/i2c.c
Outdated
| [I2C_3] = MUTEX_INIT | ||
| #endif | ||
| }; | ||
| static mutex_t locks[I2C_NUMOF]; |
There was a problem hiding this comment.
Locks should be initialized in the init function
There was a problem hiding this comment.
What about something like
static mutex_t locks[I2C_NUMOF] = {[0 ... I2C_NUMOF-1]= MUTEX_INIT }; ?
There was a problem hiding this comment.
It's a good options, but I think this syntax is only GCC compliant
There was a problem hiding this comment.
Indeed, g++ cannot handle this. It is a no-go ?
| void i2c_poweron(i2c_t bus) | ||
| { | ||
| if (sercom == NULL) { | ||
| if (dev(bus) == NULL) { |
There was a problem hiding this comment.
bus should be tested against NUMOF (also in many other functions)
|
@lebrush Thanks for your review. I'll address all your comments asap. |
|
@lebrush I added more tests against |
53b2496 to
15cfcc1
Compare
|
#7241 solved the NUMOF issue. |
Signed-off-by: dylad <dylan.laduranty@mesotic.com>
Signed-off-by: dylad <dylan.laduranty@mesotic.com>
Signed-off-by: dylad <dylan.laduranty@mesotic.com>
|
I rebased this PR to lastest master. |
aabadie
left a comment
There was a problem hiding this comment.
I like this PR. I don't think it will go into the next release but it's a good work already.
| #define I2C_NUMOF (sizeof(i2c_config) / sizeof(i2c_config[0])) | ||
|
|
||
| #define I2C_0_DEV SERCOM3->I2CM | ||
| #define I2C_IRQ_PRIO 1 |
There was a problem hiding this comment.
This define is unsused with sam0 cpus (only used with cc2538 and stm32). Maybe just remove ?
| .scl_pin = GPIO_PIN(PA, 23), | ||
| .mux = GPIO_MUX_C, | ||
| .gclk_src = GCLK_CLKCTRL_GEN_GCLK0, | ||
| .runstdby = 0 |
There was a problem hiding this comment.
What about a flags field containing a list of enums, for example: (ENUM1 | ENUM2). Then you could use bitwise comparison in the driver? This will allow future potential extensions of the driver implementation (I don't see any right now though)
|
Thanks for the review @aabadie |
|
I'm closing this in favor of the I2C refactoring. |
This PR introduces a common i2c_config struct in
periph_conf.hfor all sam0 based boards. Additionnal I2C SERCOM can be add more easily.SAML21 can know use SERCOM5 if desired.
I'm wondering if I can remove the init of GCLK_SLOW because it is only for some SMBus timeout (no used yet by RIOT). Should I remove it ? This should not impact the current driver state but I want the community's opinion first :)
I also tried to keep the 80 characters limit per lines.