rtems_status_code lpc24xx_gpio_config( unsigned pin, lpc24xx_gpio_settings settings ) { if (pin <= LPC24XX_IO_INDEX_MAX) { rtems_interrupt_level level; unsigned port = LPC24XX_IO_PORT(pin); unsigned bit = LPC24XX_IO_PORT_BIT(pin); unsigned select = LPC24XX_IO_SELECT(pin); unsigned shift = LPC24XX_IO_SELECT_SHIFT(pin); unsigned resistor = settings & LPC24XX_GPIO_RESISTOR_MASK; unsigned output = (settings & LPC24XX_GPIO_OUTPUT) != 0 ? 1U : 0U; /* Get resistor flags */ switch (resistor) { case LPC24XX_GPIO_RESISTOR_PULL_UP: case LPC24XX_GPIO_RESISTOR_DEFAULT: resistor = 0x0U; break; case LPC24XX_GPIO_RESISTOR_NONE: resistor = 0x2U; break; case LPC24XX_GPIO_RESISTOR_PULL_DOWN: resistor = 0x3U; break; default: return RTEMS_INVALID_NUMBER; } rtems_interrupt_disable(level); /* Resistor */ LPC24XX_PINMODE [select] = (LPC24XX_PINMODE [select] & ~(LPC24XX_IO_SELECT_MASK << shift)) | ((resistor & LPC24XX_IO_SELECT_MASK) << shift); rtems_interrupt_flash(level); /* Input or output */ LPC24XX_FIO [port].dir = (LPC24XX_FIO [port].dir & ~(1U << bit)) | (output << bit); rtems_interrupt_enable(level); } else { return RTEMS_INVALID_ID; } return RTEMS_SUCCESSFUL; }
rtems_status_code lpc24xx_gpio_config( unsigned index, lpc24xx_gpio_settings settings ) { if (index <= LPC24XX_IO_INDEX_MAX) { rtems_interrupt_level level; uint32_t port = LPC24XX_IO_PORT(index); uint32_t port_bit = LPC24XX_IO_PORT_BIT(index); uint32_t output = (settings & LPC24XX_GPIO_OUTPUT) != 0 ? 1U : 0U; uint32_t resistor = settings & 0x3U; #ifdef ARM_MULTILIB_ARCH_V4 uint32_t select = LPC24XX_PIN_SELECT(index); uint32_t shift = LPC24XX_PIN_SELECT_SHIFT(index); /* Get resistor flags */ switch (resistor) { case LPC24XX_GPIO_RESISTOR_PULL_UP: resistor = 0x0U; break; case LPC24XX_GPIO_RESISTOR_NONE: resistor = 0x2U; break; case LPC24XX_GPIO_RESISTOR_PULL_DOWN: resistor = 0x3U; break; default: return RTEMS_INVALID_NUMBER; } #else uint32_t iocon_mask = IOCON_HYS | IOCON_INV | IOCON_SLEW | IOCON_OD | IOCON_FILTER; uint32_t iocon = (settings & iocon_mask) | IOCON_ADMODE; uint32_t iocon_invalid = settings & ~(iocon_mask | LPC24XX_GPIO_OUTPUT); /* Get resistor flags */ switch (resistor) { case LPC24XX_GPIO_RESISTOR_NONE: resistor = IOCON_MODE(0); break; case LPC24XX_GPIO_RESISTOR_PULL_DOWN: resistor = IOCON_MODE(1); break; case LPC24XX_GPIO_RESISTOR_PULL_UP: resistor = IOCON_MODE(2); break; case LPC17XX_GPIO_HYSTERESIS: resistor = IOCON_MODE(3); break; } iocon |= resistor; if (iocon_invalid != 0) { return RTEMS_INVALID_NUMBER; } if (output && (settings & LPC17XX_GPIO_INPUT_INVERT) != 0) { return RTEMS_INVALID_NUMBER; } if ((settings & LPC17XX_GPIO_INPUT_FILTER) == 0) { iocon |= IOCON_FILTER; } else { iocon &= ~IOCON_FILTER; } #endif rtems_interrupt_disable(level); #ifdef ARM_MULTILIB_ARCH_V4 /* Resistor */ LPC24XX_PINMODE [select] = (LPC24XX_PINMODE [select] & ~(LPC24XX_PIN_SELECT_MASK << shift)) | ((resistor & LPC24XX_PIN_SELECT_MASK) << shift); #else LPC17XX_IOCON [index] = iocon; #endif rtems_interrupt_flash(level); /* Input or output */ LPC24XX_FIO [port].dir = (LPC24XX_FIO [port].dir & ~(1U << port_bit)) | (output << port_bit); rtems_interrupt_enable(level); } else { return RTEMS_INVALID_ID; } return RTEMS_SUCCESSFUL; }