Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
arm_hal_timer.cpp
00001 /* 00002 * Copyright (c) 2016 ARM Limited, All Rights Reserved 00003 */ 00004 00005 // Include before mbed.h to properly get UINT*_C() 00006 #include "ns_types.h" 00007 00008 #include "mbed.h" 00009 #include "platform/SingletonPtr.h" 00010 #include "platform/arm_hal_timer.h" 00011 #include "platform/arm_hal_interrupt.h" 00012 #include <mbed_assert.h> 00013 00014 static SingletonPtr<Timer> timer; 00015 static SingletonPtr<Timeout> timeout; 00016 00017 // If critical sections are implemented using mutexes, timers must be called in thread context, and 00018 // we use the high-priority event queue for this. 00019 // If critical sections disable interrupts, we can call timers directly from interrupt. Avoiding the 00020 // event queue can save ~1600B of RAM if the rest of the system is not using the event queue either. 00021 // Caveats of this tunable are listed on arm_hal_interrupt.c. 00022 #if !MBED_CONF_NANOSTACK_HAL_CRITICAL_SECTION_USABLE_FROM_INTERRUPT 00023 static EventQueue *equeue; 00024 #endif 00025 00026 static uint32_t due; 00027 static void (*arm_hal_callback)(void); 00028 00029 // Called once at boot 00030 void platform_timer_enable(void) 00031 { 00032 #if !MBED_CONF_NANOSTACK_HAL_CRITICAL_SECTION_USABLE_FROM_INTERRUPT 00033 equeue = mbed_highprio_event_queue(); 00034 MBED_ASSERT(equeue != NULL); 00035 #endif 00036 // Prime the SingletonPtrs - can't construct from IRQ/critical section 00037 timer.get(); 00038 timeout.get(); 00039 } 00040 00041 // Actually cancels a timer, not the opposite of enable 00042 void platform_timer_disable(void) 00043 { 00044 timeout->detach(); 00045 } 00046 00047 // Not called while running, fortunately 00048 void platform_timer_set_cb(void (*new_fp)(void)) 00049 { 00050 arm_hal_callback = new_fp; 00051 } 00052 00053 static void timer_callback(void) 00054 { 00055 due = 0; 00056 00057 #if MBED_CONF_NANOSTACK_HAL_CRITICAL_SECTION_USABLE_FROM_INTERRUPT 00058 // Callback is interrupt safe so it can be called directly without 00059 // bouncing via event queue thread. 00060 arm_hal_callback(); 00061 #else 00062 equeue->call(arm_hal_callback); 00063 #endif 00064 } 00065 00066 // This is called from inside platform_enter_critical - IRQs can't happen 00067 void platform_timer_start(uint16_t slots) 00068 { 00069 timer->reset(); 00070 due = slots * UINT32_C(50); 00071 timeout->attach_us(timer_callback, due); 00072 } 00073 00074 // This is called from inside platform_enter_critical - IRQs can't happen 00075 uint16_t platform_timer_get_remaining_slots(void) 00076 { 00077 uint32_t elapsed = timer->read_us(); 00078 if (elapsed < due) { 00079 return (uint16_t) ((due - elapsed) / 50); 00080 } else { 00081 return 0; 00082 } 00083 } 00084
Generated on Tue Jul 12 2022 12:43:32 by
