-
Notifications
You must be signed in to change notification settings - Fork 6.9k
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
i2c: unable to configure SAMD51 i2c clock frequency for standard (100 KHz) speeds #42432
Comments
Hi @maxmclau , Feel free to send a patch. Maybe we can have this fix for v3.0. |
This issue has been marked as stale because it has been open (more than) 60 days with no activity. Remove the stale label or add a comment saying that you would like to have the label removed otherwise this issue will automatically be closed in 14 days. Note, that you can always re-open a closed issue at any time. |
Hello |
Hi @joelguittet , Zephyr will be release in two days 17th Feb. In my case, I don`t have a board to test it and time to look at. |
Hello @nandojve I will be happy to do it, but actually thinking to the right solution because it's a bit harder that a few lines playing with the baud rate generator probably... A bit of details on this:
Solution to use standard i2c speed would be:
If somebody can confirm/oppose some explanation to this details I have given I will be happy to discuss of that. Joel PS: problem disappear when using 400kHz and more frequency for the clock because division to do is 4 time smaller. |
Hi @joelguittet , I think the problem is that the clock source for GCLK_SERCOMx_CORE is GCLK_PCHCTRL_GEN_GCLK0. Lines 686 to 699 in c9225e4
The GCLK0 is defined as a high speed clock at zephyr/soc/arm/atmel_sam0/common/soc_samd5x.c Line 134 in c4c8583
and because of that slow peripherals can't configure a proper clock. On my view, the solution is define another generic clock source to be used by slow peripherals, like I2C. With that, you can switch the source in the driver. Problem is, this MUST be made for all SAM0 series, otherwise you will broke the driver. The selected GLKx to solve the issue must be shared between all series and should not be used yet, otherwise a refactor must be made in preparation to this change. I'll even suggest that GLKCx should have a period to allow slower speeds like 50 kbit, maybe 10 kbit, but allow high speeds like 3.4Mbit too. So, I think change is not about reduce GCLK0 speed but apply a correct source of clock into peripheral. |
Hello @nandojve Not bad, I'm not used to work with Atmel devices to be honest, I just focused on the clock generators and realized we have 12 clocks generators available on SAMD51. GCLK0 is just the first one. I have just realized we have GLKC2 configured at 48MHz on SAMD51: zephyr/soc/arm/atmel_sam0/samd51/soc.h Line 54 in 4d4e252
So I have replaced GCLK0 by GCLK2 in the i2c_sam0 driver : working, I can reach the 100kbits/s SCL clock! 400kbits/s and 1Mbits/s are also working. Not able to use 3.4Mbits/s with GCLK2 but I don't succeed even with GLKC0 (I don't know why at the moment). So a solution can be to replace GLKC0 by GCLK2 in i2c_sam0.c Problem: GCLK2 not defined for all SAM0 devices. Some have GLKC1 or GLKC3 defined but not always the same clock frequency, for example: zephyr/soc/arm/atmel_sam0/samd21/soc.h Line 72 in 4d4e252
The devices with GLKC2 defined are always defining this clock at 48MHz. Is it a convention in Zephyr ? In this case probably we can write something like that in the sam0 i2c driver:
I'm new to Zephyr and I already develop a small project, but not able to known if this is a good approach. You will probably indicate me the best is to define the clock in the dts? Do you have an example for that ? another simple Atmel driver doing this ? Joel PS: as you mentioned the modification will impact all sam0 devices so it's important to do it properly. I don't want to submit a PR that will break plenty of users :-) |
Hi @joelguittet ,
Thank you for the info. With this info here at least people have a workaround till a proper solution is in place.
As I already mentioned, it will be necessary define a new GCLKx for the all series to have the correct solution.
Currently there is no convention on Zephyr and project should not impose restrictions. I see that complexity is growing and maybe at least a recommendation should be in place. This has became a problem because there is no clock drivers for Atmel SAM/SAM0 series. On my perspective below is a good compromise:
I think above can be be achieved but it will require mode investigation and it will be necessary changes in some series. |
hello @nandojve , i just ran into this and i don't follow the solution here. i have a EDIT: so i have GCLK2 as 48M so i will give a try and just replace GCK0 with GCLK2 and see how it goes. Why is this issue closed? it should be open i think |
Was closed because it was Stale, but I agree it should remain opened. Any way to block the bot for this ? |
a discord user mentioned #36649 as perhaps more relevant issue, which is open. so maybe that is sufficient |
I don`t know, usually it should close PRs not issues. Anyway, anyone is free to reopen when it is relevant. For a more short term, the solution should be something like #42432 (comment) . Are there someone with free time to implement? Remember that Atmel is community driven. |
This issue has been marked as stale because it has been open (more than) 60 days with no activity. Remove the stale label or add a comment saying that you would like to have the label removed otherwise this issue will automatically be closed in 14 days. Note, that you can always re-open a closed issue at any time. |
Describe the bug
When trying to set i2c clock frequency for SAMDxx cores
i2c_sam0_set_apply_bitrate()
uses GCLK0 frequency for baud rate computation. On SAMD51 cores, typically clocked at 120MHz, this results in a baud range error. I believe this is incorrect for SAMD51 cores as they use a separate 48MHz peripheral clock for SERCOMs and should use this value for computing baud.This is solved in the Adafruit ArduinoCore-samd implementation by checking for SAMD51 cores and calculating their rate off of the 48MHz peripheral clock.
To Reproduce
Expected behavior
i2c_sam0_set_apply_bitrate()
should seti2c->BAUD.reg
to a register value representing I2C_BITRATE_STANDARD (100KHz). Instead it returns-ERANGE
as the computed baud is above 255.Impact
There are still many i2c peripherals not compatible with <I2C_BITRATE_FAST> (400KHz).
Modifying the implementation to reflect something similar to the Adafruit implementation shouldn't be very difficult.
The text was updated successfully, but these errors were encountered: