From 7fcd8160f78cf3158ce71a589dc6c2cdf2b3a852 Mon Sep 17 00:00:00 2001 From: Gunar Schorcht Date: Fri, 17 Jul 2020 16:54:55 +0200 Subject: [PATCH] cpu/atmega*: changes for new GPIO API --- cpu/atmega1281/include/periph_cpu.h | 1 + cpu/atmega1284p/include/periph_cpu.h | 8 +- cpu/atmega128rfa1/include/periph_cpu.h | 11 +- cpu/atmega2560/include/periph_cpu.h | 23 ++-- cpu/atmega256rfr2/include/periph_cpu.h | 11 +- cpu/atmega328p/include/periph_cpu.h | 8 +- cpu/atmega32u4/include/periph_cpu.h | 3 +- cpu/atmega_common/Kconfig | 1 + cpu/atmega_common/Makefile.dep | 3 + cpu/atmega_common/Makefile.features | 2 +- cpu/atmega_common/include/atmega_gpio.h | 50 +++---- cpu/atmega_common/include/gpio_arch.h | 123 ++++++++++++++++++ cpu/atmega_common/include/periph_cpu_common.h | 41 +----- cpu/atmega_common/periph/gpio.c | 88 ++++++------- cpu/atmega_common/periph/pwm.c | 22 ++-- cpu/atmega_common/periph/spi.c | 4 +- drivers/ws281x/atmega.c | 8 +- 17 files changed, 245 insertions(+), 162 deletions(-) create mode 100644 cpu/atmega_common/include/gpio_arch.h diff --git a/cpu/atmega1281/include/periph_cpu.h b/cpu/atmega1281/include/periph_cpu.h index 52ff42c91ba92..01a4f6c083823 100644 --- a/cpu/atmega1281/include/periph_cpu.h +++ b/cpu/atmega1281/include/periph_cpu.h @@ -40,6 +40,7 @@ enum { PORT_E = 4, /**< port E */ PORT_F = 5, /**< port F */ PORT_G = 6, /**< port G */ + GPIO_EXP_PORT = 7 /**< first GPIO expander port */ }; /** diff --git a/cpu/atmega1284p/include/periph_cpu.h b/cpu/atmega1284p/include/periph_cpu.h index 53590eadb059a..64d89c6855a92 100644 --- a/cpu/atmega1284p/include/periph_cpu.h +++ b/cpu/atmega1284p/include/periph_cpu.h @@ -29,11 +29,6 @@ extern "C" { #endif -/** - * @brief Define a CPU specific GPIO pin generator macro - */ -#define GPIO_PIN(x, y) ((x << 4) | y) - /** * @brief Available ports on the ATmega1284p family */ @@ -41,7 +36,8 @@ enum { PORT_A = 0, /**< port A */ PORT_B = 1, /**< port B */ PORT_C = 2, /**< port C */ - PORT_D = 3 /**< port D */ + PORT_D = 3, /**< port D */ + GPIO_EXP_PORT = 4 /**< first GPIO expander port */ }; /** diff --git a/cpu/atmega128rfa1/include/periph_cpu.h b/cpu/atmega128rfa1/include/periph_cpu.h index eeb80e4c7caf0..45f9c612ec458 100644 --- a/cpu/atmega128rfa1/include/periph_cpu.h +++ b/cpu/atmega128rfa1/include/periph_cpu.h @@ -32,11 +32,12 @@ extern "C" { * @{ */ enum { - PORT_B = 1, /**< port B */ - PORT_D = 3, /**< port D */ - PORT_E = 4, /**< port E */ - PORT_F = 5, /**< port F */ - PORT_G = 6, /**< port G */ + PORT_B = 1, /**< port B */ + PORT_D = 3, /**< port D */ + PORT_E = 4, /**< port E */ + PORT_F = 5, /**< port F */ + PORT_G = 6, /**< port G */ + GPIO_EXP_PORT = 7 /**< first GPIO expander port */ }; /** @} */ diff --git a/cpu/atmega2560/include/periph_cpu.h b/cpu/atmega2560/include/periph_cpu.h index 00cd85dc21cac..042e985f722ef 100644 --- a/cpu/atmega2560/include/periph_cpu.h +++ b/cpu/atmega2560/include/periph_cpu.h @@ -31,17 +31,18 @@ extern "C" { * @brief Available ports on the ATmega2560 family */ enum { - PORT_A = 0, /**< port A */ - PORT_B = 1, /**< port B */ - PORT_C = 2, /**< port C */ - PORT_D = 3, /**< port D */ - PORT_E = 4, /**< port E */ - PORT_F = 5, /**< port F */ - PORT_G = 6, /**< port G */ - PORT_H = 7, /**< port H */ - PORT_J = 8, /**< port J */ - PORT_K = 9, /**< port K */ - PORT_L = 10 /**< port L */ + PORT_A = 0, /**< port A */ + PORT_B = 1, /**< port B */ + PORT_C = 2, /**< port C */ + PORT_D = 3, /**< port D */ + PORT_E = 4, /**< port E */ + PORT_F = 5, /**< port F */ + PORT_G = 6, /**< port G */ + PORT_H = 7, /**< port H */ + PORT_J = 8, /**< port J */ + PORT_K = 9, /**< port K */ + PORT_L = 10, /**< port L */ + GPIO_EXP_PORT = 11 /**< first GPIO expander port */ }; /** diff --git a/cpu/atmega256rfr2/include/periph_cpu.h b/cpu/atmega256rfr2/include/periph_cpu.h index d2ffd79cd2802..d2794f5d53c79 100644 --- a/cpu/atmega256rfr2/include/periph_cpu.h +++ b/cpu/atmega256rfr2/include/periph_cpu.h @@ -32,11 +32,12 @@ extern "C" { * @{ */ enum { - PORT_B = 1, /**< port B */ - PORT_D = 3, /**< port D */ - PORT_E = 4, /**< port E */ - PORT_F = 5, /**< port F */ - PORT_G = 6, /**< port G */ + PORT_B = 1, /**< port B */ + PORT_D = 3, /**< port D */ + PORT_E = 4, /**< port E */ + PORT_F = 5, /**< port F */ + PORT_G = 6, /**< port G */ + GPIO_EXP_PORT = 7 /**< first GPIO expander port */ }; /** @} */ diff --git a/cpu/atmega328p/include/periph_cpu.h b/cpu/atmega328p/include/periph_cpu.h index 9b8a7c9d5fb0d..feba731979624 100644 --- a/cpu/atmega328p/include/periph_cpu.h +++ b/cpu/atmega328p/include/periph_cpu.h @@ -27,18 +27,14 @@ extern "C" { #endif -/** - * @brief Define a CPU specific GPIO pin generator macro - */ -#define GPIO_PIN(x, y) ((x << 4) | y) - /** * @brief Available ports on the ATmega328p family */ enum { PORT_B = 1, /**< port B */ PORT_C = 2, /**< port C */ - PORT_D = 3 /**< port D */ + PORT_D = 3, /**< port D */ + GPIO_EXP_PORT = 4 /**< first GPIO expander port */ }; /** diff --git a/cpu/atmega32u4/include/periph_cpu.h b/cpu/atmega32u4/include/periph_cpu.h index 6a6bf86b94322..e36bbfe669411 100644 --- a/cpu/atmega32u4/include/periph_cpu.h +++ b/cpu/atmega32u4/include/periph_cpu.h @@ -34,7 +34,8 @@ enum { PORT_C = 2, /**< port C */ PORT_D = 3, /**< port D */ PORT_E = 4, /**< port E */ - PORT_F = 5 /**< port F */ + PORT_F = 5, /**< port F */ + GPIO_EXP_PORT = 6 /**< first GPIO expander port */ }; /** diff --git a/cpu/atmega_common/Kconfig b/cpu/atmega_common/Kconfig index 386916f5bdf19..86fa75463dee1 100644 --- a/cpu/atmega_common/Kconfig +++ b/cpu/atmega_common/Kconfig @@ -20,6 +20,7 @@ config CPU_COMMON_ATMEGA select HAS_PERIPH_CPUID select HAS_PERIPH_EEPROM select HAS_PERIPH_GPIO + select HAS_PERIPH_GPIO_EXP select HAS_PERIPH_GPIO_IRQ select HAS_PERIPH_PM select HAS_PERIPH_TIMER_PERIODIC diff --git a/cpu/atmega_common/Makefile.dep b/cpu/atmega_common/Makefile.dep index 33fa82c5cfa50..e4aefb34add99 100644 --- a/cpu/atmega_common/Makefile.dep +++ b/cpu/atmega_common/Makefile.dep @@ -7,6 +7,9 @@ USEMODULE += atmega_common # peripheral drivers are linked into the final binary USEMODULE += atmega_common_periph +# 8 bit GPIO pin mask required +USEMODULE += gpio_mask_8bit + # the atmel port uses stdio_uart USEMODULE += stdio_uart diff --git a/cpu/atmega_common/Makefile.features b/cpu/atmega_common/Makefile.features index eb49bcd72fb5e..e8d0fce6b7495 100644 --- a/cpu/atmega_common/Makefile.features +++ b/cpu/atmega_common/Makefile.features @@ -3,7 +3,7 @@ FEATURES_PROVIDED += arch_avr8 FEATURES_PROVIDED += atmega_pcint0 FEATURES_PROVIDED += periph_cpuid FEATURES_PROVIDED += periph_eeprom -FEATURES_PROVIDED += periph_gpio periph_gpio_irq +FEATURES_PROVIDED += periph_gpio periph_gpio_irq periph_gpio_exp FEATURES_PROVIDED += periph_pm FEATURES_PROVIDED += periph_timer_periodic FEATURES_PROVIDED += periph_wdt diff --git a/cpu/atmega_common/include/atmega_gpio.h b/cpu/atmega_common/include/atmega_gpio.h index f4befd77192a6..771b0bf94f3b1 100644 --- a/cpu/atmega_common/include/atmega_gpio.h +++ b/cpu/atmega_common/include/atmega_gpio.h @@ -43,55 +43,55 @@ extern "C" { #define ATMEGA_GPIO_OFFSET_PIN_PORT (0x02) #define ATMEGA_GPIO_OFFSET_PIN_PIN (0x03) + /** * @brief Extract the pin number of the given pin */ -static inline uint8_t atmega_pin_num(gpio_t pin) +static inline uint8_t atmega_pin_num(gpio_pin_t pin) { - return (pin & 0x0f); + return (pin & 0x07); } /** - * @brief Extract the port number of the given pin + * @brief Generate the PORTx address of the give port. */ -static inline uint8_t atmega_port_num(gpio_t pin) +static inline gpio_reg_t atmega_port_addr(gpio_port_t port) { - return (pin >> 4) & 0x0f; + return port.reg; } /** - * @brief Generate the PORTx address of the give pin. + * @brief Generate the DDRx address of the given port. */ -static inline uint16_t atmega_port_addr(gpio_t pin) +static inline gpio_reg_t atmega_ddr_addr(gpio_port_t port) { - uint8_t port_num = atmega_port_num(pin); - uint16_t port_addr = port_num * ATMEGA_GPIO_OFFSET_PIN_PIN; - - port_addr += ATMEGA_GPIO_BASE_PORT_A; - port_addr += ATMEGA_GPIO_OFFSET_PIN_PORT; - -#if defined (PORTG) - if (port_num > PORT_G) { - port_addr += ATMEGA_GPIO_OFFSET_PORT_H; - } -#endif - return port_addr; + return (atmega_port_addr(port) - 0x01); } /** - * @brief Generate the DDRx address of the given pin + * @brief Generate the PINx address of the given port. */ -static inline uint16_t atmega_ddr_addr(gpio_t pin) +static inline gpio_reg_t atmega_pin_addr(gpio_port_t port) { - return (atmega_port_addr(pin) - 0x01); + return (atmega_port_addr(port) - 0x02); } /** - * @brief Generate the PINx address of the given pin. + * @brief Generate the port number of the given port */ -static inline uint16_t atmega_pin_addr(gpio_t pin) +static inline uint8_t atmega_port_num(gpio_port_t port) { - return (atmega_port_addr(pin) - 0x02); + gpio_reg_t port_addr = atmega_port_addr(port); + +#ifdef PORTG + if (port_addr > ATMEGA_GPIO_OFFSET_PORT_H) { + port_addr -= ATMEGA_GPIO_OFFSET_PORT_H; + } +#endif + port_addr -= ATMEGA_GPIO_OFFSET_PIN_PORT; + port_addr -= ATMEGA_GPIO_BASE_PORT_A; + + return port_addr / ATMEGA_GPIO_OFFSET_PIN_PIN; } #ifdef __cplusplus diff --git a/cpu/atmega_common/include/gpio_arch.h b/cpu/atmega_common/include/gpio_arch.h new file mode 100644 index 0000000000000..7b3cd5bd40479 --- /dev/null +++ b/cpu/atmega_common/include/gpio_arch.h @@ -0,0 +1,123 @@ +/* + * Copyright (C) 2015 HAW Hamburg + * 2016 Freie Universität Berlin + * 2016 INRIA + * + * This file is subject to the terms and conditions of the GNU Lesser + * General Public License v2.1. See the file LICENSE in the top level + * directory for more details. + */ + +/** + * @ingroup cpu_atmega_common + * @{ + * + * @file + * @brief CPU specific definitions for GPIOs + * + * @author René Herthel + * @author Hauke Petersen + * @author Francisco Acosta + */ + +#ifndef GPIO_ARCH_H +#define GPIO_ARCH_H + +#include "cpu.h" + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef DOXYGEN +/** + * @brief Defines for port register addresses + * @{ + */ +#define GPIO_PORT_H (7) +#define GPIO_BASE_PORT_A (0x20) +#define GPIO_OFFSET_PORT_H (0xCB) +#define GPIO_OFFSET_PIN_PORT (0x02) +#define GPIO_OFFSET_PIN_PIN (0x03) +/** @} */ + +/** + * @brief Define a mask for GPIO port register addresses + * + * In the AVR architecture, the register addresses are between 0x000 and 0x1ff. + * Pointers to data in SRAM start at 0x200. + */ +#define GPIO_CPU_PORT_MASK (0xfe00) + +/** + * @brief Base register address for MCU GPIO ports + */ +#define GPIO_CPU_PORT_BASE (0x0000) + +/** + * @brief Convert a MCU port number into its register address + */ +#ifndef PORTH +#define GPIO_CPU_PORT(x) \ + ((gpio_reg_t)((x * GPIO_OFFSET_PIN_PIN) + GPIO_BASE_PORT_A \ + + GPIO_OFFSET_PIN_PORT)) +#else +#define GPIO_CPU_PORT(x) \ + ((gpio_reg_t)((x < GPIO_PORT_H) ? ((x * GPIO_OFFSET_PIN_PIN) + \ + GPIO_BASE_PORT_A + \ + GPIO_OFFSET_PIN_PORT) \ + : ((x * GPIO_OFFSET_PIN_PIN) + \ + GPIO_BASE_PORT_A + \ + GPIO_OFFSET_PIN_PORT + \ + GPIO_OFFSET_PORT_H))) +#endif + +/** + * @brief Convert a MCU port register address into its port number + */ +#ifndef PORTH +#define GPIO_CPU_PORT_NUM(x) \ + ((gpio_pin_t)((x - GPIO_OFFSET_PIN_PORT - GPIO_BASE_PORT_A) / GPIO_OFFSET_PIN_PIN)) +#else +#define GPIO_CPU_PORT_NUM(x) \ + ((gpio_pin_t)((x > GPIO_OFFSET_PORT_H) ? ((x - GPIO_OFFSET_PORT_H \ + - GPIO_OFFSET_PIN_PORT \ + - GPIO_BASE_PORT_A) / GPIO_OFFSET_PIN_PIN) \ + : ((x - GPIO_OFFSET_PIN_PORT \ + - GPIO_BASE_PORT_A) / GPIO_OFFSET_PIN_PIN))) +#endif + +/** + * @brief Override register address type for GPIO ports of the MCU + * + * The size of this type must match the size of a pointer to distinguish + * between MCU GPIO register addresses and pointers on GPIO devices. + */ +#define HAVE_GPIO_REG_T +typedef uint16_t gpio_reg_t; + +/** + * @brief Override the GPIO flanks + * + * This device has an additional mode in which the interrupt is triggered + * when the pin is low. + * + * Enumeration order is important, do not modify. + * @{ + */ +#define HAVE_GPIO_FLANK_T +typedef enum { + GPIO_LOW, /**< emit interrupt when pin low */ + GPIO_BOTH, /**< emit interrupt on both flanks */ + GPIO_FALLING, /**< emit interrupt on falling flank */ + GPIO_RISING, /**< emit interrupt on rising flank */ +} gpio_flank_t; +/** @} */ +#endif /* ndef DOXYGEN */ + +#ifdef __cplusplus +} +#endif + +#endif /* GPIO_ARCH_H */ +/** @} */ diff --git a/cpu/atmega_common/include/periph_cpu_common.h b/cpu/atmega_common/include/periph_cpu_common.h index 4f0beb5ab4d83..f3e4814795788 100644 --- a/cpu/atmega_common/include/periph_cpu_common.h +++ b/cpu/atmega_common/include/periph_cpu_common.h @@ -24,6 +24,7 @@ #define PERIPH_CPU_COMMON_H #include "cpu.h" +#include "periph/gpio.h" #ifdef __cplusplus extern "C" { @@ -36,46 +37,6 @@ extern "C" { #define CPUID_LEN (4U) /** @} */ -#ifndef DOXYGEN -/** - * @brief Overwrite the default gpio_t type definition - * @{ - */ -#define HAVE_GPIO_T -typedef uint8_t gpio_t; -/** @} */ -#endif - -/** - * @brief Definition of a fitting UNDEF value - */ -#define GPIO_UNDEF (0xff) - -/** - * @brief Define a CPU specific GPIO pin generator macro - */ -#define GPIO_PIN(x, y) ((x << 4) | y) - -#ifndef DOXYGEN -/** - * @brief Override the GPIO flanks - * - * This device has an additional mode in which the interrupt is triggered - * when the pin is low. - * - * Enumeration order is important, do not modify. - * @{ - */ -#define HAVE_GPIO_FLANK_T -typedef enum { - GPIO_LOW, /**< emit interrupt when pin low */ - GPIO_BOTH, /**< emit interrupt on both flanks */ - GPIO_FALLING, /**< emit interrupt on falling flank */ - GPIO_RISING, /**< emit interrupt on rising flank */ -} gpio_flank_t; -/** @} */ -#endif /* ndef DOXYGEN */ - /** * @brief Use some common SPI functions * @{ diff --git a/cpu/atmega_common/periph/gpio.c b/cpu/atmega_common/periph/gpio.c index ba7b462004515..976390586c03d 100644 --- a/cpu/atmega_common/periph/gpio.c +++ b/cpu/atmega_common/periph/gpio.c @@ -150,21 +150,21 @@ static gpio_isr_ctx_pcint_t pcint_config[8 * PCINT_NUM_BANKS]; #endif /* MODULE_PERIPH_GPIO_IRQ */ -int gpio_init(gpio_t pin, gpio_mode_t mode) +int gpio_cpu_init(gpio_port_t port, gpio_pin_t pin, gpio_mode_t mode) { uint8_t pin_mask = (1 << atmega_pin_num(pin)); switch (mode) { case GPIO_OUT: - _SFR_MEM8(atmega_ddr_addr(pin)) |= pin_mask; + _SFR_MEM8(atmega_ddr_addr(port)) |= pin_mask; break; case GPIO_IN: - _SFR_MEM8(atmega_ddr_addr(pin)) &= ~pin_mask; - _SFR_MEM8(atmega_port_addr(pin)) &= ~pin_mask; + _SFR_MEM8(atmega_ddr_addr(port)) &= ~pin_mask; + _SFR_MEM8(atmega_port_addr(port)) &= ~pin_mask; break; case GPIO_IN_PU: - _SFR_MEM8(atmega_ddr_addr(pin)) &= ~pin_mask; - _SFR_MEM8(atmega_port_addr(pin)) |= pin_mask; + _SFR_MEM8(atmega_ddr_addr(port)) &= ~pin_mask; + _SFR_MEM8(atmega_port_addr(port)) |= pin_mask; break; default: return -1; @@ -173,50 +173,44 @@ int gpio_init(gpio_t pin, gpio_mode_t mode) return 0; } -int gpio_read(gpio_t pin) +gpio_mask_t gpio_cpu_read(gpio_port_t port) { - return (_SFR_MEM8(atmega_pin_addr(pin)) & (1 << atmega_pin_num(pin))); + return _SFR_MEM8(atmega_pin_addr(port)); } -void gpio_set(gpio_t pin) +void gpio_cpu_set(gpio_port_t port, gpio_mask_t pins) { - _SFR_MEM8(atmega_port_addr(pin)) |= (1 << atmega_pin_num(pin)); + _SFR_MEM8(atmega_port_addr(port)) |= pins; } -void gpio_clear(gpio_t pin) +void gpio_cpu_clear(gpio_port_t port, gpio_mask_t pins) { - _SFR_MEM8(atmega_port_addr(pin)) &= ~(1 << atmega_pin_num(pin)); + _SFR_MEM8(atmega_port_addr(port)) &= ~pins; } -void gpio_toggle(gpio_t pin) +void gpio_cpu_toggle(gpio_port_t port, gpio_mask_t pins) { - if (gpio_read(pin)) { - gpio_clear(pin); - } - else { - gpio_set(pin); - } + /* + * According to the data sheet, writing a one to PIN toggles the bit in + * the PORT register, independent on the value of DDR. + */ + _SFR_MEM8(atmega_pin_addr(port)) = _SFR_MEM8(atmega_ddr_addr(port)) & pins; } -void gpio_write(gpio_t pin, int value) +void gpio_cpu_write(gpio_port_t port, gpio_mask_t values) { - if (value) { - gpio_set(pin); - } - else { - gpio_clear(pin); - } + _SFR_MEM8(atmega_port_addr(port)) &= _SFR_MEM8(atmega_ddr_addr(port)) & values; } #ifdef MODULE_PERIPH_GPIO_IRQ -static inline int8_t _int_num(gpio_t pin) +static inline int8_t _int_num(gpio_port_t port, gpio_pin_t pin) { uint8_t num; const gpio_t ext_ints[GPIO_EXT_INT_NUMOF] = CPU_ATMEGA_EXT_INTS; /* find pin in ext_ints array to get the interrupt number */ for (num = 0; num < GPIO_EXT_INT_NUMOF; num++) { - if (pin == ext_ints[num]) { + if (port.reg == ext_ints[num].port.reg && pin == ext_ints[num].pin) { return num; } } @@ -225,15 +219,16 @@ static inline int8_t _int_num(gpio_t pin) } #ifdef ENABLE_PCINT -static inline int pcint_init_int(gpio_t pin, gpio_mode_t mode, - gpio_flank_t flank, +static inline int pcint_init_int(gpio_port_t port, gpio_pin_t pin, + gpio_mode_t mode, gpio_flank_t flank, gpio_cb_t cb, void *arg) { int8_t offset = -1; uint8_t pin_num = atmega_pin_num(pin); for (unsigned i = 0; i < ARRAY_SIZE(pcint_mapping); i++) { - if (pin != GPIO_UNDEF && pin == pcint_mapping[i]) { + if (port.dev != NULL && pin != GPIO_PIN_UNDEF && + port.dev == pcint_mapping[i].port.dev && pin == pcint_mapping[i].pin) { offset = i; break; } @@ -255,7 +250,7 @@ static inline int pcint_init_int(gpio_t pin, gpio_mode_t mode, pcint_config[offset].cb = cb; /* init gpio */ - gpio_init(pin, mode); + gpio_cpu_init(port, pin, mode); /* configure pcint */ cli(); switch (bank) { @@ -288,7 +283,7 @@ static inline int pcint_init_int(gpio_t pin, gpio_mode_t mode, break; } /* As ports are mixed in a bank (e.g. PCINT0), we can only save a single bit here! */ - uint8_t port_value = (_SFR_MEM8(atmega_pin_addr( pin ))); + uint8_t port_value = (_SFR_MEM8(atmega_pin_addr( port ))); uint8_t pin_mask = (1 << pin_num); uint8_t pin_value = ((port_value & pin_mask) != 0); if (pin_value) { @@ -302,10 +297,10 @@ static inline int pcint_init_int(gpio_t pin, gpio_mode_t mode, } #endif /* ENABLE_PCINT */ -int gpio_init_int(gpio_t pin, gpio_mode_t mode, gpio_flank_t flank, - gpio_cb_t cb, void *arg) +int gpio_cpu_init_int(gpio_port_t port, gpio_pin_t pin, gpio_mode_t mode, + gpio_flank_t flank, gpio_cb_t cb, void *arg) { - int8_t int_num = _int_num(pin); + int8_t int_num = _int_num(port, pin); /* mode not supported */ if ((mode != GPIO_IN) && (mode != GPIO_IN_PU)) { @@ -316,7 +311,7 @@ int gpio_init_int(gpio_t pin, gpio_mode_t mode, gpio_flank_t flank, if (int_num < 0) { #ifdef ENABLE_PCINT /* If pin change interrupts are enabled, enable mask and interrupt */ - return pcint_init_int(pin, mode, flank, cb, arg); + return pcint_init_int(port, pin, mode, flank, cb, arg); #else return -1; #endif /* ENABLE_PCINT */ @@ -327,7 +322,7 @@ int gpio_init_int(gpio_t pin, gpio_mode_t mode, gpio_flank_t flank, return -1; } - gpio_init(pin, mode); + gpio_cpu_init(port, pin, mode); /* clear global interrupt flag */ cli(); @@ -358,15 +353,18 @@ int gpio_init_int(gpio_t pin, gpio_mode_t mode, gpio_flank_t flank, return 0; } -void gpio_irq_enable(gpio_t pin) +void gpio_cpu_irq_enable(gpio_port_t port, gpio_pin_t pin) { - EIFR |= (1 << _int_num(pin)); - EIMSK |= (1 << _int_num(pin)); + (void)port; + int8_t int_num = _int_num(port, pin); + EIFR |= (1 << int_num); + EIMSK |= (1 << int_num); } -void gpio_irq_disable(gpio_t pin) +void gpio_cpu_irq_disable(gpio_port_t port, gpio_pin_t pin) { - EIMSK &= ~(1 << _int_num(pin)); + (void)port; + EIMSK &= ~(1 << _int_num(port, pin)); } static inline void irq_handler(uint8_t int_num) @@ -390,9 +388,9 @@ static inline void pcint_handler(uint8_t bank, uint8_t enabled_pcints) /* get pin from mapping (assumes 8 entries per bank!) */ gpio_t pin = pcint_mapping[bank * 8 + idx]; /* re-construct mask from pin */ - uint8_t pin_mask = (1 << (atmega_pin_num(pin))); + uint8_t pin_mask = (1 << (atmega_pin_num(pin.pin))); uint8_t idx_mask = (1 << idx); - uint8_t port_value = (_SFR_MEM8(atmega_pin_addr( pin ))); + uint8_t port_value = (_SFR_MEM8(atmega_pin_addr( pin.port ))); uint8_t pin_value = ((port_value & pin_mask) != 0); uint8_t old_state = ((pcint_state[bank] & idx_mask) != 0); gpio_isr_ctx_pcint_t *conf = &pcint_config[bank * 8 + idx]; diff --git a/cpu/atmega_common/periph/pwm.c b/cpu/atmega_common/periph/pwm.c index 6f1d970777c0d..76817d12df143 100644 --- a/cpu/atmega_common/periph/pwm.c +++ b/cpu/atmega_common/periph/pwm.c @@ -65,14 +65,14 @@ static inline void compute_cra_and_crb(pwm_t dev, uint8_t pre) uint8_t cra = (1 << WGM1) | (1 << WGM0); uint8_t crb = pre; - if (pwm_conf[dev].pin_ch[0] != GPIO_UNDEF) { + if (!gpio_is_undef(pwm_conf[dev].pin_ch[0])) { cra |= (1 << COMA1); } else { crb |= (1 << WGM2); } - if (pwm_conf[dev].pin_ch[1] != GPIO_UNDEF) { + if (!gpio_is_undef(pwm_conf[dev].pin_ch[1])) { cra |= (1 << COMB1); } @@ -85,7 +85,7 @@ static inline void apply_config(pwm_t dev) pwm_conf[dev].dev->CRA = state[dev].CRA; pwm_conf[dev].dev->CRB = state[dev].CRB; - if (pwm_conf[dev].pin_ch[0] == GPIO_UNDEF) { + if (gpio_is_undef(pwm_conf[dev].pin_ch[0])) { /* If channel 0 is not used, variable resolutions can be used for * channel 1 */ pwm_conf[dev].dev->OCR[0] = state[dev].res; @@ -98,7 +98,7 @@ uint32_t pwm_init(pwm_t dev, pwm_mode_t mode, uint32_t freq, uint16_t res) /* only left implemented, max resolution 256 */ assert(dev < PWM_NUMOF && mode == PWM_LEFT && res <= 256); /* resolution != 256 only valid if ch0 not used */ - assert(!(res != 256 && pwm_conf[dev].pin_ch[0] != GPIO_UNDEF)); + assert(!(res != 256 && !gpio_is_undef(pwm_conf[dev].pin_ch[0]))); /* disable PWM */ pwm_conf[dev].dev->CRA = 0x00; @@ -128,10 +128,10 @@ uint32_t pwm_init(pwm_t dev, pwm_mode_t mode, uint32_t freq, uint16_t res) apply_config(dev); /* Enable outputs */ - if (pwm_conf[dev].pin_ch[0] != GPIO_UNDEF) { + if (!gpio_is_undef(pwm_conf[dev].pin_ch[0])) { gpio_init(pwm_conf[dev].pin_ch[0], GPIO_OUT); } - if (pwm_conf[dev].pin_ch[1] != GPIO_UNDEF) { + if (!gpio_is_undef(pwm_conf[dev].pin_ch[1])) { gpio_init(pwm_conf[dev].pin_ch[1], GPIO_OUT); } @@ -145,8 +145,8 @@ uint8_t pwm_channels(pwm_t dev) /* a pwm with no channels enabled makes no sense. Assume at least one is * enabled */ - if (pwm_conf[dev].pin_ch[0] == GPIO_UNDEF || - pwm_conf[dev].pin_ch[1] == GPIO_UNDEF) { + if (gpio_is_undef(pwm_conf[dev].pin_ch[0]) || + gpio_is_undef(pwm_conf[dev].pin_ch[1])) { return 1; } @@ -155,7 +155,7 @@ uint8_t pwm_channels(pwm_t dev) void pwm_set(pwm_t dev, uint8_t ch, uint16_t value) { - assert(dev < PWM_NUMOF && ch <= 1 && pwm_conf[dev].pin_ch[ch] != GPIO_UNDEF); + assert(dev < PWM_NUMOF && ch <= 1 && !gpio_is_undef(pwm_conf[dev].pin_ch[ch])); if (value > state[dev].res) { pwm_conf[dev].dev->OCR[ch] = state[dev].res; } @@ -191,11 +191,11 @@ void pwm_poweroff(pwm_t dev) power_timer0_disable(); } - if (pwm_conf[dev].pin_ch[0] != GPIO_UNDEF) { + if (!gpio_is_undef(pwm_conf[dev].pin_ch[0])) { gpio_clear(pwm_conf[dev].pin_ch[0]); } - if (pwm_conf[dev].pin_ch[1] != GPIO_UNDEF) { + if (!gpio_is_undef(pwm_conf[dev].pin_ch[1])) { gpio_clear(pwm_conf[dev].pin_ch[1]); } } diff --git a/cpu/atmega_common/periph/spi.c b/cpu/atmega_common/periph/spi.c index bbb023015cfbc..3e224b8abae84 100644 --- a/cpu/atmega_common/periph/spi.c +++ b/cpu/atmega_common/periph/spi.c @@ -117,7 +117,7 @@ void spi_transfer_bytes(spi_t bus, spi_cs_t cs, bool cont, assert(out_buf || in_buf); - if (cs != SPI_CS_UNDEF) { + if (!gpio_is_equal(cs, SPI_CS_UNDEF)) { gpio_clear((gpio_t)cs); } @@ -131,7 +131,7 @@ void spi_transfer_bytes(spi_t bus, spi_cs_t cs, bool cont, } } - if ((!cont) && (cs != SPI_CS_UNDEF)) { + if ((!cont) && !gpio_is_equal(cs, SPI_CS_UNDEF)) { gpio_set((gpio_t)cs); } } diff --git a/drivers/ws281x/atmega.c b/drivers/ws281x/atmega.c index b549d39812a17..9f0e5bc71f344 100644 --- a/drivers/ws281x/atmega.c +++ b/drivers/ws281x/atmega.c @@ -85,17 +85,17 @@ void ws281x_write_buffer(ws281x_t *dev, const void *buf, size_t size) assert(dev); const uint8_t *pos = buf; const uint8_t *end = pos + size; - uint16_t port_addr = atmega_port_addr(dev->params.pin); + uint16_t port_addr = atmega_port_addr(dev->params.pin.port); uint8_t mask_on, mask_off; { uint8_t port_state = _SFR_MEM8(port_addr); - mask_on = port_state | (1 << atmega_pin_num(dev->params.pin)); - mask_off = port_state & ~(1 << atmega_pin_num(dev->params.pin)); + mask_on = port_state | (1 << atmega_pin_num(dev->params.pin.pin)); + mask_off = port_state & ~(1 << atmega_pin_num(dev->params.pin.pin)); } #if (CLOCK_CORECLOCK >= 7500000U) && (CLOCK_CORECLOCK <= 8500000U) - const uint8_t port_num = atmega_port_num(dev->params.pin); + const uint8_t port_num = atmega_port_num(dev->params.pin.port); switch (port_num) { case PORT_B: while (pos < end) {