Exemplo n.º 1
0
static void mpc55xx_clock_initialize(void)
{
  volatile struct EMIOS_CH_tag *regs = &EMIOS.CH [MPC55XX_CLOCK_EMIOS_CHANNEL];
  union EMIOS_CCR_tag ccr = MPC55XX_ZERO_FLAGS;
  union EMIOS_CSR_tag csr = MPC55XX_ZERO_FLAGS;
  unsigned prescaler = mpc55xx_emios_global_prescaler();
  uint64_t reference_clock = bsp_clock_speed;
  uint64_t us_per_tick = rtems_configuration_get_microseconds_per_tick();
  uint64_t interval = (reference_clock * us_per_tick) / 1000000;

  /* Apply prescaler */
  if (prescaler > 0) {
    interval /= (uint64_t) prescaler;
  } else {
    bsp_fatal(MPC55XX_FATAL_CLOCK_EMIOS_PRESCALER);
  }

  /* Check interval */
  if (interval == 0 || interval > MPC55XX_EMIOS_VALUE_MAX) {
    bsp_fatal(MPC55XX_FATAL_CLOCK_EMIOS_INTERVAL);
  }

  /* Configure eMIOS channel */

  /* Set channel in GPIO mode */
  ccr.B.MODE = MPC55XX_EMIOS_MODE_GPIO_INPUT;
  regs->CCR.R = ccr.R;

  /* Clear status flags */
  csr.B.OVR = 1;
  csr.B.OVFL = 1;
  csr.B.FLAG = 1;
  regs->CSR.R = csr.R;

  /* Set internal counter start value */
  regs->CCNTR.R = 1;

  /* Set timer period */
  regs->CADR.R = (uint32_t) interval - 1;

  /* Set control register */
  #if MPC55XX_CHIP_FAMILY == 551
    ccr.B.MODE = MPC55XX_EMIOS_MODE_MCB_UP_INT_CLK;
  #else
    ccr.B.MODE = MPC55XX_EMIOS_MODE_MC_UP_INT_CLK;
  #endif
  ccr.B.UCPREN = 1;
  ccr.B.FEN = 1;
  ccr.B.FREN = 1;
  regs->CCR.R = ccr.R;

  rtems_timecounter_simple_install(
    &mpc55xx_tc,
    reference_clock,
    interval,
    mpc55xx_tc_get_timecount
  );
}
Exemplo n.º 2
0
static void mpc55xx_clock_initialize( void)
{
  volatile struct EMIOS_CH_tag *regs = &EMIOS.CH [MPC55XX_CLOCK_EMIOS_CHANNEL];
  union EMIOS_CCR_tag ccr = MPC55XX_ZERO_FLAGS;
  union EMIOS_CSR_tag csr = MPC55XX_ZERO_FLAGS;
  unsigned prescaler = mpc55xx_emios_global_prescaler();
  uint64_t interval = ((uint64_t) bsp_clock_speed
    * (uint64_t) rtems_configuration_get_microseconds_per_tick()) / 1000000;

  /* Apply prescaler */
  if (prescaler > 0) {
    interval /= (uint64_t) prescaler;
  } else {
    RTEMS_SYSLOG_ERROR( "unexpected global eMIOS prescaler\n");
  }

  /* Check interval */
  if (interval == 0 || interval > MPC55XX_EMIOS_VALUE_MAX) {
    interval = MPC55XX_EMIOS_VALUE_MAX;
    RTEMS_SYSLOG_ERROR( "clock timer interval out of range\n");
  }

  /* Configure eMIOS channel */

  /* Set channel in GPIO mode */
  ccr.B.MODE = MPC55XX_EMIOS_MODE_GPIO_INPUT;
  regs->CCR.R = ccr.R;

  /* Clear status flags */
  csr.B.OVR = 1;
  csr.B.OVFL = 1;
  csr.B.FLAG = 1;
  regs->CSR.R = csr.R;

  /* Set timer period */
  regs->CADR.R = (uint32_t) interval - 1;

  /* Set unused registers */
  regs->CBDR.R = 0;
  regs->CCNTR.R = 0;
  regs->ALTCADR.R = 0;

  /* Set control register */
  ccr.B.MODE = MPC55XX_EMIOS_MODE_MCB_UP_INT_CLK;
  ccr.B.UCPREN = 1;
  ccr.B.FEN = 1;
  ccr.B.FREN = 1;
  regs->CCR.R = ccr.R;
}