123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184 |
- /*
- * Copyright (c) 2011-2012, Freescale Semiconductor, Inc.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without modification,
- * are permitted provided that the following conditions are met:
- *
- * o Redistributions of source code must retain the above copyright notice, this list
- * of conditions and the following disclaimer.
- *
- * o Redistributions in binary form must reproduce the above copyright notice, this
- * list of conditions and the following disclaimer in the documentation and/or
- * other materials provided with the distribution.
- *
- * o Neither the name of Freescale Semiconductor, Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from this
- * software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
- * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
- /*!
- * @file timer.c
- * @brief Basic timer functions
- *
- * @ingroup diag_timer
- */
- #include <assert.h>
- #include "imx_timer.h"
- #include "sdk.h"
- #include "epit.h"
- #include "registers/regsarmglobaltimer.h"
- #include "ccm_pll.h"
- ////////////////////////////////////////////////////////////////////////////////
- // Prototypes
- ////////////////////////////////////////////////////////////////////////////////
- static void time_init_global_timer();
- ////////////////////////////////////////////////////////////////////////////////
- // Variables
- ////////////////////////////////////////////////////////////////////////////////
- uint32_t g_microsecondTimerMultiple=8;
- ////////////////////////////////////////////////////////////////////////////////
- // Code
- ////////////////////////////////////////////////////////////////////////////////
- void hal_delay_us(uint32_t usecs)
- {
- uint32_t instance = g_system_timer_port;
- if (usecs == 0) {
- return;
- }
- /* enable the counter first */
- epit_counter_enable(instance, usecs, POLLING_MODE);
-
- /* wait for the compare event */
- while (!epit_get_compare_event(instance)) ;
-
- /* disable the counter to save power */
- epit_counter_disable(instance);
- }
- void system_time_init(void)
- {
- uint32_t freq;
- // Init microsecond tick counter.
- time_init_global_timer();
-
- /* EPIT1 is used for the delay function */
- /* Initialize the EPIT timer used for system time functions */
- /* typical IPG_CLK is in MHz, so divide it to get a reference
- clock of 1MHz => 1us per count */
- freq = get_main_clock(IPG_CLK);
- epit_init(g_system_timer_port, CLKSRC_IPG_CLK, freq / 1000000,
- SET_AND_FORGET, 1000, WAIT_MODE_EN | STOP_MODE_EN);
- }
- #if defined(CHIP_MX6UL)
- //! Init the ARM global timer to a microsecond-frequency clock.
- void time_init_global_timer()
- {
- // Make sure the timer is off.
- HW_ARMGLOBALTIMER_CONTROL.B.TIMER_ENABLE = 0;
-
- HW_ARMGLOBALTIMER_CONTROL.B.FCR0 =1;
-
- HW_ARMGLOBALTIMER_CONTROL.B.FCR1 =0;
-
- HW_ARMGLOBALTIMER_CONTROL.B.DBG_ENABLE =0;
-
- // Clear counter.
- HW_ARMGLOBALTIMER_COUNTER_HI_WR(0);
- HW_ARMGLOBALTIMER_COUNTER_LO_WR(0);
-
- // Now turn on the timer.
- HW_ARMGLOBALTIMER_CONTROL.B.TIMER_ENABLE = 1;
- }
- uint64_t time_get_microseconds()
- {
- // First read upper.
- uint32_t upper = HW_ARMGLOBALTIMER_COUNTER_HI_RD();
- uint32_t lower = HW_ARMGLOBALTIMER_COUNTER_LO_RD();
- return (((uint64_t)upper << 32) | (uint64_t)lower)/8;
- }
- #else
- //! Init the ARM global timer to a microsecond-frequency clock.
- void time_init_global_timer()
- {
- // The ARM private peripheral clock is half the CPU clock.
- uint32_t periphClock = get_main_clock(CPU_CLK) / 2;
- uint32_t prescaler = (periphClock / 1000000) - 1;
-
- // Divide down the prescaler until it fits into 8 bits. We add up the number of ticks
- // it takes to equal a microsecond interval.
- g_microsecondTimerMultiple = 1;
- while (prescaler > 0xff)
- {
- prescaler /= 2;
- ++g_microsecondTimerMultiple;
- }
-
- // Make sure the timer is off.
- HW_ARMGLOBALTIMER_CONTROL.B.TIMER_ENABLE = 0;
-
- // Clear counter.
- HW_ARMGLOBALTIMER_COUNTERn_WR(0, 0);
- HW_ARMGLOBALTIMER_COUNTERn_WR(1, 0);
-
- // Set prescaler and clear other flags.
- HW_ARMGLOBALTIMER_CONTROL_WR(BF_ARMGLOBALTIMER_CONTROL_PRESCALER(prescaler));
-
- // Now turn on the timer.
- HW_ARMGLOBALTIMER_CONTROL.B.TIMER_ENABLE = 1;
- }
- uint64_t time_get_microseconds()
- {
- // First read upper.
- uint32_t upper = HW_ARMGLOBALTIMER_COUNTERn_RD(1);
- uint32_t lower;
-
- while (true)
- {
- // Read lower.
- lower = HW_ARMGLOBALTIMER_COUNTERn_RD(0);
-
- // Read upper again.
- uint32_t newUpper = HW_ARMGLOBALTIMER_COUNTERn_RD(1);
-
- // If the first and second read of the upper bits are the same, then return.
- if (newUpper == upper)
- {
- return (((uint64_t)upper << 32) | (uint64_t)lower) / g_microsecondTimerMultiple;
- }
-
- // Otherwise, start over again.
- upper = newUpper;
- }
-
- return 0;
- }
- #endif
- ////////////////////////////////////////////////////////////////////////////////
- // EOF
- ////////////////////////////////////////////////////////////////////////////////
|