Skip to content
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

cpu/stm32: fix periph_i2c for F1, F2, L1 and F4 families #20100

Merged
merged 2 commits into from
Dec 12, 2023

Conversation

maribu
Copy link
Member

@maribu maribu commented Nov 22, 2023

Contribution description

  • boot the I2C after init in low power mode
    • otherwise I2C will consume more power until the first time it is used, which is surprising
  • STM32 F1 only: reconfigure SCL and SDA as GPIOs while the I2C peripheral is powered down
    • When the I2C peripheral is not clocked, it drives SCL and SDA down. This will dissipate power across the pull up resistor.
  • improve debug output

Testing procedure

  • On master, the MCU should use more power on F2, F4, L1 when periph_i2c is enabled but not used compared to this PR, as the peripheral is only put into low power mode after the first use
  • On master the idle level of SCL and SDA on F1 is low after the first use of the I2C peripheral, with this PR it is high
  • On master, the tests/periph/selftest_shield will fail for the nucleo-f103rb due to I2C communication errors after the first time i2c_release() is called. With this PR, the I2C communication should succeed consistently

I tested this locally in a branch that also contains the commits of this PR and of #20084:

~/Repos/software/RIOT/stm32_spi/tests/periph/selftest_shield % make BOARD=nucleo-f103rb flash test-with-config -j
Building application "tests_selftest_shield" for "nucleo-f103rb" with MCU "stm32".

"make" -C /home/maribu/Repos/software/RIOT/stm32_spi/pkg/cmsis/ 
"make" -C /home/maribu/Repos/software/RIOT/stm32_spi/boards/common/init
"make" -C /home/maribu/Repos/software/RIOT/stm32_spi/boards/nucleo-f103rb
"make" -C /home/maribu/Repos/software/RIOT/stm32_spi/core
"make" -C /home/maribu/Repos/software/RIOT/stm32_spi/core/lib
"make" -C /home/maribu/Repos/software/RIOT/stm32_spi/cpu/stm32
"make" -C /home/maribu/Repos/software/RIOT/stm32_spi/drivers
"make" -C /home/maribu/Repos/software/RIOT/stm32_spi/sys
"make" -C /home/maribu/Repos/software/RIOT/stm32_spi/boards/common/nucleo
"make" -C /home/maribu/Repos/software/RIOT/stm32_spi/drivers/pcf857x
"make" -C /home/maribu/Repos/software/RIOT/stm32_spi/drivers/periph_common
"make" -C /home/maribu/Repos/software/RIOT/stm32_spi/sys/auto_init
"make" -C /home/maribu/Repos/software/RIOT/stm32_spi/sys/div
"make" -C /home/maribu/Repos/software/RIOT/stm32_spi/sys/isrpipe
"make" -C /home/maribu/Repos/software/RIOT/stm32_spi/cpu/cortexm_common
"make" -C /home/maribu/Repos/software/RIOT/stm32_spi/sys/libc
"make" -C /home/maribu/Repos/software/RIOT/stm32_spi/cpu/stm32/periph
"make" -C /home/maribu/Repos/software/RIOT/stm32_spi/sys/malloc_thread_safe
"make" -C /home/maribu/Repos/software/RIOT/stm32_spi/cpu/stm32/stmclk
"make" -C /home/maribu/Repos/software/RIOT/stm32_spi/cpu/stm32/vectors
"make" -C /home/maribu/Repos/software/RIOT/stm32_spi/sys/newlib_syscalls_default
"make" -C /home/maribu/Repos/software/RIOT/stm32_spi/sys/pm_layered
"make" -C /home/maribu/Repos/software/RIOT/stm32_spi/sys/preprocessor
"make" -C /home/maribu/Repos/software/RIOT/stm32_spi/sys/stdio_uart
"make" -C /home/maribu/Repos/software/RIOT/stm32_spi/sys/test_utils/interactive_sync
"make" -C /home/maribu/Repos/software/RIOT/stm32_spi/sys/test_utils/print_stack_usage
"make" -C /home/maribu/Repos/software/RIOT/stm32_spi/sys/tiny_strerror
"make" -C /home/maribu/Repos/software/RIOT/stm32_spi/sys/tsrb
"make" -C /home/maribu/Repos/software/RIOT/stm32_spi/cpu/cortexm_common/periph
   text	  data	   bss	   dec	   hex	filename
  18040	   124	  2772	 20936	  51c8	/home/maribu/Repos/software/RIOT/stm32_spi/tests/periph/selftest_shield/bin/nucleo-f103rb/tests_selftest_shield.elf
