-
Notifications
You must be signed in to change notification settings - Fork 996
feather-stm32f405: add I2C support #1378
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
feather-stm32f405: add I2C support #1378
Conversation
|
Hello @ardnew please note that the test failures in this PR look like actual failures. |
|
Ah, indeed, sorry about that! Will clean this up |
1fdcb33 to
21985c2
Compare
| Frequency uint32 | ||
| SCL Pin | ||
| SDA Pin | ||
| DutyCycle uint8 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What does DutyCycle mean? How is it different from Frequency?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was confused by this one too. It seems to represent some constant factor that affects the I2C Fast Mode frequency calculation only (Standard Mode is unaffected). Unfortunately, I'm not sure if it is something we can determine automatically (based on requested frequency) or if it's an independent setting the user needs access to in order to configure the bus clock. Therefore, I left it available for the user.
You can see how I'm using it to calculate frequency (machine_stm32f405.go:109-115), which, again, comes from a combination of the STM32 programming manual and the STM32CubeIDE auto-generated HAL and LL I2C drivers (in C).
For reference, I've copied the register definition below, which is basically the only location this DutyCycle (DUTY) is discussed, but it also includes an example calculation. Maybe you or someone else can infer how to best handle this item?
27.6.8 I2C Clock control register (I2C_CCR)
Address offset: 0x1C
Reset value: 0x0000
Note: fPCLK1 must be at least 2 MHz to achieve Sm mode I²C frequencies. It must be at least 4
MHz to achieve Fm mode I²C frequencies. It must be a multiple of 10MHz to reach the
400 kHz maximum I²C Fm mode clock.
The CCR register must be configured only when the I2C is disabled (PE = 0).
+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+
| 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+
| F/S | DUTY | | CCR[11:0] |
+------+------+ Reserved +------+------+------+------+------+------+------+------+------+------+------+------+
| rw | rw | | rw | rw | rw | rw | rw | rw | rw | rw | rw | rw | rw | rw |
+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+------+
Bit 15 F/S: I2C master mode selection
0: Sm mode I2C
1: Fm mode I2C
Bit 14 DUTY: Fm mode duty cycle
0: Fm mode Tlow/Thigh = 2
1: Fm mode Tlow/Thigh = 16/9 (see CCR)
Bits 13:12 Reserved, must be kept at reset value
Bits 11:0 CCR[11:0]: Clock control register in Fm/Sm mode (Master mode)
Controls the SCL clock in master mode.
Sm mode or SMBus:
Thigh = CCR * TPCLK1
Tlow = CCR * TPCLK1
Fm mode:
If DUTY = 0:
Thigh = CCR * TPCLK1
Tlow = 2 * CCR * TPCLK1
If DUTY = 1: (to reach 400 kHz)
Thigh = 9 * CCR * TPCLK1
Tlow = 16 * CCR * TPCLK1
For instance: in Sm mode, to generate a 100 kHz SCL frequency:
If FREQR = 08, TPCLK1 = 125 ns so CCR must be programmed with 0x28
(0x28 <=> 40d x 125 ns = 5000 ns.)
Note: The minimum allowed value is 0x04, except in FAST DUTY mode where the minimum
allowed value is 0x01.
Thigh = tr(SCL) + tw(SCLH). See device datasheet for the definitions of parameters.
Tlow = tf(SCL) + tw(SCLL). See device datasheet for the definitions of parameters.
I2C communication speed, fSCL ~ 1/(thigh + tlow). The real frequency may differ due to
the analog noise filter input delay.
The CCR register must be configured only when the I2C is disabled (PE = 0).
Also, if you are at all interested in the STM32 driver code a lot of these PRs are derived from, I've copied them here:
https://github.com/ardnew/ardnew/tree/master/share/tinygo/sago35
ST provides 2 types of drivers for their peripherals: a HAL driver and a LL (low-level) driver. Both are included as separate packages in that repo. The relevant files would be, for example, feather-stm32f405/Drivers/STM32F4xx_HAL_Driver/stm32f4xx_hal_i2c.c
|
Since the board that is not in this PR (STM32F407) is the only board in this family I actually have on hand, I cannot test it myself directly. However, since all the feedback has been responded to, and @ardnew you presumably have tested it on your own hardware, I am predisposed to squash/merge, and then we can work on STM32 further from there. Thanks @ardnew |
This adds support for the two I2C peripherals on the target
feather-stm32f405.This I2C implementation supports the entire STM32 family (except for the Bluepill
stm32f103xx, which has its own implementation).