mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2024-12-29 04:50:03 +01:00
cpu/sam3/gpio: use gpio_irq feature
This commit is contained in:
parent
c7e6d15990
commit
e53abca10a
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user