/home/maribu/Repos/software/RIOT/stm32_spi/dist/tools/openocd/openocd.sh flash /home/maribu/Repos/software/RIOT/stm32_spi/tests/periph/selftest_shield/bin/nucleo-f103rb/tests_selftest_shield.elf
### Flashing Target ###
Open On-Chip Debugger 0.12.0+dev-snapshot (2023-06-12-09:31)
Licensed under GNU GPL v2
For bug reports, read
	http://openocd.org/doc/doxygen/bugs.html
DEPRECATED! use 'adapter serial' not 'hla_serial'
hla_swd
Info : The selected transport took over low-level target control. The results might differ compared to plain JTAG/SWD
srst_only separate srst_nogate srst_open_drain connect_assert_srst
Info : clock speed 1000 kHz
Info : STLINK V2J29M18 (API v2) VID:PID 0483:374B
Info : Target voltage: 3.252528
Info : [stm32f1x.cpu] Cortex-M3 r1p1 processor detected
Info : [stm32f1x.cpu] target has 6 breakpoints, 4 watchpoints
Info : starting gdb server for stm32f1x.cpu on 0
Info : Listening on port 33919 for gdb connections
    TargetName         Type       Endian TapName            State       
--  ------------------ ---------- ------ ------------------ ------------
 0* stm32f1x.cpu       hla_target little stm32f1x.cpu       unknown
[stm32f1x.cpu] halted due to debug-request, current mode: Thread 
xPSR: 0x01000000 pc: 0x08001560 msp: 0x20000200
Info : device id = 0x20036410
Info : flash size = 128 KiB
Warn : Adding extra erase range, 0x080046f4 .. 0x080047ff
auto erase enabled
wrote 18164 bytes from file /home/maribu/Repos/software/RIOT/stm32_spi/tests/periph/selftest_shield/bin/nucleo-f103rb/tests_selftest_shield.elf in 1.045045s (16.974 KiB/s)
verified 18164 bytes in 0.293970s (60.340 KiB/s)
shutdown command invoked
Done flashing
Connect to serial port /dev/ttyACM1
Welcome to pyterm!
Type '/exit' to exit.
READY
s
START
main(): This is RIOT! (Version: 2023.10-devel-560-g69afa-stm32_spi)
self-testing peripheral drivers
===============================
Starting test for GPIO at tests/periph/selftest_shield/main.c:346
[OK]
Starting test for GPIO at tests/periph/selftest_shield/main.c:368
[OK]
Starting test for GPIO at tests/periph/selftest_shield/main.c:398
[OK]
Starting test for GPIO at tests/periph/selftest_shield/main.c:428
(skipped)
Starting test for GPIO at tests/periph/selftest_shield/main.c:454
(skipped)
Starting test for GPIO-IRQ at tests/periph/selftest_shield/main.c:501
[OK]
Starting test for GPIO-IRQ at tests/periph/selftest_shield/main.c:564
[OK]
Starting test for GPIO-IRQ at tests/periph/selftest_shield/main.c:627
[OK]
Starting test for I2C at tests/periph/selftest_shield/main.c:701
[OK]
Starting test for SPI at tests/periph/selftest_shield/main.c:829
[OK]
Starting test for SPI at tests/periph/selftest_shield/main.c:829
[OK]
Starting test for SPI at tests/periph/selftest_shield/main.c:829
[OK]
Starting test for SPI at tests/periph/selftest_shield/main.c:829
[OK]
Starting test for SPI at tests/periph/selftest_shield/main.c:829
[OK]
Starting test for SPI at tests/periph/selftest_shield/main.c:829
[OK]
Starting test for SPI at tests/periph/selftest_shield/main.c:829
[OK]
Starting test for SPI at tests/periph/selftest_shield/main.c:829
[OK]
Starting test for SPI at tests/periph/selftest_shield/main.c:829
[OK]
Starting test for SPI at tests/periph/selftest_shield/main.c:829
[OK]
Starting test for SPI at tests/periph/selftest_shield/main.c:829
[OK]
Starting test for SPI at tests/periph/selftest_shield/main.c:829
[OK]


