microbit-dal

Dependencies:   BLE_API mbed-dev-bin nRF51822

Fork of microbit-dal by Lancaster University

Committer:
LancasterUniversity
Date:
Wed Jul 13 12:18:11 2016 +0100
Revision:
32:ece16b5987dd
Parent:
31:87789e55bac7
Child:
35:8ce23bc1af38
Synchronized with git rev 36d9130b

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Jonathan Austin 1:8aa5cdb4ab67 1 /*
Jonathan Austin 1:8aa5cdb4ab67 2 The MIT License (MIT)
Jonathan Austin 1:8aa5cdb4ab67 3
Jonathan Austin 1:8aa5cdb4ab67 4 Copyright (c) 2016 British Broadcasting Corporation.
Jonathan Austin 1:8aa5cdb4ab67 5 This software is provided by Lancaster University by arrangement with the BBC.
Jonathan Austin 1:8aa5cdb4ab67 6
Jonathan Austin 1:8aa5cdb4ab67 7 Permission is hereby granted, free of charge, to any person obtaining a
Jonathan Austin 1:8aa5cdb4ab67 8 copy of this software and associated documentation files (the "Software"),
Jonathan Austin 1:8aa5cdb4ab67 9 to deal in the Software without restriction, including without limitation
Jonathan Austin 1:8aa5cdb4ab67 10 the rights to use, copy, modify, merge, publish, distribute, sublicense,
Jonathan Austin 1:8aa5cdb4ab67 11 and/or sell copies of the Software, and to permit persons to whom the
Jonathan Austin 1:8aa5cdb4ab67 12 Software is furnished to do so, subject to the following conditions:
Jonathan Austin 1:8aa5cdb4ab67 13
Jonathan Austin 1:8aa5cdb4ab67 14 The above copyright notice and this permission notice shall be included in
Jonathan Austin 1:8aa5cdb4ab67 15 all copies or substantial portions of the Software.
Jonathan Austin 1:8aa5cdb4ab67 16
Jonathan Austin 1:8aa5cdb4ab67 17 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
Jonathan Austin 1:8aa5cdb4ab67 18 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
Jonathan Austin 1:8aa5cdb4ab67 19 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
Jonathan Austin 1:8aa5cdb4ab67 20 THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
Jonathan Austin 1:8aa5cdb4ab67 21 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
Jonathan Austin 1:8aa5cdb4ab67 22 FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
Jonathan Austin 1:8aa5cdb4ab67 23 DEALINGS IN THE SOFTWARE.
Jonathan Austin 1:8aa5cdb4ab67 24 */
Jonathan Austin 1:8aa5cdb4ab67 25
Jonathan Austin 1:8aa5cdb4ab67 26 /**
Jonathan Austin 1:8aa5cdb4ab67 27 * Definitions for the MicroBit system timer.
Jonathan Austin 1:8aa5cdb4ab67 28 *
Jonathan Austin 1:8aa5cdb4ab67 29 * This module provides:
Jonathan Austin 1:8aa5cdb4ab67 30 *
Jonathan Austin 1:8aa5cdb4ab67 31 * 1) a concept of global system time since power up
Jonathan Austin 1:8aa5cdb4ab67 32 * 2) a simple periodic multiplexing API for the underlying mbed implementation.
Jonathan Austin 1:8aa5cdb4ab67 33 *
Jonathan Austin 1:8aa5cdb4ab67 34 * The latter is useful to avoid costs associated with multiple mbed Ticker instances
Jonathan Austin 1:8aa5cdb4ab67 35 * in microbit-dal components, as each incurs a significant additional RAM overhead (circa 80 bytes).
Jonathan Austin 1:8aa5cdb4ab67 36 */
Jonathan Austin 1:8aa5cdb4ab67 37 #include "MicroBitConfig.h"
Jonathan Austin 1:8aa5cdb4ab67 38 #include "MicroBitSystemTimer.h"
Jonathan Austin 1:8aa5cdb4ab67 39 #include "ErrorNo.h"
Jonathan Austin 1:8aa5cdb4ab67 40
Jonathan Austin 1:8aa5cdb4ab67 41 /*
Jonathan Austin 1:8aa5cdb4ab67 42 * Time since power on. Measured in milliseconds.
Jonathan Austin 1:8aa5cdb4ab67 43 * When stored as an unsigned long, this gives us approx 50 days between rollover, which is ample. :-)
Jonathan Austin 1:8aa5cdb4ab67 44 */
LancasterUniversity 32:ece16b5987dd 45 static unsigned long ticks = 0;
Jonathan Austin 1:8aa5cdb4ab67 46 static unsigned int tick_period = 0;
Jonathan Austin 1:8aa5cdb4ab67 47
Jonathan Austin 1:8aa5cdb4ab67 48 // Array of components which are iterated during a system tick
Jonathan Austin 1:8aa5cdb4ab67 49 static MicroBitComponent* systemTickComponents[MICROBIT_SYSTEM_COMPONENTS];
Jonathan Austin 1:8aa5cdb4ab67 50
Jonathan Austin 1:8aa5cdb4ab67 51 // Periodic callback interrupt
LancasterUniversity 32:ece16b5987dd 52 static Ticker *timer = NULL;
Jonathan Austin 1:8aa5cdb4ab67 53
Jonathan Austin 1:8aa5cdb4ab67 54
Jonathan Austin 1:8aa5cdb4ab67 55 /**
LancasterUniversity 32:ece16b5987dd 56 * Initialises the system wide timer.
Jonathan Austin 1:8aa5cdb4ab67 57 *
Jonathan Austin 1:8aa5cdb4ab67 58 * This must be called before any components register to receive periodic periodic callbacks.
Jonathan Austin 1:8aa5cdb4ab67 59 *
Jonathan Austin 1:8aa5cdb4ab67 60 * @param timer_period The initial period between interrupts, in millseconds.
Jonathan Austin 1:8aa5cdb4ab67 61 *
Jonathan Austin 1:8aa5cdb4ab67 62 * @return MICROBIT_OK on success.
Jonathan Austin 1:8aa5cdb4ab67 63 */
Jonathan Austin 1:8aa5cdb4ab67 64 int system_timer_init(int period)
Jonathan Austin 1:8aa5cdb4ab67 65 {
Jonathan Austin 1:8aa5cdb4ab67 66 if (timer == NULL)
LancasterUniversity 32:ece16b5987dd 67 timer = new Ticker();
Jonathan Austin 1:8aa5cdb4ab67 68
Jonathan Austin 1:8aa5cdb4ab67 69 return system_timer_set_period(period);
Jonathan Austin 1:8aa5cdb4ab67 70 }
Jonathan Austin 1:8aa5cdb4ab67 71
Jonathan Austin 1:8aa5cdb4ab67 72 /**
Jonathan Austin 1:8aa5cdb4ab67 73 * Reconfigures the system wide timer to the given period in milliseconds.
Jonathan Austin 1:8aa5cdb4ab67 74 *
Jonathan Austin 1:8aa5cdb4ab67 75 * @param period the new period of the timer in milliseconds
Jonathan Austin 1:8aa5cdb4ab67 76 *
Jonathan Austin 1:8aa5cdb4ab67 77 * @return MICROBIT_OK on success. MICROBIT_INVALID_PARAMETER is returned if period < 1
Jonathan Austin 1:8aa5cdb4ab67 78 */
Jonathan Austin 1:8aa5cdb4ab67 79 int system_timer_set_period(int period)
Jonathan Austin 1:8aa5cdb4ab67 80 {
Jonathan Austin 1:8aa5cdb4ab67 81 if (period < 1)
Jonathan Austin 1:8aa5cdb4ab67 82 return MICROBIT_INVALID_PARAMETER;
Jonathan Austin 1:8aa5cdb4ab67 83
Jonathan Austin 1:8aa5cdb4ab67 84 // If a timer is already running, ensure it is disabled before reconfiguring.
Jonathan Austin 1:8aa5cdb4ab67 85 if (tick_period)
LancasterUniversity 32:ece16b5987dd 86 timer->detach();
Jonathan Austin 1:8aa5cdb4ab67 87
Jonathan Austin 1:8aa5cdb4ab67 88 // register a period callback to drive the scheduler and any other registered components.
Jonathan Austin 1:8aa5cdb4ab67 89 tick_period = period;
LancasterUniversity 32:ece16b5987dd 90 timer->attach_us(system_timer_tick, period * 1000);
Jonathan Austin 1:8aa5cdb4ab67 91
Jonathan Austin 1:8aa5cdb4ab67 92 return MICROBIT_OK;
Jonathan Austin 1:8aa5cdb4ab67 93 }
Jonathan Austin 1:8aa5cdb4ab67 94
Jonathan Austin 1:8aa5cdb4ab67 95 /**
Jonathan Austin 1:8aa5cdb4ab67 96 * Accessor to obtain the current tick period in milliseconds
Jonathan Austin 1:8aa5cdb4ab67 97 *
Jonathan Austin 1:8aa5cdb4ab67 98 * @return the current tick period in milliseconds
Jonathan Austin 1:8aa5cdb4ab67 99 */
Jonathan Austin 1:8aa5cdb4ab67 100 int system_timer_get_period()
Jonathan Austin 1:8aa5cdb4ab67 101 {
Jonathan Austin 1:8aa5cdb4ab67 102 return tick_period;
Jonathan Austin 1:8aa5cdb4ab67 103 }
Jonathan Austin 1:8aa5cdb4ab67 104
Jonathan Austin 1:8aa5cdb4ab67 105 /**
Jonathan Austin 1:8aa5cdb4ab67 106 * Determines the time since the device was powered on.
Jonathan Austin 1:8aa5cdb4ab67 107 *
Jonathan Austin 1:8aa5cdb4ab67 108 * @return the current time since power on in milliseconds
Jonathan Austin 1:8aa5cdb4ab67 109 */
LancasterUniversity 32:ece16b5987dd 110 unsigned long system_timer_current_time()
Jonathan Austin 1:8aa5cdb4ab67 111 {
LancasterUniversity 32:ece16b5987dd 112 return ticks;
Jonathan Austin 1:8aa5cdb4ab67 113 }
Jonathan Austin 1:8aa5cdb4ab67 114
Jonathan Austin 1:8aa5cdb4ab67 115 /**
Jonathan Austin 1:8aa5cdb4ab67 116 * Timer callback. Called from interrupt context, once per period.
Jonathan Austin 1:8aa5cdb4ab67 117 *
Jonathan Austin 1:8aa5cdb4ab67 118 * Simply checks to determine if any fibers blocked on the sleep queue need to be woken up
Jonathan Austin 1:8aa5cdb4ab67 119 * and made runnable.
Jonathan Austin 1:8aa5cdb4ab67 120 */
Jonathan Austin 1:8aa5cdb4ab67 121 void system_timer_tick()
Jonathan Austin 1:8aa5cdb4ab67 122 {
LancasterUniversity 32:ece16b5987dd 123 // increment our real-time counter.
LancasterUniversity 32:ece16b5987dd 124 ticks += system_timer_get_period();
Jonathan Austin 1:8aa5cdb4ab67 125
Jonathan Austin 1:8aa5cdb4ab67 126 // Update any components registered for a callback
Jonathan Austin 1:8aa5cdb4ab67 127 for(int i = 0; i < MICROBIT_SYSTEM_COMPONENTS; i++)
Jonathan Austin 1:8aa5cdb4ab67 128 if(systemTickComponents[i] != NULL)
Jonathan Austin 1:8aa5cdb4ab67 129 systemTickComponents[i]->systemTick();
Jonathan Austin 1:8aa5cdb4ab67 130 }
Jonathan Austin 1:8aa5cdb4ab67 131
Jonathan Austin 1:8aa5cdb4ab67 132 /**
Jonathan Austin 1:8aa5cdb4ab67 133 * Add a component to the array of system components. This component will then receive
Jonathan Austin 1:8aa5cdb4ab67 134 * periodic callbacks, once every tick period.
Jonathan Austin 1:8aa5cdb4ab67 135 *
Jonathan Austin 1:8aa5cdb4ab67 136 * @param component The component to add.
Jonathan Austin 1:8aa5cdb4ab67 137 *
Jonathan Austin 1:8aa5cdb4ab67 138 * @return MICROBIT_OK on success. MICROBIT_NO_RESOURCES is returned if the component array is full.
Jonathan Austin 1:8aa5cdb4ab67 139 *
Jonathan Austin 1:8aa5cdb4ab67 140 * @note The callback will be in interrupt context.
Jonathan Austin 1:8aa5cdb4ab67 141 */
Jonathan Austin 1:8aa5cdb4ab67 142 int system_timer_add_component(MicroBitComponent *component)
Jonathan Austin 1:8aa5cdb4ab67 143 {
Jonathan Austin 1:8aa5cdb4ab67 144 int i = 0;
Jonathan Austin 1:8aa5cdb4ab67 145
Jonathan Austin 1:8aa5cdb4ab67 146 // If we haven't been initialized, bring up the timer with the default period.
LancasterUniversity 32:ece16b5987dd 147 if (timer == NULL)
Jonathan Austin 1:8aa5cdb4ab67 148 system_timer_init(SYSTEM_TICK_PERIOD_MS);
Jonathan Austin 1:8aa5cdb4ab67 149
Jonathan Austin 1:8aa5cdb4ab67 150 while(systemTickComponents[i] != NULL && i < MICROBIT_SYSTEM_COMPONENTS)
Jonathan Austin 1:8aa5cdb4ab67 151 i++;
Jonathan Austin 1:8aa5cdb4ab67 152
Jonathan Austin 1:8aa5cdb4ab67 153 if(i == MICROBIT_SYSTEM_COMPONENTS)
Jonathan Austin 1:8aa5cdb4ab67 154 return MICROBIT_NO_RESOURCES;
Jonathan Austin 1:8aa5cdb4ab67 155
Jonathan Austin 1:8aa5cdb4ab67 156 systemTickComponents[i] = component;
Jonathan Austin 1:8aa5cdb4ab67 157 return MICROBIT_OK;
Jonathan Austin 1:8aa5cdb4ab67 158 }
Jonathan Austin 1:8aa5cdb4ab67 159
Jonathan Austin 1:8aa5cdb4ab67 160 /**
Jonathan Austin 1:8aa5cdb4ab67 161 * Remove a component from the array of system components. This component will no longer receive
Jonathan Austin 1:8aa5cdb4ab67 162 * periodic callbacks.
Jonathan Austin 1:8aa5cdb4ab67 163 *
Jonathan Austin 1:8aa5cdb4ab67 164 * @param component The component to remove.
Jonathan Austin 1:8aa5cdb4ab67 165 *
Jonathan Austin 1:8aa5cdb4ab67 166 * @return MICROBIT_OK on success. MICROBIT_INVALID_PARAMETER is returned if the given component has not been previously added.
Jonathan Austin 1:8aa5cdb4ab67 167 */
Jonathan Austin 1:8aa5cdb4ab67 168 int system_timer_remove_component(MicroBitComponent *component)
Jonathan Austin 1:8aa5cdb4ab67 169 {
Jonathan Austin 1:8aa5cdb4ab67 170 int i = 0;
Jonathan Austin 1:8aa5cdb4ab67 171
Jonathan Austin 1:8aa5cdb4ab67 172 while(systemTickComponents[i] != component && i < MICROBIT_SYSTEM_COMPONENTS)
Jonathan Austin 1:8aa5cdb4ab67 173 i++;
Jonathan Austin 1:8aa5cdb4ab67 174
Jonathan Austin 1:8aa5cdb4ab67 175 if(i == MICROBIT_SYSTEM_COMPONENTS)
Jonathan Austin 1:8aa5cdb4ab67 176 return MICROBIT_INVALID_PARAMETER;
Jonathan Austin 1:8aa5cdb4ab67 177
Jonathan Austin 1:8aa5cdb4ab67 178 systemTickComponents[i] = NULL;
Jonathan Austin 1:8aa5cdb4ab67 179
Jonathan Austin 1:8aa5cdb4ab67 180 return MICROBIT_OK;
LancasterUniversity 31:87789e55bac7 181 }