Skip to content

Conversation

@ardnew
Copy link
Contributor

@ardnew ardnew commented Sep 13, 2020

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).

@deadprogram
Copy link
Member

Hello @ardnew please note that the test failures in this PR look like actual failures.

tinygo build -size short -o test.hex -target=stm32f4disco        examples/blinky1
# machine
/home/circleci/lib/tinygo/src/machine/i2c.go:32:11: undeclared name: I2C
/home/circleci/lib/tinygo/src/machine/i2c.go:45:11: undeclared name: I2C
/home/circleci/lib/tinygo/src/machine/machine_stm32_i2c.go:31:11: undeclared name: I2C
/home/circleci/lib/tinygo/src/machine/machine_stm32_i2c.go:40:11: undeclared name: I2C
/home/circleci/lib/tinygo/src/machine/machine_stm32_i2c.go:46:11: undeclared name: I2C
/home/circleci/lib/tinygo/src/machine/machine_stm32_i2c.go:51:11: undeclared name: I2C
/home/circleci/lib/tinygo/src/machine/machine_stm32_i2c.go:60:11: undeclared name: I2C
/home/circleci/lib/tinygo/src/machine/machine_stm32_i2c.go:145:11: undeclared name: I2C
/home/circleci/lib/tinygo/src/machine/machine_stm32_i2c.go:193:11: undeclared name: I2C
/home/circleci/lib/tinygo/src/machine/machine_stm32_i2c.go:204:11: undeclared name: I2C
/home/circleci/lib/tinygo/src/machine/machine_stm32_i2c.go:261:11: undeclared name: I2C
/home/circleci/lib/tinygo/src/machine/machine_stm32_i2c.go:293:11: undeclared name: I2C
/home/circleci/lib/tinygo/src/machine/machine_stm32_i2c.go:448:11: undeclared name: I2C
/home/circleci/lib/tinygo/src/machine/machine_stm32_i2c.go:167:16: undeclared name: I2C0_SCL_PIN
/home/circleci/lib/tinygo/src/machine/machine_stm32_i2c.go:168:16: undeclared name: I2C0_SDA_PIN
Makefile:204: recipe for target 'smoketest' failed
make: *** [smoketest] Error 1

@ardnew
Copy link
Contributor Author

ardnew commented Sep 13, 2020

Ah, indeed, sorry about that! Will clean this up

@ardnew ardnew force-pushed the feature/feather-stm32f405-i2c branch from 1fdcb33 to 21985c2 Compare September 14, 2020 15:13
Frequency uint32
SCL Pin
SDA Pin
DutyCycle uint8
Copy link
Member

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?

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 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

@deadprogram
Copy link
Member

@ardnew can you please change "master" to "controller" and "slave" to "peripheral" as discussed previously in PR #1216 thank you!

@deadprogram
Copy link
Member

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

@deadprogram deadprogram merged commit 3eb33df into tinygo-org:dev Oct 14, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants