1*a8f7f3fcSMatthias Ringwald /**************************************************************************//** 2*a8f7f3fcSMatthias Ringwald * @file os_systick.c 3*a8f7f3fcSMatthias Ringwald * @brief CMSIS OS Tick SysTick implementation 4*a8f7f3fcSMatthias Ringwald * @version V1.0.1 5*a8f7f3fcSMatthias Ringwald * @date 24. November 2017 6*a8f7f3fcSMatthias Ringwald ******************************************************************************/ 7*a8f7f3fcSMatthias Ringwald /* 8*a8f7f3fcSMatthias Ringwald * Copyright (c) 2017-2017 ARM Limited. All rights reserved. 9*a8f7f3fcSMatthias Ringwald * 10*a8f7f3fcSMatthias Ringwald * SPDX-License-Identifier: Apache-2.0 11*a8f7f3fcSMatthias Ringwald * 12*a8f7f3fcSMatthias Ringwald * Licensed under the Apache License, Version 2.0 (the License); you may 13*a8f7f3fcSMatthias Ringwald * not use this file except in compliance with the License. 14*a8f7f3fcSMatthias Ringwald * You may obtain a copy of the License at 15*a8f7f3fcSMatthias Ringwald * 16*a8f7f3fcSMatthias Ringwald * www.apache.org/licenses/LICENSE-2.0 17*a8f7f3fcSMatthias Ringwald * 18*a8f7f3fcSMatthias Ringwald * Unless required by applicable law or agreed to in writing, software 19*a8f7f3fcSMatthias Ringwald * distributed under the License is distributed on an AS IS BASIS, WITHOUT 20*a8f7f3fcSMatthias Ringwald * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 21*a8f7f3fcSMatthias Ringwald * See the License for the specific language governing permissions and 22*a8f7f3fcSMatthias Ringwald * limitations under the License. 23*a8f7f3fcSMatthias Ringwald */ 24*a8f7f3fcSMatthias Ringwald 25*a8f7f3fcSMatthias Ringwald #include "os_tick.h" 26*a8f7f3fcSMatthias Ringwald 27*a8f7f3fcSMatthias Ringwald //lint -emacro((923,9078),SCB,SysTick) "cast from unsigned long to pointer" 28*a8f7f3fcSMatthias Ringwald #include "RTE_Components.h" 29*a8f7f3fcSMatthias Ringwald #include CMSIS_device_header 30*a8f7f3fcSMatthias Ringwald 31*a8f7f3fcSMatthias Ringwald #ifdef SysTick 32*a8f7f3fcSMatthias Ringwald 33*a8f7f3fcSMatthias Ringwald #ifndef SYSTICK_IRQ_PRIORITY 34*a8f7f3fcSMatthias Ringwald #define SYSTICK_IRQ_PRIORITY 0xFFU 35*a8f7f3fcSMatthias Ringwald #endif 36*a8f7f3fcSMatthias Ringwald 37*a8f7f3fcSMatthias Ringwald static uint8_t PendST; 38*a8f7f3fcSMatthias Ringwald 39*a8f7f3fcSMatthias Ringwald // Setup OS Tick. OS_Tick_Setup(uint32_t freq,IRQHandler_t handler)40*a8f7f3fcSMatthias Ringwald__WEAK int32_t OS_Tick_Setup (uint32_t freq, IRQHandler_t handler) { 41*a8f7f3fcSMatthias Ringwald uint32_t load; 42*a8f7f3fcSMatthias Ringwald (void)handler; 43*a8f7f3fcSMatthias Ringwald 44*a8f7f3fcSMatthias Ringwald if (freq == 0U) { 45*a8f7f3fcSMatthias Ringwald //lint -e{904} "Return statement before end of function" 46*a8f7f3fcSMatthias Ringwald return (-1); 47*a8f7f3fcSMatthias Ringwald } 48*a8f7f3fcSMatthias Ringwald 49*a8f7f3fcSMatthias Ringwald load = (SystemCoreClock / freq) - 1U; 50*a8f7f3fcSMatthias Ringwald if (load > 0x00FFFFFFU) { 51*a8f7f3fcSMatthias Ringwald //lint -e{904} "Return statement before end of function" 52*a8f7f3fcSMatthias Ringwald return (-1); 53*a8f7f3fcSMatthias Ringwald } 54*a8f7f3fcSMatthias Ringwald 55*a8f7f3fcSMatthias Ringwald // Set SysTick Interrupt Priority 56*a8f7f3fcSMatthias Ringwald #if ((defined(__ARM_ARCH_8M_MAIN__) && (__ARM_ARCH_8M_MAIN__ != 0)) || \ 57*a8f7f3fcSMatthias Ringwald (defined(__CORTEX_M) && (__CORTEX_M == 7U))) 58*a8f7f3fcSMatthias Ringwald SCB->SHPR[11] = SYSTICK_IRQ_PRIORITY; 59*a8f7f3fcSMatthias Ringwald #elif (defined(__ARM_ARCH_8M_BASE__) && (__ARM_ARCH_8M_BASE__ != 0)) 60*a8f7f3fcSMatthias Ringwald SCB->SHPR[1] |= ((uint32_t)SYSTICK_IRQ_PRIORITY << 24); 61*a8f7f3fcSMatthias Ringwald #elif ((defined(__ARM_ARCH_7M__) && (__ARM_ARCH_7M__ != 0)) || \ 62*a8f7f3fcSMatthias Ringwald (defined(__ARM_ARCH_7EM__) && (__ARM_ARCH_7EM__ != 0))) 63*a8f7f3fcSMatthias Ringwald SCB->SHP[11] = SYSTICK_IRQ_PRIORITY; 64*a8f7f3fcSMatthias Ringwald #elif (defined(__ARM_ARCH_6M__) && (__ARM_ARCH_6M__ != 0)) 65*a8f7f3fcSMatthias Ringwald SCB->SHP[1] |= ((uint32_t)SYSTICK_IRQ_PRIORITY << 24); 66*a8f7f3fcSMatthias Ringwald #else 67*a8f7f3fcSMatthias Ringwald #error "Unknown ARM Core!" 68*a8f7f3fcSMatthias Ringwald #endif 69*a8f7f3fcSMatthias Ringwald 70*a8f7f3fcSMatthias Ringwald SysTick->CTRL = SysTick_CTRL_CLKSOURCE_Msk | SysTick_CTRL_TICKINT_Msk; 71*a8f7f3fcSMatthias Ringwald SysTick->LOAD = load; 72*a8f7f3fcSMatthias Ringwald SysTick->VAL = 0U; 73*a8f7f3fcSMatthias Ringwald 74*a8f7f3fcSMatthias Ringwald PendST = 0U; 75*a8f7f3fcSMatthias Ringwald 76*a8f7f3fcSMatthias Ringwald return (0); 77*a8f7f3fcSMatthias Ringwald } 78*a8f7f3fcSMatthias Ringwald 79*a8f7f3fcSMatthias Ringwald /// Enable OS Tick. OS_Tick_Enable(void)80*a8f7f3fcSMatthias Ringwald__WEAK void OS_Tick_Enable (void) { 81*a8f7f3fcSMatthias Ringwald 82*a8f7f3fcSMatthias Ringwald if (PendST != 0U) { 83*a8f7f3fcSMatthias Ringwald PendST = 0U; 84*a8f7f3fcSMatthias Ringwald SCB->ICSR = SCB_ICSR_PENDSTSET_Msk; 85*a8f7f3fcSMatthias Ringwald } 86*a8f7f3fcSMatthias Ringwald 87*a8f7f3fcSMatthias Ringwald SysTick->CTRL |= SysTick_CTRL_ENABLE_Msk; 88*a8f7f3fcSMatthias Ringwald } 89*a8f7f3fcSMatthias Ringwald 90*a8f7f3fcSMatthias Ringwald /// Disable OS Tick. OS_Tick_Disable(void)91*a8f7f3fcSMatthias Ringwald__WEAK void OS_Tick_Disable (void) { 92*a8f7f3fcSMatthias Ringwald 93*a8f7f3fcSMatthias Ringwald SysTick->CTRL &= ~SysTick_CTRL_ENABLE_Msk; 94*a8f7f3fcSMatthias Ringwald 95*a8f7f3fcSMatthias Ringwald if ((SCB->ICSR & SCB_ICSR_PENDSTSET_Msk) != 0U) { 96*a8f7f3fcSMatthias Ringwald SCB->ICSR = SCB_ICSR_PENDSTCLR_Msk; 97*a8f7f3fcSMatthias Ringwald PendST = 1U; 98*a8f7f3fcSMatthias Ringwald } 99*a8f7f3fcSMatthias Ringwald } 100*a8f7f3fcSMatthias Ringwald 101*a8f7f3fcSMatthias Ringwald // Acknowledge OS Tick IRQ. OS_Tick_AcknowledgeIRQ(void)102*a8f7f3fcSMatthias Ringwald__WEAK void OS_Tick_AcknowledgeIRQ (void) { 103*a8f7f3fcSMatthias Ringwald (void)SysTick->CTRL; 104*a8f7f3fcSMatthias Ringwald } 105*a8f7f3fcSMatthias Ringwald 106*a8f7f3fcSMatthias Ringwald // Get OS Tick IRQ number. OS_Tick_GetIRQn(void)107*a8f7f3fcSMatthias Ringwald__WEAK int32_t OS_Tick_GetIRQn (void) { 108*a8f7f3fcSMatthias Ringwald return ((int32_t)SysTick_IRQn); 109*a8f7f3fcSMatthias Ringwald } 110*a8f7f3fcSMatthias Ringwald 111*a8f7f3fcSMatthias Ringwald // Get OS Tick clock. OS_Tick_GetClock(void)112*a8f7f3fcSMatthias Ringwald__WEAK uint32_t OS_Tick_GetClock (void) { 113*a8f7f3fcSMatthias Ringwald return (SystemCoreClock); 114*a8f7f3fcSMatthias Ringwald } 115*a8f7f3fcSMatthias Ringwald 116*a8f7f3fcSMatthias Ringwald // Get OS Tick interval. OS_Tick_GetInterval(void)117*a8f7f3fcSMatthias Ringwald__WEAK uint32_t OS_Tick_GetInterval (void) { 118*a8f7f3fcSMatthias Ringwald return (SysTick->LOAD + 1U); 119*a8f7f3fcSMatthias Ringwald } 120*a8f7f3fcSMatthias Ringwald 121*a8f7f3fcSMatthias Ringwald // Get OS Tick count value. OS_Tick_GetCount(void)122*a8f7f3fcSMatthias Ringwald__WEAK uint32_t OS_Tick_GetCount (void) { 123*a8f7f3fcSMatthias Ringwald uint32_t load = SysTick->LOAD; 124*a8f7f3fcSMatthias Ringwald return (load - SysTick->VAL); 125*a8f7f3fcSMatthias Ringwald } 126*a8f7f3fcSMatthias Ringwald 127*a8f7f3fcSMatthias Ringwald // Get OS Tick overflow status. OS_Tick_GetOverflow(void)128*a8f7f3fcSMatthias Ringwald__WEAK uint32_t OS_Tick_GetOverflow (void) { 129*a8f7f3fcSMatthias Ringwald return ((SysTick->CTRL >> 16) & 1U); 130*a8f7f3fcSMatthias Ringwald } 131*a8f7f3fcSMatthias Ringwald 132*a8f7f3fcSMatthias Ringwald #endif // SysTick 133