ALL TESTS SUCCEEDED
~/Repos/software/RIOT/stm32_spi/tests/periph/selftest_shield % make BOARD=nucleo-l152re flash test-with-config -j
Building application "tests_selftest_shield" for "nucleo-l152re" with MCU "stm32".

"make" -C /home/maribu/Repos/software/RIOT/stm32_spi/pkg/cmsis/ 
"make" -C /home/maribu/Repos/software/RIOT/stm32_spi/boards/common/init
"make" -C /home/maribu/Repos/software/RIOT/stm32_spi/boards/nucleo-l152re
"make" -C /home/maribu/Repos/software/RIOT/stm32_spi/core
"make" -C /home/maribu/Repos/software/RIOT/stm32_spi/core/lib
"make" -C /home/maribu/Repos/software/RIOT/stm32_spi/cpu/stm32
"make" -C /home/maribu/Repos/software/RIOT/stm32_spi/drivers
"make" -C /home/maribu/Repos/software/RIOT/stm32_spi/sys
"make" -C /home/maribu/Repos/software/RIOT/stm32_spi/boards/common/nucleo
"make" -C /home/maribu/Repos/software/RIOT/stm32_spi/cpu/cortexm_common
"make" -C /home/maribu/Repos/software/RIOT/stm32_spi/drivers/pcf857x
"make" -C /home/maribu/Repos/software/RIOT/stm32_spi/cpu/stm32/periph
"make" -C /home/maribu/Repos/software/RIOT/stm32_spi/cpu/stm32/stmclk
"make" -C /home/maribu/Repos/software/RIOT/stm32_spi/drivers/periph_common
"make" -C /home/maribu/Repos/software/RIOT/stm32_spi/cpu/stm32/vectors
"make" -C /home/maribu/Repos/software/RIOT/stm32_spi/sys/auto_init
"make" -C /home/maribu/Repos/software/RIOT/stm32_spi/sys/div
"make" -C /home/maribu/Repos/software/RIOT/stm32_spi/sys/isrpipe
"make" -C /home/maribu/Repos/software/RIOT/stm32_spi/sys/libc
"make" -C /home/maribu/Repos/software/RIOT/stm32_spi/sys/malloc_thread_safe
"make" -C /home/maribu/Repos/software/RIOT/stm32_spi/sys/newlib_syscalls_default
"make" -C /home/maribu/Repos/software/RIOT/stm32_spi/sys/pm_layered
"make" -C /home/maribu/Repos/software/RIOT/stm32_spi/cpu/cortexm_common/periph
"make" -C /home/maribu/Repos/software/RIOT/stm32_spi/sys/preprocessor
"make" -C /home/maribu/Repos/software/RIOT/stm32_spi/sys/stdio_uart
"make" -C /home/maribu/Repos/software/RIOT/stm32_spi/sys/test_utils/interactive_sync
"make" -C /home/maribu/Repos/software/RIOT/stm32_spi/sys/test_utils/print_stack_usage
"make" -C /home/maribu/Repos/software/RIOT/stm32_spi/sys/tiny_strerror
"make" -C /home/maribu/Repos/software/RIOT/stm32_spi/sys/tsrb
   text	  data	   bss	   dec	   hex	filename
  18600	   124	  2760	 21484	  53ec	/home/maribu/Repos/software/RIOT/stm32_spi/tests/periph/selftest_shield/bin/nucleo-l152re/tests_selftest_shield.elf
