Exemplo n.º 1
0
unsigned lpc24xx_cclk(void)
{
  /* Get PLL output frequency */
  unsigned pllclk = lpc24xx_pllclk();

  /* Get CPU frequency */
  unsigned cclk = pllclk / (GET_CCLKCFG_CCLKSEL(CCLKCFG) + 1);

  return cclk;
}
Exemplo n.º 2
0
static rtems_status_code lpc24xx_module_do_enable(
  lpc24xx_module module,
  lpc24xx_module_clock clock,
  bool enable
)
{
  rtems_interrupt_level level;
  bool has_power = false;
  bool has_clock = false;
  unsigned index = 0;
  #ifdef ARM_MULTILIB_ARCH_V7M
    volatile lpc17xx_scb *scb = &LPC17XX_SCB;
  #endif

  if ((unsigned) module >= LPC24XX_MODULE_COUNT) {
      return RTEMS_INVALID_ID;
  }

  #ifdef ARM_MULTILIB_ARCH_V4
    if (clock == LPC24XX_MODULE_PCLK_DEFAULT) {
      #if LPC24XX_PCLKDIV == 1U
        clock = LPC24XX_MODULE_CCLK;
      #elif LPC24XX_PCLKDIV == 2U
        clock = LPC24XX_MODULE_CCLK_2;
      #elif LPC24XX_PCLKDIV == 4U
        clock = LPC24XX_MODULE_CCLK_4;
      #elif LPC24XX_PCLKDIV == 8U
        clock = LPC24XX_MODULE_CCLK_8;
      #endif
    }

    if ((clock & ~LPC24XX_MODULE_CLOCK_MASK) != 0U) {
      return RTEMS_INVALID_CLOCK;
    }
  #else
    if (clock != LPC24XX_MODULE_PCLK_DEFAULT) {
      return RTEMS_INVALID_CLOCK;
    }
  #endif

  has_power = lpc24xx_module_table [module].power;
  has_clock = lpc24xx_module_table [module].clock;
  index = lpc24xx_module_table [module].index;

  /* Enable or disable module */
  if (enable) {
    if (has_power) {
      rtems_interrupt_disable(level);
      #ifdef ARM_MULTILIB_ARCH_V4
        PCONP |= 1U << index;
      #else
        scb->pconp |= 1U << index;
      #endif
      rtems_interrupt_enable(level);
    }

    if (module != LPC24XX_MODULE_USB) {
      if (has_clock) {
        #ifdef ARM_MULTILIB_ARCH_V4
          unsigned clock_shift = 2U * index;

          rtems_interrupt_disable(level);
          if (clock_shift < 32U) {
            PCLKSEL0 = (PCLKSEL0 & ~(LPC24XX_MODULE_CLOCK_MASK << clock_shift))
                | (clock << clock_shift);
          } else {
            clock_shift -= 32U;
            PCLKSEL1 = (PCLKSEL1 & ~(LPC24XX_MODULE_CLOCK_MASK << clock_shift))
                | (clock << clock_shift);
          }
          rtems_interrupt_enable(level);
        #endif
      }
    } else {
      #ifdef ARM_MULTILIB_ARCH_V4
        unsigned pllclk = lpc24xx_pllclk();
        unsigned usbsel = pllclk / 48000000U - 1U;

        if (
          usbsel > 15U
            || (usbsel % 2U != 1U)
            || (pllclk % 48000000U) != 0U
        ) {
          return RTEMS_INCORRECT_STATE;
        }

        USBCLKCFG = usbsel;
      #else
        uint32_t pllclk = lpc24xx_pllclk();
        uint32_t usbclk = 48000000U;

        if (pllclk % usbclk == 0U) {
          uint32_t usbdiv = pllclk / usbclk;

          scb->usbclksel = LPC17XX_SCB_USBCLKSEL_USBDIV(usbdiv)
            | LPC17XX_SCB_USBCLKSEL_USBSEL(1);
        } else {
          return RTEMS_INCORRECT_STATE;
        }
      #endif
    }
  } else {
    if (has_power) {
      rtems_interrupt_disable(level);
      #ifdef ARM_MULTILIB_ARCH_V4
        PCONP &= ~(1U << index);
      #else
        scb->pconp &= ~(1U << index);
      #endif
      rtems_interrupt_enable(level);
    }
  }

  return RTEMS_SUCCESSFUL;
}
Exemplo n.º 3
0
static rtems_status_code lpc24xx_module_do_enable(
  lpc24xx_module module,
  lpc24xx_module_clock clock,
  bool enable
)
{
  rtems_interrupt_level level;
  bool has_power = false;
  bool has_clock = false;
  unsigned index = 0;

  if ((unsigned) module >= LPC24XX_MODULE_COUNT) {
      return RTEMS_INVALID_ID;
  }

  if ((clock & ~LPC24XX_MODULE_CLOCK_MASK) != 0U) {
    return RTEMS_INVALID_NUMBER;
  }

  has_power = lpc24xx_module_table [module].power;
  has_clock = lpc24xx_module_table [module].clock;
  index = lpc24xx_module_table [module].index;

  /* Enable or disable module */
  if (enable) {
    if (has_power) {
      rtems_interrupt_disable(level);
      PCONP |= 1U << index;
      rtems_interrupt_enable(level);
    }

    if (module != LPC24XX_MODULE_USB) {
      if (has_clock) {
        unsigned clock_shift = 2U * index;

        rtems_interrupt_disable(level);
        if (clock_shift < 32U) {
          PCLKSEL0 = (PCLKSEL0 & ~(LPC24XX_MODULE_CLOCK_MASK << clock_shift))
              | (clock << clock_shift);
        } else {
          clock_shift -= 32U;
          PCLKSEL1 = (PCLKSEL1 & ~(LPC24XX_MODULE_CLOCK_MASK << clock_shift))
              | (clock << clock_shift);
        }
        rtems_interrupt_enable(level);
      }
    } else {
      unsigned pllclk = lpc24xx_pllclk();
      unsigned usbsel = pllclk / 48000000U - 1U;

      if (usbsel > 15U || (usbsel % 2U != 1U) || (pllclk % 48000000U) != 0U) {
        return RTEMS_INCORRECT_STATE;
      }

      USBCLKCFG = usbsel;
    }
  } else {
    if (has_power) {
      rtems_interrupt_disable(level);
      PCONP &= ~(1U << index);
      rtems_interrupt_enable(level);
    }
  }

  return RTEMS_SUCCESSFUL;
}