void port_init(port_t *obj, PortName port, int mask, PinDirection dir) { MBED_ASSERT(obj); struct port_config pin_conf; int i, j; int start; port_get_config_defaults(&pin_conf); switch (dir) { case PIN_INPUT : pin_conf.direction = PORT_PIN_DIR_INPUT; break; case PIN_OUTPUT: pin_conf.direction = PORT_PIN_DIR_OUTPUT; break; case PIN_INPUT_OUTPUT: pin_conf.direction = PORT_PIN_DIR_OUTPUT_WTH_READBACK; break; default: return; } PortGroup *const port_base = (PortGroup*)port_get_group_from_gpio_pin(port * 32); // 32 pins in port // function reused to get the port base if(port_base == NULL) return; /* returns NULL if invalid*/ switch (port) { case PortA: obj->mask = (uint32_t)mask & PORTA_MASK; break; case PortB: obj->mask = (uint32_t)mask & PORTB_MASK; break; #if defined(TARGET_SAMR21G18A) case PortC: obj->mask = (uint32_t)mask & PORTC_MASK; break; #endif default: return; } start = start_pin(port); if(start == NC) return; obj->port = port; obj->direction = dir; obj->powersave = pin_conf.powersave; obj->mode = PORT_PIN_PULL_UP; for (i = start, j = 0; j < 32; i++, j++) { if (obj->mask & (1<<j)) { port_pin_set_config((PinName)i, &pin_conf); } } obj->OUTCLR = &port_base->OUTCLR.reg; obj->OUTSET = &port_base->OUTSET.reg; obj->IN = &port_base->IN.reg; obj->OUT = &port_base->OUT.reg; }
void gpio_init(gpio_t *obj, PinName pin) { struct port_config pin_conf; PortGroup *const port_base = (PortGroup*)port_get_group_from_gpio_pin(pin); obj->pin = pin; if (pin == (PinName)NC) return; obj->mask = gpio_set(pin); port_get_config_defaults(&pin_conf); obj->powersave = pin_conf.powersave; obj->direction = PORT_PIN_DIR_INPUT; obj->mode = PORT_PIN_PULL_UP; port_pin_set_config(pin, &pin_conf); obj->OUTCLR = &port_base->OUTCLR.reg; obj->OUTSET = &port_base->OUTSET.reg; obj->IN = &port_base->IN.reg; obj->OUT = &port_base->OUT.reg; }
void gpio_irq(void) { uint32_t current_channel; uint32_t mask; gpio_irq_event event; PortGroup *port_base; for (current_channel = 0; current_channel < EIC_NUMBER_OF_INTERRUPTS ; current_channel++) { if (extint_chan_is_detected(current_channel)) { extint_chan_clear_detected(current_channel); port_base = (PortGroup*)port_get_group_from_gpio_pin(ext_int_pins[current_channel]); mask = gpio_set(ext_int_pins[current_channel]); if ((port_base->IN.reg & mask) != 0) { event = IRQ_RISE; } else { event = IRQ_FALL; } if(irq_handler) { irq_handler(channel_ids[current_channel], event); } } } }