コード例 #1
0
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;
}
コード例 #2
0
ファイル: io.c プロジェクト: AndroidMarv/rtems
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;
}