Skip to content
Snippets Groups Projects
Commit 9bd848f1 authored by Hauke Petersen's avatar Hauke Petersen
Browse files

cpu/saml21: adapted GPIO driver

parent d3b21ddf
No related branches found
No related tags found
No related merge requests found
......@@ -33,6 +33,31 @@ enum {
PB = 1, /**< port B */
};
/**
* @brief Generate GPIO mode bitfields
*
* We use 3 bit to determine the pin functions:
* - bit 0: PU or PU
* - bit 1: input enable
* - bit 2: pull enable
*/
#define GPIO_MODE(pr, ie, pe) (pr | (ie << 1) | (pe << 2))
/**
* @brief Override GPIO modes
* @{
*/
#define HAVE_GPIO_MODE_T
typedef enum {
GPIO_IN = GPIO_MODE(0, 1, 0), /**< IN */
GPIO_IN_PD = GPIO_MODE(0, 1, 1), /**< IN with pull-down */
GPIO_IN_PU = GPIO_MODE(1, 1, 1), /**< IN with pull-up */
GPIO_OUT = GPIO_MODE(0, 0, 0), /**< OUT (push-pull) */
GPIO_OD = 0xfe, /**< not supported by HW */
GPIO_OD_PU = 0xff /**< not supported by HW */
} gpio_mode_t;
/** @} */
#ifdef __cplusplus
}
#endif
......
......@@ -41,6 +41,11 @@
*/
#define NUMOF_IRQS (16U)
/**
* @brief Mask to get PINCFG reg value from mode value
*/
#define MODE_PINCFG_MASK (0x06)
/**
* @brief Mapping of pins to EXTI lines, -1 means not EXTI possible
*/
......@@ -89,42 +94,38 @@ void gpio_init_mux(gpio_t pin, gpio_mux_t mux)
port->PMUX[pin_pos >> 1].reg |= (mux << (4 * (pin_pos & 0x1)));
}
int gpio_init(gpio_t pin, gpio_dir_t dir, gpio_pp_t pushpull)
int gpio_init(gpio_t pin, gpio_mode_t mode)
{
PortGroup* port = _port(pin);
int pin_pos = _pin_pos(pin);
int pin_mask = _pin_mask(pin);
/* configure the pin's pull resistor and reset all other configuration */
switch (pushpull) {
case GPIO_PULLDOWN:
port->OUTCLR.reg = pin_mask;
port->PINCFG[pin_pos].reg = PORT_PINCFG_PULLEN;
break;
case GPIO_PULLUP:
port->OUTSET.reg = pin_mask;
port->PINCFG[pin_pos].reg = PORT_PINCFG_PULLEN;
break;
case GPIO_NOPULL:
port->PINCFG[pin_pos].reg = 0;
break;
/* make sure pin mode is applicable */
if (mode > 0x7) {
return -1;
}
/* set pin_pos direction */
if (dir == GPIO_DIR_OUT) {
if (pushpull == GPIO_PULLDOWN) {
return -1;
}
port->DIRSET.reg = pin_mask; /* configure as output */
port->OUTCLR.reg = pin_mask; /* set pin LOW on init */
/* set pin direction */
if (mode & 0x2) {
port->DIRCLR.reg = pin_mask;
}
else {
port->DIRCLR.reg = pin_mask; /* configure as input */
port->PINCFG[pin_pos].reg |= PORT_PINCFG_INEN;
port->DIRSET.reg = pin_mask;
}
/* configure the pin cfg and clear output register */
port->PINCFG[pin_pos].reg = (mode & MODE_PINCFG_MASK);
port->OUTCLR.reg = pin_mask;
/* and set pull-up/pull-down if applicable */
if (mode == 0x7) {
port->OUTSET.reg = pin_mask;
}
return 0;
}
int gpio_init_int(gpio_t pin, gpio_pp_t pullup, gpio_flank_t flank,
int gpio_init_int(gpio_t pin, gpio_mode_t mode, gpio_flank_t flank,
gpio_cb_t cb, void *arg)
{
int exti = _exti(pin);
......@@ -138,7 +139,7 @@ int gpio_init_int(gpio_t pin, gpio_pp_t pullup, gpio_flank_t flank,
gpio_config[exti].cb = cb;
gpio_config[exti].arg = arg;
/* configure pin as input and set MUX to peripheral function A */
gpio_init(pin, GPIO_DIR_IN, pullup);
gpio_init(pin, mode);
gpio_init_mux(pin, GPIO_MUX_A);
/* enable clocks for the EIC module */
MCLK->APBAMASK.reg |= MCLK_APBAMASK_EIC;
......
......@@ -134,10 +134,10 @@ int spi_init_master(spi_t dev, spi_conf_t conf, spi_speed_t speed)
while (!(GCLK->PCHCTRL[spi[dev].gclk_id].reg & GCLK_PCHCTRL_CHEN)) {}
/* SCLK+MOSI = output */
gpio_init(spi[dev].sclk.pin, GPIO_DIR_OUT, GPIO_NOPULL);
gpio_init(spi[dev].mosi.pin, GPIO_DIR_OUT, GPIO_NOPULL);
gpio_init(spi[dev].sclk.pin, GPIO_OUT);
gpio_init(spi[dev].mosi.pin, GPIO_OUT);
/* MISO = input */
gpio_init(spi[dev].miso.pin, GPIO_DIR_IN, GPIO_PULLUP);
gpio_init(spi[dev].miso.pin, GPIO_IN);
/*
* Set alternate funcion (PMUX) for our ports.
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment