Skip to content

drivers/periph: Added gpio_abc implementation for STM32F3#12016

Closed
maribu wants to merge 3 commits intoRIOT-OS:masterfrom
maribu:gpio_abc_stm32f3
Closed

drivers/periph: Added gpio_abc implementation for STM32F3#12016
maribu wants to merge 3 commits intoRIOT-OS:masterfrom
maribu:gpio_abc_stm32f3

Conversation

@maribu
Copy link
Member

@maribu maribu commented Aug 15, 2019

Contribution description

Implements the API proposed in #12015 for STM32F3.

Testing procedure

Run the test application provided in #12015 (tests/periph_gpio_abc). The application will print instructions in the shell. You'll need a scope or logic analyzer with a sample rate of at least 20 MHz.

Issues/PRs references

#12015

@maribu maribu added Type: new feature The issue requests / The PR implemements a new feature for RIOT Area: drivers Area: Device drivers Area: cpu Area: CPU/MCU ports State: waiting for other PR State: The PR requires another PR to be merged first labels Aug 15, 2019
@maribu maribu force-pushed the gpio_abc_stm32f3 branch 2 times, most recently from 0024f63 to 51163a3 Compare October 7, 2019 21:03
Comment on lines +261 to +268
static inline __attribute__((always_inline)) void _delay(int32_t loops)
{
__asm__ volatile(
"0:" "SUBS %[iterator], #1;"
"BPL 0b;"
: [iterator]"+r"(loops)
);
}
Copy link
Contributor

Choose a reason for hiding this comment

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

This is not STM32 specific, it could go in cpu/cortexm_commom.

Comment on lines +270 to +281
void gpio_set_for(gpio_t pin, int delay)
{
_port(pin)->BSRR = (1 << _pin_num(pin));
_delay(delay);
}

void gpio_clear_for(gpio_t pin, int delay)
{
_port(pin)->BSRR = (1 << (_pin_num(pin) + 16));
_delay(delay);
}

Copy link
Contributor

Choose a reason for hiding this comment

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

Maybe a better idea would be to allow for gpio_set() to be inlinable so everyone benefits from the reduced overhead.

Then you could have a generic gpio_set_for()/gpio_clear_for() wrapper.

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'm not that sure about this. If the GPIO API remains a periph-only API, that would surely be an option. (I'm however not sure if it would increase the ROM size for non-LTO builds in cases where the value of the pin parameter is not known at compile time.)

I do hope however that the GPIO API opens up for external GPIOs as well. @gschorcht is currently working on that. I would like to wait for that to happen before checking if implementing the GPIO API as static inline functions is generally feasible.

The submodule periph_gpio_abc extends the GPIO driver by Advanced Bitbanging
Capabilities (ABC). It provides means to control GPIOs with a precision of
0.15µs or better.
@stale
Copy link

stale bot commented Jun 7, 2020

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. If you want me to ignore this issue, please mark it with the "State: don't stale" label. Thank you for your contributions.

@stale stale bot added the State: stale State: The issue / PR has no activity for >185 days label Jun 7, 2020
@stale stale bot closed this Jul 8, 2020

void gpio_set_for(gpio_t pin, int delay)
{
_port(pin)->BSRR = (1 << _pin_num(pin));
Copy link
Contributor

@benpicco benpicco Jul 14, 2020

Choose a reason for hiding this comment

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

STM32 support bit-banding, so you can be even faster

#define BITBAND_SRAM_REF   0x20000000
#define BITBAND_SRAM_BASE  0x22000000
#define BITBAND_SRAM(a,b)  (*((volatile uint8_t *) ((BITBAND_SRAM_BASE + ((uintptr_t) (a)-BITBAND_SRAM_REF)*32 + (b*4)))))  /* Translate SRAM address to Bit-Band space */

#define BITBAND_PERI_REF   0x40000000
#define BITBAND_PERI_BASE  0x42000000
#define BITBAND_PERI(a,b)  (*((volatile uint8_t *) ((BITBAND_PERI_BASE + ((uintptr_t) (a)-BITBAND_PERI_REF)*32 + (b*4))))) /* Translate PERIPHERAL address  to Bit-Band space */

#define BIT_SET_HW(val, bit)    (BITBAND_PERI(&(val), (bit)) = 1)
#define BIT_DEL_HW(val, bit)    (BITBAND_PERI(&(val), (bit)) = 0)
#define BIT_CHK_HW(val, bit)    (BITBAND_PERI(&(val), (bit)))
Suggested change
_port(pin)->BSRR = (1 << _pin_num(pin));
BIT_SET_HW(_port(pin)->BSRR, _pin_num(pin));

Copy link
Contributor

Choose a reason for hiding this comment

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

Hm now I wonder if this is still faster with all the added math, it would sure be if all parameters were compile-time constant 🤔

@maribu maribu deleted the gpio_abc_stm32f3 branch January 21, 2023 21:41
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: drivers Area: Device drivers State: stale State: The issue / PR has no activity for >185 days State: waiting for other PR State: The PR requires another PR to be merged first 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