1 /* 2 * Copyright (c) 2016, Freescale Semiconductor, Inc. 3 * Copyright 2016-2017 NXP 4 * All rights reserved. 5 * 6 * SPDX-License-Identifier: BSD-3-Clause 7 */ 8 9 /** 10 * @file systick_utils.c 11 * @brief Encapsulates the ARM sysTick counter, which is used for computing delays. 12 * ARM-core specific function that enables the ARM systick timer on Kinetis uCs. 13 * the timer is 24 bit so allows measurement of intervals up to 2^24/CORE_SYSTICK_HZ secs=0.35s for a 48MHz uC. 14 */ 15 16 #include "issdk_hal.h" 17 18 // SysTick register definitions based on CMSIS definitions. 19 #define SYST_CSR SysTick->CTRL // SysTick Control & Status Register 20 #define SYST_RVR SysTick->LOAD // SysTick Reload Value Register 21 #define SYST_CVR SysTick->VAL // SysTick Current Value Register 22 23 uint32_t g_ovf_stamp; 24 volatile uint32_t g_ovf_counter = 0; 25 26 #ifndef SDK_OS_FREE_RTOS 27 // SDK specific SysTick Interrupt Handler SysTick_Handler(void)28void SysTick_Handler(void) 29 { 30 g_ovf_counter += 1; 31 } 32 #endif 33 34 // ARM-core specific function to enable systicks. BOARD_SystickEnable(void)35void BOARD_SystickEnable(void) 36 { 37 SYST_CSR = SysTick_CTRL_CLKSOURCE_Msk | SysTick_CTRL_TICKINT_Msk | 38 SysTick_CTRL_ENABLE_Msk; // Enable systick from internal clock with Interrupts. 39 SYST_RVR = 0x00FFFFFFu; // Set reload to maximum 24 bit value. 40 return; 41 } 42 43 // ARM-core specific function to store the current systick timer ticks. BOARD_SystickStart(int32_t * pStart)44void BOARD_SystickStart(int32_t *pStart) 45 { 46 // Store the 24 bit systick timer. 47 g_ovf_stamp = g_ovf_counter; 48 *pStart = SYST_CVR & 0x00FFFFFF; 49 } 50 51 // ARM-core specific function to compute the elapsed systick timer ticks. BOARD_SystickElapsedTicks(int32_t * pStart)52int32_t BOARD_SystickElapsedTicks(int32_t *pStart) 53 { 54 int32_t elapsed; 55 56 // Subtract the stored start ticks and check for wraparound down through zero. 57 elapsed = *pStart - (SYST_CVR & 0x00FFFFFF); 58 elapsed += SYST_RVR * (g_ovf_counter - g_ovf_stamp); 59 60 return elapsed; 61 } 62 63 // ARM-core specific function to compute the elapsed time in micro seconds. BOARD_SystickElapsedTime_us(int32_t * pStart)64uint32_t BOARD_SystickElapsedTime_us(int32_t *pStart) 65 { 66 uint32_t time_us, elapsed; 67 uint32_t systemCoreClock; 68 69 elapsed = BOARD_SystickElapsedTicks(pStart); 70 systemCoreClock = CLOCK_GetFreq(kCLOCK_CoreSysClk); 71 72 time_us = COUNT_TO_USEC(elapsed, systemCoreClock); 73 74 // Update the 24 bit systick timer. 75 BOARD_SystickStart(pStart); 76 77 return time_us; 78 } 79 80 // ARM-core specific function to insert delays in milli seconds. BOARD_DELAY_ms(uint32_t delay_ms)81void BOARD_DELAY_ms(uint32_t delay_ms) 82 { 83 int32_t start, elapsed; 84 uint32_t systemCoreClock = CLOCK_GetFreq(kCLOCK_CoreSysClk); 85 86 BOARD_SystickStart(&start); 87 do // Loop for requested number of ms. 88 { 89 elapsed = BOARD_SystickElapsedTicks(&start); 90 } while(COUNT_TO_MSEC(elapsed, systemCoreClock) < delay_ms); 91 } 92