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