diff --git a/cpu/sam3/periph/gpio.c b/cpu/sam3/periph/gpio.c index ebe7d73a24..c803fa8c21 100644 --- a/cpu/sam3/periph/gpio.c +++ b/cpu/sam3/periph/gpio.c @@ -30,6 +30,16 @@ #define ENABLE_DEBUG (0) #include "debug.h" +/** + * @brief Bit positions in the GPIO mode value + * @{ + */ +#define MODE_BIT_IO (0x1) +#define MODE_BIT_PUE (0x2) +#define MODE_BIT_ODE (0x4) +/** @} */ + +#ifdef MODULE_PERIPH_GPIO_IRQ /** * @brief We store 4 bit for each external interrupt line (each pin) that can * mapped to an entry in the exti_ctx table @@ -41,15 +51,6 @@ */ #define CTX_NUMOF (7U) -/** - * @brief Bit positions in the GPIO mode value - * @{ - */ -#define MODE_BIT_IO (0x1) -#define MODE_BIT_PUE (0x2) -#define MODE_BIT_ODE (0x4) -/** @} */ - /** * @brief Allocation of memory for 7 independent interrupt slots */ @@ -65,44 +66,6 @@ static uint32_t exti_map[EXTI_MAP_LENGTH] = { 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff }; -/** - * @brief Extract the pin's port base address from the given pin identifier - */ -static inline Pio *_port(gpio_t pin) -{ - return (Pio *)(pin & ~(0x1f)); -} - -/** - * @brief Extract the port number from the given pin identifier - * - * Isolating bits 9 to 12 of the port base addresses leads to unique port - * numbers. - */ -static inline int _port_num(gpio_t pin) -{ - return (((pin >> 9) & 0x0f) - 7); -} - -/** - * @brief Test if the given port is valid - */ -static bool _port_valid(Pio *port) -{ - if (port == PIOA || port == PIOB || port == PIOC || port == PIOD) { - return true; - } - return false; -} - -/** - * @brief Get the pin number from the pin identifier, encoded in the LSB 5 bit - */ -static inline int _pin_num(gpio_t pin) -{ - return (pin & 0x1f); -} - /** * @brief Get context for a specific pin */ @@ -144,6 +107,45 @@ static void _ctx_clear(int port, int pin) _write_map(port, pin, CTX_NUMOF); } } +#endif + +/** + * @brief Extract the pin's port base address from the given pin identifier + */ +static inline Pio *_port(gpio_t pin) +{ + return (Pio *)(pin & ~(0x1f)); +} + +/** + * @brief Extract the port number from the given pin identifier + * + * Isolating bits 9 to 12 of the port base addresses leads to unique port + * numbers. + */ +static inline int _port_num(gpio_t pin) +{ + return (((pin >> 9) & 0x0f) - 7); +} + +/** + * @brief Test if the given port is valid + */ +static bool _port_valid(Pio *port) +{ + if (port == PIOA || port == PIOB || port == PIOC || port == PIOD) { + return true; + } + return false; +} + +/** + * @brief Get the pin number from the pin identifier, encoded in the LSB 5 bit + */ +static inline int _pin_num(gpio_t pin) +{ + return (pin & 0x1f); +} int gpio_init(gpio_t pin, gpio_mode_t mode) { @@ -161,7 +163,9 @@ int gpio_init(gpio_t pin, gpio_mode_t mode) /* disable interrupt and clear context (to be safe) */ port->PIO_IDR = (1 << pin_num); +#ifdef MODULE_PERIPH_GPIO_IRQ _ctx_clear(port_num, pin_num); +#endif /* give the PIO module the power over the corresponding pin */ port->PIO_PER = (1 << pin_num); @@ -191,6 +195,69 @@ int gpio_init(gpio_t pin, gpio_mode_t mode) return 0; } +void gpio_init_mux(gpio_t pin, gpio_mux_t mux) +{ + /* power on the corresponding port */ + PMC->PMC_PCER0 = (1 << (_port_num(pin) + 11)); + /* give peripheral control over the pin */ + _port(pin)->PIO_PDR = (1 << _pin_num(pin)); + /* and configure the MUX */ + _port(pin)->PIO_ABSR &= ~(1 << _pin_num(pin)); + _port(pin)->PIO_ABSR |= (mux << _pin_num(pin)); +} + +void gpio_set(gpio_t pin) +{ + _port(pin)->PIO_SODR = (1 << _pin_num(pin)); +} + +void gpio_clear(gpio_t pin) +{ + _port(pin)->PIO_CODR = (1 << _pin_num(pin)); +} + +void gpio_toggle(gpio_t pin) +{ + if (gpio_read(pin)) { + _port(pin)->PIO_CODR = (1 << _pin_num(pin)); + } else { + _port(pin)->PIO_SODR = (1 << _pin_num(pin)); + } +} + +void gpio_write(gpio_t pin, int value) +{ + if (value) { + _port(pin)->PIO_SODR = (1 << _pin_num(pin)); + } else { + _port(pin)->PIO_CODR = (1 << _pin_num(pin)); + } +} + +void gpio_irq_enable(gpio_t pin) +{ + NVIC_EnableIRQ((1 << (_port_num(pin) + PIOA_IRQn))); +} + +void gpio_irq_disable(gpio_t pin) +{ + NVIC_DisableIRQ((1 << (_port_num(pin) + PIOA_IRQn))); +} + +int gpio_read(gpio_t pin) +{ + Pio *port = _port(pin); + int pin_num = _pin_num(pin); + + if (port->PIO_OSR & (1 << pin_num)) { + return (port->PIO_ODSR & (1 << pin_num)) ? 1 : 0; + } + else { + return (port->PIO_PDSR & (1 << pin_num)) ? 1 : 0; + } +} + +#ifdef MODULE_PERIPH_GPIO_IRQ int gpio_init_int(gpio_t pin, gpio_mode_t mode, gpio_flank_t flank, gpio_cb_t cb, void *arg) { @@ -241,68 +308,6 @@ int gpio_init_int(gpio_t pin, gpio_mode_t mode, gpio_flank_t flank, return 0; } -void gpio_init_mux(gpio_t pin, gpio_mux_t mux) -{ - /* power on the corresponding port */ - PMC->PMC_PCER0 = (1 << (_port_num(pin) + 11)); - /* give peripheral control over the pin */ - _port(pin)->PIO_PDR = (1 << _pin_num(pin)); - /* and configure the MUX */ - _port(pin)->PIO_ABSR &= ~(1 << _pin_num(pin)); - _port(pin)->PIO_ABSR |= (mux << _pin_num(pin)); -} - -void gpio_irq_enable(gpio_t pin) -{ - NVIC_EnableIRQ((1 << (_port_num(pin) + PIOA_IRQn))); -} - -void gpio_irq_disable(gpio_t pin) -{ - NVIC_DisableIRQ((1 << (_port_num(pin) + PIOA_IRQn))); -} - -int gpio_read(gpio_t pin) -{ - Pio *port = _port(pin); - int pin_num = _pin_num(pin); - - if (port->PIO_OSR & (1 << pin_num)) { - return (port->PIO_ODSR & (1 << pin_num)) ? 1 : 0; - } - else { - return (port->PIO_PDSR & (1 << pin_num)) ? 1 : 0; - } -} - -void gpio_set(gpio_t pin) -{ - _port(pin)->PIO_SODR = (1 << _pin_num(pin)); -} - -void gpio_clear(gpio_t pin) -{ - _port(pin)->PIO_CODR = (1 << _pin_num(pin)); -} - -void gpio_toggle(gpio_t pin) -{ - if (gpio_read(pin)) { - _port(pin)->PIO_CODR = (1 << _pin_num(pin)); - } else { - _port(pin)->PIO_SODR = (1 << _pin_num(pin)); - } -} - -void gpio_write(gpio_t pin, int value) -{ - if (value) { - _port(pin)->PIO_SODR = (1 << _pin_num(pin)); - } else { - _port(pin)->PIO_CODR = (1 << _pin_num(pin)); - } -} - static inline void isr_handler(Pio *port, int port_num) { /* take interrupt flags only from pins which interrupt is enabled */ @@ -336,3 +341,4 @@ void isr_piod(void) { isr_handler(PIOD, PD); } +#endif