takashi kadono / Mbed OS Nucleo446_SSD1331

Dependencies:   ssd1331

Committer:
kadonotakashi
Date:
Thu Oct 11 02:27:46 2018 +0000
Revision:
3:f3764f852aa8
Parent:
0:8fdf9a60065b
Nucreo 446 + SSD1331 test version;

Who changed what in which revision?

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