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(); } }
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; } }
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); } }
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); } }
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; } }
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; } }
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; }
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)); }
mcal::gpt::value_type mcal::gpt::get_time_elapsed() { return (gpt_is_initialized() ? consistent_microsecond_tick() : mcal::gpt::value_type(0U)); }