-
Notifications
You must be signed in to change notification settings - Fork 2k
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
drivers/gpio: changed periph driver interface #3095
Conversation
and by the way, the test application is no optimized at all, this should be done later if anyone feels the urge... |
Wouh. I see the motivation behind it, sure. But at the same time I'm wondering if we really "need" this. Anyway, improvement is never bad! But as this proposal requires a lot of work I'd suggest not to plan it for the release in June and just start to intensively work on it after all the network-stack excitement is over. I don't like to end in a situation where the |
PS: When writing my post I already had the potential changes for other peripheral drivers in mind |
Actually, the work for this PR is not so bad... Regarding the release, I would argue exactly in the different direction: This should definitely be in, as there are more and more new boards coming in and this PR gives them a good baseline. Also the part on the device drivers is not bad at all... |
I can imagine that me and @jfischer-phytec-iot might actually get to implement proper hardware CS support for the Kinetis SPI with this change, but I agree with @PeterKietzmann, this is going to be a lot of work and we need to ensure that we have a proper design for the new periph drivers. We also need to set a hard deadline for deleting the compat layer to make sure we don't get stuck with two similar APIs and lots of confused users. |
Just for clarification: I didn't want to say that the work is bad or that your approach displeases me. My scepticism is more about organisation, workload and manpower. Let's see if there appear some other opinions. But in the end I definitively won't NACK this PR ;-) |
*/ | ||
int gpio_init_in(gpio_t dev, gpio_pp_t pullup); | ||
int gpio_init_exti(gpio_t pin, gpio_pp_t pullup, gpio_flank_t flank, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
IMHO this name change is unrelated and with no improvement, but I don't care enough to see this as a showstopper.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
true, but see argumentation above.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
well, if there's no gpio_init_in
the chance of mixing up is smaller. (I actually never mixed that up).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When starting to touch so many things I'd also argue pro gpio_init_exti
. I think this semantic is used more often and prevents to be misread.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
but "exti" is MCU specific... Most cortex use exti as the name, some don't. I just wrote a gpio implementation for a board that has 5 GPIO ports with an ISR line to MCU per port, and an additional "exti" line. So the function name feels somehow wrong when not using it for "exti".
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The fact that most cortex platforms use this semantics was my pro-argument :-) . In the situation you described it I do agree with you that it feels wrong.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does gpio_init_isr
look less confusing to gpio_init_int
?
edit
Maybe gpio_init_callback
or _cb
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In this case I'd suggest to stay with the current name. ..._isr
brings the same problem like ..._exti
as you described above. .._callback
appears too specific to me.
I totally agree with Hauke, we need to get this in! This is already a +900 -2600 change, and it will get better as soon all platforms are integrated. Also, the use of all those #ifdef's in the implementations is horrible, we need to get rid of it before it get's more exposure. |
The "compat" workaround just wraps the completely useless enum defining |
@@ -0,0 +1,157 @@ | |||
/* |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Doesn't make gpio_compat.h more sense?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The idea was to use the same file to also include spi_t
, uart_t
and so on until they are optimized for a certain platform instead of introducing one file for each module...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fine with me.
@haukepetersen One thing I stumbled over when implementing a driver against this: Maybe we can make the defines in gpio.h optional, as in, |
After looking into the implementation a bit deeper I see the benefit (not to say "need") more and more. Still I don't like the situation that some drivers are implemented in many different ways. Afaik there are still implementations with really old peripheral drivers which don't fit the current API. With this proposal there will be more-or-less old implementations that will be wrapped and new implementations that will "totally fit" the new approach. This could lead to confusion. That's why I tend to skip this for the release and spend "much" work in an organized way afterwards. |
@PeterKietzmann I agree, let's postpone this to the next release after 2015.06 |
@gebart Really? there will be more implementations using all those #ifdefs popping up. Using the compat header, the changes to every platform are very small (basically only merging gpio_init_in+out). |
Hm, not sure I agree. The beauty is that the new interface fits the old one naturally. If an implementation decides to use 0..n for the gpio pin descriptors (as all of them had to with the old interface), it still fits in, perfectly. |
@kaspar030 I don't think we'll be able to review it in time: Showing 32 changed files with 978 additions and 2,649 deletions. The release date is set to Wednesday this week, two days from now, and this is quite a major overhaul. |
You know what I like best from deadlines? The sound when they pass by: swoooooooooooooooooooshh ... |
To be serious, that date was set by @OlegHahm months ago. As I understand the situation, we'll never release in two days. So if we aim for a release this month, with a feature freeze int the next 14 days, this should be reviewable. |
OK, I did not know that about the release date. I guess we should be able to finish this for release at the end of June. |
The xbee driver had trouble, as it was using the |
Travis is happy. ACK from my side. Let's merge before it get's stale. Hauke, wanna push the button? |
Yes! |
drivers/gpio: changed periph driver interface
Just to show appreciation: Big +1! |
This is a rewrite of the Kinetis GPIO driver which follows the refactored API in [1]. Pins are specified using the GPIO_PIN(PORT_x, y) macro, e.g. GPIO_PIN(PORT_E, 25) for the PTE25 pin. The interrupt pin handling is now implemented as a linked list, this is more memory efficient, but with a minor variation in interrupt latency depending on in what order the pins were initialized at runtime. Because the linked list entries are taken from a shared pool, there is also the possibility of running out of available configuration slots, define the preprocessor macro GPIO_INT_POOL_SIZE in periph_conf.h if you need more than 16 pins configured for interrupts in the same application. [1]: RIOT-OS#3095
This is a rewrite of the Kinetis GPIO driver which follows the refactored API in [1]. Pins are specified using the GPIO_PIN(PORT_x, y) macro, e.g. GPIO_PIN(PORT_E, 25) for the PTE25 pin. The interrupt pin handling is now implemented as a linked list, this is more memory efficient, but with a minor variation in interrupt latency depending on in what order the pins were initialized at runtime. Because the linked list entries are taken from a shared pool, there is also the possibility of running out of available configuration slots, define the preprocessor macro GPIO_INT_POOL_SIZE in periph_conf.h if you need more than 16 pins configured for interrupts in the same application. [1]: RIOT-OS#3095
This is a rewrite of the Kinetis GPIO driver which follows the refactored API in [1]. Pins are specified using the GPIO_PIN(PORT_x, y) macro, e.g. GPIO_PIN(PORT_E, 25) for the PTE25 pin. The interrupt pin handling is now implemented as a linked list, this is more memory efficient, but with a minor variation in interrupt latency depending on in what order the pins were initialized at runtime. Because the linked list entries are taken from a shared pool, there is also the possibility of running out of available configuration slots, define the preprocessor macro GPIO_INT_POOL_SIZE in periph_conf.h if you need more than 16 pins configured for interrupts in the same application. [1]: RIOT-OS#3095
This is a rewrite of the Kinetis GPIO driver which follows the refactored API in [1]. Pins are specified using the GPIO_PIN(PORT_x, y) macro, e.g. GPIO_PIN(PORT_E, 25) for the PTE25 pin. The interrupt pin handling is now implemented as a linked list, this is more memory efficient, but with a minor variation in interrupt latency depending on in what order the pins were initialized at runtime. Because the linked list entries are taken from a shared pool, there is also the possibility of running out of available configuration slots, define the preprocessor macro GPIO_INT_POOL_SIZE in periph_conf.h if you need more than 16 pins configured for interrupts in the same application. [1]: RIOT-OS#3095
This is a rewrite of the Kinetis GPIO driver which follows the refactored API in [1]. Pins are specified using the GPIO_PIN(PORT_x, y) macro, e.g. GPIO_PIN(PORT_E, 25) for the PTE25 pin. The interrupt pin handling is now implemented as a linked list, this is more memory efficient, but with a minor variation in interrupt latency depending on in what order the pins were initialized at runtime. Because the linked list entries are taken from a shared pool, there is also the possibility of running out of available configuration slots, define the preprocessor macro GPIO_INT_POOL_SIZE in periph_conf.h if you need more than 16 pins configured for interrupts in the same application. [1]: RIOT-OS#3095
This is a rewrite of the Kinetis GPIO driver which follows the refactored API in [1]. Pins are specified using the GPIO_PIN(PORT_x, y) macro, e.g. GPIO_PIN(PORT_E, 25) for the PTE25 pin. The interrupt pin handling is now implemented as a linked list, this is more memory efficient, but with a minor variation in interrupt latency depending on in what order the pins were initialized at runtime. Because the linked list entries are taken from a shared pool, there is also the possibility of running out of available configuration slots, define the preprocessor macro GPIO_INT_POOL_SIZE in periph_conf.h if you need more than 16 pins configured for interrupts in the same application. [1]: RIOT-OS#3095
This is a rewrite of the Kinetis GPIO driver which follows the refactored API in [1]. Pins are specified using the GPIO_PIN(PORT_x, y) macro, e.g. GPIO_PIN(PORT_E, 25) for the PTE25 pin. The interrupt pin handling is now implemented as a linked list, this is more memory efficient, but with a minor variation in interrupt latency depending on in what order the pins were initialized at runtime. Because the linked list entries are taken from a shared pool, there is also the possibility of running out of available configuration slots, define the preprocessor macro GPIO_INT_POOL_SIZE in periph_conf.h if you need more than 16 pins configured for interrupts in the same application. [1]: RIOT-OS#3095
After talking a lot with @kaspar030, we decided to give the peripheral driver a little overhaul to make them more efficient and portable. In this effort, the GPIO driver is the first I touched.
The main motivation behind this is to allow for more efficient implementation through more control on a platform to platform level. The most important difference is, that CPUs have now to define the peripheral device types (i.e.
gpio_t
,spi_t
, etc.). This allows platforms for example to use base register addresses as peripheral identifiers directly, making these very ugly (and huge) swith-case structures superfluous in many times.Another important change for the GPIO driver: Now are all pins accessible and it is not needed anymore to define them in the
periph_conf.h
.Summarized the changes tot he GPIO peripheral driver interface:
gpio_t
type must be defined by the CPUgpio_init_out()
andgpio_init_in()
are merged into a single functiongpio_init_int()
is renamed togpio_init_exti()
(I regularly readin
instead ofint
-> this won't happy with this change...)gpio_init_mux()
for internal use only was added. This will make other peripheral drivers easier to implement/make their code easier to readTo make the migration to this change interface easier, I added a compatibility header, that still allows for the known
gpio_t
type. To make all existing code work with the new interface, these steps have to be done:gpio_init_int()
togpio_init_exti()
gpio_init_out
andgpio_init_int()
periph_cpu.h
toCPU/include/
and add `#include "periph/compat.h" to this fileThe plan is to agree on the interface and make all CPUs work with the new interface through the compatiblity layer as first step. As second step we would need to improve all GPIO implementations, but this can then be done step-by-step.
Contents of this PR so far:
drivers/include/periph/gpio.h
)drivers/include/periph/compat.h
)samd21
,nrf51822
, and thestm32f4
iot-lab_M3
(stm32f1
) works already through the compat headerAs you can see, the code is much much much more easy to read and way smaller (~1kB on the
stm32f4
) by offering more functionality...I will adapt all effected CPUs once the new Interface is ACKed (and help with this is very welcome...).