Example #1
0
void mcal::gpt::init(const config_type*)
{
  if(gpt_is_initialized() == false)
  {
    gpt_is_initialized() = true;

    // Setup the rpi_arm timer period.
    // Timer frequency = (Clock / 1) * 0x10000.
    mcal::reg::access<std::uint32_t,
                      std::uint32_t,
                      mcal::reg::rpi_armtimer_load,
                      system_timer_reload>::reg_set();

    // Setup the rpi_arm timer control register.
    mcal::reg::access<std::uint32_t,
                      std::uint32_t,
                      mcal::reg::rpi_armtimer_control,
                      (  rpi_armtimer_ctrl_enable
                       | rpi_armtimer_ctrl_int_enable
                       | rpi_armtimer_ctrl_prescale_1)>::reg_set();

    // Enable the rpi_arm timer interrupt.
    mcal::reg::access<std::uint32_t,
                      std::uint32_t,
                      mcal::reg::rpi_interrupt_enable_basic_irqs,
                      rpi_basic_arm_timer_irq>::reg_set();
  }
}
Example #2
0
void mcal::gpt::init(const config_type*)
{
  if(gpt_is_initialized() == false)
  {
    // Protection off
    // SYSTEM.PRCR.WORD = 0xA503u;
    mcal::reg::access<std::uint32_t,
                      std::uint16_t,
                      mcal::reg::prcr,
                      UINT16_C(0xA503)>::reg_set();

    // Activate timer0/timer1 by clearing bit-5 in the module-stop register.
    mcal::reg::access<std::uint32_t,
                      std::uint32_t,
                      mcal::reg::mstpcra,
                      UINT8_C(5)>::bit_clr();

    // Protection on
    // SYSTEM.PRCR.WORD = 0xA500u;
    mcal::reg::access<std::uint32_t,
                      std::uint16_t,
                      mcal::reg::prcr,
                      UINT16_C(0xA500)>::reg_set();

    // Set timer0 to have an interrupt on overflow.
    mcal::reg::access<std::uint32_t,
                      std::uint8_t,
                      mcal::reg::tmr0_tcr,
                      UINT8_C(0x20)>::reg_set();

    // Enable the timer0 overflow interrupt at ier15.4.
    mcal::reg::access<std::uint32_t,
                      std::uint8_t,
                      mcal::reg::icu_ier15,
                      UINT8_C(0x04)>::bit_set();

    // Set the timer0 overflow interrupt priority to 7.
    mcal::reg::access<std::uint32_t,
                      std::uint8_t,
                      mcal::reg::icu_ipr170,
                      UINT8_C(0x07)>::reg_set();

    // Select the internal clock (not external) with the value 8.
    // Also select a prescaler of 32 with the value 3.
    mcal::reg::access<std::uint32_t,
                      std::uint8_t,
                      mcal::reg::tmr0_tccr,
                      static_cast<std::uint8_t>(UINT8_C(0x08) | UINT8_C(0x03))>::reg_set();

    // Start timer0 counting up.
    mcal::reg::access<std::uint32_t,
                      std::uint16_t,
                      mcal::reg::cmt_cmstr0,
                      UINT16_C(0x01)>::reg_set();

    gpt_is_initialized() = true;
  }
}
Example #3
0
mcal::gpt::value_type mcal::gpt::secure::get_time_elapsed()
{
  if(gpt_is_initialized())
  {
    // Return the system tick using a multiple read to ensure data consistency.

    typedef std::uint32_t timer_address_type;
    typedef std::uint16_t timer_register_type;

    // Do the first read of the rpi_arm timer value and the system tick.
    const timer_register_type   tmr_tick_1 = system_timer_reload - mcal::reg::access<timer_address_type, timer_register_type, mcal::reg::rpi_armtimer_value>::reg_get();
    const mcal::gpt::value_type sys_tick_1 = system_tick;

    // Do the second read of the rpi_arm timer value.
    const timer_register_type   tmr_tick_2 = system_timer_reload - mcal::reg::access<timer_address_type, timer_register_type, mcal::reg::rpi_armtimer_value>::reg_get();

    // Perform the consistency check.
    const mcal::gpt::value_type consistent_microsecond_tick
      = ((tmr_tick_2 >= tmr_tick_1) ? mcal::gpt::value_type(sys_tick_1  | tmr_tick_1)
                                    : mcal::gpt::value_type(system_tick | tmr_tick_2));

    return consistent_microsecond_tick;
  }
  else
  {
    return mcal::gpt::value_type(0U);
  }
}
Example #4
0
mcal::gpt::value_type mcal::gpt::secure::get_time_elapsed()
{
  if(gpt_is_initialized())
  {
    // Return the system tick using a multiple read to ensure data consistency.

    typedef std::uint32_t timer_address_type;
    typedef std::uint8_t  timer_register_type;

    // Do the first read of the timer0 counter and the system tick.
    const timer_register_type timer_cnt_1  = mcal::reg::access<timer_address_type, timer_register_type, mcal::reg::tmr0_tcnt>::reg_get();
    const mcal::gpt::value_type sys_tick_1 = system_tick;

    // Do the second read of the timer0 counter.
    const timer_register_type timer_cnt_2  = mcal::reg::access<timer_address_type, timer_register_type, mcal::reg::tmr0_tcnt>::reg_get();

    // Perform the consistency check.
    mcal::gpt::value_type consistent_microsecond_tick =
      ((timer_cnt_2 >= timer_cnt_1) ? static_cast<mcal::gpt::value_type>(sys_tick_1  | timer_cnt_1)
                                    : static_cast<mcal::gpt::value_type>(system_tick | timer_cnt_2));

    // Convert the consistent tick to microseconds.
    consistent_microsecond_tick = static_cast<mcal::gpt::value_type>(static_cast<mcal::gpt::value_type>(consistent_microsecond_tick * 4U)  + 3U) / 6U;

    return consistent_microsecond_tick;
  }
  else
  {
    return mcal::gpt::value_type(0U);
  }
}
Example #5
0
void mcal::gpt::init(const config_type*)
{
  if(gpt_is_initialized() == false)
  {
    // Clear the timer0 overflow flag.
    mcal::reg::access<std::uint8_t, std::uint8_t, mcal::reg::tifr0, 0x01U>::reg_set();

    // Enable the timer0 overflow interrupt.
    mcal::reg::access<std::uint8_t, std::uint8_t, mcal::reg::timsk0, 0x01U>::reg_set();

    // Set the timer0 clock source to f_osc/8 = 2MHz and begin counting.
    mcal::reg::access<std::uint8_t, std::uint8_t, mcal::reg::tccr0b, 0x02U>::reg_set();

    // Set the is-initialized indication flag.
    gpt_is_initialized() = true;
  }
}
Example #6
0
void mcal::gpt::init(const config_type*)
{
  if(gpt_is_initialized() == false)
  {
    mcal::reg::access<std::uint32_t, std::uint32_t, mcal::reg::dmtimer7::tsicr, UINT32_C(6)>::reg_set();

    while(std::uint32_t(mcal::reg::access<std::uint32_t, std::uint32_t, mcal::reg::dmtimer7::tiocp_cfg>::reg_get() & UINT32_C(1)) != UINT32_C(0))
    {
      mcal::cpu::nop();
    }

    // Register the dmtimer7 interrupt, including priority, routing, etc.
    mcal::irq::interrupt_descriptor::register_interrupt<mcal::irq::interrupt_descriptor::isr_id_tint7,
                                                        mcal::irq::interrupt_descriptor::priority_type(0U),
                                                        mcal::irq::interrupt_descriptor::route_to_irq>();

    // Enable the dmtimer7 overflow interrupt.
    mcal::reg::access<std::uint32_t, std::uint32_t, mcal::reg::dmtimer7::irqenable_set, UINT32_C(2)>::reg_msk<UINT32_C(7)>();

    // Set the dmtimer7 counter register.
    while(mcal::reg::access<std::uint32_t, std::uint32_t, mcal::reg::dmtimer7::twps>::reg_get() != UINT32_C(0))
    {
      mcal::cpu::nop();
    }
    mcal::reg::access<std::uint32_t, std::uint32_t, mcal::reg::dmtimer7::tcrr, UINT32_C(0xFFFFFFFE - 24000)>::reg_set();

    // Set the dmtimer7 reload register.
    while(mcal::reg::access<std::uint32_t, std::uint32_t, mcal::reg::dmtimer7::twps>::reg_get() != UINT32_C(0))
    {
      mcal::cpu::nop();
    }
    mcal::reg::access<std::uint32_t, std::uint32_t, mcal::reg::dmtimer7::tldr, UINT32_C(0xFFFFFFFE - 24000)>::reg_set();

    // Setup auto reload mode and start dmtimer7, with no prescaler.
    mcal::reg::access<std::uint32_t, std::uint32_t, mcal::reg::dmtimer7::tclr, UINT32_C(3)>::reg_set();

    gpt_is_initialized() = true;
  }
}
Example #7
0
void mcal::gpt::init(const config_type*)
{
  // Set up an interrupt on timer0 for a system tick based
  // on the free-running 32-bit timer0 with a frequency of 2,625MHz.

  // Set the timer prescaler to 84 resulting in a 10,5MHz frequency.
  util::dma<uint32,
            uint32>::reg_set(mcal::reg::tc_cmr0_c0, UINT32_C(0x01));

  // Start Timer.
  util::dma<uint32,
            uint32>::reg_set(mcal::reg::tc_ier0_c0, UINT32_C(0x01));

  // Enable the update interrupt.
  util::dma<uint32,
            uint32>::reg_set(mcal::reg::tc_ier0_c0, UINT32_C(0x01));

  // Set the is-initialized indication flag.
  gpt_is_initialized() = true;
}
Example #8
0
mcal::gpt::value_type mcal::gpt::secure::get_time_elapsed()
{
  // Return the system tick using a multiple read to ensure
  // data consistency of the high-byte of the system tick.

  typedef std::uint8_t timer_address_type;
  typedef std::uint8_t timer_register_type;

  // Do the first read of the timer0 counter and the system tick.
  const timer_register_type tim0_cnt_1 = mcal::reg::access<timer_address_type, timer_register_type, mcal::reg::tcnt0>::reg_get();

  // Read the system tick.
  const mcal::gpt::value_type sys_tick_1 = system_tick;

  // Do the second read of the timer0 counter and the system tick.
  const timer_register_type tim0_cnt_2 = mcal::reg::access<timer_address_type, timer_register_type, mcal::reg::tcnt0>::reg_get();

  // Perform the consistency check and obtain the consistent microsecond tick.
  const mcal::gpt::value_type consistent_microsecond_tick
    = ((tim0_cnt_2 >= tim0_cnt_1) ? mcal::gpt::value_type(sys_tick_1  | std::uint8_t(tim0_cnt_1 >> 1U))
                                  : mcal::gpt::value_type(system_tick | std::uint8_t(tim0_cnt_2 >> 1U)));

  return (gpt_is_initialized() ? consistent_microsecond_tick : mcal::gpt::value_type(0U));
}
Example #9
0
mcal::gpt::value_type mcal::gpt::get_time_elapsed()
{
  return (gpt_is_initialized() ? consistent_microsecond_tick()
                               : mcal::gpt::value_type(0U));
}