/home/maribu/Repos/software/RIOT/stm32_spi/dist/tools/openocd/openocd.sh flash /home/maribu/Repos/software/RIOT/stm32_spi/tests/periph/selftest_shield/bin/nucleo-l152re/tests_selftest_shield.elf
### Flashing Target ###
Open On-Chip Debugger 0.12.0+dev-snapshot (2023-06-12-09:31)
Licensed under GNU GPL v2
For bug reports, read
	http://openocd.org/doc/doxygen/bugs.html
DEPRECATED! use 'adapter serial' not 'hla_serial'
hla_swd
Info : The selected transport took over low-level target control. The results might differ compared to plain JTAG/SWD
srst_only separate srst_nogate srst_open_drain connect_assert_srst
Info : clock speed 300 kHz
Info : STLINK V2J33M25 (API v2) VID:PID 0483:374B
Info : Target voltage: 3.252984
Info : [stm32l1.cpu] Cortex-M3 r2p0 processor detected
Info : [stm32l1.cpu] target has 6 breakpoints, 4 watchpoints
Info : starting gdb server for stm32l1.cpu on 0
Info : Listening on port 45589 for gdb connections
    TargetName         Type       Endian TapName            State       
--  ------------------ ---------- ------ ------------------ ------------
 0* stm32l1.cpu        hla_target little stm32l1.cpu        unknown
Info : Unable to match requested speed 300 kHz, using 240 kHz
Info : Unable to match requested speed 300 kHz, using 240 kHz
[stm32l1.cpu] halted due to debug-request, current mode: Thread 
xPSR: 0x01000000 pc: 0x08002398 msp: 0x20001170
Info : Device: STM32L1xx (Cat.5/Cat.6)
Info : STM32L flash has dual banks. Bank (0) size is 256kb, base address is 0x8000000
auto erase enabled
wrote 20480 bytes from file /home/maribu/Repos/software/RIOT/stm32_spi/tests/periph/selftest_shield/bin/nucleo-l152re/tests_selftest_shield.elf in 2.701192s (7.404 KiB/s)
verified 18724 bytes in 1.129167s (16.193 KiB/s)
Info : Unable to match requested speed 300 kHz, using 240 kHz
Info : Unable to match requested speed 300 kHz, using 240 kHz
shutdown command invoked
Done flashing
r
/home/maribu/Repos/software/RIOT/stm32_spi/dist/tools/pyterm/pyterm -p "/dev/ttyACM1" -b "115200" --no-reconnect --noprefix --no-repeat-command-on-empty-line 
Connect to serial port /dev/ttyACM1
Welcome to pyterm!
Type '/exit' to exit.
�W�� r to print it is ready
Help: Press s to start test, r to print it is ready
Help: Press s to start test, r to print it is ready
Help: Press s to start test, r to print it is ready
Help: Press s to start test, r to print it is ready
Help: Press s to start test, r to print it is ready
Help: Press s to start test, r to print it is ready
Help: Press s to start test, r to print it is ready
Help: Press s to start test, r to print it is ready
Help: Press s to start test, r to print it is ready
Help: Press s to start test, r to print it is ready
READY
s
START
main(): This is RIOT! (Version: 2023.10-devel-561-g5784aa-stm32_spi)
self-testing peripheral drivers
===============================
Starting test for GPIO at tests/periph/selftest_shield/main.c:346
[OK]
Starting test for GPIO at tests/periph/selftest_shield/main.c:368
[OK]
Starting test for GPIO at tests/periph/selftest_shield/main.c:398
[OK]
Starting test for GPIO at tests/periph/selftest_shield/main.c:428
[OK]
Starting test for GPIO at tests/periph/selftest_shield/main.c:454
(skipped)
Starting test for GPIO-IRQ at tests/periph/selftest_shield/main.c:501
[OK]
Starting test for GPIO-IRQ at tests/periph/selftest_shield/main.c:564
[OK]
Starting test for GPIO-IRQ at tests/periph/selftest_shield/main.c:627
[OK]
Starting test for I2C at tests/periph/selftest_shield/main.c:701
[OK]
Starting test for SPI at tests/periph/selftest_shield/main.c:829
[OK]
Starting test for SPI at tests/periph/selftest_shield/main.c:829
[OK]
Starting test for SPI at tests/periph/selftest_shield/main.c:829
[OK]
Starting test for SPI at tests/periph/selftest_shield/main.c:829
[OK]
Starting test for SPI at tests/periph/selftest_shield/main.c:829
[OK]
Starting test for SPI at tests/periph/selftest_shield/main.c:829
[OK]
Starting test for SPI at tests/periph/selftest_shield/main.c:829
[OK]
Starting test for SPI at tests/periph/selftest_shield/main.c:829
[OK]
Starting test for SPI at tests/periph/selftest_shield/main.c:829
[OK]
Starting test for SPI at tests/periph/selftest_shield/main.c:829
[OK]
Starting test for SPI at tests/periph/selftest_shield/main.c:829
[OK]
Starting test for SPI at tests/periph/selftest_shield/main.c:829
[OK]
Starting test for ADC at tests/periph/selftest_shield/main.c:1027
[OK]


ALL TESTS SUCCEEDED
~/Repos/software/RIOT/stm32_spi/tests/periph/selftest_shield % make BOARD=nucleo-f446re flash test-with-config -j
Building application "tests_selftest_shield" for "nucleo-f446re" with MCU "stm32".

"make" -C /home/maribu/Repos/software/RIOT/stm32_spi/pkg/cmsis/ 
"make" -C /home/maribu/Repos/software/RIOT/stm32_spi/boards/common/init
"make" -C /home/maribu/Repos/software/RIOT/stm32_spi/boards/nucleo-f446re
"make" -C /home/maribu/Repos/software/RIOT/stm32_spi/core
"make" -C /home/maribu/Repos/software/RIOT/stm32_spi/core/lib
"make" -C /home/maribu/Repos/software/RIOT/stm32_spi/cpu/stm32
"make" -C /home/maribu/Repos/software/RIOT/stm32_spi/drivers
"make" -C /home/maribu/Repos/software/RIOT/stm32_spi/sys
"make" -C /home/maribu/Repos/software/RIOT/stm32_spi/boards/common/nucleo
"make" -C /home/maribu/Repos/software/RIOT/stm32_spi/drivers/pcf857x
"make" -C /home/maribu/Repos/software/RIOT/stm32_spi/drivers/periph_common
"make" -C /home/maribu/Repos/software/RIOT/stm32_spi/sys/auto_init
"make" -C /home/maribu/Repos/software/RIOT/stm32_spi/sys/div
"make" -C /home/maribu/Repos/software/RIOT/stm32_spi/sys/isrpipe
"make" -C /home/maribu/Repos/software/RIOT/stm32_spi/sys/libc
"make" -C /home/maribu/Repos/software/RIOT/stm32_spi/sys/malloc_thread_safe
"make" -C /home/maribu/Repos/software/RIOT/stm32_spi/sys/newlib_syscalls_default
"make" -C /home/maribu/Repos/software/RIOT/stm32_spi/cpu/cortexm_common
"make" -C /home/maribu/Repos/software/RIOT/stm32_spi/sys/pm_layered
"make" -C /home/maribu/Repos/software/RIOT/stm32_spi/cpu/stm32/periph
"make" -C /home/maribu/Repos/software/RIOT/stm32_spi/sys/preprocessor
"make" -C /home/maribu/Repos/software/RIOT/stm32_spi/cpu/stm32/stmclk
"make" -C /home/maribu/Repos/software/RIOT/stm32_spi/cpu/stm32/vectors
"make" -C /home/maribu/Repos/software/RIOT/stm32_spi/sys/stdio_uart
"make" -C /home/maribu/Repos/software/RIOT/stm32_spi/sys/test_utils/interactive_sync
"make" -C /home/maribu/Repos/software/RIOT/stm32_spi/sys/test_utils/print_stack_usage
"make" -C /home/maribu/Repos/software/RIOT/stm32_spi/sys/tiny_strerror
"make" -C /home/maribu/Repos/software/RIOT/stm32_spi/cpu/cortexm_common/periph
"make" -C /home/maribu/Repos/software/RIOT/stm32_spi/sys/tsrb
   text	  data	   bss	   dec	   hex	filename
  19512	   128	  2780	 22420	  5794	/home/maribu/Repos/software/RIOT/stm32_spi/tests/periph/selftest_shield/bin/nucleo-f446re/tests_selftest_shield.elf
