mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2024-12-29 04:50:03 +01:00
Merge pull request #14804 from bergzand/pr/sam0/gpio_iobus
sam0_common: Use Single-cycle I/O Port for GPIO when available
This commit is contained in:
commit
5715f5776b
@ -75,6 +75,8 @@ typedef uint32_t gpio_t;
|
||||
*/
|
||||
#ifdef CPU_FAM_SAML11
|
||||
#define GPIO_PIN(x, y) (((gpio_t)(&PORT_SEC->Group[x])) | y)
|
||||
#elif defined(PORT_IOBUS) /* Use IOBUS access when available */
|
||||
#define GPIO_PIN(x, y) (((gpio_t)(&PORT_IOBUS->Group[x])) | y)
|
||||
#else
|
||||
#define GPIO_PIN(x, y) (((gpio_t)(&PORT->Group[x])) | y)
|
||||
#endif
|
||||
|
@ -21,6 +21,19 @@
|
||||
* @author Kaspar Schleiser <kaspar@schleiser.de>
|
||||
* @author Hauke Petersen <hauke.petersen@fu-berlin.de>
|
||||
*
|
||||
* The GPIO implementation here support the PERIPH_GPIO_FAST_READ pseudomodule
|
||||
* on the cortex-m0/m23 based devices. This trades an increase in power
|
||||
* consumption for a decrease in GPIO pin read latency. Enable this in your
|
||||
* makefile with:
|
||||
*
|
||||
* ```
|
||||
* FEATURES_OPTIONAL += periph_gpio_fast_read
|
||||
* ```
|
||||
*
|
||||
* This switches the GPIO reads to use the Cortex-M0+ single-cycle I/O port
|
||||
* instead of the regular APB acces. The single-cycle I/O port is always used
|
||||
* for writes when it is available on the device.
|
||||
*
|
||||
* @}
|
||||
*/
|
||||
|
||||
@ -75,11 +88,29 @@ typedef enum {
|
||||
static gpio_isr_ctx_t gpio_config[NUMOF_IRQS];
|
||||
#endif /* MODULE_PERIPH_GPIO_IRQ */
|
||||
|
||||
static inline PortGroup *_port(gpio_t pin)
|
||||
/* The Cortex-m0 based ATSAM devices can use the Single-cycle I/O Port for GPIO.
|
||||
* When used, the gpio_t is mapped to the IOBUS area and must be mapped back to
|
||||
* the peripheral memory space for configuration access. When it is not
|
||||
* available, the _port_iobus() and _port() functions behave identical.
|
||||
*/
|
||||
static inline PortGroup *_port_iobus(gpio_t pin)
|
||||
{
|
||||
return (PortGroup *)(pin & ~(0x1f));
|
||||
}
|
||||
|
||||
static inline PortGroup *_port(gpio_t pin)
|
||||
{
|
||||
#ifdef PORT_IOBUS
|
||||
/* Shift the PortGroup address back from the IOBUS region to the peripheral
|
||||
* region
|
||||
*/
|
||||
return (PortGroup *)((uintptr_t)_port_iobus(pin) -
|
||||
(uintptr_t)PORT_IOBUS + (uintptr_t)PORT);
|
||||
#else
|
||||
return _port_iobus(pin);
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline int _pin_pos(gpio_t pin)
|
||||
{
|
||||
return (pin & 0x1f);
|
||||
@ -121,9 +152,15 @@ int gpio_init(gpio_t pin, gpio_mode_t mode)
|
||||
|
||||
/* set pin direction */
|
||||
if (mode & 0x2) {
|
||||
if (IS_ACTIVE(MODULE_PERIPH_GPIO_FAST_READ)) {
|
||||
port->CTRL.reg |= pin_mask;
|
||||
}
|
||||
port->DIRCLR.reg = pin_mask;
|
||||
}
|
||||
else {
|
||||
if (IS_ACTIVE(MODULE_PERIPH_GPIO_FAST_READ)) {
|
||||
port->CTRL.reg &= ~pin_mask;
|
||||
}
|
||||
port->DIRSET.reg = pin_mask;
|
||||
}
|
||||
|
||||
@ -143,9 +180,16 @@ int gpio_init(gpio_t pin, gpio_mode_t mode)
|
||||
|
||||
int gpio_read(gpio_t pin)
|
||||
{
|
||||
PortGroup *port = _port(pin);
|
||||
PortGroup *port;
|
||||
int mask = _pin_mask(pin);
|
||||
|
||||
if (IS_ACTIVE(MODULE_PERIPH_GPIO_FAST_READ)) {
|
||||
port = _port_iobus(pin);
|
||||
}
|
||||
else {
|
||||
port = _port(pin);
|
||||
}
|
||||
|
||||
if (port->DIR.reg & mask) {
|
||||
return (port->OUT.reg & mask) ? 1 : 0;
|
||||
}
|
||||
@ -156,25 +200,25 @@ int gpio_read(gpio_t pin)
|
||||
|
||||
void gpio_set(gpio_t pin)
|
||||
{
|
||||
_port(pin)->OUTSET.reg = _pin_mask(pin);
|
||||
_port_iobus(pin)->OUTSET.reg = _pin_mask(pin);
|
||||
}
|
||||
|
||||
void gpio_clear(gpio_t pin)
|
||||
{
|
||||
_port(pin)->OUTCLR.reg = _pin_mask(pin);
|
||||
_port_iobus(pin)->OUTCLR.reg = _pin_mask(pin);
|
||||
}
|
||||
|
||||
void gpio_toggle(gpio_t pin)
|
||||
{
|
||||
_port(pin)->OUTTGL.reg = _pin_mask(pin);
|
||||
_port_iobus(pin)->OUTTGL.reg = _pin_mask(pin);
|
||||
}
|
||||
|
||||
void gpio_write(gpio_t pin, int value)
|
||||
{
|
||||
if (value) {
|
||||
_port(pin)->OUTSET.reg = _pin_mask(pin);
|
||||
_port_iobus(pin)->OUTSET.reg = _pin_mask(pin);
|
||||
} else {
|
||||
_port(pin)->OUTCLR.reg = _pin_mask(pin);
|
||||
_port_iobus(pin)->OUTCLR.reg = _pin_mask(pin);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -10,6 +10,7 @@ config CPU_COMMON_SAMD21
|
||||
select CPU_COMMON_SAM0
|
||||
select CPU_CORE_CORTEX_M0PLUS
|
||||
select HAS_CPU_SAMD21
|
||||
select HAS_PERIPH_GPIO_FAST_READ
|
||||
select HAS_PUF_SRAM
|
||||
|
||||
config CPU_FAM_SAMD21
|
||||
|
@ -1,5 +1,6 @@
|
||||
CPU_CORE = cortex-m0plus
|
||||
|
||||
FEATURES_PROVIDED += puf_sram
|
||||
FEATURES_PROVIDED += periph_gpio_fast_read
|
||||
|
||||
-include $(RIOTCPU)/sam0_common/Makefile.features
|
||||
|
@ -10,6 +10,7 @@ config CPU_COMMON_SAML1X
|
||||
select CPU_COMMON_SAM0
|
||||
select CPU_CORE_CORTEX_M23
|
||||
select HAS_CPU_SAML1X
|
||||
select HAS_PERIPH_GPIO_FAST_READ
|
||||
select HAS_PERIPH_HWRNG
|
||||
|
||||
config CPU_FAM_SAML10
|
||||
|
@ -4,5 +4,6 @@ CPU_CORE = cortex-m23
|
||||
# FEATURES_PROVIDED += cortexm_mpu
|
||||
|
||||
FEATURES_PROVIDED += periph_hwrng
|
||||
FEATURES_PROVIDED += periph_gpio_fast_read
|
||||
|
||||
include $(RIOTCPU)/sam0_common/Makefile.features
|
||||
|
@ -11,6 +11,7 @@ config CPU_COMMON_SAML21
|
||||
select CPU_CORE_CORTEX_M0PLUS
|
||||
select HAS_BACKUP_RAM
|
||||
select HAS_CPU_SAML21
|
||||
select HAS_PERIPH_GPIO_FAST_READ
|
||||
|
||||
config CPU_FAM_SAML21
|
||||
bool
|
||||
|
@ -3,6 +3,8 @@ CPU_CORE = cortex-m0plus
|
||||
# The SAMR30 line of MCUs does not contain a TRNG
|
||||
CPU_MODELS_WITHOUT_HWRNG += samr30%
|
||||
|
||||
FEATURES_PROVIDED += periph_gpio_fast_read
|
||||
|
||||
# Low Power SRAM is *not* retained during Backup Sleep.
|
||||
# It therefore does not fulfill the requirements of the 'backup_ram' interface.
|
||||
# It can still be used in normal and standby mode, but code that relies on it
|
||||
|
@ -143,6 +143,13 @@ config HAS_PERIPH_GPIO_IRQ
|
||||
Indicates that the GPIO peripheral supports external interrupts is
|
||||
present.
|
||||
|
||||
config HAS_PERIPH_GPIO_FAST_READ
|
||||
bool
|
||||
help
|
||||
Indicates that the GPIO peripheral supports a mode in which pin read
|
||||
operations are faster, usually with a tradeoff against a different
|
||||
property.
|
||||
|
||||
config HAS_PERIPH_HWRNG
|
||||
bool
|
||||
help
|
||||
|
@ -2,6 +2,7 @@ include ../Makefile.tests_common
|
||||
|
||||
FEATURES_REQUIRED = periph_gpio
|
||||
FEATURES_OPTIONAL = periph_gpio_irq
|
||||
FEATURES_OPTIONAL += periph_gpio_fast_read
|
||||
|
||||
USEMODULE += shell
|
||||
USEMODULE += shell_commands
|
||||
|
Loading…
Reference in New Issue
Block a user