static int __nmk_config_pins(pin_cfg_t *cfgs, int num, bool sleep) { static unsigned int slpm[NUM_BANKS]; unsigned long flags; bool glitch = false; int ret = 0; int i; for (i = 0; i < num; i++) { if (PIN_ALT(cfgs[i]) == NMK_GPIO_ALT_C) { glitch = true; break; } } spin_lock_irqsave(&nmk_gpio_slpm_lock, flags); if (glitch) { memset(slpm, 0xff, sizeof(slpm)); for (i = 0; i < num; i++) { int pin = PIN_NUM(cfgs[i]); int offset = pin % NMK_GPIO_PER_CHIP; if (PIN_ALT(cfgs[i]) == NMK_GPIO_ALT_C) slpm[pin / NMK_GPIO_PER_CHIP] &= ~BIT(offset); } nmk_gpio_glitch_slpm_init(slpm); } for (i = 0; i < num; i++) { struct nmk_gpio_chip *nmk_chip; int pin = PIN_NUM(cfgs[i]); nmk_chip = nmk_gpio_chips[pin / NMK_GPIO_PER_CHIP]; if (!nmk_chip) { ret = -EINVAL; break; } clk_enable(nmk_chip->clk); spin_lock(&nmk_chip->lock); __nmk_config_pin(nmk_chip, pin % NMK_GPIO_PER_CHIP, cfgs[i], sleep, glitch ? slpm : NULL); spin_unlock(&nmk_chip->lock); clk_disable(nmk_chip->clk); } if (glitch) nmk_gpio_glitch_slpm_restore(slpm); spin_unlock_irqrestore(&nmk_gpio_slpm_lock, flags); return ret; }
static int pin_read(struct rt_device *device, rt_base_t pin) { if ((pin > PIN_NUM(pin_index)) || (pin_index[pin].magic != PIN_MAGIC)) { dbg_log(DBG_ERROR, "pin:%d value wrongful\n", pin); return 0; } return gpio_get_value(pin_index[pin].pin_port, pin_index[pin].pin); }
static void pin_write(struct rt_device *dev, rt_base_t pin, rt_base_t value) { if ((pin > PIN_NUM(pin_index)) || (pin_index[pin].magic != PIN_MAGIC)) { dbg_log(DBG_ERROR, "pin:%d value wrongful\n", pin); return; } gpio_set_value(pin_index[pin].pin_port, pin_index[pin].pin, value); }
static rt_err_t pin_detach_irq(struct rt_device *device, rt_int32_t pin) { if ((pin > PIN_NUM(pin_index)) || (pin_index[pin].magic != PIN_MAGIC)) { dbg_log(DBG_ERROR, "pin:%d value wrongful\n", pin); return RT_ERROR; } gpio_clear_irq_callback(pin_index[pin].pin_port, pin_index[pin].pin); return RT_EOK; }
static rt_err_t pin_attach_irq(struct rt_device *device, rt_int32_t pin, rt_uint32_t mode, void (*hdr)(void *args), void *args) { if ((pin > PIN_NUM(pin_index)) || (pin_index[pin].magic != PIN_MAGIC)) { dbg_log(DBG_ERROR, "pin:%d value wrongful\n", pin); return RT_ERROR; } gpio_set_irq_callback(pin_index[pin].pin_port, pin_index[pin].pin, hdr, args); gpio_set_irq_type(pin_index[pin].pin_port, pin_index[pin].pin, mode); return RT_EOK; }
void mcp2515_init(void) { // Aktivieren der Pins fuer das SPI Interface PORT_SPI &= ~((1 << PIN_NUM(P_SCK)) | (1 << PIN_NUM(P_MOSI))); DDR_SPI |= (1 << PIN_NUM(P_SCK)) | (1 << PIN_NUM(P_MOSI)); SET(MCP2515_CS); SET_OUTPUT(MCP2515_CS); // Aktivieren des SPI Master Interfaces SPCR = (1 << SPE) | (1 << MSTR) | R_SPCR; SPSR = R_SPSR; _delay_us(1); // MCP2515 per Software Reset zuruecksetzten, // danach ist er automatisch im Konfigurations Modus RESET(MCP2515_CS); spi_putc(SPI_RESET); SET(MCP2515_CS); // ein bisschen warten bis der MCP2515 sich neu gestartet hat _delay_ms(0.1); // Filter usw. setzen RESET(MCP2515_CS); spi_putc(SPI_WRITE); spi_putc(RXF0SIDH); for (uint8_t i = 0; i < sizeof(mcp2515_register_map); i++) { spi_putc(pgm_read_byte(&mcp2515_register_map[i])); } SET(MCP2515_CS); // nur Standard IDs, Message Rollover nach Puffer 1 mcp2515_write_register(RXB0CTRL, (0 << RXM1) | (1 << RXM0) | (1 << BUKT)); mcp2515_write_register(RXB1CTRL, (0 << RXM1) | (1 << RXM0)); // MCP2515 zurueck in den normalen Modus versetzten mcp2515_write_register(CANCTRL, CLKOUT_PRESCALER_); }
rt_err_t pin_irq_enable(struct rt_device *device, rt_base_t pin, rt_uint32_t enabled) { if ((pin > PIN_NUM(pin_index)) || (pin_index[pin].magic != PIN_MAGIC)) { dbg_log(DBG_ERROR, "pin:%d value wrongful\n", pin); return RT_ERROR; } if (enabled) gpio_irq_enable(pin_index[pin].pin_port, pin_index[pin].pin); else gpio_irq_disable(pin_index[pin].pin_port, pin_index[pin].pin); return RT_EOK; }
/** * config_pin - configure a pin's mux attributes * @cfg: pin confguration * * Configures a pin's mode (alternate function or GPIO), its pull up status, * and its sleep mode based on the specified configuration. The @cfg is * usually one of the SoC specific macros defined in mach/<soc>-pins.h. These * are constructed using, and can be further enhanced with, the macros in * plat/pincfg.h. * * If a pin's mode is set to GPIO, it is configured as an input to avoid * side-effects. The gpio can be manipulated later using standard GPIO API * calls. */ static void config_pin(pin_cfg_t cfg) { int pin = PIN_NUM(cfg); int pull = PIN_PULL(cfg); int af = PIN_ALT(cfg); int output = PIN_DIR(cfg); int val = PIN_VAL(cfg); if (output) db8500_gpio_make_output(pin, val); else { db8500_gpio_make_input(pin); db8500_gpio_set_pull(pin, pull); } gpio_set_mode(pin, af); }
static void __nmk_config_pin(struct nmk_gpio_chip *nmk_chip, unsigned offset, pin_cfg_t cfg, bool sleep, unsigned int *slpmregs) { static const char *afnames[] = { [NMK_GPIO_ALT_GPIO] = "GPIO", [NMK_GPIO_ALT_A] = "A", [NMK_GPIO_ALT_B] = "B", [NMK_GPIO_ALT_C] = "C" }; static const char *pullnames[] = { [NMK_GPIO_PULL_NONE] = "none", [NMK_GPIO_PULL_UP] = "up", [NMK_GPIO_PULL_DOWN] = "down", [3] /* illegal */ = "??" }; static const char *slpmnames[] = { [NMK_GPIO_SLPM_INPUT] = "input/wakeup", [NMK_GPIO_SLPM_NOCHANGE] = "no-change/no-wakeup", }; int pin = PIN_NUM(cfg); int pull = PIN_PULL(cfg); int af = PIN_ALT(cfg); int slpm = PIN_SLPM(cfg); int output = PIN_DIR(cfg); int val = PIN_VAL(cfg); bool glitch = af == NMK_GPIO_ALT_C; dev_dbg(nmk_chip->chip.dev, "pin %d [%#lx]: af %s, pull %s, slpm %s (%s%s)\n", pin, cfg, afnames[af], pullnames[pull], slpmnames[slpm], output ? "output " : "input", output ? (val ? "high" : "low") : ""); if (sleep) { int slpm_pull = PIN_SLPM_PULL(cfg); int slpm_output = PIN_SLPM_DIR(cfg); int slpm_val = PIN_SLPM_VAL(cfg); af = NMK_GPIO_ALT_GPIO; /* * The SLPM_* values are normal values + 1 to allow zero to * mean "same as normal". */ if (slpm_pull) pull = slpm_pull - 1; if (slpm_output) output = slpm_output - 1; if (slpm_val) val = slpm_val - 1; dev_dbg(nmk_chip->chip.dev, "pin %d: sleep pull %s, dir %s, val %s\n", pin, slpm_pull ? pullnames[pull] : "same", slpm_output ? (output ? "output" : "input") : "same", slpm_val ? (val ? "high" : "low") : "same"); } if (output) __nmk_gpio_make_output(nmk_chip, offset, val); else { __nmk_gpio_make_input(nmk_chip, offset); __nmk_gpio_set_pull(nmk_chip, offset, pull); } __nmk_gpio_set_lowemi(nmk_chip, offset, PIN_LOWEMI(cfg)); /* * If the pin is switching to altfunc, and there was an interrupt * installed on it which has been lazy disabled, actually mask the * interrupt to prevent spurious interrupts that would occur while the * pin is under control of the peripheral. Only SKE does this. */ if (af != NMK_GPIO_ALT_GPIO) nmk_gpio_disable_lazy_irq(nmk_chip, offset); /* * If we've backed up the SLPM registers (glitch workaround), modify * the backups since they will be restored. */ if (slpmregs) { if (slpm == NMK_GPIO_SLPM_NOCHANGE) slpmregs[nmk_chip->bank] |= BIT(offset); else slpmregs[nmk_chip->bank] &= ~BIT(offset); } else __nmk_gpio_set_slpm(nmk_chip, offset, slpm); __nmk_gpio_set_mode_safe(nmk_chip, offset, af, glitch); }
static void __nmk_config_pin(struct nmk_gpio_chip *nmk_chip, unsigned offset, pin_cfg_t cfg, bool sleep, unsigned int *slpmregs) { static const char *afnames[] = { [NMK_GPIO_ALT_GPIO] = "GPIO", [NMK_GPIO_ALT_A] = "A", [NMK_GPIO_ALT_B] = "B", [NMK_GPIO_ALT_C] = "C" }; static const char *pullnames[] = { [NMK_GPIO_PULL_NONE] = "none", [NMK_GPIO_PULL_UP] = "up", [NMK_GPIO_PULL_DOWN] = "down", [3] /* illegal */ = "??" }; static const char *slpmnames[] = { [NMK_GPIO_SLPM_INPUT] = "input/wakeup", [NMK_GPIO_SLPM_NOCHANGE] = "no-change/no-wakeup", }; int pin = PIN_NUM(cfg); int pull = PIN_PULL(cfg); int af = PIN_ALT(cfg); int slpm = PIN_SLPM(cfg); int output = PIN_DIR(cfg); int val = PIN_VAL(cfg); bool glitch = af == NMK_GPIO_ALT_C; dev_dbg(nmk_chip->chip.dev, "pin %d [%#lx]: af %s, pull %s, slpm %s (%s%s)\n", pin, cfg, afnames[af], pullnames[pull], slpmnames[slpm], output ? "output " : "input", output ? (val ? "high" : "low") : ""); if (sleep) { int slpm_pull = PIN_SLPM_PULL(cfg); int slpm_output = PIN_SLPM_DIR(cfg); int slpm_val = PIN_SLPM_VAL(cfg); af = NMK_GPIO_ALT_GPIO; /* * The SLPM_* values are normal values + 1 to allow zero to * mean "same as normal". */ if (slpm_pull) pull = slpm_pull - 1; if (slpm_output) output = slpm_output - 1; if (slpm_val) val = slpm_val - 1; dev_dbg(nmk_chip->chip.dev, "pin %d: sleep pull %s, dir %s, val %s\n", pin, slpm_pull ? pullnames[pull] : "same", slpm_output ? (output ? "output" : "input") : "same", slpm_val ? (val ? "high" : "low") : "same"); } if (output) __nmk_gpio_make_output(nmk_chip, offset, val); else { __nmk_gpio_make_input(nmk_chip, offset); __nmk_gpio_set_pull(nmk_chip, offset, pull); } /* * If we've backed up the SLPM registers (glitch workaround), modify * the backups since they will be restored. */ if (slpmregs) { if (slpm == NMK_GPIO_SLPM_NOCHANGE) slpmregs[nmk_chip->bank] |= BIT(offset); else slpmregs[nmk_chip->bank] &= ~BIT(offset); } else __nmk_gpio_set_slpm(nmk_chip, offset, slpm); __nmk_gpio_set_mode_safe(nmk_chip, offset, af, glitch); }