Kenji Arai / mbed-os_TYBLE16

Dependents:   TYBLE16_simple_data_logger TYBLE16_MP3_Air

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers LowPowerTickerWrapper.h Source File

LowPowerTickerWrapper.h

00001 
00002 /** \addtogroup hal */
00003 /** @{*/
00004 /* mbed Microcontroller Library
00005  * Copyright (c) 2018-2019 ARM Limited
00006  * SPDX-License-Identifier: Apache-2.0
00007  *
00008  * Licensed under the Apache License, Version 2.0 (the "License");
00009  * you may not use this file except in compliance with the License.
00010  * You may obtain a copy of the License at
00011  *
00012  *     http://www.apache.org/licenses/LICENSE-2.0
00013  *
00014  * Unless required by applicable law or agreed to in writing, software
00015  * distributed under the License is distributed on an "AS IS" BASIS,
00016  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00017  * See the License for the specific language governing permissions and
00018  * limitations under the License.
00019  */
00020 #ifndef MBED_LOW_POWER_TICKER_WRAPPER_H
00021 #define MBED_LOW_POWER_TICKER_WRAPPER_H
00022 
00023 #include "device.h"
00024 
00025 #include "hal/ticker_api.h"
00026 #include "hal/us_ticker_api.h"
00027 #include "drivers/Timeout.h"
00028 
00029 #include "platform/mbed_critical.h"
00030 
00031 
00032 class LowPowerTickerWrapper {
00033 public:
00034 
00035 
00036     /**
00037      * Create a new wrapped low power ticker object
00038      *
00039      * @param data Low power ticker data to wrap
00040      * @param interface new ticker interface functions
00041      * @param min_cycles_between_writes The number of whole low power clock periods
00042      * which must complete before subsequent calls to set_interrupt
00043      * @param min_cycles_until_match The minimum number of whole low power clock periods
00044      * from the current time for which the match timestamp passed to set_interrupt is
00045      * guaranteed to fire.
00046      *
00047      *  N = min_cycles_between_writes
00048      *
00049      *       0       1             N - 1     N     N + 1   N + 2   N + 3
00050      *       |-------|------...------|-------|-------|-------|-------|
00051      *           ^                                    ^
00052      *           |                                    |
00053      *       set_interrupt                   Next set_interrupt allowed
00054      *
00055      * N = min_cycles_until_match
00056      *
00057      *      0       1             N - 1     N     N + 1   N + 2   N + 3
00058      *      |-------|------...------|-------|-------|-------|-------|
00059      *          ^                                   ^
00060      *          |                                   |
00061      *      set_interrupt              Earliest match timestamp allowed
00062      *
00063      *
00064      */
00065 
00066     LowPowerTickerWrapper(const ticker_data_t *data, const ticker_interface_t *interface, uint32_t min_cycles_between_writes, uint32_t min_cycles_until_match);
00067 
00068     /**
00069      * Interrupt handler called by the underlying driver/hardware
00070      *
00071      * @param handler The callback which would normally be called by the underlying driver/hardware
00072      */
00073     void irq_handler(ticker_irq_handler_type handler);
00074 
00075     /**
00076      * Suspend wrapper operation and pass through interrupts.
00077      *
00078      * This stops to wrapper layer from using the microsecond ticker.
00079      * This should be called before using the low power ticker APIs directly.
00080      *
00081      * @warning: Make sure to suspend the LP ticker first (call ticker_suspend()),
00082      * otherwise the behavior is undefined.
00083      */
00084     void suspend();
00085 
00086     /**
00087      * Resume wrapper operation and filter interrupts normally
00088      */
00089     void resume();
00090 
00091     /**
00092      * Check if a Timeout object is being used
00093      *
00094      * @return true if Timeout is used for scheduling false otherwise
00095      */
00096     bool timeout_pending();
00097 
00098     /*
00099      * Implementation of ticker_init
00100      */
00101     void init();
00102 
00103     /*
00104      * Implementation of free
00105      */
00106     void free();
00107 
00108     /*
00109      * Implementation of read
00110      */
00111     uint32_t read();
00112 
00113     /*
00114      * Implementation of set_interrupt
00115      */
00116     void set_interrupt(timestamp_t timestamp);
00117 
00118     /*
00119      * Implementation of disable_interrupt
00120      */
00121     void disable_interrupt();
00122 
00123     /*
00124      * Implementation of clear_interrupt
00125      */
00126     void clear_interrupt();
00127 
00128     /*
00129      * Implementation of fire_interrupt
00130      */
00131     void fire_interrupt();
00132 
00133     /*
00134      * Implementation of get_info
00135      */
00136     const ticker_info_t *get_info();
00137 
00138     ticker_data_t data;
00139 
00140 private:
00141     mbed::Timeout _timeout;
00142     const ticker_interface_t *const _intf;
00143 
00144     /*
00145      * The number of low power clock cycles which must pass between subsequent
00146      * calls to intf->set_interrupt
00147      */
00148     const uint32_t _min_count_between_writes;
00149 
00150     /*
00151      * The minimum number of low power clock cycles in the future that
00152      * a match value can be set to and still fire
00153      */
00154     const uint32_t _min_count_until_match;
00155 
00156     /*
00157      * Flag to indicate if the timer is suspended
00158      */
00159     bool _suspended;
00160 
00161     /*
00162      * _cur_match_time is valid and Timeout is scheduled to fire
00163      */
00164     bool _pending_timeout;
00165 
00166     /*
00167      * set_interrupt has been called and _cur_match_time is valid
00168      */
00169     bool _pending_match;
00170 
00171     /*
00172      * The function LowPowerTickerWrapper::fire_interrupt has been called
00173      * and an interrupt is expected.
00174      */
00175     bool _pending_fire_now;
00176 
00177     /*
00178      * It is safe to call intf->set_interrupt
00179      */
00180     bool _set_interrupt_allowed;
00181 
00182     /*
00183      * Last value written by LowPowerTickerWrapper::set_interrupt
00184      */
00185     timestamp_t _cur_match_time;
00186 
00187     /*
00188      * Time of last call to LowPowerTickerWrapper::set_interrupt
00189      */
00190     uint32_t _last_set_interrupt;
00191 
00192     /*
00193      * Time of last call to intf->set_interrupt
00194      */
00195     uint32_t _last_actual_set_interrupt;
00196 
00197     /*
00198      * Mask of valid bits from intf->read()
00199      */
00200     uint32_t _mask;
00201 
00202     /*
00203      * Microsecond per low power tick (rounded up)
00204      */
00205     uint32_t _us_per_tick;
00206 
00207 
00208     void _reset();
00209 
00210     /**
00211      * Set the low power ticker match time when hardware is ready
00212      *
00213      * This event is scheduled to set the lp timer after the previous write
00214      * has taken effect and it is safe to write a new value without blocking.
00215      * If the time has already passed then this function fires and interrupt
00216      * immediately.
00217      */
00218     void _timeout_handler();
00219 
00220     /*
00221      * Check match time has passed
00222      */
00223     bool _match_check(timestamp_t current);
00224 
00225     /*
00226      * Convert low power ticks to approximate microseconds
00227      *
00228      * This value is always larger or equal to exact value.
00229      */
00230     uint32_t _lp_ticks_to_us(uint32_t);
00231 
00232     /*
00233      * Schedule a match interrupt to fire at the correct time
00234      *
00235      * @param current The current low power ticker time
00236      */
00237     void _schedule_match(timestamp_t current);
00238 
00239 };
00240 
00241 #endif
00242 
00243 /** @}*/
00244 
00245