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/efm32: Minimal support for gpio_ll #18023

Merged
merged 4 commits into from
May 3, 2022

Conversation

chrysn
Copy link
Member

@chrysn chrysn commented Apr 27, 2022

Contribution description

This is a minimal implementation of gpio_ll for EFM32; it is minimal in that

  • it just supports the input and push-pull modes, no resistors or drive strengths (even though the hardware would), and
    • [edit: it supports resistors now, but still no drive strengths]
  • it doesn't cover interrupts (even though the hardware could); also,
  • drive and pull up strengths were not even defined to the same value (as AIU they should be for a device not supporting any), because they're still to be extended.
    • [edit: they are defined to the same value now]

The choice of using indices for gpio_port_t is certainly unconventional, and not using gpio_ll to its full potential. For (at least some of -- it's a diverse group) EFM32 chips it is necessary, though: On some families, there is one register block that has members like P[n]->{DIN,DOUT}, but a separate block P_SET[n]->DOUT for setting (and a similar one for clearing) pins. As these blocks generally have different sizes, using &P[n] as gpio_port_t would require division and multiplication to get to the toggle blocks.

Alternatives that were rejected (for now) are:

  • Using a struct for gpio_port_t that contains all the relevant base pointers,
  • having that struct in constant memory and indexing it by the port number,
  • implementing gpio_ll only for those chips that have DOUT_{SET,CLEAR,TOGGLE} registers in the main block.

The third alternative can still be done, specializing the implementation for a subset of the EFM32 group. (I haven't tried to find out which of the 3 or more generations of EFM32 use which behavior).

Testing procedure

I've used an stk3700 kit; if it sits on a table in front of you, place two jumpers vertically on the right connectors, on the second and third pin pair closest to you.

$ make -C tests/periph_gpio_ll BOARD=stk3700 all flash term
[...]
s
2022-04-27 11:08:34,581 # START
2022-04-27 11:08:34,584 # main(): This is RIOT! (Version: 2022.07-devel-226-ga86635-efm32-gpio-ll)
2022-04-27 11:08:34,585 # Test / Hardware Deatils:
2022-04-27 11:08:34,593 # ========================
2022-04-27 11:08:34,594 # Cabling:
2022-04-27 11:08:34,596 #   P3.0 (PD0) -- P2.0 (PC0)
2022-04-27 11:08:34,597 #   P3.1 (PD1) -- P2.3 (PC3)
2022-04-27 11:08:34,600 # Number of pull resistor values supported: 4
2022-04-27 11:08:34,605 # Number of drive strengths supported: 4
2022-04-27 11:08:34,607 # Number of slew rates supported: 4
2022-04-27 11:08:34,608 # Valid GPIO ports:
2022-04-27 11:08:34,609 # - PORT 0 (PORT A)
2022-04-27 11:08:34,610 # - PORT 1 (PORT B)
2022-04-27 11:08:34,610 # - PORT 2 (PORT C)
2022-04-27 11:08:34,616 # - PORT 3 (PORT D)
2022-04-27 11:08:34,617 # - PORT 4 (PORT E)
2022-04-27 11:08:34,618 # - PORT 5 (PORT F)
2022-04-27 11:08:34,618 # 
2022-04-27 11:08:34,619 # Testing gpio_port_pack_addr()
2022-04-27 11:08:34,620 # =============================
2022-04-27 11:08:34,621 # 
2022-04-27 11:08:34,621 # All OK
2022-04-27 11:08:34,621 # 
2022-04-27 11:08:34,628 # Testing gpip_ng_init()
2022-04-27 11:08:34,629 # ======================
2022-04-27 11:08:34,629 # 
2022-04-27 11:08:34,632 # Testing is_gpio_port_num_valid() is true for PORT_OUT and PORT_IN:
2022-04-27 11:08:34,632 # 
2022-04-27 11:08:34,639 # Testing input configurations for PIN_IN_0:
2022-04-27 11:08:34,641 # Support for input with pull up: no
2022-04-27 11:08:34,642 # Support for input with pull down: no
2022-04-27 11:08:34,650 # Support for input with pull to bus level: no
2022-04-27 11:08:34,652 # Support for floating input (no pull resistors): yes
2022-04-27 11:08:34,654 # state: in, pull: none, schmitt trigger: on, value: off
2022-04-27 11:08:34,655 # 
2022-04-27 11:08:34,662 # Testing output configurations for PIN_OUT_0:
2022-04-27 11:08:34,664 # Support for output (push-pull) with initial value of LOW: yes
2022-04-27 11:08:34,675 # state: out-pp, drive: strong, slew: fast, value: off
2022-04-27 11:08:34,676 # Output is indeed LOW: yes
2022-04-27 11:08:34,678 # state: out-pp, drive: strong, slew: fast, value: on
2022-04-27 11:08:34,687 # Output can be pushed HIGH: yes
2022-04-27 11:08:34,689 # Support for output (push-pull) with initial value of HIGH: yes
2022-04-27 11:08:34,691 # state: out-pp, drive: strong, slew: fast, value: on
2022-04-27 11:08:34,699 # Output is indeed HIGH: yes
2022-04-27 11:08:34,701 # Support for output (open drain with pull up) with initial value of LOW: no
2022-04-27 11:08:34,711 # Support for output (open drain with pull up) with initial value of HIGH: no
2022-04-27 11:08:34,713 # Support for output (open drain) with initial value of LOW: no
2022-04-27 11:08:34,722 # Support for output (open drain) with initial value of HIGH: no
2022-04-27 11:08:34,724 # Support for output (open source) with initial value of LOW: no
2022-04-27 11:08:34,733 # Support for output (open drain) with initial value of HIGH: no
2022-04-27 11:08:34,736 # Support for output (open drain with pull up) with initial value of HIGH: no
2022-04-27 11:08:34,745 # Support for output (open drain with pull up) with initial value of LOW: no
2022-04-27 11:08:34,746 # Support for disconnecting GPIO: yes
2022-04-27 11:08:34,756 # WARN: Cannot enable pull down of PIN_IN_0 to verify correct disabled behavior
2022-04-27 11:08:34,757 # WARN: Cannot enable pull up of PIN_IN_0 to verify correct disabled behavior
2022-04-27 11:08:34,757 # 
2022-04-27 11:08:34,767 # Testing Reading/Writing GPIO Ports
2022-04-27 11:08:34,768 # ==================================
2022-04-27 11:08:34,768 # 
2022-04-27 11:08:34,768 # testing initial value of 0 after init
2022-04-27 11:08:34,769 # ...OK
2022-04-27 11:08:34,780 # testing setting both outputs_optional simultaneously
2022-04-27 11:08:34,781 # ...OK
2022-04-27 11:08:34,781 # testing clearing both outputs_optional simultaneously
2022-04-27 11:08:34,782 # ...OK
2022-04-27 11:08:34,795 # testing toggling first output (0 --> 1)
2022-04-27 11:08:34,795 # ...OK
2022-04-27 11:08:34,796 # testing toggling first output (1 --> 0)
2022-04-27 11:08:34,796 # ...OK
2022-04-27 11:08:34,796 # testing toggling second output (0 --> 1)
2022-04-27 11:08:34,797 # ...OK
2022-04-27 11:08:34,808 # testing toggling second output (1 --> 0)
2022-04-27 11:08:34,808 # ...OK
2022-04-27 11:08:34,809 # testing setting first output and clearing second with write
2022-04-27 11:08:34,809 # ...OK
2022-04-27 11:08:34,820 # testing setting second output and clearing first with write
2022-04-27 11:08:34,820 # ...OK
2022-04-27 11:08:34,821 # All input/output operations worked as expected
2022-04-27 11:08:34,821 # 
2022-04-27 11:08:34,821 # 
2022-04-27 11:08:34,822 # TEST SUCCEEDED
2022-04-27 11:08:34,844 # { "threads": [{ "name": "main", "stack_size": 1536, "stack_used": 404 }]}

Benchmarks show 6 cycles per period -- not great, not terrible, and in the ball park of what I'd expect with the indexed peripherals:

$ make -C tests/bench_periph_gpio_ll BOARD=stk3700 all flash term PROGRAMMER=openocd
[...]
2022-04-27 11:06:53,408 # Help: Press s to start test, r to print it is ready
s
2022-04-27 11:06:56,071 # START
2022-04-27 11:06:56,074 # main(): This is RIOT! (Version: 2022.07-devel-226-ga86635-efm32-gpio-ll)
2022-04-27 11:06:56,074 # 
2022-04-27 11:06:56,075 # Benchmarking GPIO APIs
2022-04-27 11:06:56,076 # ======================
2022-04-27 11:06:56,076 # 
2022-04-27 11:06:56,086 # estimating loop overhead for compensation
2022-04-27 11:06:56,088 # -----------------------------------------
2022-04-27 11:06:56,089 # 3128 us for 50000 iterations
2022-04-27 11:06:56,090 # 
2022-04-27 11:06:56,114 # periph/gpio: Using 2x gpio_set() and 2x gpio_clear()
2022-04-27 11:06:56,116 # ---------------------------------------------------
2022-04-27 11:06:56,172 # 50000 iterations took 62500 us (65628 us uncompensated)
2022-04-27 11:06:56,181 # Two square waves pins at       800000 Hz (      761869 Hz uncompensated)
2022-04-27 11:06:56,183 # ~60 CPU cycles per square wave period (~63 cycles uncompensated)
2022-04-27 11:06:56,184 # :'-(
2022-04-27 11:06:56,184 # 
2022-04-27 11:06:56,186 # periph/gpio_ll: Using gpio_ll_set() and gpio_ll_clear()
2022-04-27 11:06:56,203 # -------------------------------------------------------
2022-04-27 11:06:56,206 # 50000 iterations took 6248 us (9376 us uncompensated)
2022-04-27 11:06:56,215 # Two square waves pins at      8002560 Hz (     5332764 Hz uncompensated)
2022-04-27 11:06:56,217 # ~6 CPU cycles per square wave period (~9 cycles uncompensated)
2022-04-27 11:06:56,217 # :-|
2022-04-27 11:06:56,218 # 
2022-04-27 11:06:56,239 # periph/gpio: Using 4x gpio_toggle()
2022-04-27 11:06:56,241 # -----------------------------------
2022-04-27 11:06:56,298 # 50000 iterations took 62500 us (65628 us uncompensated)
2022-04-27 11:06:56,308 # Two square waves pins at       800000 Hz (      761869 Hz uncompensated)
2022-04-27 11:06:56,310 # ~60 CPU cycles per square wave period (~63 cycles uncompensated)
2022-04-27 11:06:56,310 # :'-(
2022-04-27 11:06:56,311 # 
2022-04-27 11:06:56,312 # periph/gpio_ll: Using 2x gpio_ll_toggle()
2022-04-27 11:06:56,329 # -----------------------------------------
2022-04-27 11:06:56,331 # 50000 iterations took 6252 us (9380 us uncompensated)
2022-04-27 11:06:56,341 # Two square waves pins at      7997440 Hz (     5330490 Hz uncompensated)
2022-04-27 11:06:56,344 # ~6 CPU cycles per square wave period (~9 cycles uncompensated)
2022-04-27 11:06:56,345 # :-|
2022-04-27 11:06:56,345 # 
2022-04-27 11:06:56,362 # periph/gpio: Using 4x gpio_write()
2022-04-27 11:06:56,364 # ----------------------------------
2022-04-27 11:06:56,488 # 50000 iterations took 129180 us (132308 us uncompensated)
2022-04-27 11:06:56,498 # Two square waves pins at       387056 Hz (      377906 Hz uncompensated)
2022-04-27 11:06:56,500 # ~124 CPU cycles per square wave period (~127 cycles uncompensated)
2022-04-27 11:06:56,501 # :'-(
2022-04-27 11:06:56,501 # 
2022-04-27 11:06:56,503 # periph/gpio_ll: Using 2x gpio_ll_write()
2022-04-27 11:06:56,520 # ----------------------------------------
2022-04-27 11:06:56,523 # 50000 iterations took 6248 us (9376 us uncompensated)
2022-04-27 11:06:56,531 # Two square waves pins at      8002560 Hz (     5332764 Hz uncompensated)
2022-04-27 11:06:56,533 # ~6 CPU cycles per square wave period (~9 cycles uncompensated)
2022-04-27 11:06:56,534 # :-|
2022-04-27 11:06:56,534 # 
2022-04-27 11:06:56,534 # 
2022-04-27 11:06:56,535 # TEST SUCCEEDED
2022-04-27 11:06:56,557 # { "threads": [{ "name": "main", "stack_size": 1536, "stack_used": 428 }]}

I'd yet like to run these with a few other boards (stk3200, sltb001a), just didn't get around to it yet.

Notes that fit nowhere in particular

If you trace the code through the library you might see that it appears that toggle and set/clear operations sometimes fan out to interrupt enabling / disabling RMW cycles (Bus_RegMasked{Set,Clear}).

While that'd even be acceptable, as far as I can tell it doesn't happen, because the families that do not have set/clear registers tell you in their manuals to defer to the set/clear memory regions. Later families (after the memory regions were deprecated, I think along with the bitbanding memory regions) have dedicated set/clear registers again. Thus, the RMW code will not be reached.

Next steps

I'm asking for a high-level initial review on the whole thing; I'd probably add strengths etc. later to the extent this can be done without going into the details of subfamilies. (Although if others prefer to have the minimal form in first, I can do the defining-to-the-same-values, and this might get mergable more easily).

[edit: It's not as minimal as originally set out, see edited list above; any further additions like IRQs or drive strengths may be done in follow-up PRs on demand.]

@chrysn chrysn requested a review from maribu April 27, 2022 09:16
@github-actions github-actions bot added Area: cpu Area: CPU/MCU ports Area: Kconfig Area: Kconfig integration Platform: ARM Platform: This PR/issue effects ARM-based platforms labels Apr 27, 2022
@chrysn chrysn added Type: new feature The issue requests / The PR implemements a new feature for RIOT CI: ready for build If set, CI server will compile all applications for all available boards for the labeled PR and removed Platform: ARM Platform: This PR/issue effects ARM-based platforms Area: Kconfig Area: Kconfig integration labels Apr 27, 2022
@benpicco benpicco requested a review from jue89 April 27, 2022 11:10
Copy link
Member

@maribu maribu 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 to me. Some comments inline.

drive and pull up strengths were not even defined to the same value (as AIU they should be for a device not supporting any), because they're still to be extended.

From a users point of view there is little difference in features missing due to missing implementation or lack of hardware support. IMO, this should be defined to a single numeric value until the feature is exposed by the driver.

cpu/efm32/include/gpio_ll_arch.h Outdated Show resolved Hide resolved
cpu/efm32/include/gpio_ll_arch.h Outdated Show resolved Hide resolved
cpu/efm32/periph/gpio_ll.c Outdated Show resolved Hide resolved
@github-actions github-actions bot added Area: Kconfig Area: Kconfig integration Platform: ARM Platform: This PR/issue effects ARM-based platforms labels Apr 27, 2022
@chrysn
Copy link
Member Author

chrysn commented Apr 28, 2022

Added support for pull-up/-down resistors, now passing tests without warnings.

Slew rates and pull-up strengths are collapsed because they are not supported in the hardware.

Drive strengths are collapsed and documented not to be implemented right now (they're tricky: there is only one alternative strength possible per port) -- I'd leave these to whoever needs them.

Interrupts are still not in, but I'd prefer to get this in with the current feature set, and add interrupts or drive strengths as they are needed.

test output
2022-04-28 11:12:11,182 # Help: Press s to start test, r to print it is ready
s
2022-04-28 11:12:12,550 # START
2022-04-28 11:12:12,553 # main(): This is RIOT! (Version: 2022.07-devel-229-g841bef-efm32-gpio-ll)
2022-04-28 11:12:12,554 # Test / Hardware Deatils:
2022-04-28 11:12:12,561 # ========================
2022-04-28 11:12:12,562 # Cabling:
2022-04-28 11:12:12,564 #   P3.0 (PD0) -- P2.0 (PC0)
2022-04-28 11:12:12,566 #   P3.1 (PD1) -- P2.3 (PC3)
2022-04-28 11:12:12,568 # Number of pull resistor values supported: 1
2022-04-28 11:12:12,573 # Number of drive strengths supported: 1
2022-04-28 11:12:12,575 # Number of slew rates supported: 1
2022-04-28 11:12:12,576 # Valid GPIO ports:
2022-04-28 11:12:12,577 # - PORT 0 (PORT A)
2022-04-28 11:12:12,578 # - PORT 1 (PORT B)
2022-04-28 11:12:12,579 # - PORT 2 (PORT C)
2022-04-28 11:12:12,585 # - PORT 3 (PORT D)
2022-04-28 11:12:12,586 # - PORT 4 (PORT E)
2022-04-28 11:12:12,587 # - PORT 5 (PORT F)
2022-04-28 11:12:12,588 # 
2022-04-28 11:12:12,589 # Testing gpio_port_pack_addr()
2022-04-28 11:12:12,590 # =============================
2022-04-28 11:12:12,591 # 
2022-04-28 11:12:12,591 # All OK
2022-04-28 11:12:12,591 # 
2022-04-28 11:12:12,596 # Testing gpip_ng_init()
2022-04-28 11:12:12,597 # ======================
2022-04-28 11:12:12,597 # 
2022-04-28 11:12:12,598 # Testing is_gpio_port_num_valid() is true for PORT_OUT and PORT_IN:
2022-04-28 11:12:12,598 # 
2022-04-28 11:12:12,607 # Testing input configurations for PIN_IN_0:
2022-04-28 11:12:12,608 # Support for input with pull up: yes
2022-04-28 11:12:12,609 # state: in, pull: up, schmitt trigger: on, value: on
2022-04-28 11:12:12,619 # Support for input with pull down: yes
2022-04-28 11:12:12,620 # state: in, pull: down, schmitt trigger: on, value: off
2022-04-28 11:12:12,621 # Support for input with pull to bus level: no
2022-04-28 11:12:12,630 # Support for floating input (no pull resistors): yes
2022-04-28 11:12:12,631 # state: in, pull: none, schmitt trigger: on, value: off
2022-04-28 11:12:12,632 # 
2022-04-28 11:12:12,642 # Testing output configurations for PIN_OUT_0:
2022-04-28 11:12:12,643 # Support for output (push-pull) with initial value of LOW: yes
2022-04-28 11:12:12,644 # state: out-pp, value: off
2022-04-28 11:12:12,654 # Output is indeed LOW: yes
2022-04-28 11:12:12,655 # state: out-pp, value: on
2022-04-28 11:12:12,655 # Output can be pushed HIGH: yes
2022-04-28 11:12:12,657 # Support for output (push-pull) with initial value of HIGH: yes
2022-04-28 11:12:12,667 # state: out-pp, value: on
2022-04-28 11:12:12,667 # Output is indeed HIGH: yes
2022-04-28 11:12:12,669 # Support for output (open drain with pull up) with initial value of LOW: yes
2022-04-28 11:12:12,680 # state: out-od, pull: up, schmitt trigger: on, value: off
2022-04-28 11:12:12,681 # Output is indeed LOW: yes
2022-04-28 11:12:12,692 # Support for output (open drain with pull up) with initial value of HIGH: yes
2022-04-28 11:12:12,694 # state: out-od, pull: up, schmitt trigger: on, value: on
2022-04-28 11:12:12,695 # Output is indeed HIGH: yes
2022-04-28 11:12:12,704 # Support for output (open drain) with initial value of LOW: yes
2022-04-28 11:12:12,706 # state: out-od, pull: none, schmitt trigger: on, value: off
2022-04-28 11:12:12,715 # Output is indeed LOW: yes
2022-04-28 11:12:12,717 # Support for output (open drain) with initial value of HIGH: yes
2022-04-28 11:12:12,718 # state: out-od, pull: none, schmitt trigger: on, value: on
2022-04-28 11:12:12,729 # state: in, pull: down, schmitt trigger: on, value: off
2022-04-28 11:12:12,730 # Output can indeed be pulled LOW: yes
2022-04-28 11:12:12,740 # state: in, pull: up, schmitt trigger: on, value: on
2022-04-28 11:12:12,742 # Output can indeed be pulled HIGH: yes
2022-04-28 11:12:12,744 # Support for output (open source) with initial value of LOW: yes
2022-04-28 11:12:12,753 # state: out-os, pull: none, schmitt trigger: on, value: off
2022-04-28 11:12:12,754 # state: in, pull: down, schmitt trigger: on, value: off
2022-04-28 11:12:12,764 # Output can indeed be pulled LOW: yes
2022-04-28 11:12:12,766 # state: in, pull: up, schmitt trigger: on, value: on
2022-04-28 11:12:12,767 # Output can indeed be pulled HIGH: yes
2022-04-28 11:12:12,777 # Support for output (open drain) with initial value of HIGH: yes
2022-04-28 11:12:12,779 # state: out-os, pull: none, schmitt trigger: on, value: on
2022-04-28 11:12:12,780 # Output is indeed HIGH: yes
2022-04-28 11:12:12,790 # Support for output (open drain with pull up) with initial value of HIGH: yes
2022-04-28 11:12:12,791 # Output is indeed HIGH: yes
2022-04-28 11:12:12,803 # Support for output (open drain with pull up) with initial value of LOW: yes
2022-04-28 11:12:12,804 # Output is indeed LOW: yes
2022-04-28 11:12:12,805 # Support for disconnecting GPIO: yes
2022-04-28 11:12:12,815 # Output can indeed be pulled LOW: yes
2022-04-28 11:12:12,816 # Output can indeed be pulled HIGH: yes
2022-04-28 11:12:12,817 # 
2022-04-28 11:12:12,818 # Testing Reading/Writing GPIO Ports
2022-04-28 11:12:12,819 # ==================================
2022-04-28 11:12:12,819 # 
2022-04-28 11:12:12,829 # testing initial value of 0 after init
2022-04-28 11:12:12,829 # ...OK
2022-04-28 11:12:12,831 # testing setting both outputs_optional simultaneously
2022-04-28 11:12:12,831 # ...OK
2022-04-28 11:12:12,843 # testing clearing both outputs_optional simultaneously
2022-04-28 11:12:12,843 # ...OK
2022-04-28 11:12:12,845 # testing toggling first output (0 --> 1)
2022-04-28 11:12:12,845 # ...OK
2022-04-28 11:12:12,846 # testing toggling first output (1 --> 0)
2022-04-28 11:12:12,847 # ...OK
2022-04-28 11:12:12,857 # testing toggling second output (0 --> 1)
2022-04-28 11:12:12,857 # ...OK
2022-04-28 11:12:12,858 # testing toggling second output (1 --> 0)
2022-04-28 11:12:12,859 # ...OK
2022-04-28 11:12:12,868 # testing setting first output and clearing second with write
2022-04-28 11:12:12,869 # ...OK
2022-04-28 11:12:12,871 # testing setting second output and clearing first with write
2022-04-28 11:12:12,871 # ...OK
2022-04-28 11:12:12,897 # All input/output operations worked as expected
2022-04-28 11:12:12,898 # 
2022-04-28 11:12:12,898 # 
2022-04-28 11:12:12,899 # TEST SUCCEEDED
2022-04-28 11:12:12,901 # { "threads": [{ "name": "main", "stack_size": 1536, "stack_used": 404 }]}

@chrysn
Copy link
Member Author

chrysn commented Apr 28, 2022

Now also tested on SLTB001a (after careful avoiding pins that are wired to any external pull-ups...).

Test results
2022-04-28 11:58:53,563 # START
2022-04-28 11:58:53,566 # main(): This is RIOT! (Version: 2022.07-devel-230-g25aab-efm32-gpio-ll)
2022-04-28 11:58:53,567 # Test / Hardware Deatils:
2022-04-28 11:58:53,568 # ========================
2022-04-28 11:58:53,576 # Cabling:
2022-04-28 11:58:53,577 #   P0.3 (PA3) -- P5.4 (PF4)
2022-04-28 11:58:53,578 #   P0.2 (PA2) -- P5.3 (PF3)
2022-04-28 11:58:53,579 # Number of pull resistor values supported: 1
2022-04-28 11:58:53,586 # Number of drive strengths supported: 1
2022-04-28 11:58:53,588 # Number of slew rates supported: 1
2022-04-28 11:58:53,588 # Valid GPIO ports:
2022-04-28 11:58:53,589 # - PORT 0 (PORT A)
2022-04-28 11:58:53,590 # - PORT 1 (PORT B)
2022-04-28 11:58:53,591 # - PORT 2 (PORT C)
2022-04-28 11:58:53,598 # - PORT 3 (PORT D)
2022-04-28 11:58:53,598 # - PORT 5 (PORT F)
2022-04-28 11:58:53,599 # 
2022-04-28 11:58:53,600 # Testing gpio_port_pack_addr()
2022-04-28 11:58:53,601 # =============================
2022-04-28 11:58:53,602 # 
2022-04-28 11:58:53,602 # All OK
2022-04-28 11:58:53,602 # 
2022-04-28 11:58:53,603 # Testing gpip_ng_init()
2022-04-28 11:58:53,609 # ======================
2022-04-28 11:58:53,610 # 
2022-04-28 11:58:53,612 # Testing is_gpio_port_num_valid() is true for PORT_OUT and PORT_IN:
2022-04-28 11:58:53,612 # 
2022-04-28 11:58:53,620 # Testing input configurations for PIN_IN_0:
2022-04-28 11:58:53,622 # Support for input with pull up: yes
2022-04-28 11:58:53,623 # state: in, pull: up, schmitt trigger: on, value: on
2022-04-28 11:58:53,631 # Support for input with pull down: yes
2022-04-28 11:58:53,633 # state: in, pull: down, schmitt trigger: on, value: off
2022-04-28 11:58:53,635 # Support for input with pull to bus level: no
2022-04-28 11:58:53,644 # Support for floating input (no pull resistors): yes
2022-04-28 11:58:53,646 # state: in, pull: none, schmitt trigger: on, value: off
2022-04-28 11:58:53,646 # 
2022-04-28 11:58:53,648 # Testing output configurations for PIN_OUT_0:
2022-04-28 11:58:53,657 # Support for output (push-pull) with initial value of LOW: yes
2022-04-28 11:58:53,658 # state: out-pp, value: off
2022-04-28 11:58:53,659 # Output is indeed LOW: yes
2022-04-28 11:58:53,668 # state: out-pp, value: on
2022-04-28 11:58:53,669 # Output can be pushed HIGH: yes
2022-04-28 11:58:53,671 # Support for output (push-pull) with initial value of HIGH: yes
2022-04-28 11:58:53,680 # state: out-pp, value: on
2022-04-28 11:58:53,681 # Output is indeed HIGH: yes
2022-04-28 11:58:53,683 # Support for output (open drain with pull up) with initial value of LOW: yes
2022-04-28 11:58:53,693 # state: out-od, pull: up, schmitt trigger: on, value: off
2022-04-28 11:58:53,694 # Output is indeed LOW: yes
2022-04-28 11:58:53,705 # Support for output (open drain with pull up) with initial value of HIGH: yes
2022-04-28 11:58:53,707 # state: out-od, pull: up, schmitt trigger: on, value: on
2022-04-28 11:58:53,708 # Output is indeed HIGH: yes
2022-04-28 11:58:53,718 # Support for output (open drain) with initial value of LOW: yes
2022-04-28 11:58:53,720 # state: out-od, pull: none, schmitt trigger: on, value: off
2022-04-28 11:58:53,721 # Output is indeed LOW: yes
2022-04-28 11:58:53,730 # Support for output (open drain) with initial value of HIGH: yes
2022-04-28 11:58:53,732 # state: out-od, pull: none, schmitt trigger: on, value: on
2022-04-28 11:58:53,743 # state: in, pull: down, schmitt trigger: on, value: off
2022-04-28 11:58:53,744 # Output can indeed be pulled LOW: yes
2022-04-28 11:58:53,746 # state: in, pull: up, schmitt trigger: on, value: on
2022-04-28 11:58:53,754 # Output can indeed be pulled HIGH: yes
2022-04-28 11:58:53,756 # Support for output (open source) with initial value of LOW: yes
2022-04-28 11:58:53,766 # state: out-os, pull: none, schmitt trigger: on, value: off
2022-04-28 11:58:53,768 # state: in, pull: down, schmitt trigger: on, value: off
2022-04-28 11:58:53,770 # Output can indeed be pulled LOW: yes
2022-04-28 11:58:53,779 # state: in, pull: up, schmitt trigger: on, value: on
2022-04-28 11:58:53,781 # Output can indeed be pulled HIGH: yes
2022-04-28 11:58:53,791 # Support for output (open drain) with initial value of HIGH: yes
2022-04-28 11:58:53,793 # state: out-os, pull: none, schmitt trigger: on, value: on
2022-04-28 11:58:53,794 # Output is indeed HIGH: yes
2022-04-28 11:58:53,804 # Support for output (open drain with pull up) with initial value of HIGH: yes
2022-04-28 11:58:53,805 # Output is indeed HIGH: yes
2022-04-28 11:58:53,818 # Support for output (open drain with pull up) with initial value of LOW: yes
2022-04-28 11:58:53,819 # Output is indeed LOW: yes
2022-04-28 11:58:53,821 # Support for disconnecting GPIO: yes
2022-04-28 11:58:53,822 # Output can indeed be pulled LOW: yes
2022-04-28 11:58:53,829 # Output can indeed be pulled HIGH: yes
2022-04-28 11:58:53,830 # 
2022-04-28 11:58:53,831 # Testing Reading/Writing GPIO Ports
2022-04-28 11:58:53,832 # ==================================
2022-04-28 11:58:53,833 # 
2022-04-28 11:58:53,842 # testing initial value of 0 after init
2022-04-28 11:58:53,843 # ...OK
2022-04-28 11:58:53,845 # testing setting both outputs_optional simultaneously
2022-04-28 11:58:53,845 # ...OK
2022-04-28 11:58:53,857 # testing clearing both outputs_optional simultaneously
2022-04-28 11:58:53,857 # ...OK
2022-04-28 11:58:53,859 # testing toggling first output (0 --> 1)
2022-04-28 11:58:53,859 # ...OK
2022-04-28 11:58:53,860 # testing toggling first output (1 --> 0)
2022-04-28 11:58:53,861 # ...OK
2022-04-28 11:58:53,870 # testing toggling second output (0 --> 1)
2022-04-28 11:58:53,871 # ...OK
2022-04-28 11:58:53,873 # testing toggling second output (1 --> 0)
2022-04-28 11:58:53,873 # ...OK
2022-04-28 11:58:53,882 # testing setting first output and clearing second with write
2022-04-28 11:58:53,883 # ...OK
2022-04-28 11:58:53,885 # testing setting second output and clearing first with write
2022-04-28 11:58:53,886 # ...OK
2022-04-28 11:58:53,887 # All input/output operations worked as expected
2022-04-28 11:58:53,888 # 
2022-04-28 11:58:53,888 # 
2022-04-28 11:58:53,892 # TEST SUCCEEDED
2022-04-28 11:58:53,895 # { "threads": [{ "name": "main", "stack_size": 1536, "stack_used": 412 }]}
benchmark results
2022-04-28 12:00:33,086 # START
2022-04-28 12:00:33,089 # main(): This is RIOT! (Version: 2022.07-devel-230-g25aab-efm32-gpio-ll)
2022-04-28 12:00:33,089 # 
2022-04-28 12:00:33,090 # Benchmarking GPIO APIs
2022-04-28 12:00:33,091 # ======================
2022-04-28 12:00:33,091 # 
2022-04-28 12:00:33,097 # estimating loop overhead for compensation
2022-04-28 12:00:33,099 # -----------------------------------------
2022-04-28 12:00:33,109 # 3924 us for 50000 iterations
2022-04-28 12:00:33,110 # 
2022-04-28 12:00:33,111 # periph/gpio: Using 2x gpio_set() and 2x gpio_clear()
2022-04-28 12:00:33,113 # ---------------------------------------------------
2022-04-28 12:00:33,210 # 50000 iterations took 83672 us (87596 us uncompensated)
2022-04-28 12:00:33,219 # Two square waves pins at       597571 Hz (      570802 Hz uncompensated)
2022-04-28 12:00:33,222 # ~64 CPU cycles per square wave period (~67 cycles uncompensated)
2022-04-28 12:00:33,222 # :'-(
2022-04-28 12:00:33,222 # 
2022-04-28 12:00:33,224 # periph/gpio_ll: Using gpio_ll_set() and gpio_ll_clear()
2022-04-28 12:00:33,228 # -------------------------------------------------------
2022-04-28 12:00:33,244 # 50000 iterations took 2616 us (6540 us uncompensated)
2022-04-28 12:00:33,246 # Two square waves pins at     19113149 Hz (     7645259 Hz uncompensated)
2022-04-28 12:00:33,255 # ~2 CPU cycles per square wave period (~5 cycles uncompensated)
2022-04-28 12:00:33,255 # :-D
2022-04-28 12:00:33,256 # 
2022-04-28 12:00:33,257 # periph/gpio: Using 4x gpio_toggle()
2022-04-28 12:00:33,259 # -----------------------------------
2022-04-28 12:00:33,349 # 50000 iterations took 78444 us (82368 us uncompensated)
2022-04-28 12:00:33,359 # Two square waves pins at       637397 Hz (      607031 Hz uncompensated)
2022-04-28 12:00:33,362 # ~60 CPU cycles per square wave period (~63 cycles uncompensated)
2022-04-28 12:00:33,362 # :'-(
2022-04-28 12:00:33,362 # 
2022-04-28 12:00:33,364 # periph/gpio_ll: Using 2x gpio_ll_toggle()
2022-04-28 12:00:33,365 # -----------------------------------------
2022-04-28 12:00:33,381 # 50000 iterations took 2616 us (6540 us uncompensated)
2022-04-28 12:00:33,383 # Two square waves pins at     19113149 Hz (     7645259 Hz uncompensated)
2022-04-28 12:00:33,393 # ~2 CPU cycles per square wave period (~5 cycles uncompensated)
2022-04-28 12:00:33,393 # :-D
2022-04-28 12:00:33,394 # 
2022-04-28 12:00:33,396 # periph/gpio: Using 4x gpio_write()
2022-04-28 12:00:33,398 # ----------------------------------
2022-04-28 12:00:33,522 # 50000 iterations took 115044 us (118968 us uncompensated)
2022-04-28 12:00:33,533 # Two square waves pins at       434616 Hz (      420281 Hz uncompensated)
2022-04-28 12:00:33,533 # ~88 CPU cycles per square wave period (~91 cycles uncompensated)
2022-04-28 12:00:33,533 # :'-(
2022-04-28 12:00:33,534 # 
2022-04-28 12:00:33,534 # periph/gpio_ll: Using 2x gpio_ll_write()
2022-04-28 12:00:33,538 # ----------------------------------------
2022-04-28 12:00:33,554 # 50000 iterations took 2616 us (6540 us uncompensated)
2022-04-28 12:00:33,554 # Two square waves pins at     19113149 Hz (     7645259 Hz uncompensated)
2022-04-28 12:00:33,565 # ~2 CPU cycles per square wave period (~5 cycles uncompensated)
2022-04-28 12:00:33,565 # :-D
2022-04-28 12:00:33,565 # 
2022-04-28 12:00:33,565 # 
2022-04-28 12:00:33,566 # TEST SUCCEEDED
2022-04-28 12:00:33,570 # { "threads": [{ "name": "main", "stack_size": 1536, "stack_used": 440 }]}
Makefile.sltb001a
# on extension port, wire pins 3 to 7 and 5 to 9 (all left side; top pin there
# is free, then every other is wired to the one 2 below); that's PA2 to PF3
# (pair 1) and PA3 to PF4 (pair 0)

# port A (top two)
PORT_IN = 0
# port C (next two)
PORT_OUT = 5
# A2
PIN_IN_0 = 3
# A3
PIN_IN_1 = 2
# C6
PIN_OUT_0 = 4
# C7
PIN_OUT_1 = 3

... and earlier I missed placing this here:

Makefile.stk3700
# on extension port, jumper pins 3 to 4 and 5 to 6 (vertical
# jumpers on second and third pin pair from the bottom edge of
# the PCB); that's PC0 to PD0 and PC3 to PD1

# port D
PORT_IN = 3
# port C
PORT_OUT = 2
# D0
PIN_IN_0 = 0
# D1
PIN_IN_1 = 1
# C0
PIN_OUT_0 = 0
# C3
PIN_OUT_1 = 3

@chrysn chrysn requested a review from maribu May 2, 2022 21:46
Copy link
Member

@maribu maribu left a comment

Choose a reason for hiding this comment

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

ACK. Code looks good and I trust your test results.

* are using an alternative drive strength, and refuse changing it if any are
* found.
*
* * There is an optional glitch suppression filter after the Schmitt tigger;
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
* * There is an optional glitch suppression filter after the Schmitt tigger;
* * There is an optional glitch suppression filter after the Schmitt trigger;

Copy link
Member Author

Choose a reason for hiding this comment

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

Thanks, fixed in squash. Christopher Robin and Eeyore will be sad, though.

Copy link
Member

Choose a reason for hiding this comment

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

gif of sad tigger

@chrysn chrysn force-pushed the efm32-gpio-ll branch 2 times, most recently from 7fe3bb2 to f86d17d Compare May 3, 2022 11:05
@chrysn chrysn enabled auto-merge May 3, 2022 11:05
@chrysn
Copy link
Member Author

chrysn commented May 3, 2022

Build tests ran through, but I missed that a static test barked.

I'm taking the liberty to set "skip build tests" on the upcoming insta-squashed fix that comes in for that; static checks will still run.

@chrysn chrysn disabled auto-merge May 3, 2022 17:31
@chrysn chrysn removed the CI: ready for build If set, CI server will compile all applications for all available boards for the labeled PR label May 3, 2022
@chrysn chrysn added CI: skip compile test If set, CI server will run only non-compile jobs, but no compile jobs or their dependent jobs CI: ready for build If set, CI server will compile all applications for all available boards for the labeled PR labels May 3, 2022
@maribu maribu enabled auto-merge May 3, 2022 18:38
@maribu maribu merged commit 2025b64 into RIOT-OS:master May 3, 2022
@chrysn chrysn deleted the efm32-gpio-ll branch May 3, 2022 23:48
@chrysn chrysn added this to the Release 2022.07 milestone Aug 25, 2022
@chrysn
Copy link
Member Author

chrysn commented Oct 11, 2022 via email

@maribu
Copy link
Member

maribu commented Oct 11, 2022

Too late, this has been merged 5 months ago ;)

@chrysn
Copy link
Member Author

chrysn commented Oct 11, 2022 via email

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 Area: Kconfig Area: Kconfig integration CI: ready for build If set, CI server will compile all applications for all available boards for the labeled PR CI: skip compile test If set, CI server will run only non-compile jobs, but no compile jobs or their dependent jobs Platform: ARM Platform: This PR/issue effects ARM-based platforms Type: new feature The issue requests / The PR implemements a new feature for RIOT
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants