RTC auf true

Committer:
kevman
Date:
Wed Mar 13 11:03:24 2019 +0000
Revision:
2:7aab896b1a3b
Parent:
0:38ceb79fef03
2019-03-13

Who changed what in which revision?

UserRevisionLine numberNew contents of line
kevman 0:38ceb79fef03 1 /* mbed Microcontroller Library
kevman 0:38ceb79fef03 2 * Copyright (c) 2006-2012 ARM Limited
kevman 0:38ceb79fef03 3 *
kevman 0:38ceb79fef03 4 * Permission is hereby granted, free of charge, to any person obtaining a copy
kevman 0:38ceb79fef03 5 * of this software and associated documentation files (the "Software"), to deal
kevman 0:38ceb79fef03 6 * in the Software without restriction, including without limitation the rights
kevman 0:38ceb79fef03 7 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
kevman 0:38ceb79fef03 8 * copies of the Software, and to permit persons to whom the Software is
kevman 0:38ceb79fef03 9 * furnished to do so, subject to the following conditions:
kevman 0:38ceb79fef03 10 *
kevman 0:38ceb79fef03 11 * The above copyright notice and this permission notice shall be included in
kevman 0:38ceb79fef03 12 * all copies or substantial portions of the Software.
kevman 0:38ceb79fef03 13 *
kevman 0:38ceb79fef03 14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
kevman 0:38ceb79fef03 15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
kevman 0:38ceb79fef03 16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
kevman 0:38ceb79fef03 17 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
kevman 0:38ceb79fef03 18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
kevman 0:38ceb79fef03 19 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
kevman 0:38ceb79fef03 20 * SOFTWARE.
kevman 0:38ceb79fef03 21 */
kevman 0:38ceb79fef03 22 #include "rtos/TARGET_CORTEX/SysTimer.h"
kevman 0:38ceb79fef03 23
kevman 0:38ceb79fef03 24 #if DEVICE_LPTICKER
kevman 0:38ceb79fef03 25
kevman 0:38ceb79fef03 26 #include "hal/lp_ticker_api.h"
kevman 0:38ceb79fef03 27 #include "mbed_critical.h"
kevman 0:38ceb79fef03 28 #if defined(TARGET_CORTEX_A)
kevman 0:38ceb79fef03 29 #include "rtx_core_ca.h"
kevman 0:38ceb79fef03 30 #else//Cortex-M
kevman 0:38ceb79fef03 31 #include "rtx_core_cm.h"
kevman 0:38ceb79fef03 32 #endif
kevman 0:38ceb79fef03 33 extern "C" {
kevman 0:38ceb79fef03 34 #include "rtx_lib.h"
kevman 0:38ceb79fef03 35 #if defined(TARGET_CORTEX_A)
kevman 0:38ceb79fef03 36 #include "irq_ctrl.h"
kevman 0:38ceb79fef03 37 #endif
kevman 0:38ceb79fef03 38 }
kevman 0:38ceb79fef03 39
kevman 0:38ceb79fef03 40 #if (defined(NO_SYSTICK))
kevman 0:38ceb79fef03 41 /**
kevman 0:38ceb79fef03 42 * Return an IRQ number that can be used in the absence of SysTick
kevman 0:38ceb79fef03 43 *
kevman 0:38ceb79fef03 44 * @return Free IRQ number that can be used
kevman 0:38ceb79fef03 45 */
kevman 0:38ceb79fef03 46 extern "C" IRQn_Type mbed_get_m0_tick_irqn(void);
kevman 0:38ceb79fef03 47 #endif
kevman 0:38ceb79fef03 48
kevman 0:38ceb79fef03 49 #if defined(TARGET_CORTEX_A)
kevman 0:38ceb79fef03 50 extern "C" IRQn_ID_t mbed_get_a9_tick_irqn(void);
kevman 0:38ceb79fef03 51 #endif
kevman 0:38ceb79fef03 52
kevman 0:38ceb79fef03 53 namespace rtos {
kevman 0:38ceb79fef03 54 namespace internal {
kevman 0:38ceb79fef03 55
kevman 0:38ceb79fef03 56 SysTimer::SysTimer() :
kevman 0:38ceb79fef03 57 TimerEvent(get_lp_ticker_data()), _start_time(0), _tick(0)
kevman 0:38ceb79fef03 58 {
kevman 0:38ceb79fef03 59 _start_time = ticker_read_us(_ticker_data);
kevman 0:38ceb79fef03 60 _suspend_time_passed = true;
kevman 0:38ceb79fef03 61 _suspended = false;
kevman 0:38ceb79fef03 62 }
kevman 0:38ceb79fef03 63
kevman 0:38ceb79fef03 64 SysTimer::SysTimer(const ticker_data_t *data) :
kevman 0:38ceb79fef03 65 TimerEvent(data), _start_time(0), _tick(0)
kevman 0:38ceb79fef03 66 {
kevman 0:38ceb79fef03 67 _start_time = ticker_read_us(_ticker_data);
kevman 0:38ceb79fef03 68 }
kevman 0:38ceb79fef03 69
kevman 0:38ceb79fef03 70 void SysTimer::setup_irq()
kevman 0:38ceb79fef03 71 {
kevman 0:38ceb79fef03 72 #if (defined(NO_SYSTICK) && !defined (TARGET_CORTEX_A))
kevman 0:38ceb79fef03 73 NVIC_SetVector(mbed_get_m0_tick_irqn(), (uint32_t)SysTick_Handler);
kevman 0:38ceb79fef03 74 NVIC_SetPriority(mbed_get_m0_tick_irqn(), 0xFF); /* RTOS requires lowest priority */
kevman 0:38ceb79fef03 75 NVIC_EnableIRQ(mbed_get_m0_tick_irqn());
kevman 0:38ceb79fef03 76 #else
kevman 0:38ceb79fef03 77 // Ensure SysTick has the correct priority as it is still used
kevman 0:38ceb79fef03 78 // to trigger software interrupts on each tick. The period does
kevman 0:38ceb79fef03 79 // not matter since it will never start counting.
kevman 0:38ceb79fef03 80 OS_Tick_Setup(osRtxConfig.tick_freq, OS_TICK_HANDLER);
kevman 0:38ceb79fef03 81 #endif
kevman 0:38ceb79fef03 82 }
kevman 0:38ceb79fef03 83
kevman 0:38ceb79fef03 84 void SysTimer::suspend(uint32_t ticks)
kevman 0:38ceb79fef03 85 {
kevman 0:38ceb79fef03 86 core_util_critical_section_enter();
kevman 0:38ceb79fef03 87
kevman 0:38ceb79fef03 88 remove();
kevman 0:38ceb79fef03 89 schedule_tick(ticks);
kevman 0:38ceb79fef03 90 _suspend_time_passed = false;
kevman 0:38ceb79fef03 91 _suspended = true;
kevman 0:38ceb79fef03 92
kevman 0:38ceb79fef03 93 core_util_critical_section_exit();
kevman 0:38ceb79fef03 94 }
kevman 0:38ceb79fef03 95
kevman 0:38ceb79fef03 96 bool SysTimer::suspend_time_passed()
kevman 0:38ceb79fef03 97 {
kevman 0:38ceb79fef03 98 return _suspend_time_passed;
kevman 0:38ceb79fef03 99 }
kevman 0:38ceb79fef03 100
kevman 0:38ceb79fef03 101 uint32_t SysTimer::resume()
kevman 0:38ceb79fef03 102 {
kevman 0:38ceb79fef03 103 core_util_critical_section_enter();
kevman 0:38ceb79fef03 104
kevman 0:38ceb79fef03 105 _suspended = false;
kevman 0:38ceb79fef03 106 _suspend_time_passed = true;
kevman 0:38ceb79fef03 107 remove();
kevman 0:38ceb79fef03 108
kevman 0:38ceb79fef03 109 uint64_t new_tick = (ticker_read_us(_ticker_data) - _start_time) * OS_TICK_FREQ / 1000000;
kevman 0:38ceb79fef03 110 if (new_tick > _tick) {
kevman 0:38ceb79fef03 111 // Don't update to the current tick. Instead, update to the
kevman 0:38ceb79fef03 112 // previous tick and let the SysTick handler increment it
kevman 0:38ceb79fef03 113 // to the current value. This allows scheduling restart
kevman 0:38ceb79fef03 114 // successfully after the OS is resumed.
kevman 0:38ceb79fef03 115 new_tick--;
kevman 0:38ceb79fef03 116 }
kevman 0:38ceb79fef03 117 uint32_t elapsed_ticks = new_tick - _tick;
kevman 0:38ceb79fef03 118 _tick = new_tick;
kevman 0:38ceb79fef03 119
kevman 0:38ceb79fef03 120 core_util_critical_section_exit();
kevman 0:38ceb79fef03 121 return elapsed_ticks;
kevman 0:38ceb79fef03 122 }
kevman 0:38ceb79fef03 123
kevman 0:38ceb79fef03 124 void SysTimer::schedule_tick(uint32_t delta)
kevman 0:38ceb79fef03 125 {
kevman 0:38ceb79fef03 126 core_util_critical_section_enter();
kevman 0:38ceb79fef03 127
kevman 0:38ceb79fef03 128 insert_absolute(_start_time + (_tick + delta) * 1000000ULL / OS_TICK_FREQ);
kevman 0:38ceb79fef03 129
kevman 0:38ceb79fef03 130 core_util_critical_section_exit();
kevman 0:38ceb79fef03 131 }
kevman 0:38ceb79fef03 132
kevman 0:38ceb79fef03 133 void SysTimer::cancel_tick()
kevman 0:38ceb79fef03 134 {
kevman 0:38ceb79fef03 135 core_util_critical_section_enter();
kevman 0:38ceb79fef03 136
kevman 0:38ceb79fef03 137 remove();
kevman 0:38ceb79fef03 138
kevman 0:38ceb79fef03 139 core_util_critical_section_exit();
kevman 0:38ceb79fef03 140 }
kevman 0:38ceb79fef03 141
kevman 0:38ceb79fef03 142 uint32_t SysTimer::get_tick()
kevman 0:38ceb79fef03 143 {
kevman 0:38ceb79fef03 144 return _tick & 0xFFFFFFFF;
kevman 0:38ceb79fef03 145 }
kevman 0:38ceb79fef03 146
kevman 0:38ceb79fef03 147 us_timestamp_t SysTimer::get_time()
kevman 0:38ceb79fef03 148 {
kevman 0:38ceb79fef03 149 return ticker_read_us(_ticker_data);
kevman 0:38ceb79fef03 150 }
kevman 0:38ceb79fef03 151
kevman 0:38ceb79fef03 152 SysTimer::~SysTimer()
kevman 0:38ceb79fef03 153 {
kevman 0:38ceb79fef03 154 }
kevman 0:38ceb79fef03 155
kevman 0:38ceb79fef03 156 void SysTimer::_set_irq_pending()
kevman 0:38ceb79fef03 157 {
kevman 0:38ceb79fef03 158 // Protected function synchronized externally
kevman 0:38ceb79fef03 159
kevman 0:38ceb79fef03 160 #if (defined(NO_SYSTICK))
kevman 0:38ceb79fef03 161 NVIC_SetPendingIRQ(mbed_get_m0_tick_irqn());
kevman 0:38ceb79fef03 162 #elif (TARGET_CORTEX_A)
kevman 0:38ceb79fef03 163 IRQ_SetPending(mbed_get_a9_tick_irqn());
kevman 0:38ceb79fef03 164 #else
kevman 0:38ceb79fef03 165 SCB->ICSR = SCB_ICSR_PENDSTSET_Msk;
kevman 0:38ceb79fef03 166 #endif
kevman 0:38ceb79fef03 167 }
kevman 0:38ceb79fef03 168
kevman 0:38ceb79fef03 169 void SysTimer::_increment_tick()
kevman 0:38ceb79fef03 170 {
kevman 0:38ceb79fef03 171 // Protected function synchronized externally
kevman 0:38ceb79fef03 172
kevman 0:38ceb79fef03 173 _tick++;
kevman 0:38ceb79fef03 174 }
kevman 0:38ceb79fef03 175
kevman 0:38ceb79fef03 176 void SysTimer::handler()
kevman 0:38ceb79fef03 177 {
kevman 0:38ceb79fef03 178 core_util_critical_section_enter();
kevman 0:38ceb79fef03 179
kevman 0:38ceb79fef03 180 if (_suspended) {
kevman 0:38ceb79fef03 181 _suspend_time_passed = true;
kevman 0:38ceb79fef03 182 } else {
kevman 0:38ceb79fef03 183 _set_irq_pending();
kevman 0:38ceb79fef03 184 _increment_tick();
kevman 0:38ceb79fef03 185 schedule_tick();
kevman 0:38ceb79fef03 186 }
kevman 0:38ceb79fef03 187
kevman 0:38ceb79fef03 188 core_util_critical_section_exit();
kevman 0:38ceb79fef03 189 }
kevman 0:38ceb79fef03 190
kevman 0:38ceb79fef03 191 }
kevman 0:38ceb79fef03 192 }
kevman 0:38ceb79fef03 193
kevman 0:38ceb79fef03 194 #endif