/home/maribu/Repos/software/RIOT/stm32_spi/dist/tools/openocd/openocd.sh flash /home/maribu/Repos/software/RIOT/stm32_spi/tests/periph/selftest_shield/bin/nucleo-f446re/tests_selftest_shield.elf
### Flashing Target ###
Open On-Chip Debugger 0.12.0+dev-snapshot (2023-06-12-09:31)
Licensed under GNU GPL v2
For bug reports, read
	http://openocd.org/doc/doxygen/bugs.html
DEPRECATED! use 'adapter serial' not 'hla_serial'
hla_swd
Info : The selected transport took over low-level target control. The results might differ compared to plain JTAG/SWD
srst_only separate srst_nogate srst_open_drain connect_assert_srst
Info : clock speed 2000 kHz
Info : STLINK V2J40M27 (API v2) VID:PID 0483:374B
Info : Target voltage: 3.255900
Info : [stm32f4x.cpu] Cortex-M4 r0p1 processor detected
Info : [stm32f4x.cpu] target has 6 breakpoints, 4 watchpoints
Info : starting gdb server for stm32f4x.cpu on 0
Info : Listening on port 36079 for gdb connections
    TargetName         Type       Endian TapName            State       
--  ------------------ ---------- ------ ------------------ ------------
 0* stm32f4x.cpu       hla_target little stm32f4x.cpu       unknown
Info : Unable to match requested speed 2000 kHz, using 1800 kHz
Info : Unable to match requested speed 2000 kHz, using 1800 kHz
[stm32f4x.cpu] halted due to debug-request, current mode: Thread 
xPSR: 0x01000000 pc: 0x08001844 msp: 0x20000200
Info : device id = 0x10006421
Info : flash size = 512 KiB
auto erase enabled
wrote 32768 bytes from file /home/maribu/Repos/software/RIOT/stm32_spi/tests/periph/selftest_shield/bin/nucleo-f446re/tests_selftest_shield.elf in 1.124534s (28.456 KiB/s)
verified 19640 bytes in 0.226550s (84.660 KiB/s)
Info : Unable to match requested speed 2000 kHz, using 1800 kHz
Info : Unable to match requested speed 2000 kHz, using 1800 kHz
shutdown command invoked
Done flashing
r
/home/maribu/Repos/software/RIOT/stm32_spi/dist/tools/pyterm/pyterm -p "/dev/ttyACM1" -b "115200" --no-reconnect --noprefix --no-repeat-command-on-empty-line 
Connect to serial port /dev/ttyACM1
Welcome to pyterm!
Type '/exit' to exit.
�est, r to print it is ready
Help: Press s to start test, r to print it is ready
READY
s
START
main(): This is RIOT! (Version: 2023.10-devel-561-g5784aa-stm32_spi)
self-testing peripheral drivers
===============================
Starting test for GPIO at tests/periph/selftest_shield/main.c:346
[OK]
Starting test for GPIO at tests/periph/selftest_shield/main.c:368
[OK]
Starting test for GPIO at tests/periph/selftest_shield/main.c:398
[OK]
Starting test for GPIO at tests/periph/selftest_shield/main.c:428
[OK]
Starting test for GPIO at tests/periph/selftest_shield/main.c:454
(skipped)
Starting test for GPIO-IRQ at tests/periph/selftest_shield/main.c:501
[OK]
Starting test for GPIO-IRQ at tests/periph/selftest_shield/main.c:564
[OK]
Starting test for GPIO-IRQ at tests/periph/selftest_shield/main.c:627
[OK]
Starting test for I2C at tests/periph/selftest_shield/main.c:701
[OK]
Starting test for SPI at tests/periph/selftest_shield/main.c:829
[OK]
Starting test for SPI at tests/periph/selftest_shield/main.c:829
[OK]
Starting test for SPI at tests/periph/selftest_shield/main.c:829
[OK]
Starting test for SPI at tests/periph/selftest_shield/main.c:829
[OK]
Starting test for SPI at tests/periph/selftest_shield/main.c:829
[OK]
Starting test for SPI at tests/periph/selftest_shield/main.c:829
[OK]
Starting test for SPI at tests/periph/selftest_shield/main.c:829
[OK]
Starting test for SPI at tests/periph/selftest_shield/main.c:829
[OK]
Starting test for SPI at tests/periph/selftest_shield/main.c:829
[OK]
Starting test for SPI at tests/periph/selftest_shield/main.c:829
[OK]
Starting test for SPI at tests/periph/selftest_shield/main.c:829
[OK]
Starting test for SPI at tests/periph/selftest_shield/main.c:829
[OK]
Starting test for ADC at tests/periph/selftest_shield/main.c:1027
[OK]


