saul/gpio: Low footprint handling of active-low signals + state initialization#7586
saul/gpio: Low footprint handling of active-low signals + state initialization#7586miri64 merged 5 commits intoRIOT-OS:masterfrom
Conversation
|
Setting With |
| .pin = LED0_PIN, | ||
| .mode = GPIO_OUT | ||
| .mode = GPIO_OUT, | ||
| .flags = 0, |
There was a problem hiding this comment.
(here and below) when using designated initializers, empty fields don't have to be specified. So IMO the .flags = 0 should go.
There was a problem hiding this comment.
That what I was thinking too, but when talking with @haukepetersen he thought they may be required for some architecture.
I will remove them all.
| .name = "LED", | ||
| .pin = LED0_PIN, | ||
| .mode = GPIO_OUT | ||
| .mode = GPIO_OUT, |
There was a problem hiding this comment.
Does this mode field mean that when using saul, a GPIO pin config (in/out, pullups) ist hard-coded at compile time?
There was a problem hiding this comment.
I think so, then at runtime in auto_init_gpio.c the mode field is used to select in or out saul driver and is given to gpio_init.
fa7d0a7 to
15fd49d
Compare
drivers/saul/gpio_saul.c
Outdated
| gpio_t pin = *((const gpio_t *)dev); | ||
| res->val[0] = (gpio_read(pin)) ? 1 : 0; | ||
| const saul_gpio_params_t *p = (const saul_gpio_params_t *)dev; | ||
| int inverted = (p->flags | SAUL_GPIO_INVERTED); |
There was a problem hiding this comment.
should be int inverted = (p->flags & SAUL_GPIO_INVERTED);, or not?
There was a problem hiding this comment.
I do this mistake all the time.
drivers/saul/gpio_saul.c
Outdated
| gpio_t pin = *((const gpio_t *)dev); | ||
| gpio_write(pin, state->val[0]); | ||
| const saul_gpio_params_t *p = (const saul_gpio_params_t *)dev; | ||
| int inverted = (p->flags | SAUL_GPIO_INVERTED); |
| const saul_gpio_params_t *p = (const saul_gpio_params_t *)dev; | ||
| int inverted = (p->flags | SAUL_GPIO_INVERTED); | ||
|
|
||
| res->val[0] = (gpio_read(p->pin)) ? !inverted : inverted; |
There was a problem hiding this comment.
I think you could use XOR here and below, i.e.,
res->val[0] = gpio_read(p->pin) ^ inverted;
There was a problem hiding this comment.
I am doing an XOR, but not a bitwise xor.
I just checked and no it cannot be replaced, gpio_read is only expected to return a positive value on HIGH. https://github.com/RIOT-OS/RIOT/blob/2017.07/drivers/include/periph/gpio.h#L189
When looking at actual implementation, the first I found in alpha order is https://github.com/RIOT-OS/RIOT/blob/2017.07/cpu/atmega_common/periph/gpio.c#L209 which in fact does not return 1.
The previous code was also doing this (gpio_read(pin) ? 1 : 0)
The thing I have here, is that I expect SAUL_GPIO_INVERTED to be equal to 1. Maybe it would require a static assert for this.
|
@haukepetersen I thought there already was some similar attempt (by you) in the past to tackle this invert stuff, so could be a duplicate here? |
15fd49d to
f0cd167
Compare
As stated in the initial comment "This could replace #7151, #7148 ", so I don't think it's a duplicate but rather a better proposal. The #7151 version increases the firmware size by 100 bytes, here it's only 20 with other improvements included: gpio being cleared at auto_init. I vote for this one. |
aabadie
left a comment
There was a problem hiding this comment.
A few minor comments. Otherwise the changes here do what they are supposed to correctly (tested on samr21-xpro and nucleo-l432).
drivers/include/saul/periph.h
Outdated
| #ifdef MODULE_SAUL_GPIO | ||
| typedef enum { | ||
| SAUL_GPIO_INVERTED = 1 << 0, /**< pin is used as inverted */ | ||
| SAUL_GPIO_CLEAR = 1 << 1, /**< set pin inactive after initialization */ |
There was a problem hiding this comment.
Maybe rename to SAUL_GPIO_INIT_CLEAR to be more explicit. Same with SAUL_GPIO_INIT_SET below
| .pin = LED0_PIN, | ||
| .mode = GPIO_OUT | ||
| .mode = GPIO_OUT, | ||
| .flags = SAUL_GPIO_INVERTED, |
There was a problem hiding this comment.
IIUC the logic, you should add SAUL_GPIO_CLEAR (or SAUL_GPIO_INIT_CLEAR) to ensure the pin initialized cleared ? Otherwise it's set after initialization (default GPIO behavior on this board).
There was a problem hiding this comment.
I think changing the initial value belongs to a different commit. So I prefer not include it in this PR.
|
I can split this PR in three if some points need to be discussed specifically. Because there really are 3 parts to it:
I will wait for @haukepetersen before changing. |
haukepetersen
left a comment
There was a problem hiding this comment.
Two minor comments, else this looks good to me.
drivers/include/saul/periph.h
Outdated
| const char *name; /**< name of the device connected to this pin */ | ||
| gpio_t pin; /**< GPIO pin to initialize and expose */ | ||
| gpio_mode_t mode; /**< pin mode to use */ | ||
| const char *name; /**< name of the device connected to this pin */ |
There was a problem hiding this comment.
here and below: please align comment to 4 spaces
drivers/include/saul/periph.h
Outdated
| typedef enum { | ||
| SAUL_GPIO_INVERTED = 1 << 0, /**< pin is used as inverted */ | ||
| SAUL_GPIO_INIT_CLEAR = 1 << 1, /**< set pin inactive after initialization */ | ||
| SAUL_GPIO_INIT_SET = 1 << 2, /**< set pin active after initialization */ |
There was a problem hiding this comment.
here and in other places of this PR: I would tend to remove the comma after the last element
There was a problem hiding this comment.
Forget about it. As we don't use C89 there is no reason, so keep it as is.
haukepetersen
left a comment
There was a problem hiding this comment.
ACK, please squash
This provides the whole structure to read and write.
This makes LED go off when set to 0 and button reads 1 when pressed.
|
Rebased and squashed |
Was addressed
This is a low footprint implementation for SAUL active-low and state init.
The basic idea, is to pass
saul_gpio_params_tstructure toread/writeinstead of onlypin(which already saves code), and add a singleflagsentry in it.This removes the need to duplicate drivers and only adds one enum entry.
I changed the
samr21-xproto invert led and button.My footprint tests where done with
examples/saulthesamr21-xprosamr21-xproiotlab-m3All steps are done in different commit so I could only put some part of it.
I did not put initial state setting in the output only mode for readability, but I could (it is harmless by default). Or put a DEVELHELP message when using it for an input.
This could replace #7151, #7148