1
0
mirror of https://github.com/RIOT-OS/RIOT.git synced 2025-01-18 12:52:44 +01:00
Commit Graph

3 Commits

Author SHA1 Message Date
Marian Buschsieweke
36e8526046
drivers/periph_gpio_ll: change API to access GPIO ports
The API was based on the assumption that GPIO ports are mapped in memory
sanely, so that a `GPIO_PORT(num)` macro would work allow for constant
folding when `num` is known and still be efficient when it is not.

Some MCUs, however, will need a look up tables to efficiently translate
GPIO port numbers to the port's base address. This will prevent the use
of such a `GPIO_PORT(num)` macro in constant initializers.

As a result, we rather provide `GPIO_PORT_0`, `GPIO_PORT_1`, etc. macros
for each GPIO port present (regardless of MCU naming scheme), as well as
`GPIO_PORT_A`, `GPIO_PORT_B`, etc. macros if (and only if) the MCU port
naming scheme uses letters rather than numbers.

These can be defined as macros to the peripheral base address even when
those are randomly mapped into the address space. In addition, a C
function `gpio_port()` replaces the role of the `GPIO_PORT()` and
`gpio_port_num()` the `GPIO_PORT_NUM()` macro. Those functions will
still be implemented as efficient as possible and will allow constant
folding where it was formerly possible. Hence, there is no downside for
MCUs with sane peripheral memory mapping, but it is highly beneficial
for the crazy ones.

There are also two benefits for the non-crazy MCUs:
1. We can now test for valid port numbers with `#ifdef GPIO_PORT_<NUM>`
    - This directly benefits the test in `tests/periph/gpio_ll`, which
      can now provide a valid GPIO port for each and every board
    - Writing to invalid memory mapped I/O addresses was treated as
      triggering undefined behavior by the compiler and used as a
      optimization opportunity
2. We can now detect at compile time if the naming scheme of the MCU
   uses letters or numbers, and produce more user friendly output.
    - This is directly applied in the test app
2024-08-02 09:55:24 +02:00
Marian Buschsieweke
dd585f9e9d
cpu/esp32/gpio_ll: fix & cleanup
- `gpio_ll_toggle()` now is race-free
- avoid using a look up table but branch to the two different registers
  in the `gpio_ll*()` functions
    - in most cases the GPIO port is a compile time constant and the
      dead branch is eliminated by the optimizer, making this vastly
      more efficient
    - some MCUs do only have a single port, in which case
      `GPIO_PORT_NUM(port)` is known to return `0` even if `port` is
      not known, resulting in one of the branch being eliminated as
      dead branch no matter what
    - in case it really is unknown at compile time which port to work
      on, the branch can still be implemented efficiently by the
      compiler e.g. using a conditional move; likely more efficient
      than fetching a value from the look up table.
2024-04-30 14:16:28 +02:00
Gunar Schorcht
581c2dd9be cpu/esp32: implement periph/gpio_ll 2022-09-02 15:03:45 +02:00