ALL TESTS SUCCEEDED

For the nucleo-f103rb I also use a logic analyzer. Here the output when running master:

image

(Note that the idle level goes to low after the first transaction during pcf857x_init() that consistets of one write and one read.) Subsequently, the I2C fails to send the start condition. This in master however resulted in the peripheral to be re-initialized, after which the I2C will work until the next i2c_release(). So users may have worked around this bug by just retrying the I2C transfer.

Here the output when running this PR:

image

Note that the idle level now is high.

Issues/PRs references

#20071

@maribu maribu added Type: bug The issue reports a bug / The PR fixes a bug (including spelling errors) CI: ready for build If set, CI server will compile all applications for all available boards for the labeled PR Area: cpu Area: CPU/MCU ports labels Nov 22, 2023
@github-actions github-actions bot added the Platform: ARM Platform: This PR/issue effects ARM-based platforms label Nov 22, 2023
@riot-ci
Copy link

riot-ci commented Nov 22, 2023

Murdock results

✔️ PASSED

3002f1e cpu/stm32: fix periph_i2c for F1, F2, L1 and F4 families

Success Failures Total Runtime
8082 0 8082 10m:17s

Artifacts

@maribu maribu force-pushed the cpu/stm32/periph/i2c_2.c branch 2 times, most recently from 34adcdc to 998a7eb Compare November 23, 2023 12:00
@maribu maribu requested a review from kfessel December 9, 2023 20:23
Copy link
Contributor

@benpicco benpicco left a comment

Choose a reason for hiding this comment

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

Looks good, the DEBUG -> DEBUG_PUTS change obscures the diff a bit, would have been better as a separate commit (but you don't have delaminate that 😉)

Do you know why the open-drain configuration was chosen?

cpu/stm32/periph/i2c_2.c Show resolved Hide resolved
break;
case I2C_SPEED_LOW:
/* 10Kbit/s */
ccr = i2c_config[dev].clk / 20000;
Copy link
Contributor

Choose a reason for hiding this comment

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

If i2c_config[dev].speed would just be the speed in Hz you could do

Suggested change
ccr = i2c_config[dev].clk / 20000;
ccr = i2c_config[dev].clk / (2 * i2c_config[dev].speed);

for arbitrary I2C frequencies. (but this is unrelated to this PR)

Copy link
Member Author

Choose a reason for hiding this comment

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

I added this as a separate PR. The change is IMO trivial enough to not require a separate review.

@maribu maribu force-pushed the cpu/stm32/periph/i2c_2.c branch from 998a7eb to ecf2f2b Compare December 10, 2023 15:41
@github-actions github-actions bot added the Area: boards Area: Board ports label Dec 10, 2023
@maribu
Copy link
Member Author

maribu commented Dec 10, 2023

the DEBUG -> DEBUG_PUTS change obscures the diff a bit, would have been better as a separate commit

I split the changes on the DEBUG output out as a separate commit

@maribu maribu force-pushed the cpu/stm32/periph/i2c_2.c branch from ecf2f2b to 10641ae Compare December 10, 2023 15:44
@github-actions github-actions bot removed the Area: boards Area: Board ports label Dec 10, 2023
#include "mutex.h"
#include "pm_layered.h"
#include "panic.h"
Copy link
Contributor

Choose a reason for hiding this comment

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

panic.h seems to be used eg.: l.:516 core_panic(PANIC_GENERAL_ERROR, "I2C FAULT");

return ret;
}
if (flags & I2C_NOSTOP) {
return 0;
}
else {
/* End transmission */
DEBUG("[i2c] write_bytes: Ending transmission\n");
DEBUG_PUTS("[i2c] i2c_write_bytes(): Ending transmission");
Copy link
Contributor

@kfessel kfessel Dec 10, 2023

Choose a reason for hiding this comment

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

why not stay with DEBUG

afaik you optimized the behavior of printf -> DEBUG on AVR (I know this isn't AVR but using the same style even on definitely not AVR leads to consistency).

a short visit to godbolt revealed printf is optimized to puts anyway ( even with gcc -O0) (probably not for AVR with your flashprint optimization )

Copy link
Member Author

Choose a reason for hiding this comment

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

DEBUG() most of the time prints (something along the line of) stacksize too small for debugging using puts(). But since puts() apparently did work, it can be used without the stack test.

Copy link
Contributor

Choose a reason for hiding this comment

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

#ifdef DEVELHELP
#include "cpu_conf.h"
#define DEBUG_PRINT(...) \
    do { \
        if ((thread_get_active() == NULL) || \
            (thread_get_active()->stack_size >= \
             THREAD_EXTRA_STACKSIZE_PRINTF)) { \
            printf(__VA_ARGS__); \
        } \
        else { \
            puts("Cannot debug, stack too small. Consider using DEBUG_PUTS()."); \
        } \
    } while (0)
#else
#define DEBUG_PRINT(...) printf(__VA_ARGS__)
#endif

wat

Copy link
Contributor

Choose a reason for hiding this comment

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

fixed that in #20166

cpu/stm32/periph/i2c_2.c Outdated Show resolved Hide resolved
- boot the I2C after init in low power mode
    - otherwise I2C will consume more power until the first time it is
      used, which is surprising
- STM32 F1 only: reconfigure SCL and SDA as GPIOs while the I2C
  peripheral is powered down
    - When the I2C peripheral is not clocked, it drives SCL and SDA
      down. This will dissipate power across the pull up resistor.
@maribu maribu force-pushed the cpu/stm32/periph/i2c_2.c branch from 6d2782e to 3002f1e Compare December 12, 2023 08:55
@maribu maribu added this pull request to the merge queue Dec 12, 2023
Merged via the queue into RIOT-OS:master with commit 4370d93 Dec 12, 2023
27 checks passed
@maribu
Copy link
Member Author

maribu commented Dec 12, 2023

🎉 thx :-)

@maribu maribu deleted the cpu/stm32/periph/i2c_2.c branch December 12, 2023 14:05
@MrKevinWeiss MrKevinWeiss added this to the Release 2024.01 milestone Feb 7, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Area: cpu Area: CPU/MCU ports CI: ready for build If set, CI server will compile all applications for all available boards for the labeled PR Platform: ARM Platform: This PR/issue effects ARM-based platforms Type: bug The issue reports a bug / The PR fixes a bug (including spelling errors)
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants