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.
Dependents: DISCO-L072CZ-LRWAN1_LoRa_PingPong
Fork of SX1276GenericLib by
Revision 65:b2d98328fcba, committed 2017-07-11
- Comitter:
- Helmut Tschemernjak
- Date:
- Tue Jul 11 13:32:34 2017 +0200
- Parent:
- 64:b721e6ab656a
- Child:
- 66:fbb2da34bd9a
- Commit message:
- Added Arduino Support, it still needs further testing
Changed in this revision
--- a/LoRa_TODO.txt Fri Jun 30 16:08:05 2017 +0200 +++ b/LoRa_TODO.txt Tue Jul 11 13:32:34 2017 +0200 @@ -1,10 +1,9 @@ - + Move finished tasks to Done section: -TODOs: -- add support for Arduino - add sx1276-Arduino-hal.h/cpp -- add support for Linux - add sx1276-Linux-hal.h/cpp -- Add support for Cad detection before sending a packet +TODOs: +- add support for Arduino - add sx1276-Arduino-hal.h/cpp +- add support for Linux - add sx1276-Linux-hal.h/cpp - Add support to provide the send/receive packet buffer, no need to allocate packet data in the sx1276 driver. Can be provided Rx/Tx parameters, this avoids double memory usage @@ -14,22 +13,25 @@ - It is a little bit strange that RX/TX/Cad Timeout Timer calling the some handler OnTimeoutIrq. Maybe we just need a single timer, or it is a good idea to split the OnTimeoutIrq function into separate - callbacks for RX/TX/Cad timeouts + callbacks for RX/TX/Cad timeouts - Test if the SX1276 timeouts. Does rx/tx/sync really uses three different timers or just one at a time. -- Add API to set the LNA gain +- Add API to set the LNA gain +- Registering a new Timeout function within the Interrupt is not malloc save. + This is a major race condition problem. + - -Done: + +Done: - Started a Generic SX1276 driver to support all SX1276 modules (May-2017 Helmut) -- Migrated typedefs code into sx1276.h (7-May-2017 Helmut) -- Migrated enum code into sx1276.h/radio.h (7-May-2017 Helmut) -- Verify the Murata ANT Switch code -- MURATA PA_BOOST case,is _antSwitchTXBoost right? (Same as STM sample code) +- Migrated typedefs code into sx1276.h (7-May-2017 Helmut) +- Migrated enum code into sx1276.h/radio.h (7-May-2017 Helmut) +- Verify the Murata ANT Switch code +- MURATA PA_BOOST case,is _antSwitchTXBoost right? (Same as STM sample code) - Check of the MURATA TCXO config is correct (implemented, check JP9 on STM L0 board) -- Make the timers more generic and move the OS code into the HAL layer. (May 2017 Helmut) +- Make the timers more generic and move the OS code into the HAL layer. (May 2017 Helmut) - Removed pull down on dio=-dio5 for L151 &LPC11U6X which make no sense to me. May 2017 Helmut -- Added radio API support to receive the MaxMTUSize (May 2017 Helmut) +- Added radio API support to receive the MaxMTUSize (May 2017 Helmut) - Added Send optional Send() parameter to include a header, this saves additional buffers. (May 2017 Helmut) - Added proper void * type from sending data, uint8_t * is not appropriate (May 2017 Helmut) @@ -41,4 +43,7 @@ - Made SetRfTxPower public to allow easily power TX changes (May 2017 Helmut) - Added userData and userThisPtr into the radio events, this allows to call C++ functions and in can include a context via the userData +- Add support for Cad detection before sending a packet, already done in higher + level protocols +- Added initial Arduino support, needs more testing/completion.
--- a/radio/radio.h Fri Jun 30 16:08:05 2017 +0200 +++ b/radio/radio.h Tue Jul 11 13:32:34 2017 +0200 @@ -15,8 +15,12 @@ #ifndef __RADIO_H__ #define __RADIO_H__ +#ifdef __MBED__ #include "mbed.h" - +#endif +#ifdef ARDUINO +#include <arduino.h> +#endif /*! * Radio driver internal state machine states definition
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sx1276/Callback-A.h Tue Jul 11 13:32:34 2017 +0200
@@ -0,0 +1,4228 @@
+/* mbed Microcontroller Library
+ * Copyright (c) 2006-2015 ARM Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+#ifdef ARDUINO
+
+#ifndef MBED_CALLBACK_H
+#define MBED_CALLBACK_H
+
+
+#include <string.h>
+#include <stdint.h>
+#include <new>
+//#include "platform/mbed_assert.h"
+//#include "platform/mbed_toolchain.h"
+#ifdef ARDUINO
+#undef F
+#endif
+
+// namespace mbed {
+/** \addtogroup platform */
+
+
+/** Callback class based on template specialization
+ *
+ * @note Synchronization level: Not protected
+ * @ingroup platform
+ */
+template <typename F>
+class Callback;
+
+// Internal sfinae declarations
+//
+// These are used to eliminate overloads based on type attributes
+// 1. Does a function object have a call operator
+// 2. Does a function object fit in the available storage
+//
+// These eliminations are handled cleanly by the compiler and avoid
+// massive and misleading error messages when confronted with an
+// invalid type (or worse, runtime failures)
+namespace detail {
+ struct nil {};
+
+ template <bool B, typename R = nil>
+ struct enable_if { typedef R type; };
+
+ template <typename R>
+ struct enable_if<false, R> {};
+
+ template <typename M, M>
+ struct is_type {
+ static const bool value = true;
+ };
+}
+
+#define MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, M) \
+ typename detail::enable_if< \
+ detail::is_type<M, &F::operator()>::value && \
+ sizeof(F) <= sizeof(uintptr_t) \
+ >::type = detail::nil()
+
+/** Callback class based on template specialization
+ *
+ * @note Synchronization level: Not protected
+ * @ingroup platform
+ */
+template <typename R>
+class Callback<R()> {
+public:
+ /** Create a Callback with a static function
+ * @param func Static function to attach
+ */
+ Callback(R (*func)() = 0) {
+ if (!func) {
+ _ops = 0;
+ } else {
+ generate(func);
+ }
+ }
+
+ /** Attach a Callback
+ * @param func The Callback to attach
+ */
+ Callback(const Callback<R()> &func) {
+ if (func._ops) {
+ func._ops->move(this, &func);
+ }
+ _ops = func._ops;
+ }
+
+ /** Create a Callback with a member function
+ * @param obj Pointer to object to invoke member function on
+ * @param method Member function to attach
+ */
+ template<typename T, typename U>
+ Callback(U *obj, R (T::*method)()) {
+ generate(method_context<T, R (T::*)()>(obj, method));
+ }
+
+ /** Create a Callback with a member function
+ * @param obj Pointer to object to invoke member function on
+ * @param method Member function to attach
+ */
+ template<typename T, typename U>
+ Callback(const U *obj, R (T::*method)() const) {
+ generate(method_context<const T, R (T::*)() const>(obj, method));
+ }
+
+ /** Create a Callback with a member function
+ * @param obj Pointer to object to invoke member function on
+ * @param method Member function to attach
+ */
+ template<typename T, typename U>
+ Callback(volatile U *obj, R (T::*method)() volatile) {
+ generate(method_context<volatile T, R (T::*)() volatile>(obj, method));
+ }
+
+ /** Create a Callback with a member function
+ * @param obj Pointer to object to invoke member function on
+ * @param method Member function to attach
+ */
+ template<typename T, typename U>
+ Callback(const volatile U *obj, R (T::*method)() const volatile) {
+ generate(method_context<const volatile T, R (T::*)() const volatile>(obj, method));
+ }
+
+ /** Create a Callback with a static function and bound pointer
+ * @param func Static function to attach
+ * @param arg Pointer argument to function
+ */
+ template<typename T, typename U>
+ Callback(R (*func)(T*), U *arg) {
+ generate(function_context<R (*)(T*), T>(func, arg));
+ }
+
+ /** Create a Callback with a static function and bound pointer
+ * @param func Static function to attach
+ * @param arg Pointer argument to function
+ */
+ template<typename T, typename U>
+ Callback(R (*func)(const T*), const U *arg) {
+ generate(function_context<R (*)(const T*), const T>(func, arg));
+ }
+
+ /** Create a Callback with a static function and bound pointer
+ * @param func Static function to attach
+ * @param arg Pointer argument to function
+ */
+ template<typename T, typename U>
+ Callback(R (*func)(volatile T*), volatile U *arg) {
+ generate(function_context<R (*)(volatile T*), volatile T>(func, arg));
+ }
+
+ /** Create a Callback with a static function and bound pointer
+ * @param func Static function to attach
+ * @param arg Pointer argument to function
+ */
+ template<typename T, typename U>
+ Callback(R (*func)(const volatile T*), const volatile U *arg) {
+ generate(function_context<R (*)(const volatile T*), const volatile T>(func, arg));
+ }
+
+ /** Create a Callback with a function object
+ * @param f Function object to attach
+ * @note The function object is limited to a single word of storage
+ */
+ template <typename F>
+ Callback(F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R (F::*)())) {
+ generate(f);
+ }
+
+ /** Create a Callback with a function object
+ * @param f Function object to attach
+ * @note The function object is limited to a single word of storage
+ */
+ template <typename F>
+ Callback(const F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R (F::*)() const)) {
+ generate(f);
+ }
+
+ /** Create a Callback with a function object
+ * @param f Function object to attach
+ * @note The function object is limited to a single word of storage
+ */
+ template <typename F>
+ Callback(volatile F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R (F::*)() volatile)) {
+ generate(f);
+ }
+
+ /** Create a Callback with a function object
+ * @param f Function object to attach
+ * @note The function object is limited to a single word of storage
+ */
+ template <typename F>
+ Callback(const volatile F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R (F::*)() const volatile)) {
+ generate(f);
+ }
+
+ /** Create a Callback with a static function and bound pointer
+ * @param obj Pointer to object to bind to function
+ * @param func Static function to attach
+ * @deprecated
+ * Arguments to callback have been reordered to Callback(func, arg)
+ */
+ template<typename T, typename U>
+ Callback(U *obj, R (*func)(T*)) {
+ new (this) Callback(func, obj);
+ }
+
+ /** Create a Callback with a static function and bound pointer
+ * @param obj Pointer to object to bind to function
+ * @param func Static function to attach
+ * @deprecated
+ * Arguments to callback have been reordered to Callback(func, arg)
+ */
+ template<typename T, typename U>
+ Callback(const U *obj, R (*func)(const T*)) {
+ new (this) Callback(func, obj);
+ }
+
+ /** Create a Callback with a static function and bound pointer
+ * @param obj Pointer to object to bind to function
+ * @param func Static function to attach
+ * @deprecated
+ * Arguments to callback have been reordered to Callback(func, arg)
+ */
+ template<typename T, typename U>
+ Callback(volatile U *obj, R (*func)(volatile T*)) {
+ new (this) Callback(func, obj);
+ }
+
+ /** Create a Callback with a static function and bound pointer
+ * @param obj Pointer to object to bind to function
+ * @param func Static function to attach
+ * @deprecated
+ * Arguments to callback have been reordered to Callback(func, arg)
+ */
+ template<typename T, typename U>
+ Callback(const volatile U *obj, R (*func)(const volatile T*)) {
+ new (this) Callback(func, obj);
+ }
+
+ /** Destroy a callback
+ */
+ ~Callback() {
+ if (_ops) {
+ _ops->dtor(this);
+ }
+ }
+
+ /** Attach a static function
+ * @param func Static function to attach
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ void attach(R (*func)()) {
+ this->~Callback();
+ new (this) Callback(func);
+ }
+
+ /** Attach a Callback
+ * @param func The Callback to attach
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ void attach(const Callback<R()> &func) {
+ this->~Callback();
+ new (this) Callback(func);
+ }
+
+ /** Attach a member function
+ * @param obj Pointer to object to invoke member function on
+ * @param method Member function to attach
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ template<typename T, typename U>
+ void attach(U *obj, R (T::*method)()) {
+ this->~Callback();
+ new (this) Callback(obj, method);
+ }
+
+ /** Attach a member function
+ * @param obj Pointer to object to invoke member function on
+ * @param method Member function to attach
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ template<typename T, typename U>
+ void attach(const U *obj, R (T::*method)() const) {
+ this->~Callback();
+ new (this) Callback(obj, method);
+ }
+
+ /** Attach a member function
+ * @param obj Pointer to object to invoke member function on
+ * @param method Member function to attach
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ template<typename T, typename U>
+ void attach(volatile U *obj, R (T::*method)() volatile) {
+ this->~Callback();
+ new (this) Callback(obj, method);
+ }
+
+ /** Attach a member function
+ * @param obj Pointer to object to invoke member function on
+ * @param method Member function to attach
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ template<typename T, typename U>
+ void attach(const volatile U *obj, R (T::*method)() const volatile) {
+ this->~Callback();
+ new (this) Callback(obj, method);
+ }
+
+ /** Attach a static function with a bound pointer
+ * @param func Static function to attach
+ * @param arg Pointer argument to function
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ template <typename T, typename U>
+ void attach(R (*func)(T*), U *arg) {
+ this->~Callback();
+ new (this) Callback(func, arg);
+ }
+
+ /** Attach a static function with a bound pointer
+ * @param func Static function to attach
+ * @param arg Pointer argument to function
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ template <typename T, typename U>
+ void attach(R (*func)(const T*), const U *arg) {
+ this->~Callback();
+ new (this) Callback(func, arg);
+ }
+
+ /** Attach a static function with a bound pointer
+ * @param func Static function to attach
+ * @param arg Pointer argument to function
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ template <typename T, typename U>
+ void attach(R (*func)(volatile T*), volatile U *arg) {
+ this->~Callback();
+ new (this) Callback(func, arg);
+ }
+
+ /** Attach a static function with a bound pointer
+ * @param func Static function to attach
+ * @param arg Pointer argument to function
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ template <typename T, typename U>
+ void attach(R (*func)(const volatile T*), const volatile U *arg) {
+ this->~Callback();
+ new (this) Callback(func, arg);
+ }
+
+ /** Attach a function object
+ * @param f Function object to attach
+ * @note The function object is limited to a single word of storage
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ template <typename F>
+ void attach(F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R (F::*)())) {
+ this->~Callback();
+ new (this) Callback(f);
+ }
+
+ /** Attach a function object
+ * @param f Function object to attach
+ * @note The function object is limited to a single word of storage
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ template <typename F>
+ void attach(const F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R (F::*)() const)) {
+ this->~Callback();
+ new (this) Callback(f);
+ }
+
+ /** Attach a function object
+ * @param f Function object to attach
+ * @note The function object is limited to a single word of storage
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ template <typename F>
+ void attach(volatile F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R (F::*)() volatile)) {
+ this->~Callback();
+ new (this) Callback(f);
+ }
+
+ /** Attach a function object
+ * @param f Function object to attach
+ * @note The function object is limited to a single word of storage
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ template <typename F>
+ void attach(const volatile F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R (F::*)() const volatile)) {
+ this->~Callback();
+ new (this) Callback(f);
+ }
+
+ /** Attach a static function with a bound pointer
+ * @param obj Pointer to object to bind to function
+ * @param func Static function to attach
+ * @deprecated
+ * Arguments to callback have been reordered to attach(func, arg)
+ */
+ template <typename T, typename U>
+ void attach(U *obj, R (*func)(T*)) {
+ this->~Callback();
+ new (this) Callback(func, obj);
+ }
+
+ /** Attach a static function with a bound pointer
+ * @param obj Pointer to object to bind to function
+ * @param func Static function to attach
+ * @deprecated
+ * Arguments to callback have been reordered to attach(func, arg)
+ */
+ template <typename T, typename U>
+ void attach(const U *obj, R (*func)(const T*)) {
+ this->~Callback();
+ new (this) Callback(func, obj);
+ }
+
+ /** Attach a static function with a bound pointer
+ * @param obj Pointer to object to bind to function
+ * @param func Static function to attach
+ * @deprecated
+ * Arguments to callback have been reordered to attach(func, arg)
+ */
+ template <typename T, typename U>
+ void attach(volatile U *obj, R (*func)(volatile T*)) {
+ this->~Callback();
+ new (this) Callback(func, obj);
+ }
+
+ /** Attach a static function with a bound pointer
+ * @param obj Pointer to object to bind to function
+ * @param func Static function to attach
+ * @deprecated
+ * Arguments to callback have been reordered to attach(func, arg)
+ */
+ template <typename T, typename U>
+ void attach(const volatile U *obj, R (*func)(const volatile T*)) {
+ this->~Callback();
+ new (this) Callback(func, obj);
+ }
+
+ /** Assign a callback
+ */
+ Callback &operator=(const Callback &that) {
+ if (this != &that) {
+ this->~Callback();
+ new (this) Callback(that);
+ }
+
+ return *this;
+ }
+
+ /** Call the attached function
+ */
+ R call() const {
+ return _ops->call(this);
+ }
+
+ /** Call the attached function
+ */
+ R operator()() const {
+ return call();
+ }
+
+ /** Test if function has been attached
+ */
+ operator bool() const {
+ return _ops;
+ }
+
+ /** Test for equality
+ */
+ friend bool operator==(const Callback &l, const Callback &r) {
+ return memcmp(&l, &r, sizeof(Callback)) == 0;
+ }
+
+ /** Test for inequality
+ */
+ friend bool operator!=(const Callback &l, const Callback &r) {
+ return !(l == r);
+ }
+
+ /** Static thunk for passing as C-style function
+ * @param func Callback to call passed as void pointer
+ * @return the value as determined by func which is of
+ * type and determined by the signiture of func
+ */
+ static R thunk(void *func) {
+ return static_cast<Callback*>(func)->call();
+ }
+
+private:
+ // Stored as pointer to function and pointer to optional object
+ // Function pointer is stored as union of possible function types
+ // to garuntee proper size and alignment
+ struct _class;
+ union {
+ void (*_staticfunc)();
+ void (*_boundfunc)(_class*);
+ void (_class::*_methodfunc)();
+ } _func;
+ void *_obj;
+
+ // Dynamically dispatched operations
+ const struct ops {
+ R (*call)(const void*);
+ void (*move)(void*, const void*);
+ void (*dtor)(void*);
+ } *_ops;
+
+
+ // Generate operations for function object
+ template <typename F>
+ void generate(const F &f) {
+ static const ops ops = {
+ &Callback::function_call<F>,
+ &Callback::function_move<F>,
+ &Callback::function_dtor<F>,
+ };
+ //MBED_STATIC_ASSERT(sizeof(Callback) - sizeof(_ops) >= sizeof(F),
+ // "Type F must not exceed the size of the Callback class");
+ new (this) F(f);
+ _ops = &ops;
+ }
+
+ // Function attributes
+ template <typename F>
+ static R function_call(const void *p) {
+ return (*(F*)p)();
+ }
+
+ template <typename F>
+ static void function_move(void *d, const void *p) {
+ new (d) F(*(F*)p);
+ }
+
+ template <typename F>
+ static void function_dtor(void *p) {
+ ((F*)p)->~F();
+ }
+
+ // Wrappers for functions with context
+ template <typename O, typename M>
+ struct method_context {
+ M method;
+ O *obj;
+
+ method_context(O *obj, M method)
+ : method(method), obj(obj) {}
+
+ R operator()() const {
+ return (obj->*method)();
+ }
+ };
+
+ template <typename F, typename A>
+ struct function_context {
+ F func;
+ A *arg;
+
+ function_context(F func, A *arg)
+ : func(func), arg(arg) {}
+
+ R operator()() const {
+ return func(arg);
+ }
+ };
+};
+
+/** Callback class based on template specialization
+ *
+ * @note Synchronization level: Not protected
+ * @ingroup platform
+ */
+template <typename R, typename A0>
+class Callback<R(A0)> {
+public:
+ /** Create a Callback with a static function
+ * @param func Static function to attach
+ */
+ Callback(R (*func)(A0) = 0) {
+ if (!func) {
+ _ops = 0;
+ } else {
+ generate(func);
+ }
+ }
+
+ /** Attach a Callback
+ * @param func The Callback to attach
+ */
+ Callback(const Callback<R(A0)> &func) {
+ if (func._ops) {
+ func._ops->move(this, &func);
+ }
+ _ops = func._ops;
+ }
+
+ /** Create a Callback with a member function
+ * @param obj Pointer to object to invoke member function on
+ * @param method Member function to attach
+ */
+ template<typename T, typename U>
+ Callback(U *obj, R (T::*method)(A0)) {
+ generate(method_context<T, R (T::*)(A0)>(obj, method));
+ }
+
+ /** Create a Callback with a member function
+ * @param obj Pointer to object to invoke member function on
+ * @param method Member function to attach
+ */
+ template<typename T, typename U>
+ Callback(const U *obj, R (T::*method)(A0) const) {
+ generate(method_context<const T, R (T::*)(A0) const>(obj, method));
+ }
+
+ /** Create a Callback with a member function
+ * @param obj Pointer to object to invoke member function on
+ * @param method Member function to attach
+ */
+ template<typename T, typename U>
+ Callback(volatile U *obj, R (T::*method)(A0) volatile) {
+ generate(method_context<volatile T, R (T::*)(A0) volatile>(obj, method));
+ }
+
+ /** Create a Callback with a member function
+ * @param obj Pointer to object to invoke member function on
+ * @param method Member function to attach
+ */
+ template<typename T, typename U>
+ Callback(const volatile U *obj, R (T::*method)(A0) const volatile) {
+ generate(method_context<const volatile T, R (T::*)(A0) const volatile>(obj, method));
+ }
+
+ /** Create a Callback with a static function and bound pointer
+ * @param func Static function to attach
+ * @param arg Pointer argument to function
+ */
+ template<typename T, typename U>
+ Callback(R (*func)(T*, A0), U *arg) {
+ generate(function_context<R (*)(T*, A0), T>(func, arg));
+ }
+
+ /** Create a Callback with a static function and bound pointer
+ * @param func Static function to attach
+ * @param arg Pointer argument to function
+ */
+ template<typename T, typename U>
+ Callback(R (*func)(const T*, A0), const U *arg) {
+ generate(function_context<R (*)(const T*, A0), const T>(func, arg));
+ }
+
+ /** Create a Callback with a static function and bound pointer
+ * @param func Static function to attach
+ * @param arg Pointer argument to function
+ */
+ template<typename T, typename U>
+ Callback(R (*func)(volatile T*, A0), volatile U *arg) {
+ generate(function_context<R (*)(volatile T*, A0), volatile T>(func, arg));
+ }
+
+ /** Create a Callback with a static function and bound pointer
+ * @param func Static function to attach
+ * @param arg Pointer argument to function
+ */
+ template<typename T, typename U>
+ Callback(R (*func)(const volatile T*, A0), const volatile U *arg) {
+ generate(function_context<R (*)(const volatile T*, A0), const volatile T>(func, arg));
+ }
+
+ /** Create a Callback with a function object
+ * @param f Function object to attach
+ * @note The function object is limited to a single word of storage
+ */
+ template <typename F>
+ Callback(F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R (F::*)(A0))) {
+ generate(f);
+ }
+
+ /** Create a Callback with a function object
+ * @param f Function object to attach
+ * @note The function object is limited to a single word of storage
+ */
+ template <typename F>
+ Callback(const F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R (F::*)(A0) const)) {
+ generate(f);
+ }
+
+ /** Create a Callback with a function object
+ * @param f Function object to attach
+ * @note The function object is limited to a single word of storage
+ */
+ template <typename F>
+ Callback(volatile F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R (F::*)(A0) volatile)) {
+ generate(f);
+ }
+
+ /** Create a Callback with a function object
+ * @param f Function object to attach
+ * @note The function object is limited to a single word of storage
+ */
+ template <typename F>
+ Callback(const volatile F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R (F::*)(A0) const volatile)) {
+ generate(f);
+ }
+
+ /** Create a Callback with a static function and bound pointer
+ * @param obj Pointer to object to bind to function
+ * @param func Static function to attach
+ * @deprecated
+ * Arguments to callback have been reordered to Callback(func, arg)
+ */
+ template<typename T, typename U>
+ Callback(U *obj, R (*func)(T*, A0)) {
+ new (this) Callback(func, obj);
+ }
+
+ /** Create a Callback with a static function and bound pointer
+ * @param obj Pointer to object to bind to function
+ * @param func Static function to attach
+ * @deprecated
+ * Arguments to callback have been reordered to Callback(func, arg)
+ */
+ template<typename T, typename U>
+ Callback(const U *obj, R (*func)(const T*, A0)) {
+ new (this) Callback(func, obj);
+ }
+
+ /** Create a Callback with a static function and bound pointer
+ * @param obj Pointer to object to bind to function
+ * @param func Static function to attach
+ * @deprecated
+ * Arguments to callback have been reordered to Callback(func, arg)
+ */
+ template<typename T, typename U>
+ Callback(volatile U *obj, R (*func)(volatile T*, A0)) {
+ new (this) Callback(func, obj);
+ }
+
+ /** Create a Callback with a static function and bound pointer
+ * @param obj Pointer to object to bind to function
+ * @param func Static function to attach
+ * @deprecated
+ * Arguments to callback have been reordered to Callback(func, arg)
+ */
+ template<typename T, typename U>
+ Callback(const volatile U *obj, R (*func)(const volatile T*, A0)) {
+ new (this) Callback(func, obj);
+ }
+
+ /** Destroy a callback
+ */
+ ~Callback() {
+ if (_ops) {
+ _ops->dtor(this);
+ }
+ }
+
+ /** Attach a static function
+ * @param func Static function to attach
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ void attach(R (*func)(A0)) {
+ this->~Callback();
+ new (this) Callback(func);
+ }
+
+ /** Attach a Callback
+ * @param func The Callback to attach
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ void attach(const Callback<R(A0)> &func) {
+ this->~Callback();
+ new (this) Callback(func);
+ }
+
+ /** Attach a member function
+ * @param obj Pointer to object to invoke member function on
+ * @param method Member function to attach
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ template<typename T, typename U>
+ void attach(U *obj, R (T::*method)(A0)) {
+ this->~Callback();
+ new (this) Callback(obj, method);
+ }
+
+ /** Attach a member function
+ * @param obj Pointer to object to invoke member function on
+ * @param method Member function to attach
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ template<typename T, typename U>
+ void attach(const U *obj, R (T::*method)(A0) const) {
+ this->~Callback();
+ new (this) Callback(obj, method);
+ }
+
+ /** Attach a member function
+ * @param obj Pointer to object to invoke member function on
+ * @param method Member function to attach
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ template<typename T, typename U>
+ void attach(volatile U *obj, R (T::*method)(A0) volatile) {
+ this->~Callback();
+ new (this) Callback(obj, method);
+ }
+
+ /** Attach a member function
+ * @param obj Pointer to object to invoke member function on
+ * @param method Member function to attach
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ template<typename T, typename U>
+ void attach(const volatile U *obj, R (T::*method)(A0) const volatile) {
+ this->~Callback();
+ new (this) Callback(obj, method);
+ }
+
+ /** Attach a static function with a bound pointer
+ * @param func Static function to attach
+ * @param arg Pointer argument to function
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ template <typename T, typename U>
+ void attach(R (*func)(T*, A0), U *arg) {
+ this->~Callback();
+ new (this) Callback(func, arg);
+ }
+
+ /** Attach a static function with a bound pointer
+ * @param func Static function to attach
+ * @param arg Pointer argument to function
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ template <typename T, typename U>
+ void attach(R (*func)(const T*, A0), const U *arg) {
+ this->~Callback();
+ new (this) Callback(func, arg);
+ }
+
+ /** Attach a static function with a bound pointer
+ * @param func Static function to attach
+ * @param arg Pointer argument to function
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ template <typename T, typename U>
+ void attach(R (*func)(volatile T*, A0), volatile U *arg) {
+ this->~Callback();
+ new (this) Callback(func, arg);
+ }
+
+ /** Attach a static function with a bound pointer
+ * @param func Static function to attach
+ * @param arg Pointer argument to function
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ template <typename T, typename U>
+ void attach(R (*func)(const volatile T*, A0), const volatile U *arg) {
+ this->~Callback();
+ new (this) Callback(func, arg);
+ }
+
+ /** Attach a function object
+ * @param f Function object to attach
+ * @note The function object is limited to a single word of storage
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ template <typename F>
+ void attach(F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R (F::*)(A0))) {
+ this->~Callback();
+ new (this) Callback(f);
+ }
+
+ /** Attach a function object
+ * @param f Function object to attach
+ * @note The function object is limited to a single word of storage
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ template <typename F>
+ void attach(const F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R (F::*)(A0) const)) {
+ this->~Callback();
+ new (this) Callback(f);
+ }
+
+ /** Attach a function object
+ * @param f Function object to attach
+ * @note The function object is limited to a single word of storage
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ template <typename F>
+ void attach(volatile F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R (F::*)(A0) volatile)) {
+ this->~Callback();
+ new (this) Callback(f);
+ }
+
+ /** Attach a function object
+ * @param f Function object to attach
+ * @note The function object is limited to a single word of storage
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ template <typename F>
+ void attach(const volatile F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R (F::*)(A0) const volatile)) {
+ this->~Callback();
+ new (this) Callback(f);
+ }
+
+ /** Attach a static function with a bound pointer
+ * @param obj Pointer to object to bind to function
+ * @param func Static function to attach
+ * @deprecated
+ * Arguments to callback have been reordered to attach(func, arg)
+ */
+ template <typename T, typename U>
+ void attach(U *obj, R (*func)(T*, A0)) {
+ this->~Callback();
+ new (this) Callback(func, obj);
+ }
+
+ /** Attach a static function with a bound pointer
+ * @param obj Pointer to object to bind to function
+ * @param func Static function to attach
+ * @deprecated
+ * Arguments to callback have been reordered to attach(func, arg)
+ */
+ template <typename T, typename U>
+ void attach(const U *obj, R (*func)(const T*, A0)) {
+ this->~Callback();
+ new (this) Callback(func, obj);
+ }
+
+ /** Attach a static function with a bound pointer
+ * @param obj Pointer to object to bind to function
+ * @param func Static function to attach
+ * @deprecated
+ * Arguments to callback have been reordered to attach(func, arg)
+ */
+ template <typename T, typename U>
+ void attach(volatile U *obj, R (*func)(volatile T*, A0)) {
+ this->~Callback();
+ new (this) Callback(func, obj);
+ }
+
+ /** Attach a static function with a bound pointer
+ * @param obj Pointer to object to bind to function
+ * @param func Static function to attach
+ * @deprecated
+ * Arguments to callback have been reordered to attach(func, arg)
+ */
+ template <typename T, typename U>
+ void attach(const volatile U *obj, R (*func)(const volatile T*, A0)) {
+ this->~Callback();
+ new (this) Callback(func, obj);
+ }
+
+ /** Assign a callback
+ */
+ Callback &operator=(const Callback &that) {
+ if (this != &that) {
+ this->~Callback();
+ new (this) Callback(that);
+ }
+
+ return *this;
+ }
+
+ /** Call the attached function
+ */
+ R call(A0 a0) const {
+ MBED_ASSERT(_ops);
+ return _ops->call(this, a0);
+ }
+
+ /** Call the attached function
+ */
+ R operator()(A0 a0) const {
+ return call(a0);
+ }
+
+ /** Test if function has been attached
+ */
+ operator bool() const {
+ return _ops;
+ }
+
+ /** Test for equality
+ */
+ friend bool operator==(const Callback &l, const Callback &r) {
+ return memcmp(&l, &r, sizeof(Callback)) == 0;
+ }
+
+ /** Test for inequality
+ */
+ friend bool operator!=(const Callback &l, const Callback &r) {
+ return !(l == r);
+ }
+
+ /** Static thunk for passing as C-style function
+ * @param func Callback to call passed as void pointer
+ * @param a0 An argument to be called with function func
+ * @return the value as determined by func which is of
+ * type and determined by the signiture of func
+ */
+ static R thunk(void *func, A0 a0) {
+ return static_cast<Callback*>(func)->call(a0);
+ }
+
+private:
+ // Stored as pointer to function and pointer to optional object
+ // Function pointer is stored as union of possible function types
+ // to garuntee proper size and alignment
+ struct _class;
+ union {
+ void (*_staticfunc)(A0);
+ void (*_boundfunc)(_class*, A0);
+ void (_class::*_methodfunc)(A0);
+ } _func;
+ void *_obj;
+
+ // Dynamically dispatched operations
+ const struct ops {
+ R (*call)(const void*, A0);
+ void (*move)(void*, const void*);
+ void (*dtor)(void*);
+ } *_ops;
+
+ // Generate operations for function object
+ template <typename F>
+ void generate(const F &f) {
+ static const ops ops = {
+ &Callback::function_call<F>,
+ &Callback::function_move<F>,
+ &Callback::function_dtor<F>,
+ };
+ new (this) F(f);
+ _ops = &ops;
+ }
+
+ // Function attributes
+ template <typename F>
+ static R function_call(const void *p, A0 a0) {
+ return (*(F*)p)(a0);
+ }
+
+ template <typename F>
+ static void function_move(void *d, const void *p) {
+ new (d) F(*(F*)p);
+ }
+
+ template <typename F>
+ static void function_dtor(void *p) {
+ ((F*)p)->~F();
+ }
+
+ // Wrappers for functions with context
+ template <typename O, typename M>
+ struct method_context {
+ M method;
+ O *obj;
+
+ method_context(O *obj, M method)
+ : method(method), obj(obj) {}
+
+ R operator()(A0 a0) const {
+ return (obj->*method)(a0);
+ }
+ };
+
+ template <typename F, typename A>
+ struct function_context {
+ F func;
+ A *arg;
+
+ function_context(F func, A *arg)
+ : func(func), arg(arg) {}
+
+ R operator()(A0 a0) const {
+ return func(arg, a0);
+ }
+ };
+};
+
+/** Callback class based on template specialization
+ *
+ * @note Synchronization level: Not protected
+ * @ingroup platform
+ */
+template <typename R, typename A0, typename A1>
+class Callback<R(A0, A1)> {
+public:
+ /** Create a Callback with a static function
+ * @param func Static function to attach
+ */
+ Callback(R (*func)(A0, A1) = 0) {
+ if (!func) {
+ _ops = 0;
+ } else {
+ generate(func);
+ }
+ }
+
+ /** Attach a Callback
+ * @param func The Callback to attach
+ */
+ Callback(const Callback<R(A0, A1)> &func) {
+ if (func._ops) {
+ func._ops->move(this, &func);
+ }
+ _ops = func._ops;
+ }
+
+ /** Create a Callback with a member function
+ * @param obj Pointer to object to invoke member function on
+ * @param method Member function to attach
+ */
+ template<typename T, typename U>
+ Callback(U *obj, R (T::*method)(A0, A1)) {
+ generate(method_context<T, R (T::*)(A0, A1)>(obj, method));
+ }
+
+ /** Create a Callback with a member function
+ * @param obj Pointer to object to invoke member function on
+ * @param method Member function to attach
+ */
+ template<typename T, typename U>
+ Callback(const U *obj, R (T::*method)(A0, A1) const) {
+ generate(method_context<const T, R (T::*)(A0, A1) const>(obj, method));
+ }
+
+ /** Create a Callback with a member function
+ * @param obj Pointer to object to invoke member function on
+ * @param method Member function to attach
+ */
+ template<typename T, typename U>
+ Callback(volatile U *obj, R (T::*method)(A0, A1) volatile) {
+ generate(method_context<volatile T, R (T::*)(A0, A1) volatile>(obj, method));
+ }
+
+ /** Create a Callback with a member function
+ * @param obj Pointer to object to invoke member function on
+ * @param method Member function to attach
+ */
+ template<typename T, typename U>
+ Callback(const volatile U *obj, R (T::*method)(A0, A1) const volatile) {
+ generate(method_context<const volatile T, R (T::*)(A0, A1) const volatile>(obj, method));
+ }
+
+ /** Create a Callback with a static function and bound pointer
+ * @param func Static function to attach
+ * @param arg Pointer argument to function
+ */
+ template<typename T, typename U>
+ Callback(R (*func)(T*, A0, A1), U *arg) {
+ generate(function_context<R (*)(T*, A0, A1), T>(func, arg));
+ }
+
+ /** Create a Callback with a static function and bound pointer
+ * @param func Static function to attach
+ * @param arg Pointer argument to function
+ */
+ template<typename T, typename U>
+ Callback(R (*func)(const T*, A0, A1), const U *arg) {
+ generate(function_context<R (*)(const T*, A0, A1), const T>(func, arg));
+ }
+
+ /** Create a Callback with a static function and bound pointer
+ * @param func Static function to attach
+ * @param arg Pointer argument to function
+ */
+ template<typename T, typename U>
+ Callback(R (*func)(volatile T*, A0, A1), volatile U *arg) {
+ generate(function_context<R (*)(volatile T*, A0, A1), volatile T>(func, arg));
+ }
+
+ /** Create a Callback with a static function and bound pointer
+ * @param func Static function to attach
+ * @param arg Pointer argument to function
+ */
+ template<typename T, typename U>
+ Callback(R (*func)(const volatile T*, A0, A1), const volatile U *arg) {
+ generate(function_context<R (*)(const volatile T*, A0, A1), const volatile T>(func, arg));
+ }
+
+ /** Create a Callback with a function object
+ * @param f Function object to attach
+ * @note The function object is limited to a single word of storage
+ */
+ template <typename F>
+ Callback(F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R (F::*)(A0, A1))) {
+ generate(f);
+ }
+
+ /** Create a Callback with a function object
+ * @param f Function object to attach
+ * @note The function object is limited to a single word of storage
+ */
+ template <typename F>
+ Callback(const F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R (F::*)(A0, A1) const)) {
+ generate(f);
+ }
+
+ /** Create a Callback with a function object
+ * @param f Function object to attach
+ * @note The function object is limited to a single word of storage
+ */
+ template <typename F>
+ Callback(volatile F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R (F::*)(A0, A1) volatile)) {
+ generate(f);
+ }
+
+ /** Create a Callback with a function object
+ * @param f Function object to attach
+ * @note The function object is limited to a single word of storage
+ */
+ template <typename F>
+ Callback(const volatile F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R (F::*)(A0, A1) const volatile)) {
+ generate(f);
+ }
+
+ /** Create a Callback with a static function and bound pointer
+ * @param obj Pointer to object to bind to function
+ * @param func Static function to attach
+ * @deprecated
+ * Arguments to callback have been reordered to Callback(func, arg)
+ */
+ template<typename T, typename U>
+ Callback(U *obj, R (*func)(T*, A0, A1)) {
+ new (this) Callback(func, obj);
+ }
+
+ /** Create a Callback with a static function and bound pointer
+ * @param obj Pointer to object to bind to function
+ * @param func Static function to attach
+ * @deprecated
+ * Arguments to callback have been reordered to Callback(func, arg)
+ */
+ template<typename T, typename U>
+ Callback(const U *obj, R (*func)(const T*, A0, A1)) {
+ new (this) Callback(func, obj);
+ }
+
+ /** Create a Callback with a static function and bound pointer
+ * @param obj Pointer to object to bind to function
+ * @param func Static function to attach
+ * @deprecated
+ * Arguments to callback have been reordered to Callback(func, arg)
+ */
+ template<typename T, typename U>
+ Callback(volatile U *obj, R (*func)(volatile T*, A0, A1)) {
+ new (this) Callback(func, obj);
+ }
+
+ /** Create a Callback with a static function and bound pointer
+ * @param obj Pointer to object to bind to function
+ * @param func Static function to attach
+ * @deprecated
+ * Arguments to callback have been reordered to Callback(func, arg)
+ */
+ template<typename T, typename U>
+ Callback(const volatile U *obj, R (*func)(const volatile T*, A0, A1)) {
+ new (this) Callback(func, obj);
+ }
+
+ /** Destroy a callback
+ */
+ ~Callback() {
+ if (_ops) {
+ _ops->dtor(this);
+ }
+ }
+
+ /** Attach a static function
+ * @param func Static function to attach
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ void attach(R (*func)(A0, A1)) {
+ this->~Callback();
+ new (this) Callback(func);
+ }
+
+ /** Attach a Callback
+ * @param func The Callback to attach
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ void attach(const Callback<R(A0, A1)> &func) {
+ this->~Callback();
+ new (this) Callback(func);
+ }
+
+ /** Attach a member function
+ * @param obj Pointer to object to invoke member function on
+ * @param method Member function to attach
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ template<typename T, typename U>
+ void attach(U *obj, R (T::*method)(A0, A1)) {
+ this->~Callback();
+ new (this) Callback(obj, method);
+ }
+
+ /** Attach a member function
+ * @param obj Pointer to object to invoke member function on
+ * @param method Member function to attach
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ template<typename T, typename U>
+ void attach(const U *obj, R (T::*method)(A0, A1) const) {
+ this->~Callback();
+ new (this) Callback(obj, method);
+ }
+
+ /** Attach a member function
+ * @param obj Pointer to object to invoke member function on
+ * @param method Member function to attach
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ template<typename T, typename U>
+ void attach(volatile U *obj, R (T::*method)(A0, A1) volatile) {
+ this->~Callback();
+ new (this) Callback(obj, method);
+ }
+
+ /** Attach a member function
+ * @param obj Pointer to object to invoke member function on
+ * @param method Member function to attach
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ template<typename T, typename U>
+ void attach(const volatile U *obj, R (T::*method)(A0, A1) const volatile) {
+ this->~Callback();
+ new (this) Callback(obj, method);
+ }
+
+ /** Attach a static function with a bound pointer
+ * @param func Static function to attach
+ * @param arg Pointer argument to function
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ template <typename T, typename U>
+ void attach(R (*func)(T*, A0, A1), U *arg) {
+ this->~Callback();
+ new (this) Callback(func, arg);
+ }
+
+ /** Attach a static function with a bound pointer
+ * @param func Static function to attach
+ * @param arg Pointer argument to function
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ template <typename T, typename U>
+ void attach(R (*func)(const T*, A0, A1), const U *arg) {
+ this->~Callback();
+ new (this) Callback(func, arg);
+ }
+
+ /** Attach a static function with a bound pointer
+ * @param func Static function to attach
+ * @param arg Pointer argument to function
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ template <typename T, typename U>
+ void attach(R (*func)(volatile T*, A0, A1), volatile U *arg) {
+ this->~Callback();
+ new (this) Callback(func, arg);
+ }
+
+ /** Attach a static function with a bound pointer
+ * @param func Static function to attach
+ * @param arg Pointer argument to function
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ template <typename T, typename U>
+ void attach(R (*func)(const volatile T*, A0, A1), const volatile U *arg) {
+ this->~Callback();
+ new (this) Callback(func, arg);
+ }
+
+ /** Attach a function object
+ * @param f Function object to attach
+ * @note The function object is limited to a single word of storage
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ template <typename F>
+ void attach(F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R (F::*)(A0, A1))) {
+ this->~Callback();
+ new (this) Callback(f);
+ }
+
+ /** Attach a function object
+ * @param f Function object to attach
+ * @note The function object is limited to a single word of storage
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ template <typename F>
+ void attach(const F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R (F::*)(A0, A1) const)) {
+ this->~Callback();
+ new (this) Callback(f);
+ }
+
+ /** Attach a function object
+ * @param f Function object to attach
+ * @note The function object is limited to a single word of storage
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ template <typename F>
+ void attach(volatile F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R (F::*)(A0, A1) volatile)) {
+ this->~Callback();
+ new (this) Callback(f);
+ }
+
+ /** Attach a function object
+ * @param f Function object to attach
+ * @note The function object is limited to a single word of storage
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ template <typename F>
+ void attach(const volatile F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R (F::*)(A0, A1) const volatile)) {
+ this->~Callback();
+ new (this) Callback(f);
+ }
+
+ /** Attach a static function with a bound pointer
+ * @param obj Pointer to object to bind to function
+ * @param func Static function to attach
+ * @deprecated
+ * Arguments to callback have been reordered to attach(func, arg)
+ */
+ template <typename T, typename U>
+ void attach(U *obj, R (*func)(T*, A0, A1)) {
+ this->~Callback();
+ new (this) Callback(func, obj);
+ }
+
+ /** Attach a static function with a bound pointer
+ * @param obj Pointer to object to bind to function
+ * @param func Static function to attach
+ * @deprecated
+ * Arguments to callback have been reordered to attach(func, arg)
+ */
+ template <typename T, typename U>
+ void attach(const U *obj, R (*func)(const T*, A0, A1)) {
+ this->~Callback();
+ new (this) Callback(func, obj);
+ }
+
+ /** Attach a static function with a bound pointer
+ * @param obj Pointer to object to bind to function
+ * @param func Static function to attach
+ * @deprecated
+ * Arguments to callback have been reordered to attach(func, arg)
+ */
+ template <typename T, typename U>
+ void attach(volatile U *obj, R (*func)(volatile T*, A0, A1)) {
+ this->~Callback();
+ new (this) Callback(func, obj);
+ }
+
+ /** Attach a static function with a bound pointer
+ * @param obj Pointer to object to bind to function
+ * @param func Static function to attach
+ * @deprecated
+ * Arguments to callback have been reordered to attach(func, arg)
+ */
+ template <typename T, typename U>
+ void attach(const volatile U *obj, R (*func)(const volatile T*, A0, A1)) {
+ this->~Callback();
+ new (this) Callback(func, obj);
+ }
+
+ /** Assign a callback
+ */
+ Callback &operator=(const Callback &that) {
+ if (this != &that) {
+ this->~Callback();
+ new (this) Callback(that);
+ }
+
+ return *this;
+ }
+
+ /** Call the attached function
+ */
+ R call(A0 a0, A1 a1) const {
+ MBED_ASSERT(_ops);
+ return _ops->call(this, a0, a1);
+ }
+
+ /** Call the attached function
+ */
+ R operator()(A0 a0, A1 a1) const {
+ return call(a0, a1);
+ }
+
+ /** Test if function has been attached
+ */
+ operator bool() const {
+ return _ops;
+ }
+
+ /** Test for equality
+ */
+ friend bool operator==(const Callback &l, const Callback &r) {
+ return memcmp(&l, &r, sizeof(Callback)) == 0;
+ }
+
+ /** Test for inequality
+ */
+ friend bool operator!=(const Callback &l, const Callback &r) {
+ return !(l == r);
+ }
+
+ /** Static thunk for passing as C-style function
+ * @param func Callback to call passed as void pointer
+ * @param a0 An argument to be called with function func
+ * @param a1 An argument to be called with function func
+ * @return the value as determined by func which is of
+ * type and determined by the signiture of func
+ */
+ static R thunk(void *func, A0 a0, A1 a1) {
+ return static_cast<Callback*>(func)->call(a0, a1);
+ }
+
+private:
+ // Stored as pointer to function and pointer to optional object
+ // Function pointer is stored as union of possible function types
+ // to garuntee proper size and alignment
+ struct _class;
+ union {
+ void (*_staticfunc)(A0, A1);
+ void (*_boundfunc)(_class*, A0, A1);
+ void (_class::*_methodfunc)(A0, A1);
+ } _func;
+ void *_obj;
+
+ // Dynamically dispatched operations
+ const struct ops {
+ R (*call)(const void*, A0, A1);
+ void (*move)(void*, const void*);
+ void (*dtor)(void*);
+ } *_ops;
+
+ // Generate operations for function object
+ template <typename F>
+ void generate(const F &f) {
+ static const ops ops = {
+ &Callback::function_call<F>,
+ &Callback::function_move<F>,
+ &Callback::function_dtor<F>,
+ };
+ new (this) F(f);
+ _ops = &ops;
+ }
+
+ // Function attributes
+ template <typename F>
+ static R function_call(const void *p, A0 a0, A1 a1) {
+ return (*(F*)p)(a0, a1);
+ }
+
+ template <typename F>
+ static void function_move(void *d, const void *p) {
+ new (d) F(*(F*)p);
+ }
+
+ template <typename F>
+ static void function_dtor(void *p) {
+ ((F*)p)->~F();
+ }
+
+ // Wrappers for functions with context
+ template <typename O, typename M>
+ struct method_context {
+ M method;
+ O *obj;
+
+ method_context(O *obj, M method)
+ : method(method), obj(obj) {}
+
+ R operator()(A0 a0, A1 a1) const {
+ return (obj->*method)(a0, a1);
+ }
+ };
+
+ template <typename F, typename A>
+ struct function_context {
+ F func;
+ A *arg;
+
+ function_context(F func, A *arg)
+ : func(func), arg(arg) {}
+
+ R operator()(A0 a0, A1 a1) const {
+ return func(arg, a0, a1);
+ }
+ };
+};
+
+/** Callback class based on template specialization
+ *
+ * @note Synchronization level: Not protected
+ * @ingroup platform
+ */
+template <typename R, typename A0, typename A1, typename A2>
+class Callback<R(A0, A1, A2)> {
+public:
+ /** Create a Callback with a static function
+ * @param func Static function to attach
+ */
+ Callback(R (*func)(A0, A1, A2) = 0) {
+ if (!func) {
+ _ops = 0;
+ } else {
+ generate(func);
+ }
+ }
+
+ /** Attach a Callback
+ * @param func The Callback to attach
+ */
+ Callback(const Callback<R(A0, A1, A2)> &func) {
+ if (func._ops) {
+ func._ops->move(this, &func);
+ }
+ _ops = func._ops;
+ }
+
+ /** Create a Callback with a member function
+ * @param obj Pointer to object to invoke member function on
+ * @param method Member function to attach
+ */
+ template<typename T, typename U>
+ Callback(U *obj, R (T::*method)(A0, A1, A2)) {
+ generate(method_context<T, R (T::*)(A0, A1, A2)>(obj, method));
+ }
+
+ /** Create a Callback with a member function
+ * @param obj Pointer to object to invoke member function on
+ * @param method Member function to attach
+ */
+ template<typename T, typename U>
+ Callback(const U *obj, R (T::*method)(A0, A1, A2) const) {
+ generate(method_context<const T, R (T::*)(A0, A1, A2) const>(obj, method));
+ }
+
+ /** Create a Callback with a member function
+ * @param obj Pointer to object to invoke member function on
+ * @param method Member function to attach
+ */
+ template<typename T, typename U>
+ Callback(volatile U *obj, R (T::*method)(A0, A1, A2) volatile) {
+ generate(method_context<volatile T, R (T::*)(A0, A1, A2) volatile>(obj, method));
+ }
+
+ /** Create a Callback with a member function
+ * @param obj Pointer to object to invoke member function on
+ * @param method Member function to attach
+ */
+ template<typename T, typename U>
+ Callback(const volatile U *obj, R (T::*method)(A0, A1, A2) const volatile) {
+ generate(method_context<const volatile T, R (T::*)(A0, A1, A2) const volatile>(obj, method));
+ }
+
+ /** Create a Callback with a static function and bound pointer
+ * @param func Static function to attach
+ * @param arg Pointer argument to function
+ */
+ template<typename T, typename U>
+ Callback(R (*func)(T*, A0, A1, A2), U *arg) {
+ generate(function_context<R (*)(T*, A0, A1, A2), T>(func, arg));
+ }
+
+ /** Create a Callback with a static function and bound pointer
+ * @param func Static function to attach
+ * @param arg Pointer argument to function
+ */
+ template<typename T, typename U>
+ Callback(R (*func)(const T*, A0, A1, A2), const U *arg) {
+ generate(function_context<R (*)(const T*, A0, A1, A2), const T>(func, arg));
+ }
+
+ /** Create a Callback with a static function and bound pointer
+ * @param func Static function to attach
+ * @param arg Pointer argument to function
+ */
+ template<typename T, typename U>
+ Callback(R (*func)(volatile T*, A0, A1, A2), volatile U *arg) {
+ generate(function_context<R (*)(volatile T*, A0, A1, A2), volatile T>(func, arg));
+ }
+
+ /** Create a Callback with a static function and bound pointer
+ * @param func Static function to attach
+ * @param arg Pointer argument to function
+ */
+ template<typename T, typename U>
+ Callback(R (*func)(const volatile T*, A0, A1, A2), const volatile U *arg) {
+ generate(function_context<R (*)(const volatile T*, A0, A1, A2), const volatile T>(func, arg));
+ }
+
+ /** Create a Callback with a function object
+ * @param f Function object to attach
+ * @note The function object is limited to a single word of storage
+ */
+ template <typename F>
+ Callback(F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R (F::*)(A0, A1, A2))) {
+ generate(f);
+ }
+
+ /** Create a Callback with a function object
+ * @param f Function object to attach
+ * @note The function object is limited to a single word of storage
+ */
+ template <typename F>
+ Callback(const F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R (F::*)(A0, A1, A2) const)) {
+ generate(f);
+ }
+
+ /** Create a Callback with a function object
+ * @param f Function object to attach
+ * @note The function object is limited to a single word of storage
+ */
+ template <typename F>
+ Callback(volatile F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R (F::*)(A0, A1, A2) volatile)) {
+ generate(f);
+ }
+
+ /** Create a Callback with a function object
+ * @param f Function object to attach
+ * @note The function object is limited to a single word of storage
+ */
+ template <typename F>
+ Callback(const volatile F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R (F::*)(A0, A1, A2) const volatile)) {
+ generate(f);
+ }
+
+ /** Create a Callback with a static function and bound pointer
+ * @param obj Pointer to object to bind to function
+ * @param func Static function to attach
+ * @deprecated
+ * Arguments to callback have been reordered to Callback(func, arg)
+ */
+ template<typename T, typename U>
+ Callback(U *obj, R (*func)(T*, A0, A1, A2)) {
+ new (this) Callback(func, obj);
+ }
+
+ /** Create a Callback with a static function and bound pointer
+ * @param obj Pointer to object to bind to function
+ * @param func Static function to attach
+ * @deprecated
+ * Arguments to callback have been reordered to Callback(func, arg)
+ */
+ template<typename T, typename U>
+ Callback(const U *obj, R (*func)(const T*, A0, A1, A2)) {
+ new (this) Callback(func, obj);
+ }
+
+ /** Create a Callback with a static function and bound pointer
+ * @param obj Pointer to object to bind to function
+ * @param func Static function to attach
+ * @deprecated
+ * Arguments to callback have been reordered to Callback(func, arg)
+ */
+ template<typename T, typename U>
+ Callback(volatile U *obj, R (*func)(volatile T*, A0, A1, A2)) {
+ new (this) Callback(func, obj);
+ }
+
+ /** Create a Callback with a static function and bound pointer
+ * @param obj Pointer to object to bind to function
+ * @param func Static function to attach
+ * @deprecated
+ * Arguments to callback have been reordered to Callback(func, arg)
+ */
+ template<typename T, typename U>
+ Callback(const volatile U *obj, R (*func)(const volatile T*, A0, A1, A2)) {
+ new (this) Callback(func, obj);
+ }
+
+ /** Destroy a callback
+ */
+ ~Callback() {
+ if (_ops) {
+ _ops->dtor(this);
+ }
+ }
+
+ /** Attach a static function
+ * @param func Static function to attach
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ void attach(R (*func)(A0, A1, A2)) {
+ this->~Callback();
+ new (this) Callback(func);
+ }
+
+ /** Attach a Callback
+ * @param func The Callback to attach
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ void attach(const Callback<R(A0, A1, A2)> &func) {
+ this->~Callback();
+ new (this) Callback(func);
+ }
+
+ /** Attach a member function
+ * @param obj Pointer to object to invoke member function on
+ * @param method Member function to attach
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ template<typename T, typename U>
+ void attach(U *obj, R (T::*method)(A0, A1, A2)) {
+ this->~Callback();
+ new (this) Callback(obj, method);
+ }
+
+ /** Attach a member function
+ * @param obj Pointer to object to invoke member function on
+ * @param method Member function to attach
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ template<typename T, typename U>
+ void attach(const U *obj, R (T::*method)(A0, A1, A2) const) {
+ this->~Callback();
+ new (this) Callback(obj, method);
+ }
+
+ /** Attach a member function
+ * @param obj Pointer to object to invoke member function on
+ * @param method Member function to attach
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ template<typename T, typename U>
+ void attach(volatile U *obj, R (T::*method)(A0, A1, A2) volatile) {
+ this->~Callback();
+ new (this) Callback(obj, method);
+ }
+
+ /** Attach a member function
+ * @param obj Pointer to object to invoke member function on
+ * @param method Member function to attach
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ template<typename T, typename U>
+ void attach(const volatile U *obj, R (T::*method)(A0, A1, A2) const volatile) {
+ this->~Callback();
+ new (this) Callback(obj, method);
+ }
+
+ /** Attach a static function with a bound pointer
+ * @param func Static function to attach
+ * @param arg Pointer argument to function
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ template <typename T, typename U>
+ void attach(R (*func)(T*, A0, A1, A2), U *arg) {
+ this->~Callback();
+ new (this) Callback(func, arg);
+ }
+
+ /** Attach a static function with a bound pointer
+ * @param func Static function to attach
+ * @param arg Pointer argument to function
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ template <typename T, typename U>
+ void attach(R (*func)(const T*, A0, A1, A2), const U *arg) {
+ this->~Callback();
+ new (this) Callback(func, arg);
+ }
+
+ /** Attach a static function with a bound pointer
+ * @param func Static function to attach
+ * @param arg Pointer argument to function
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ template <typename T, typename U>
+ void attach(R (*func)(volatile T*, A0, A1, A2), volatile U *arg) {
+ this->~Callback();
+ new (this) Callback(func, arg);
+ }
+
+ /** Attach a static function with a bound pointer
+ * @param func Static function to attach
+ * @param arg Pointer argument to function
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ template <typename T, typename U>
+ void attach(R (*func)(const volatile T*, A0, A1, A2), const volatile U *arg) {
+ this->~Callback();
+ new (this) Callback(func, arg);
+ }
+
+ /** Attach a function object
+ * @param f Function object to attach
+ * @note The function object is limited to a single word of storage
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ template <typename F>
+ void attach(F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R (F::*)(A0, A1, A2))) {
+ this->~Callback();
+ new (this) Callback(f);
+ }
+
+ /** Attach a function object
+ * @param f Function object to attach
+ * @note The function object is limited to a single word of storage
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ template <typename F>
+ void attach(const F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R (F::*)(A0, A1, A2) const)) {
+ this->~Callback();
+ new (this) Callback(f);
+ }
+
+ /** Attach a function object
+ * @param f Function object to attach
+ * @note The function object is limited to a single word of storage
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ template <typename F>
+ void attach(volatile F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R (F::*)(A0, A1, A2) volatile)) {
+ this->~Callback();
+ new (this) Callback(f);
+ }
+
+ /** Attach a function object
+ * @param f Function object to attach
+ * @note The function object is limited to a single word of storage
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ template <typename F>
+ void attach(const volatile F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R (F::*)(A0, A1, A2) const volatile)) {
+ this->~Callback();
+ new (this) Callback(f);
+ }
+
+ /** Attach a static function with a bound pointer
+ * @param obj Pointer to object to bind to function
+ * @param func Static function to attach
+ * @deprecated
+ * Arguments to callback have been reordered to attach(func, arg)
+ */
+ template <typename T, typename U>
+ void attach(U *obj, R (*func)(T*, A0, A1, A2)) {
+ this->~Callback();
+ new (this) Callback(func, obj);
+ }
+
+ /** Attach a static function with a bound pointer
+ * @param obj Pointer to object to bind to function
+ * @param func Static function to attach
+ * @deprecated
+ * Arguments to callback have been reordered to attach(func, arg)
+ */
+ template <typename T, typename U>
+ void attach(const U *obj, R (*func)(const T*, A0, A1, A2)) {
+ this->~Callback();
+ new (this) Callback(func, obj);
+ }
+
+ /** Attach a static function with a bound pointer
+ * @param obj Pointer to object to bind to function
+ * @param func Static function to attach
+ * @deprecated
+ * Arguments to callback have been reordered to attach(func, arg)
+ */
+ template <typename T, typename U>
+ void attach(volatile U *obj, R (*func)(volatile T*, A0, A1, A2)) {
+ this->~Callback();
+ new (this) Callback(func, obj);
+ }
+
+ /** Attach a static function with a bound pointer
+ * @param obj Pointer to object to bind to function
+ * @param func Static function to attach
+ * @deprecated
+ * Arguments to callback have been reordered to attach(func, arg)
+ */
+ template <typename T, typename U>
+ void attach(const volatile U *obj, R (*func)(const volatile T*, A0, A1, A2)) {
+ this->~Callback();
+ new (this) Callback(func, obj);
+ }
+
+ /** Assign a callback
+ */
+ Callback &operator=(const Callback &that) {
+ if (this != &that) {
+ this->~Callback();
+ new (this) Callback(that);
+ }
+
+ return *this;
+ }
+
+ /** Call the attached function
+ */
+ R call(A0 a0, A1 a1, A2 a2) const {
+ MBED_ASSERT(_ops);
+ return _ops->call(this, a0, a1, a2);
+ }
+
+ /** Call the attached function
+ */
+ R operator()(A0 a0, A1 a1, A2 a2) const {
+ return call(a0, a1, a2);
+ }
+
+ /** Test if function has been attached
+ */
+ operator bool() const {
+ return _ops;
+ }
+
+ /** Test for equality
+ */
+ friend bool operator==(const Callback &l, const Callback &r) {
+ return memcmp(&l, &r, sizeof(Callback)) == 0;
+ }
+
+ /** Test for inequality
+ */
+ friend bool operator!=(const Callback &l, const Callback &r) {
+ return !(l == r);
+ }
+
+ /** Static thunk for passing as C-style function
+ * @param func Callback to call passed as void pointer
+ * @param a0 An argument to be called with function func
+ * @param a1 An argument to be called with function func
+ * @param a2 An argument to be called with function func
+ * @return the value as determined by func which is of
+ * type and determined by the signiture of func
+ */
+ static R thunk(void *func, A0 a0, A1 a1, A2 a2) {
+ return static_cast<Callback*>(func)->call(a0, a1, a2);
+ }
+
+private:
+ // Stored as pointer to function and pointer to optional object
+ // Function pointer is stored as union of possible function types
+ // to garuntee proper size and alignment
+ struct _class;
+ union {
+ void (*_staticfunc)(A0, A1, A2);
+ void (*_boundfunc)(_class*, A0, A1, A2);
+ void (_class::*_methodfunc)(A0, A1, A2);
+ } _func;
+ void *_obj;
+
+ // Dynamically dispatched operations
+ const struct ops {
+ R (*call)(const void*, A0, A1, A2);
+ void (*move)(void*, const void*);
+ void (*dtor)(void*);
+ } *_ops;
+
+ // Generate operations for function object
+ template <typename F>
+ void generate(const F &f) {
+ static const ops ops = {
+ &Callback::function_call<F>,
+ &Callback::function_move<F>,
+ &Callback::function_dtor<F>,
+ };
+
+ new (this) F(f);
+ _ops = &ops;
+ }
+
+ // Function attributes
+ template <typename F>
+ static R function_call(const void *p, A0 a0, A1 a1, A2 a2) {
+ return (*(F*)p)(a0, a1, a2);
+ }
+
+ template <typename F>
+ static void function_move(void *d, const void *p) {
+ new (d) F(*(F*)p);
+ }
+
+ template <typename F>
+ static void function_dtor(void *p) {
+ ((F*)p)->~F();
+ }
+
+ // Wrappers for functions with context
+ template <typename O, typename M>
+ struct method_context {
+ M method;
+ O *obj;
+
+ method_context(O *obj, M method)
+ : method(method), obj(obj) {}
+
+ R operator()(A0 a0, A1 a1, A2 a2) const {
+ return (obj->*method)(a0, a1, a2);
+ }
+ };
+
+ template <typename F, typename A>
+ struct function_context {
+ F func;
+ A *arg;
+
+ function_context(F func, A *arg)
+ : func(func), arg(arg) {}
+
+ R operator()(A0 a0, A1 a1, A2 a2) const {
+ return func(arg, a0, a1, a2);
+ }
+ };
+};
+
+/** Callback class based on template specialization
+ *
+ * @note Synchronization level: Not protected
+ * @ingroup platform
+ */
+template <typename R, typename A0, typename A1, typename A2, typename A3>
+class Callback<R(A0, A1, A2, A3)> {
+public:
+ /** Create a Callback with a static function
+ * @param func Static function to attach
+ */
+ Callback(R (*func)(A0, A1, A2, A3) = 0) {
+ if (!func) {
+ _ops = 0;
+ } else {
+ generate(func);
+ }
+ }
+
+ /** Attach a Callback
+ * @param func The Callback to attach
+ */
+ Callback(const Callback<R(A0, A1, A2, A3)> &func) {
+ if (func._ops) {
+ func._ops->move(this, &func);
+ }
+ _ops = func._ops;
+ }
+
+ /** Create a Callback with a member function
+ * @param obj Pointer to object to invoke member function on
+ * @param method Member function to attach
+ */
+ template<typename T, typename U>
+ Callback(U *obj, R (T::*method)(A0, A1, A2, A3)) {
+ generate(method_context<T, R (T::*)(A0, A1, A2, A3)>(obj, method));
+ }
+
+ /** Create a Callback with a member function
+ * @param obj Pointer to object to invoke member function on
+ * @param method Member function to attach
+ */
+ template<typename T, typename U>
+ Callback(const U *obj, R (T::*method)(A0, A1, A2, A3) const) {
+ generate(method_context<const T, R (T::*)(A0, A1, A2, A3) const>(obj, method));
+ }
+
+ /** Create a Callback with a member function
+ * @param obj Pointer to object to invoke member function on
+ * @param method Member function to attach
+ */
+ template<typename T, typename U>
+ Callback(volatile U *obj, R (T::*method)(A0, A1, A2, A3) volatile) {
+ generate(method_context<volatile T, R (T::*)(A0, A1, A2, A3) volatile>(obj, method));
+ }
+
+ /** Create a Callback with a member function
+ * @param obj Pointer to object to invoke member function on
+ * @param method Member function to attach
+ */
+ template<typename T, typename U>
+ Callback(const volatile U *obj, R (T::*method)(A0, A1, A2, A3) const volatile) {
+ generate(method_context<const volatile T, R (T::*)(A0, A1, A2, A3) const volatile>(obj, method));
+ }
+
+ /** Create a Callback with a static function and bound pointer
+ * @param func Static function to attach
+ * @param arg Pointer argument to function
+ */
+ template<typename T, typename U>
+ Callback(R (*func)(T*, A0, A1, A2, A3), U *arg) {
+ generate(function_context<R (*)(T*, A0, A1, A2, A3), T>(func, arg));
+ }
+
+ /** Create a Callback with a static function and bound pointer
+ * @param func Static function to attach
+ * @param arg Pointer argument to function
+ */
+ template<typename T, typename U>
+ Callback(R (*func)(const T*, A0, A1, A2, A3), const U *arg) {
+ generate(function_context<R (*)(const T*, A0, A1, A2, A3), const T>(func, arg));
+ }
+
+ /** Create a Callback with a static function and bound pointer
+ * @param func Static function to attach
+ * @param arg Pointer argument to function
+ */
+ template<typename T, typename U>
+ Callback(R (*func)(volatile T*, A0, A1, A2, A3), volatile U *arg) {
+ generate(function_context<R (*)(volatile T*, A0, A1, A2, A3), volatile T>(func, arg));
+ }
+
+ /** Create a Callback with a static function and bound pointer
+ * @param func Static function to attach
+ * @param arg Pointer argument to function
+ */
+ template<typename T, typename U>
+ Callback(R (*func)(const volatile T*, A0, A1, A2, A3), const volatile U *arg) {
+ generate(function_context<R (*)(const volatile T*, A0, A1, A2, A3), const volatile T>(func, arg));
+ }
+
+ /** Create a Callback with a function object
+ * @param f Function object to attach
+ * @note The function object is limited to a single word of storage
+ */
+ template <typename F>
+ Callback(F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R (F::*)(A0, A1, A2, A3))) {
+ generate(f);
+ }
+
+ /** Create a Callback with a function object
+ * @param f Function object to attach
+ * @note The function object is limited to a single word of storage
+ */
+ template <typename F>
+ Callback(const F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R (F::*)(A0, A1, A2, A3) const)) {
+ generate(f);
+ }
+
+ /** Create a Callback with a function object
+ * @param f Function object to attach
+ * @note The function object is limited to a single word of storage
+ */
+ template <typename F>
+ Callback(volatile F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R (F::*)(A0, A1, A2, A3) volatile)) {
+ generate(f);
+ }
+
+ /** Create a Callback with a function object
+ * @param f Function object to attach
+ * @note The function object is limited to a single word of storage
+ */
+ template <typename F>
+ Callback(const volatile F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R (F::*)(A0, A1, A2, A3) const volatile)) {
+ generate(f);
+ }
+
+ /** Create a Callback with a static function and bound pointer
+ * @param obj Pointer to object to bind to function
+ * @param func Static function to attach
+ * @deprecated
+ * Arguments to callback have been reordered to Callback(func, arg)
+ */
+ template<typename T, typename U>
+ Callback(U *obj, R (*func)(T*, A0, A1, A2, A3)) {
+ new (this) Callback(func, obj);
+ }
+
+ /** Create a Callback with a static function and bound pointer
+ * @param obj Pointer to object to bind to function
+ * @param func Static function to attach
+ * @deprecated
+ * Arguments to callback have been reordered to Callback(func, arg)
+ */
+ template<typename T, typename U>
+ Callback(const U *obj, R (*func)(const T*, A0, A1, A2, A3)) {
+ new (this) Callback(func, obj);
+ }
+
+ /** Create a Callback with a static function and bound pointer
+ * @param obj Pointer to object to bind to function
+ * @param func Static function to attach
+ * @deprecated
+ * Arguments to callback have been reordered to Callback(func, arg)
+ */
+ template<typename T, typename U>
+ Callback(volatile U *obj, R (*func)(volatile T*, A0, A1, A2, A3)) {
+ new (this) Callback(func, obj);
+ }
+
+ /** Create a Callback with a static function and bound pointer
+ * @param obj Pointer to object to bind to function
+ * @param func Static function to attach
+ * @deprecated
+ * Arguments to callback have been reordered to Callback(func, arg)
+ */
+ template<typename T, typename U>
+ Callback(const volatile U *obj, R (*func)(const volatile T*, A0, A1, A2, A3)) {
+ new (this) Callback(func, obj);
+ }
+
+ /** Destroy a callback
+ */
+ ~Callback() {
+ if (_ops) {
+ _ops->dtor(this);
+ }
+ }
+
+ /** Attach a static function
+ * @param func Static function to attach
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ void attach(R (*func)(A0, A1, A2, A3)) {
+ this->~Callback();
+ new (this) Callback(func);
+ }
+
+ /** Attach a Callback
+ * @param func The Callback to attach
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ void attach(const Callback<R(A0, A1, A2, A3)> &func) {
+ this->~Callback();
+ new (this) Callback(func);
+ }
+
+ /** Attach a member function
+ * @param obj Pointer to object to invoke member function on
+ * @param method Member function to attach
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ template<typename T, typename U>
+ void attach(U *obj, R (T::*method)(A0, A1, A2, A3)) {
+ this->~Callback();
+ new (this) Callback(obj, method);
+ }
+
+ /** Attach a member function
+ * @param obj Pointer to object to invoke member function on
+ * @param method Member function to attach
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ template<typename T, typename U>
+ void attach(const U *obj, R (T::*method)(A0, A1, A2, A3) const) {
+ this->~Callback();
+ new (this) Callback(obj, method);
+ }
+
+ /** Attach a member function
+ * @param obj Pointer to object to invoke member function on
+ * @param method Member function to attach
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ template<typename T, typename U>
+ void attach(volatile U *obj, R (T::*method)(A0, A1, A2, A3) volatile) {
+ this->~Callback();
+ new (this) Callback(obj, method);
+ }
+
+ /** Attach a member function
+ * @param obj Pointer to object to invoke member function on
+ * @param method Member function to attach
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ template<typename T, typename U>
+ void attach(const volatile U *obj, R (T::*method)(A0, A1, A2, A3) const volatile) {
+ this->~Callback();
+ new (this) Callback(obj, method);
+ }
+
+ /** Attach a static function with a bound pointer
+ * @param func Static function to attach
+ * @param arg Pointer argument to function
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ template <typename T, typename U>
+ void attach(R (*func)(T*, A0, A1, A2, A3), U *arg) {
+ this->~Callback();
+ new (this) Callback(func, arg);
+ }
+
+ /** Attach a static function with a bound pointer
+ * @param func Static function to attach
+ * @param arg Pointer argument to function
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ template <typename T, typename U>
+ void attach(R (*func)(const T*, A0, A1, A2, A3), const U *arg) {
+ this->~Callback();
+ new (this) Callback(func, arg);
+ }
+
+ /** Attach a static function with a bound pointer
+ * @param func Static function to attach
+ * @param arg Pointer argument to function
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ template <typename T, typename U>
+ void attach(R (*func)(volatile T*, A0, A1, A2, A3), volatile U *arg) {
+ this->~Callback();
+ new (this) Callback(func, arg);
+ }
+
+ /** Attach a static function with a bound pointer
+ * @param func Static function to attach
+ * @param arg Pointer argument to function
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ template <typename T, typename U>
+ void attach(R (*func)(const volatile T*, A0, A1, A2, A3), const volatile U *arg) {
+ this->~Callback();
+ new (this) Callback(func, arg);
+ }
+
+ /** Attach a function object
+ * @param f Function object to attach
+ * @note The function object is limited to a single word of storage
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ template <typename F>
+ void attach(F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R (F::*)(A0, A1, A2, A3))) {
+ this->~Callback();
+ new (this) Callback(f);
+ }
+
+ /** Attach a function object
+ * @param f Function object to attach
+ * @note The function object is limited to a single word of storage
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ template <typename F>
+ void attach(const F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R (F::*)(A0, A1, A2, A3) const)) {
+ this->~Callback();
+ new (this) Callback(f);
+ }
+
+ /** Attach a function object
+ * @param f Function object to attach
+ * @note The function object is limited to a single word of storage
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ template <typename F>
+ void attach(volatile F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R (F::*)(A0, A1, A2, A3) volatile)) {
+ this->~Callback();
+ new (this) Callback(f);
+ }
+
+ /** Attach a function object
+ * @param f Function object to attach
+ * @note The function object is limited to a single word of storage
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ template <typename F>
+ void attach(const volatile F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R (F::*)(A0, A1, A2, A3) const volatile)) {
+ this->~Callback();
+ new (this) Callback(f);
+ }
+
+ /** Attach a static function with a bound pointer
+ * @param obj Pointer to object to bind to function
+ * @param func Static function to attach
+ * @deprecated
+ * Arguments to callback have been reordered to attach(func, arg)
+ */
+ template <typename T, typename U>
+ void attach(U *obj, R (*func)(T*, A0, A1, A2, A3)) {
+ this->~Callback();
+ new (this) Callback(func, obj);
+ }
+
+ /** Attach a static function with a bound pointer
+ * @param obj Pointer to object to bind to function
+ * @param func Static function to attach
+ * @deprecated
+ * Arguments to callback have been reordered to attach(func, arg)
+ */
+ template <typename T, typename U>
+ void attach(const U *obj, R (*func)(const T*, A0, A1, A2, A3)) {
+ this->~Callback();
+ new (this) Callback(func, obj);
+ }
+
+ /** Attach a static function with a bound pointer
+ * @param obj Pointer to object to bind to function
+ * @param func Static function to attach
+ * @deprecated
+ * Arguments to callback have been reordered to attach(func, arg)
+ */
+ template <typename T, typename U>
+ void attach(volatile U *obj, R (*func)(volatile T*, A0, A1, A2, A3)) {
+ this->~Callback();
+ new (this) Callback(func, obj);
+ }
+
+ /** Attach a static function with a bound pointer
+ * @param obj Pointer to object to bind to function
+ * @param func Static function to attach
+ * @deprecated
+ * Arguments to callback have been reordered to attach(func, arg)
+ */
+ template <typename T, typename U>
+ void attach(const volatile U *obj, R (*func)(const volatile T*, A0, A1, A2, A3)) {
+ this->~Callback();
+ new (this) Callback(func, obj);
+ }
+
+ /** Assign a callback
+ */
+ Callback &operator=(const Callback &that) {
+ if (this != &that) {
+ this->~Callback();
+ new (this) Callback(that);
+ }
+
+ return *this;
+ }
+
+ /** Call the attached function
+ */
+ R call(A0 a0, A1 a1, A2 a2, A3 a3) const {
+ MBED_ASSERT(_ops);
+ return _ops->call(this, a0, a1, a2, a3);
+ }
+
+ /** Call the attached function
+ */
+ R operator()(A0 a0, A1 a1, A2 a2, A3 a3) const {
+ return call(a0, a1, a2, a3);
+ }
+
+ /** Test if function has been attached
+ */
+ operator bool() const {
+ return _ops;
+ }
+
+ /** Test for equality
+ */
+ friend bool operator==(const Callback &l, const Callback &r) {
+ return memcmp(&l, &r, sizeof(Callback)) == 0;
+ }
+
+ /** Test for inequality
+ */
+ friend bool operator!=(const Callback &l, const Callback &r) {
+ return !(l == r);
+ }
+
+ /** Static thunk for passing as C-style function
+ * @param func Callback to call passed as void pointer
+ * @param a0 An argument to be called with function func
+ * @param a1 An argument to be called with function func
+ * @param a2 An argument to be called with function func
+ * @param a3 An argument to be called with function func
+ * @return the value as determined by func which is of
+ * type and determined by the signiture of func
+ */
+ static R thunk(void *func, A0 a0, A1 a1, A2 a2, A3 a3) {
+ return static_cast<Callback*>(func)->call(a0, a1, a2, a3);
+ }
+
+private:
+ // Stored as pointer to function and pointer to optional object
+ // Function pointer is stored as union of possible function types
+ // to garuntee proper size and alignment
+ struct _class;
+ union {
+ void (*_staticfunc)(A0, A1, A2, A3);
+ void (*_boundfunc)(_class*, A0, A1, A2, A3);
+ void (_class::*_methodfunc)(A0, A1, A2, A3);
+ } _func;
+ void *_obj;
+
+ // Dynamically dispatched operations
+ const struct ops {
+ R (*call)(const void*, A0, A1, A2, A3);
+ void (*move)(void*, const void*);
+ void (*dtor)(void*);
+ } *_ops;
+
+ // Generate operations for function object
+ template <typename F>
+ void generate(const F &f) {
+ static const ops ops = {
+ &Callback::function_call<F>,
+ &Callback::function_move<F>,
+ &Callback::function_dtor<F>,
+ };
+
+ new (this) F(f);
+ _ops = &ops;
+ }
+
+ // Function attributes
+ template <typename F>
+ static R function_call(const void *p, A0 a0, A1 a1, A2 a2, A3 a3) {
+ return (*(F*)p)(a0, a1, a2, a3);
+ }
+
+ template <typename F>
+ static void function_move(void *d, const void *p) {
+ new (d) F(*(F*)p);
+ }
+
+ template <typename F>
+ static void function_dtor(void *p) {
+ ((F*)p)->~F();
+ }
+
+ // Wrappers for functions with context
+ template <typename O, typename M>
+ struct method_context {
+ M method;
+ O *obj;
+
+ method_context(O *obj, M method)
+ : method(method), obj(obj) {}
+
+ R operator()(A0 a0, A1 a1, A2 a2, A3 a3) const {
+ return (obj->*method)(a0, a1, a2, a3);
+ }
+ };
+
+ template <typename F, typename A>
+ struct function_context {
+ F func;
+ A *arg;
+
+ function_context(F func, A *arg)
+ : func(func), arg(arg) {}
+
+ R operator()(A0 a0, A1 a1, A2 a2, A3 a3) const {
+ return func(arg, a0, a1, a2, a3);
+ }
+ };
+};
+
+/** Callback class based on template specialization
+ *
+ * @note Synchronization level: Not protected
+ * @ingroup platform
+ */
+template <typename R, typename A0, typename A1, typename A2, typename A3, typename A4>
+class Callback<R(A0, A1, A2, A3, A4)> {
+public:
+ /** Create a Callback with a static function
+ * @param func Static function to attach
+ */
+ Callback(R (*func)(A0, A1, A2, A3, A4) = 0) {
+ if (!func) {
+ _ops = 0;
+ } else {
+ generate(func);
+ }
+ }
+
+ /** Attach a Callback
+ * @param func The Callback to attach
+ */
+ Callback(const Callback<R(A0, A1, A2, A3, A4)> &func) {
+ if (func._ops) {
+ func._ops->move(this, &func);
+ }
+ _ops = func._ops;
+ }
+
+ /** Create a Callback with a member function
+ * @param obj Pointer to object to invoke member function on
+ * @param method Member function to attach
+ */
+ template<typename T, typename U>
+ Callback(U *obj, R (T::*method)(A0, A1, A2, A3, A4)) {
+ generate(method_context<T, R (T::*)(A0, A1, A2, A3, A4)>(obj, method));
+ }
+
+ /** Create a Callback with a member function
+ * @param obj Pointer to object to invoke member function on
+ * @param method Member function to attach
+ */
+ template<typename T, typename U>
+ Callback(const U *obj, R (T::*method)(A0, A1, A2, A3, A4) const) {
+ generate(method_context<const T, R (T::*)(A0, A1, A2, A3, A4) const>(obj, method));
+ }
+
+ /** Create a Callback with a member function
+ * @param obj Pointer to object to invoke member function on
+ * @param method Member function to attach
+ */
+ template<typename T, typename U>
+ Callback(volatile U *obj, R (T::*method)(A0, A1, A2, A3, A4) volatile) {
+ generate(method_context<volatile T, R (T::*)(A0, A1, A2, A3, A4) volatile>(obj, method));
+ }
+
+ /** Create a Callback with a member function
+ * @param obj Pointer to object to invoke member function on
+ * @param method Member function to attach
+ */
+ template<typename T, typename U>
+ Callback(const volatile U *obj, R (T::*method)(A0, A1, A2, A3, A4) const volatile) {
+ generate(method_context<const volatile T, R (T::*)(A0, A1, A2, A3, A4) const volatile>(obj, method));
+ }
+
+ /** Create a Callback with a static function and bound pointer
+ * @param func Static function to attach
+ * @param arg Pointer argument to function
+ */
+ template<typename T, typename U>
+ Callback(R (*func)(T*, A0, A1, A2, A3, A4), U *arg) {
+ generate(function_context<R (*)(T*, A0, A1, A2, A3, A4), T>(func, arg));
+ }
+
+ /** Create a Callback with a static function and bound pointer
+ * @param func Static function to attach
+ * @param arg Pointer argument to function
+ */
+ template<typename T, typename U>
+ Callback(R (*func)(const T*, A0, A1, A2, A3, A4), const U *arg) {
+ generate(function_context<R (*)(const T*, A0, A1, A2, A3, A4), const T>(func, arg));
+ }
+
+ /** Create a Callback with a static function and bound pointer
+ * @param func Static function to attach
+ * @param arg Pointer argument to function
+ */
+ template<typename T, typename U>
+ Callback(R (*func)(volatile T*, A0, A1, A2, A3, A4), volatile U *arg) {
+ generate(function_context<R (*)(volatile T*, A0, A1, A2, A3, A4), volatile T>(func, arg));
+ }
+
+ /** Create a Callback with a static function and bound pointer
+ * @param func Static function to attach
+ * @param arg Pointer argument to function
+ */
+ template<typename T, typename U>
+ Callback(R (*func)(const volatile T*, A0, A1, A2, A3, A4), const volatile U *arg) {
+ generate(function_context<R (*)(const volatile T*, A0, A1, A2, A3, A4), const volatile T>(func, arg));
+ }
+
+ /** Create a Callback with a function object
+ * @param f Function object to attach
+ * @note The function object is limited to a single word of storage
+ */
+ template <typename F>
+ Callback(F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R (F::*)(A0, A1, A2, A3, A4))) {
+ generate(f);
+ }
+
+ /** Create a Callback with a function object
+ * @param f Function object to attach
+ * @note The function object is limited to a single word of storage
+ */
+ template <typename F>
+ Callback(const F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R (F::*)(A0, A1, A2, A3, A4) const)) {
+ generate(f);
+ }
+
+ /** Create a Callback with a function object
+ * @param f Function object to attach
+ * @note The function object is limited to a single word of storage
+ */
+ template <typename F>
+ Callback(volatile F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R (F::*)(A0, A1, A2, A3, A4) volatile)) {
+ generate(f);
+ }
+
+ /** Create a Callback with a function object
+ * @param f Function object to attach
+ * @note The function object is limited to a single word of storage
+ */
+ template <typename F>
+ Callback(const volatile F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R (F::*)(A0, A1, A2, A3, A4) const volatile)) {
+ generate(f);
+ }
+
+ /** Create a Callback with a static function and bound pointer
+ * @param obj Pointer to object to bind to function
+ * @param func Static function to attach
+ * @deprecated
+ * Arguments to callback have been reordered to Callback(func, arg)
+ */
+ template<typename T, typename U>
+ Callback(U *obj, R (*func)(T*, A0, A1, A2, A3, A4)) {
+ new (this) Callback(func, obj);
+ }
+
+ /** Create a Callback with a static function and bound pointer
+ * @param obj Pointer to object to bind to function
+ * @param func Static function to attach
+ * @deprecated
+ * Arguments to callback have been reordered to Callback(func, arg)
+ */
+ template<typename T, typename U>
+ Callback(const U *obj, R (*func)(const T*, A0, A1, A2, A3, A4)) {
+ new (this) Callback(func, obj);
+ }
+
+ /** Create a Callback with a static function and bound pointer
+ * @param obj Pointer to object to bind to function
+ * @param func Static function to attach
+ * @deprecated
+ * Arguments to callback have been reordered to Callback(func, arg)
+ */
+ template<typename T, typename U>
+ Callback(volatile U *obj, R (*func)(volatile T*, A0, A1, A2, A3, A4)) {
+ new (this) Callback(func, obj);
+ }
+
+ /** Create a Callback with a static function and bound pointer
+ * @param obj Pointer to object to bind to function
+ * @param func Static function to attach
+ * @deprecated
+ * Arguments to callback have been reordered to Callback(func, arg)
+ */
+ template<typename T, typename U>
+ Callback(const volatile U *obj, R (*func)(const volatile T*, A0, A1, A2, A3, A4)) {
+ new (this) Callback(func, obj);
+ }
+
+ /** Destroy a callback
+ */
+ ~Callback() {
+ if (_ops) {
+ _ops->dtor(this);
+ }
+ }
+
+ /** Attach a static function
+ * @param func Static function to attach
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ void attach(R (*func)(A0, A1, A2, A3, A4)) {
+ this->~Callback();
+ new (this) Callback(func);
+ }
+
+ /** Attach a Callback
+ * @param func The Callback to attach
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ void attach(const Callback<R(A0, A1, A2, A3, A4)> &func) {
+ this->~Callback();
+ new (this) Callback(func);
+ }
+
+ /** Attach a member function
+ * @param obj Pointer to object to invoke member function on
+ * @param method Member function to attach
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ template<typename T, typename U>
+ void attach(U *obj, R (T::*method)(A0, A1, A2, A3, A4)) {
+ this->~Callback();
+ new (this) Callback(obj, method);
+ }
+
+ /** Attach a member function
+ * @param obj Pointer to object to invoke member function on
+ * @param method Member function to attach
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ template<typename T, typename U>
+ void attach(const U *obj, R (T::*method)(A0, A1, A2, A3, A4) const) {
+ this->~Callback();
+ new (this) Callback(obj, method);
+ }
+
+ /** Attach a member function
+ * @param obj Pointer to object to invoke member function on
+ * @param method Member function to attach
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ template<typename T, typename U>
+ void attach(volatile U *obj, R (T::*method)(A0, A1, A2, A3, A4) volatile) {
+ this->~Callback();
+ new (this) Callback(obj, method);
+ }
+
+ /** Attach a member function
+ * @param obj Pointer to object to invoke member function on
+ * @param method Member function to attach
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ template<typename T, typename U>
+ void attach(const volatile U *obj, R (T::*method)(A0, A1, A2, A3, A4) const volatile) {
+ this->~Callback();
+ new (this) Callback(obj, method);
+ }
+
+ /** Attach a static function with a bound pointer
+ * @param func Static function to attach
+ * @param arg Pointer argument to function
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ template <typename T, typename U>
+ void attach(R (*func)(T*, A0, A1, A2, A3, A4), U *arg) {
+ this->~Callback();
+ new (this) Callback(func, arg);
+ }
+
+ /** Attach a static function with a bound pointer
+ * @param func Static function to attach
+ * @param arg Pointer argument to function
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ template <typename T, typename U>
+ void attach(R (*func)(const T*, A0, A1, A2, A3, A4), const U *arg) {
+ this->~Callback();
+ new (this) Callback(func, arg);
+ }
+
+ /** Attach a static function with a bound pointer
+ * @param func Static function to attach
+ * @param arg Pointer argument to function
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ template <typename T, typename U>
+ void attach(R (*func)(volatile T*, A0, A1, A2, A3, A4), volatile U *arg) {
+ this->~Callback();
+ new (this) Callback(func, arg);
+ }
+
+ /** Attach a static function with a bound pointer
+ * @param func Static function to attach
+ * @param arg Pointer argument to function
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ template <typename T, typename U>
+ void attach(R (*func)(const volatile T*, A0, A1, A2, A3, A4), const volatile U *arg) {
+ this->~Callback();
+ new (this) Callback(func, arg);
+ }
+
+ /** Attach a function object
+ * @param f Function object to attach
+ * @note The function object is limited to a single word of storage
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ template <typename F>
+ void attach(F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R (F::*)(A0, A1, A2, A3, A4))) {
+ this->~Callback();
+ new (this) Callback(f);
+ }
+
+ /** Attach a function object
+ * @param f Function object to attach
+ * @note The function object is limited to a single word of storage
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ template <typename F>
+ void attach(const F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R (F::*)(A0, A1, A2, A3, A4) const)) {
+ this->~Callback();
+ new (this) Callback(f);
+ }
+
+ /** Attach a function object
+ * @param f Function object to attach
+ * @note The function object is limited to a single word of storage
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ template <typename F>
+ void attach(volatile F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R (F::*)(A0, A1, A2, A3, A4) volatile)) {
+ this->~Callback();
+ new (this) Callback(f);
+ }
+
+ /** Attach a function object
+ * @param f Function object to attach
+ * @note The function object is limited to a single word of storage
+ * @deprecated
+ * Replaced by simple assignment 'Callback cb = func'
+ */
+ template <typename F>
+ void attach(const volatile F f, MBED_ENABLE_IF_CALLBACK_COMPATIBLE(F, R (F::*)(A0, A1, A2, A3, A4) const volatile)) {
+ this->~Callback();
+ new (this) Callback(f);
+ }
+
+ /** Attach a static function with a bound pointer
+ * @param obj Pointer to object to bind to function
+ * @param func Static function to attach
+ * @deprecated
+ * Arguments to callback have been reordered to attach(func, arg)
+ */
+ template <typename T, typename U>
+ void attach(U *obj, R (*func)(T*, A0, A1, A2, A3, A4)) {
+ this->~Callback();
+ new (this) Callback(func, obj);
+ }
+
+ /** Attach a static function with a bound pointer
+ * @param obj Pointer to object to bind to function
+ * @param func Static function to attach
+ * @deprecated
+ * Arguments to callback have been reordered to attach(func, arg)
+ */
+ template <typename T, typename U>
+ void attach(const U *obj, R (*func)(const T*, A0, A1, A2, A3, A4)) {
+ this->~Callback();
+ new (this) Callback(func, obj);
+ }
+
+ /** Attach a static function with a bound pointer
+ * @param obj Pointer to object to bind to function
+ * @param func Static function to attach
+ * @deprecated
+ * Arguments to callback have been reordered to attach(func, arg)
+ */
+ template <typename T, typename U>
+ void attach(volatile U *obj, R (*func)(volatile T*, A0, A1, A2, A3, A4)) {
+ this->~Callback();
+ new (this) Callback(func, obj);
+ }
+
+ /** Attach a static function with a bound pointer
+ * @param obj Pointer to object to bind to function
+ * @param func Static function to attach
+ * @deprecated
+ * Arguments to callback have been reordered to attach(func, arg)
+ */
+ template <typename T, typename U>
+ void attach(const volatile U *obj, R (*func)(const volatile T*, A0, A1, A2, A3, A4)) {
+ this->~Callback();
+ new (this) Callback(func, obj);
+ }
+
+ /** Assign a callback
+ */
+ Callback &operator=(const Callback &that) {
+ if (this != &that) {
+ this->~Callback();
+ new (this) Callback(that);
+ }
+
+ return *this;
+ }
+
+ /** Call the attached function
+ */
+ R call(A0 a0, A1 a1, A2 a2, A3 a3, A4 a4) const {
+ MBED_ASSERT(_ops);
+ return _ops->call(this, a0, a1, a2, a3, a4);
+ }
+
+ /** Call the attached function
+ */
+ R operator()(A0 a0, A1 a1, A2 a2, A3 a3, A4 a4) const {
+ return call(a0, a1, a2, a3, a4);
+ }
+
+ /** Test if function has been attached
+ */
+ operator bool() const {
+ return _ops;
+ }
+
+ /** Test for equality
+ */
+ friend bool operator==(const Callback &l, const Callback &r) {
+ return memcmp(&l, &r, sizeof(Callback)) == 0;
+ }
+
+ /** Test for inequality
+ */
+ friend bool operator!=(const Callback &l, const Callback &r) {
+ return !(l == r);
+ }
+
+ /** Static thunk for passing as C-style function
+ * @param func Callback to call passed as void pointer
+ * @param a0 An argument to be called with function func
+ * @param a1 An argument to be called with function func
+ * @param a2 An argument to be called with function func
+ * @param a3 An argument to be called with function func
+ * @param a4 An argument to be called with function func
+ * @return the value as determined by func which is of
+ * type and determined by the signiture of func
+ */
+ static R thunk(void *func, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4) {
+ return static_cast<Callback*>(func)->call(a0, a1, a2, a3, a4);
+ }
+
+private:
+ // Stored as pointer to function and pointer to optional object
+ // Function pointer is stored as union of possible function types
+ // to garuntee proper size and alignment
+ struct _class;
+ union {
+ void (*_staticfunc)(A0, A1, A2, A3, A4);
+ void (*_boundfunc)(_class*, A0, A1, A2, A3, A4);
+ void (_class::*_methodfunc)(A0, A1, A2, A3, A4);
+ } _func;
+ void *_obj;
+
+ // Dynamically dispatched operations
+ const struct ops {
+ R (*call)(const void*, A0, A1, A2, A3, A4);
+ void (*move)(void*, const void*);
+ void (*dtor)(void*);
+ } *_ops;
+
+ // Generate operations for function object
+ template <typename F>
+ void generate(const F &f) {
+ static const ops ops = {
+ &Callback::function_call<F>,
+ &Callback::function_move<F>,
+ &Callback::function_dtor<F>,
+ };
+
+ new (this) F(f);
+ _ops = &ops;
+ }
+
+ // Function attributes
+ template <typename F>
+ static R function_call(const void *p, A0 a0, A1 a1, A2 a2, A3 a3, A4 a4) {
+ return (*(F*)p)(a0, a1, a2, a3, a4);
+ }
+
+ template <typename F>
+ static void function_move(void *d, const void *p) {
+ new (d) F(*(F*)p);
+ }
+
+ template <typename F>
+ static void function_dtor(void *p) {
+ ((F*)p)->~F();
+ }
+
+ // Wrappers for functions with context
+ template <typename O, typename M>
+ struct method_context {
+ M method;
+ O *obj;
+
+ method_context(O *obj, M method)
+ : method(method), obj(obj) {}
+
+ R operator()(A0 a0, A1 a1, A2 a2, A3 a3, A4 a4) const {
+ return (obj->*method)(a0, a1, a2, a3, a4);
+ }
+ };
+
+ template <typename F, typename A>
+ struct function_context {
+ F func;
+ A *arg;
+
+ function_context(F func, A *arg)
+ : func(func), arg(arg) {}
+
+ R operator()(A0 a0, A1 a1, A2 a2, A3 a3, A4 a4) const {
+ return func(arg, a0, a1, a2, a3, a4);
+ }
+ };
+};
+
+// Internally used event type
+typedef Callback<void(int)> event_callback_t;
+
+
+/** Create a callback class with type infered from the arguments
+ *
+ * @param func Static function to attach
+ * @return Callback with infered type
+ */
+template <typename R>
+Callback<R()> callback(R (*func)() = 0) {
+ return Callback<R()>(func);
+}
+
+/** Create a callback class with type infered from the arguments
+ *
+ * @param func Static function to attach
+ * @return Callback with infered type
+ */
+template <typename R>
+Callback<R()> callback(const Callback<R()> &func) {
+ return Callback<R()>(func);
+}
+
+/** Create a callback class with type infered from the arguments
+ *
+ * @param obj Optional pointer to object to bind to function
+ * @param method Member function to attach
+ * @return Callback with infered type
+ */
+template<typename T, typename U, typename R>
+Callback<R()> callback(U *obj, R (T::*method)()) {
+ return Callback<R()>(obj, method);
+}
+
+/** Create a callback class with type infered from the arguments
+ *
+ * @param obj Optional pointer to object to bind to function
+ * @param method Member function to attach
+ * @return Callback with infered type
+ */
+template<typename T, typename U, typename R>
+Callback<R()> callback(const U *obj, R (T::*method)() const) {
+ return Callback<R()>(obj, method);
+}
+
+/** Create a callback class with type infered from the arguments
+ *
+ * @param obj Optional pointer to object to bind to function
+ * @param method Member function to attach
+ * @return Callback with infered type
+ */
+template<typename T, typename U, typename R>
+Callback<R()> callback(volatile U *obj, R (T::*method)() volatile) {
+ return Callback<R()>(obj, method);
+}
+
+/** Create a callback class with type infered from the arguments
+ *
+ * @param obj Optional pointer to object to bind to function
+ * @param method Member function to attach
+ * @return Callback with infered type
+ */
+template<typename T, typename U, typename R>
+Callback<R()> callback(const volatile U *obj, R (T::*method)() const volatile) {
+ return Callback<R()>(obj, method);
+}
+
+/** Create a callback class with type infered from the arguments
+ *
+ * @param func Static function to attach
+ * @param arg Pointer argument to function
+ * @return Callback with infered type
+ */
+template <typename T, typename U, typename R>
+Callback<R()> callback(R (*func)(T*), U *arg) {
+ return Callback<R()>(func, arg);
+}
+
+/** Create a callback class with type infered from the arguments
+ *
+ * @param func Static function to attach
+ * @param arg Pointer argument to function
+ * @return Callback with infered type
+ */
+template <typename T, typename U, typename R>
+Callback<R()> callback(R (*func)(const T*), const U *arg) {
+ return Callback<R()>(func, arg);
+}
+
+/** Create a callback class with type infered from the arguments
+ *
+ * @param func Static function to attach
+ * @param arg Pointer argument to function
+ * @return Callback with infered type
+ */
+template <typename T, typename U, typename R>
+Callback<R()> callback(R (*func)(volatile T*), volatile U *arg) {
+ return Callback<R()>(func, arg);
+}
+
+/** Create a callback class with type infered from the arguments
+ *
+ * @param func Static function to attach
+ * @param arg Pointer argument to function
+ * @return Callback with infered type
+ */
+template <typename T, typename U, typename R>
+Callback<R()> callback(R (*func)(const volatile T*), const volatile U *arg) {
+ return Callback<R()>(func, arg);
+}
+
+/** Create a callback class with type infered from the arguments
+ *
+ * @param obj Optional pointer to object to bind to function
+ * @param func Static function to attach
+ * @return Callback with infered type
+ * @deprecated
+ * Arguments to callback have been reordered to callback(func, arg)
+ */
+template <typename T, typename U, typename R>
+Callback<R()> callback(U *obj, R (*func)(T*)) {
+ return Callback<R()>(func, obj);
+}
+
+/** Create a callback class with type infered from the arguments
+ *
+ * @param obj Optional pointer to object to bind to function
+ * @param func Static function to attach
+ * @return Callback with infered type
+ * @deprecated
+ * Arguments to callback have been reordered to callback(func, arg)
+ */
+template <typename T, typename U, typename R>
+Callback<R()> callback(const U *obj, R (*func)(const T*)) {
+ return Callback<R()>(func, obj);
+}
+
+/** Create a callback class with type infered from the arguments
+ *
+ * @param obj Optional pointer to object to bind to function
+ * @param func Static function to attach
+ * @return Callback with infered type
+ * @deprecated
+ * Arguments to callback have been reordered to callback(func, arg)
+ */
+template <typename T, typename U, typename R>
+Callback<R()> callback(volatile U *obj, R (*func)(volatile T*)) {
+ return Callback<R()>(func, obj);
+}
+
+/** Create a callback class with type infered from the arguments
+ *
+ * @param obj Optional pointer to object to bind to function
+ * @param func Static function to attach
+ * @return Callback with infered type
+ * @deprecated
+ * Arguments to callback have been reordered to callback(func, arg)
+ */
+template <typename T, typename U, typename R>
+Callback<R()> callback(const volatile U *obj, R (*func)(const volatile T*)) {
+ return Callback<R()>(func, obj);
+}
+
+
+/** Create a callback class with type infered from the arguments
+ *
+ * @param func Static function to attach
+ * @return Callback with infered type
+ */
+template <typename R, typename A0>
+Callback<R(A0)> callback(R (*func)(A0) = 0) {
+ return Callback<R(A0)>(func);
+}
+
+/** Create a callback class with type infered from the arguments
+ *
+ * @param func Static function to attach
+ * @return Callback with infered type
+ */
+template <typename R, typename A0>
+Callback<R(A0)> callback(const Callback<R(A0)> &func) {
+ return Callback<R(A0)>(func);
+}
+
+/** Create a callback class with type infered from the arguments
+ *
+ * @param obj Optional pointer to object to bind to function
+ * @param method Member function to attach
+ * @return Callback with infered type
+ */
+template<typename T, typename U, typename R, typename A0>
+Callback<R(A0)> callback(U *obj, R (T::*method)(A0)) {
+ return Callback<R(A0)>(obj, method);
+}
+
+/** Create a callback class with type infered from the arguments
+ *
+ * @param obj Optional pointer to object to bind to function
+ * @param method Member function to attach
+ * @return Callback with infered type
+ */
+template<typename T, typename U, typename R, typename A0>
+Callback<R(A0)> callback(const U *obj, R (T::*method)(A0) const) {
+ return Callback<R(A0)>(obj, method);
+}
+
+/** Create a callback class with type infered from the arguments
+ *
+ * @param obj Optional pointer to object to bind to function
+ * @param method Member function to attach
+ * @return Callback with infered type
+ */
+template<typename T, typename U, typename R, typename A0>
+Callback<R(A0)> callback(volatile U *obj, R (T::*method)(A0) volatile) {
+ return Callback<R(A0)>(obj, method);
+}
+
+/** Create a callback class with type infered from the arguments
+ *
+ * @param obj Optional pointer to object to bind to function
+ * @param method Member function to attach
+ * @return Callback with infered type
+ */
+template<typename T, typename U, typename R, typename A0>
+Callback<R(A0)> callback(const volatile U *obj, R (T::*method)(A0) const volatile) {
+ return Callback<R(A0)>(obj, method);
+}
+
+/** Create a callback class with type infered from the arguments
+ *
+ * @param func Static function to attach
+ * @param arg Pointer argument to function
+ * @return Callback with infered type
+ */
+template <typename T, typename U, typename R, typename A0>
+Callback<R(A0)> callback(R (*func)(T*, A0), U *arg) {
+ return Callback<R(A0)>(func, arg);
+}
+
+/** Create a callback class with type infered from the arguments
+ *
+ * @param func Static function to attach
+ * @param arg Pointer argument to function
+ * @return Callback with infered type
+ */
+template <typename T, typename U, typename R, typename A0>
+Callback<R(A0)> callback(R (*func)(const T*, A0), const U *arg) {
+ return Callback<R(A0)>(func, arg);
+}
+
+/** Create a callback class with type infered from the arguments
+ *
+ * @param func Static function to attach
+ * @param arg Pointer argument to function
+ * @return Callback with infered type
+ */
+template <typename T, typename U, typename R, typename A0>
+Callback<R(A0)> callback(R (*func)(volatile T*, A0), volatile U *arg) {
+ return Callback<R(A0)>(func, arg);
+}
+
+/** Create a callback class with type infered from the arguments
+ *
+ * @param func Static function to attach
+ * @param arg Pointer argument to function
+ * @return Callback with infered type
+ */
+template <typename T, typename U, typename R, typename A0>
+Callback<R(A0)> callback(R (*func)(const volatile T*, A0), const volatile U *arg) {
+ return Callback<R(A0)>(func, arg);
+}
+
+/** Create a callback class with type infered from the arguments
+ *
+ * @param obj Optional pointer to object to bind to function
+ * @param func Static function to attach
+ * @return Callback with infered type
+ * @deprecated
+ * Arguments to callback have been reordered to callback(func, arg)
+ */
+template <typename T, typename U, typename R, typename A0>
+Callback<R(A0)> callback(U *obj, R (*func)(T*, A0)) {
+ return Callback<R(A0)>(func, obj);
+}
+
+/** Create a callback class with type infered from the arguments
+ *
+ * @param obj Optional pointer to object to bind to function
+ * @param func Static function to attach
+ * @return Callback with infered type
+ * @deprecated
+ * Arguments to callback have been reordered to callback(func, arg)
+ */
+template <typename T, typename U, typename R, typename A0>
+Callback<R(A0)> callback(const U *obj, R (*func)(const T*, A0)) {
+ return Callback<R(A0)>(func, obj);
+}
+
+/** Create a callback class with type infered from the arguments
+ *
+ * @param obj Optional pointer to object to bind to function
+ * @param func Static function to attach
+ * @return Callback with infered type
+ * @deprecated
+ * Arguments to callback have been reordered to callback(func, arg)
+ */
+template <typename T, typename U, typename R, typename A0>
+Callback<R(A0)> callback(volatile U *obj, R (*func)(volatile T*, A0)) {
+ return Callback<R(A0)>(func, obj);
+}
+
+/** Create a callback class with type infered from the arguments
+ *
+ * @param obj Optional pointer to object to bind to function
+ * @param func Static function to attach
+ * @return Callback with infered type
+ * @deprecated
+ * Arguments to callback have been reordered to callback(func, arg)
+ */
+template <typename T, typename U, typename R, typename A0>
+Callback<R(A0)> callback(const volatile U *obj, R (*func)(const volatile T*, A0)) {
+ return Callback<R(A0)>(func, obj);
+}
+
+
+/** Create a callback class with type infered from the arguments
+ *
+ * @param func Static function to attach
+ * @return Callback with infered type
+ */
+template <typename R, typename A0, typename A1>
+Callback<R(A0, A1)> callback(R (*func)(A0, A1) = 0) {
+ return Callback<R(A0, A1)>(func);
+}
+
+/** Create a callback class with type infered from the arguments
+ *
+ * @param func Static function to attach
+ * @return Callback with infered type
+ */
+template <typename R, typename A0, typename A1>
+Callback<R(A0, A1)> callback(const Callback<R(A0, A1)> &func) {
+ return Callback<R(A0, A1)>(func);
+}
+
+/** Create a callback class with type infered from the arguments
+ *
+ * @param obj Optional pointer to object to bind to function
+ * @param method Member function to attach
+ * @return Callback with infered type
+ */
+template<typename T, typename U, typename R, typename A0, typename A1>
+Callback<R(A0, A1)> callback(U *obj, R (T::*method)(A0, A1)) {
+ return Callback<R(A0, A1)>(obj, method);
+}
+
+/** Create a callback class with type infered from the arguments
+ *
+ * @param obj Optional pointer to object to bind to function
+ * @param method Member function to attach
+ * @return Callback with infered type
+ */
+template<typename T, typename U, typename R, typename A0, typename A1>
+Callback<R(A0, A1)> callback(const U *obj, R (T::*method)(A0, A1) const) {
+ return Callback<R(A0, A1)>(obj, method);
+}
+
+/** Create a callback class with type infered from the arguments
+ *
+ * @param obj Optional pointer to object to bind to function
+ * @param method Member function to attach
+ * @return Callback with infered type
+ */
+template<typename T, typename U, typename R, typename A0, typename A1>
+Callback<R(A0, A1)> callback(volatile U *obj, R (T::*method)(A0, A1) volatile) {
+ return Callback<R(A0, A1)>(obj, method);
+}
+
+/** Create a callback class with type infered from the arguments
+ *
+ * @param obj Optional pointer to object to bind to function
+ * @param method Member function to attach
+ * @return Callback with infered type
+ */
+template<typename T, typename U, typename R, typename A0, typename A1>
+Callback<R(A0, A1)> callback(const volatile U *obj, R (T::*method)(A0, A1) const volatile) {
+ return Callback<R(A0, A1)>(obj, method);
+}
+
+/** Create a callback class with type infered from the arguments
+ *
+ * @param func Static function to attach
+ * @param arg Pointer argument to function
+ * @return Callback with infered type
+ */
+template <typename T, typename U, typename R, typename A0, typename A1>
+Callback<R(A0, A1)> callback(R (*func)(T*, A0, A1), U *arg) {
+ return Callback<R(A0, A1)>(func, arg);
+}
+
+/** Create a callback class with type infered from the arguments
+ *
+ * @param func Static function to attach
+ * @param arg Pointer argument to function
+ * @return Callback with infered type
+ */
+template <typename T, typename U, typename R, typename A0, typename A1>
+Callback<R(A0, A1)> callback(R (*func)(const T*, A0, A1), const U *arg) {
+ return Callback<R(A0, A1)>(func, arg);
+}
+
+/** Create a callback class with type infered from the arguments
+ *
+ * @param func Static function to attach
+ * @param arg Pointer argument to function
+ * @return Callback with infered type
+ */
+template <typename T, typename U, typename R, typename A0, typename A1>
+Callback<R(A0, A1)> callback(R (*func)(volatile T*, A0, A1), volatile U *arg) {
+ return Callback<R(A0, A1)>(func, arg);
+}
+
+/** Create a callback class with type infered from the arguments
+ *
+ * @param func Static function to attach
+ * @param arg Pointer argument to function
+ * @return Callback with infered type
+ */
+template <typename T, typename U, typename R, typename A0, typename A1>
+Callback<R(A0, A1)> callback(R (*func)(const volatile T*, A0, A1), const volatile U *arg) {
+ return Callback<R(A0, A1)>(func, arg);
+}
+
+/** Create a callback class with type infered from the arguments
+ *
+ * @param obj Optional pointer to object to bind to function
+ * @param func Static function to attach
+ * @return Callback with infered type
+ * @deprecated
+ * Arguments to callback have been reordered to callback(func, arg)
+ */
+template <typename T, typename U, typename R, typename A0, typename A1>
+Callback<R(A0, A1)> callback(U *obj, R (*func)(T*, A0, A1)) {
+ return Callback<R(A0, A1)>(func, obj);
+}
+
+/** Create a callback class with type infered from the arguments
+ *
+ * @param obj Optional pointer to object to bind to function
+ * @param func Static function to attach
+ * @return Callback with infered type
+ * @deprecated
+ * Arguments to callback have been reordered to callback(func, arg)
+ */
+template <typename T, typename U, typename R, typename A0, typename A1>
+Callback<R(A0, A1)> callback(const U *obj, R (*func)(const T*, A0, A1)) {
+ return Callback<R(A0, A1)>(func, obj);
+}
+
+/** Create a callback class with type infered from the arguments
+ *
+ * @param obj Optional pointer to object to bind to function
+ * @param func Static function to attach
+ * @return Callback with infered type
+ * @deprecated
+ * Arguments to callback have been reordered to callback(func, arg)
+ */
+template <typename T, typename U, typename R, typename A0, typename A1>
+Callback<R(A0, A1)> callback(volatile U *obj, R (*func)(volatile T*, A0, A1)) {
+ return Callback<R(A0, A1)>(func, obj);
+}
+
+/** Create a callback class with type infered from the arguments
+ *
+ * @param obj Optional pointer to object to bind to function
+ * @param func Static function to attach
+ * @return Callback with infered type
+ * @deprecated
+ * Arguments to callback have been reordered to callback(func, arg)
+ */
+template <typename T, typename U, typename R, typename A0, typename A1>
+Callback<R(A0, A1)> callback(const volatile U *obj, R (*func)(const volatile T*, A0, A1)) {
+ return Callback<R(A0, A1)>(func, obj);
+}
+
+
+/** Create a callback class with type infered from the arguments
+ *
+ * @param func Static function to attach
+ * @return Callback with infered type
+ */
+template <typename R, typename A0, typename A1, typename A2>
+Callback<R(A0, A1, A2)> callback(R (*func)(A0, A1, A2) = 0) {
+ return Callback<R(A0, A1, A2)>(func);
+}
+
+/** Create a callback class with type infered from the arguments
+ *
+ * @param func Static function to attach
+ * @return Callback with infered type
+ */
+template <typename R, typename A0, typename A1, typename A2>
+Callback<R(A0, A1, A2)> callback(const Callback<R(A0, A1, A2)> &func) {
+ return Callback<R(A0, A1, A2)>(func);
+}
+
+/** Create a callback class with type infered from the arguments
+ *
+ * @param obj Optional pointer to object to bind to function
+ * @param method Member function to attach
+ * @return Callback with infered type
+ */
+template<typename T, typename U, typename R, typename A0, typename A1, typename A2>
+Callback<R(A0, A1, A2)> callback(U *obj, R (T::*method)(A0, A1, A2)) {
+ return Callback<R(A0, A1, A2)>(obj, method);
+}
+
+/** Create a callback class with type infered from the arguments
+ *
+ * @param obj Optional pointer to object to bind to function
+ * @param method Member function to attach
+ * @return Callback with infered type
+ */
+template<typename T, typename U, typename R, typename A0, typename A1, typename A2>
+Callback<R(A0, A1, A2)> callback(const U *obj, R (T::*method)(A0, A1, A2) const) {
+ return Callback<R(A0, A1, A2)>(obj, method);
+}
+
+/** Create a callback class with type infered from the arguments
+ *
+ * @param obj Optional pointer to object to bind to function
+ * @param method Member function to attach
+ * @return Callback with infered type
+ */
+template<typename T, typename U, typename R, typename A0, typename A1, typename A2>
+Callback<R(A0, A1, A2)> callback(volatile U *obj, R (T::*method)(A0, A1, A2) volatile) {
+ return Callback<R(A0, A1, A2)>(obj, method);
+}
+
+/** Create a callback class with type infered from the arguments
+ *
+ * @param obj Optional pointer to object to bind to function
+ * @param method Member function to attach
+ * @return Callback with infered type
+ */
+template<typename T, typename U, typename R, typename A0, typename A1, typename A2>
+Callback<R(A0, A1, A2)> callback(const volatile U *obj, R (T::*method)(A0, A1, A2) const volatile) {
+ return Callback<R(A0, A1, A2)>(obj, method);
+}
+
+/** Create a callback class with type infered from the arguments
+ *
+ * @param func Static function to attach
+ * @param arg Pointer argument to function
+ * @return Callback with infered type
+ */
+template <typename T, typename U, typename R, typename A0, typename A1, typename A2>
+Callback<R(A0, A1, A2)> callback(R (*func)(T*, A0, A1, A2), U *arg) {
+ return Callback<R(A0, A1, A2)>(func, arg);
+}
+
+/** Create a callback class with type infered from the arguments
+ *
+ * @param func Static function to attach
+ * @param arg Pointer argument to function
+ * @return Callback with infered type
+ */
+template <typename T, typename U, typename R, typename A0, typename A1, typename A2>
+Callback<R(A0, A1, A2)> callback(R (*func)(const T*, A0, A1, A2), const U *arg) {
+ return Callback<R(A0, A1, A2)>(func, arg);
+}
+
+/** Create a callback class with type infered from the arguments
+ *
+ * @param func Static function to attach
+ * @param arg Pointer argument to function
+ * @return Callback with infered type
+ */
+template <typename T, typename U, typename R, typename A0, typename A1, typename A2>
+Callback<R(A0, A1, A2)> callback(R (*func)(volatile T*, A0, A1, A2), volatile U *arg) {
+ return Callback<R(A0, A1, A2)>(func, arg);
+}
+
+/** Create a callback class with type infered from the arguments
+ *
+ * @param func Static function to attach
+ * @param arg Pointer argument to function
+ * @return Callback with infered type
+ */
+template <typename T, typename U, typename R, typename A0, typename A1, typename A2>
+Callback<R(A0, A1, A2)> callback(R (*func)(const volatile T*, A0, A1, A2), const volatile U *arg) {
+ return Callback<R(A0, A1, A2)>(func, arg);
+}
+
+/** Create a callback class with type infered from the arguments
+ *
+ * @param obj Optional pointer to object to bind to function
+ * @param func Static function to attach
+ * @return Callback with infered type
+ * @deprecated
+ * Arguments to callback have been reordered to callback(func, arg)
+ */
+template <typename T, typename U, typename R, typename A0, typename A1, typename A2>
+Callback<R(A0, A1, A2)> callback(U *obj, R (*func)(T*, A0, A1, A2)) {
+ return Callback<R(A0, A1, A2)>(func, obj);
+}
+
+/** Create a callback class with type infered from the arguments
+ *
+ * @param obj Optional pointer to object to bind to function
+ * @param func Static function to attach
+ * @return Callback with infered type
+ * @deprecated
+ * Arguments to callback have been reordered to callback(func, arg)
+ */
+template <typename T, typename U, typename R, typename A0, typename A1, typename A2>
+Callback<R(A0, A1, A2)> callback(const U *obj, R (*func)(const T*, A0, A1, A2)) {
+ return Callback<R(A0, A1, A2)>(func, obj);
+}
+
+/** Create a callback class with type infered from the arguments
+ *
+ * @param obj Optional pointer to object to bind to function
+ * @param func Static function to attach
+ * @return Callback with infered type
+ * @deprecated
+ * Arguments to callback have been reordered to callback(func, arg)
+ */
+template <typename T, typename U, typename R, typename A0, typename A1, typename A2>
+Callback<R(A0, A1, A2)> callback(volatile U *obj, R (*func)(volatile T*, A0, A1, A2)) {
+ return Callback<R(A0, A1, A2)>(func, obj);
+}
+
+/** Create a callback class with type infered from the arguments
+ *
+ * @param obj Optional pointer to object to bind to function
+ * @param func Static function to attach
+ * @return Callback with infered type
+ * @deprecated
+ * Arguments to callback have been reordered to callback(func, arg)
+ */
+template <typename T, typename U, typename R, typename A0, typename A1, typename A2>
+Callback<R(A0, A1, A2)> callback(const volatile U *obj, R (*func)(const volatile T*, A0, A1, A2)) {
+ return Callback<R(A0, A1, A2)>(func, obj);
+}
+
+
+/** Create a callback class with type infered from the arguments
+ *
+ * @param func Static function to attach
+ * @return Callback with infered type
+ */
+template <typename R, typename A0, typename A1, typename A2, typename A3>
+Callback<R(A0, A1, A2, A3)> callback(R (*func)(A0, A1, A2, A3) = 0) {
+ return Callback<R(A0, A1, A2, A3)>(func);
+}
+
+/** Create a callback class with type infered from the arguments
+ *
+ * @param func Static function to attach
+ * @return Callback with infered type
+ */
+template <typename R, typename A0, typename A1, typename A2, typename A3>
+Callback<R(A0, A1, A2, A3)> callback(const Callback<R(A0, A1, A2, A3)> &func) {
+ return Callback<R(A0, A1, A2, A3)>(func);
+}
+
+/** Create a callback class with type infered from the arguments
+ *
+ * @param obj Optional pointer to object to bind to function
+ * @param method Member function to attach
+ * @return Callback with infered type
+ */
+template<typename T, typename U, typename R, typename A0, typename A1, typename A2, typename A3>
+Callback<R(A0, A1, A2, A3)> callback(U *obj, R (T::*method)(A0, A1, A2, A3)) {
+ return Callback<R(A0, A1, A2, A3)>(obj, method);
+}
+
+/** Create a callback class with type infered from the arguments
+ *
+ * @param obj Optional pointer to object to bind to function
+ * @param method Member function to attach
+ * @return Callback with infered type
+ */
+template<typename T, typename U, typename R, typename A0, typename A1, typename A2, typename A3>
+Callback<R(A0, A1, A2, A3)> callback(const U *obj, R (T::*method)(A0, A1, A2, A3) const) {
+ return Callback<R(A0, A1, A2, A3)>(obj, method);
+}
+
+/** Create a callback class with type infered from the arguments
+ *
+ * @param obj Optional pointer to object to bind to function
+ * @param method Member function to attach
+ * @return Callback with infered type
+ */
+template<typename T, typename U, typename R, typename A0, typename A1, typename A2, typename A3>
+Callback<R(A0, A1, A2, A3)> callback(volatile U *obj, R (T::*method)(A0, A1, A2, A3) volatile) {
+ return Callback<R(A0, A1, A2, A3)>(obj, method);
+}
+
+/** Create a callback class with type infered from the arguments
+ *
+ * @param obj Optional pointer to object to bind to function
+ * @param method Member function to attach
+ * @return Callback with infered type
+ */
+template<typename T, typename U, typename R, typename A0, typename A1, typename A2, typename A3>
+Callback<R(A0, A1, A2, A3)> callback(const volatile U *obj, R (T::*method)(A0, A1, A2, A3) const volatile) {
+ return Callback<R(A0, A1, A2, A3)>(obj, method);
+}
+
+/** Create a callback class with type infered from the arguments
+ *
+ * @param func Static function to attach
+ * @param arg Pointer argument to function
+ * @return Callback with infered type
+ */
+template <typename T, typename U, typename R, typename A0, typename A1, typename A2, typename A3>
+Callback<R(A0, A1, A2, A3)> callback(R (*func)(T*, A0, A1, A2, A3), U *arg) {
+ return Callback<R(A0, A1, A2, A3)>(func, arg);
+}
+
+/** Create a callback class with type infered from the arguments
+ *
+ * @param func Static function to attach
+ * @param arg Pointer argument to function
+ * @return Callback with infered type
+ */
+template <typename T, typename U, typename R, typename A0, typename A1, typename A2, typename A3>
+Callback<R(A0, A1, A2, A3)> callback(R (*func)(const T*, A0, A1, A2, A3), const U *arg) {
+ return Callback<R(A0, A1, A2, A3)>(func, arg);
+}
+
+/** Create a callback class with type infered from the arguments
+ *
+ * @param func Static function to attach
+ * @param arg Pointer argument to function
+ * @return Callback with infered type
+ */
+template <typename T, typename U, typename R, typename A0, typename A1, typename A2, typename A3>
+Callback<R(A0, A1, A2, A3)> callback(R (*func)(volatile T*, A0, A1, A2, A3), volatile U *arg) {
+ return Callback<R(A0, A1, A2, A3)>(func, arg);
+}
+
+/** Create a callback class with type infered from the arguments
+ *
+ * @param func Static function to attach
+ * @param arg Pointer argument to function
+ * @return Callback with infered type
+ */
+template <typename T, typename U, typename R, typename A0, typename A1, typename A2, typename A3>
+Callback<R(A0, A1, A2, A3)> callback(R (*func)(const volatile T*, A0, A1, A2, A3), const volatile U *arg) {
+ return Callback<R(A0, A1, A2, A3)>(func, arg);
+}
+
+/** Create a callback class with type infered from the arguments
+ *
+ * @param obj Optional pointer to object to bind to function
+ * @param func Static function to attach
+ * @return Callback with infered type
+ * @deprecated
+ * Arguments to callback have been reordered to callback(func, arg)
+ */
+template <typename T, typename U, typename R, typename A0, typename A1, typename A2, typename A3>
+Callback<R(A0, A1, A2, A3)> callback(U *obj, R (*func)(T*, A0, A1, A2, A3)) {
+ return Callback<R(A0, A1, A2, A3)>(func, obj);
+}
+
+/** Create a callback class with type infered from the arguments
+ *
+ * @param obj Optional pointer to object to bind to function
+ * @param func Static function to attach
+ * @return Callback with infered type
+ * @deprecated
+ * Arguments to callback have been reordered to callback(func, arg)
+ */
+template <typename T, typename U, typename R, typename A0, typename A1, typename A2, typename A3>
+Callback<R(A0, A1, A2, A3)> callback(const U *obj, R (*func)(const T*, A0, A1, A2, A3)) {
+ return Callback<R(A0, A1, A2, A3)>(func, obj);
+}
+
+/** Create a callback class with type infered from the arguments
+ *
+ * @param obj Optional pointer to object to bind to function
+ * @param func Static function to attach
+ * @return Callback with infered type
+ * @deprecated
+ * Arguments to callback have been reordered to callback(func, arg)
+ */
+template <typename T, typename U, typename R, typename A0, typename A1, typename A2, typename A3>
+Callback<R(A0, A1, A2, A3)> callback(volatile U *obj, R (*func)(volatile T*, A0, A1, A2, A3)) {
+ return Callback<R(A0, A1, A2, A3)>(func, obj);
+}
+
+/** Create a callback class with type infered from the arguments
+ *
+ * @param obj Optional pointer to object to bind to function
+ * @param func Static function to attach
+ * @return Callback with infered type
+ * @deprecated
+ * Arguments to callback have been reordered to callback(func, arg)
+ */
+template <typename T, typename U, typename R, typename A0, typename A1, typename A2, typename A3>
+Callback<R(A0, A1, A2, A3)> callback(const volatile U *obj, R (*func)(const volatile T*, A0, A1, A2, A3)) {
+ return Callback<R(A0, A1, A2, A3)>(func, obj);
+}
+
+
+/** Create a callback class with type infered from the arguments
+ *
+ * @param func Static function to attach
+ * @return Callback with infered type
+ */
+template <typename R, typename A0, typename A1, typename A2, typename A3, typename A4>
+Callback<R(A0, A1, A2, A3, A4)> callback(R (*func)(A0, A1, A2, A3, A4) = 0) {
+ return Callback<R(A0, A1, A2, A3, A4)>(func);
+}
+
+/** Create a callback class with type infered from the arguments
+ *
+ * @param func Static function to attach
+ * @return Callback with infered type
+ */
+template <typename R, typename A0, typename A1, typename A2, typename A3, typename A4>
+Callback<R(A0, A1, A2, A3, A4)> callback(const Callback<R(A0, A1, A2, A3, A4)> &func) {
+ return Callback<R(A0, A1, A2, A3, A4)>(func);
+}
+
+/** Create a callback class with type infered from the arguments
+ *
+ * @param obj Optional pointer to object to bind to function
+ * @param method Member function to attach
+ * @return Callback with infered type
+ */
+template<typename T, typename U, typename R, typename A0, typename A1, typename A2, typename A3, typename A4>
+Callback<R(A0, A1, A2, A3, A4)> callback(U *obj, R (T::*method)(A0, A1, A2, A3, A4)) {
+ return Callback<R(A0, A1, A2, A3, A4)>(obj, method);
+}
+
+/** Create a callback class with type infered from the arguments
+ *
+ * @param obj Optional pointer to object to bind to function
+ * @param method Member function to attach
+ * @return Callback with infered type
+ */
+template<typename T, typename U, typename R, typename A0, typename A1, typename A2, typename A3, typename A4>
+Callback<R(A0, A1, A2, A3, A4)> callback(const U *obj, R (T::*method)(A0, A1, A2, A3, A4) const) {
+ return Callback<R(A0, A1, A2, A3, A4)>(obj, method);
+}
+
+/** Create a callback class with type infered from the arguments
+ *
+ * @param obj Optional pointer to object to bind to function
+ * @param method Member function to attach
+ * @return Callback with infered type
+ */
+template<typename T, typename U, typename R, typename A0, typename A1, typename A2, typename A3, typename A4>
+Callback<R(A0, A1, A2, A3, A4)> callback(volatile U *obj, R (T::*method)(A0, A1, A2, A3, A4) volatile) {
+ return Callback<R(A0, A1, A2, A3, A4)>(obj, method);
+}
+
+/** Create a callback class with type infered from the arguments
+ *
+ * @param obj Optional pointer to object to bind to function
+ * @param method Member function to attach
+ * @return Callback with infered type
+ */
+template<typename T, typename U, typename R, typename A0, typename A1, typename A2, typename A3, typename A4>
+Callback<R(A0, A1, A2, A3, A4)> callback(const volatile U *obj, R (T::*method)(A0, A1, A2, A3, A4) const volatile) {
+ return Callback<R(A0, A1, A2, A3, A4)>(obj, method);
+}
+
+/** Create a callback class with type infered from the arguments
+ *
+ * @param func Static function to attach
+ * @param arg Pointer argument to function
+ * @return Callback with infered type
+ */
+template <typename T, typename U, typename R, typename A0, typename A1, typename A2, typename A3, typename A4>
+Callback<R(A0, A1, A2, A3, A4)> callback(R (*func)(T*, A0, A1, A2, A3, A4), U *arg) {
+ return Callback<R(A0, A1, A2, A3, A4)>(func, arg);
+}
+
+/** Create a callback class with type infered from the arguments
+ *
+ * @param func Static function to attach
+ * @param arg Pointer argument to function
+ * @return Callback with infered type
+ */
+template <typename T, typename U, typename R, typename A0, typename A1, typename A2, typename A3, typename A4>
+Callback<R(A0, A1, A2, A3, A4)> callback(R (*func)(const T*, A0, A1, A2, A3, A4), const U *arg) {
+ return Callback<R(A0, A1, A2, A3, A4)>(func, arg);
+}
+
+/** Create a callback class with type infered from the arguments
+ *
+ * @param func Static function to attach
+ * @param arg Pointer argument to function
+ * @return Callback with infered type
+ */
+template <typename T, typename U, typename R, typename A0, typename A1, typename A2, typename A3, typename A4>
+Callback<R(A0, A1, A2, A3, A4)> callback(R (*func)(volatile T*, A0, A1, A2, A3, A4), volatile U *arg) {
+ return Callback<R(A0, A1, A2, A3, A4)>(func, arg);
+}
+
+/** Create a callback class with type infered from the arguments
+ *
+ * @param func Static function to attach
+ * @param arg Pointer argument to function
+ * @return Callback with infered type
+ */
+template <typename T, typename U, typename R, typename A0, typename A1, typename A2, typename A3, typename A4>
+Callback<R(A0, A1, A2, A3, A4)> callback(R (*func)(const volatile T*, A0, A1, A2, A3, A4), const volatile U *arg) {
+ return Callback<R(A0, A1, A2, A3, A4)>(func, arg);
+}
+
+/** Create a callback class with type infered from the arguments
+ *
+ * @param obj Optional pointer to object to bind to function
+ * @param func Static function to attach
+ * @return Callback with infered type
+ * @deprecated
+ * Arguments to callback have been reordered to callback(func, arg)
+ */
+template <typename T, typename U, typename R, typename A0, typename A1, typename A2, typename A3, typename A4>
+Callback<R(A0, A1, A2, A3, A4)> callback(U *obj, R (*func)(T*, A0, A1, A2, A3, A4)) {
+ return Callback<R(A0, A1, A2, A3, A4)>(func, obj);
+}
+
+/** Create a callback class with type infered from the arguments
+ *
+ * @param obj Optional pointer to object to bind to function
+ * @param func Static function to attach
+ * @return Callback with infered type
+ * @deprecated
+ * Arguments to callback have been reordered to callback(func, arg)
+ */
+template <typename T, typename U, typename R, typename A0, typename A1, typename A2, typename A3, typename A4>
+Callback<R(A0, A1, A2, A3, A4)> callback(const U *obj, R (*func)(const T*, A0, A1, A2, A3, A4)) {
+ return Callback<R(A0, A1, A2, A3, A4)>(func, obj);
+}
+
+/** Create a callback class with type infered from the arguments
+ *
+ * @param obj Optional pointer to object to bind to function
+ * @param func Static function to attach
+ * @return Callback with infered type
+ * @deprecated
+ * Arguments to callback have been reordered to callback(func, arg)
+ */
+template <typename T, typename U, typename R, typename A0, typename A1, typename A2, typename A3, typename A4>
+Callback<R(A0, A1, A2, A3, A4)> callback(volatile U *obj, R (*func)(volatile T*, A0, A1, A2, A3, A4)) {
+ return Callback<R(A0, A1, A2, A3, A4)>(func, obj);
+}
+
+/** Create a callback class with type infered from the arguments
+ *
+ * @param obj Optional pointer to object to bind to function
+ * @param func Static function to attach
+ * @return Callback with infered type
+ * @deprecated
+ * Arguments to callback have been reordered to callback(func, arg)
+ */
+template <typename T, typename U, typename R, typename A0, typename A1, typename A2, typename A3, typename A4>
+Callback<R(A0, A1, A2, A3, A4)> callback(const volatile U *obj, R (*func)(const volatile T*, A0, A1, A2, A3, A4)) {
+ return Callback<R(A0, A1, A2, A3, A4)>(func, obj);
+}
+
+
+// } // namespace mbed
+
+#endif
+#endif // Arduino
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sx1276/arduino-mbed.cpp Tue Jul 11 13:32:34 2017 +0200
@@ -0,0 +1,441 @@
+/*
+ * The file is Licensed under the Apache License, Version 2.0
+ * (c) 2017 Helmut Tschemernjak
+ * 30826 Garbsen (Hannover) Germany
+ */
+
+#ifdef ARDUINO
+
+using namespace std;
+
+#include "arduino-mbed.h"
+
+
+static void pinInt00(void);
+static void pinInt01(void);
+static void pinInt02(void);
+static void pinInt03(void);
+static void pinInt04(void);
+static void pinInt05(void);
+static void pinInt06(void);
+static void pinInt07(void);
+static void pinInt08(void);
+static void pinInt09(void);
+static void pinInt10(void);
+static void pinInt11(void);
+static void pinInt12(void);
+static void pinInt13(void);
+static void pinInt14(void);
+static void pinInt15(void);
+static void pinInt16(void);
+static void pinInt17(void);
+static void pinInt18(void);
+static void pinInt19(void);
+static void pinInt20(void);
+static void pinInt21(void);
+static void pinInt22(void);
+static void pinInt23(void);
+static void pinInt24(void);
+static void pinInt25(void);
+static void pinInt26(void);
+static void pinInt27(void);
+static void pinInt28(void);
+static void pinInt29(void);
+static void pinInt30(void);
+static void pinInt31(void);
+static void pinInt32(void);
+static void pinInt33(void);
+static void pinInt34(void);
+static void pinInt35(void);
+static void pinInt36(void);
+static void pinInt37(void);
+static void pinInt38(void);
+static void pinInt39(void);
+static void pinInt40(void);
+static void pinInt41(void);
+static void pinInt42(void);
+static void pinInt43(void);
+static void pinInt44(void);
+static void pinInt45(void);
+static void pinInt46(void);
+static void pinInt47(void);
+
+
+
+#define MAX_MCU_PINS 48
+class InterruptIn;
+struct intPtrTable {
+ void (*func)(void);
+ InterruptIn *context;
+} intPtrTable[MAX_MCU_PINS] = {
+ { pinInt00, NULL },
+ { pinInt01, NULL },
+ { pinInt02, NULL },
+ { pinInt03, NULL },
+ { pinInt04, NULL },
+ { pinInt05, NULL },
+ { pinInt06, NULL },
+ { pinInt07, NULL },
+ { pinInt08, NULL },
+ { pinInt09, NULL },
+ { pinInt10, NULL },
+ { pinInt11, NULL },
+ { pinInt12, NULL },
+ { pinInt13, NULL },
+ { pinInt14, NULL },
+ { pinInt15, NULL },
+ { pinInt16, NULL },
+ { pinInt17, NULL },
+ { pinInt18, NULL },
+ { pinInt19, NULL },
+ { pinInt20, NULL },
+ { pinInt21, NULL },
+ { pinInt22, NULL },
+ { pinInt23, NULL },
+ { pinInt24, NULL },
+ { pinInt25, NULL },
+ { pinInt26, NULL },
+ { pinInt27, NULL },
+ { pinInt28, NULL },
+ { pinInt29, NULL },
+ { pinInt30, NULL },
+ { pinInt31, NULL },
+ { pinInt32, NULL },
+ { pinInt33, NULL },
+ { pinInt34, NULL },
+ { pinInt35, NULL },
+ { pinInt36, NULL },
+ { pinInt37, NULL },
+ { pinInt38, NULL },
+ { pinInt39, NULL },
+ { pinInt40, NULL },
+ { pinInt41, NULL },
+ { pinInt42, NULL },
+ { pinInt43, NULL },
+ { pinInt44, NULL },
+ { pinInt45, NULL },
+ { pinInt46, NULL },
+ { pinInt47, NULL }
+}; // our max MCUs pins
+
+
+
+static void pinInt00(void) { InterruptIn::_irq_handler(intPtrTable[0].context); }
+static void pinInt01(void) { InterruptIn::_irq_handler(intPtrTable[1].context); }
+static void pinInt02(void) { InterruptIn::_irq_handler(intPtrTable[2].context); }
+static void pinInt03(void) { InterruptIn::_irq_handler(intPtrTable[3].context); }
+static void pinInt04(void) { InterruptIn::_irq_handler(intPtrTable[4].context); }
+static void pinInt05(void) { InterruptIn::_irq_handler(intPtrTable[5].context); }
+static void pinInt06(void) { InterruptIn::_irq_handler(intPtrTable[6].context); }
+static void pinInt07(void) { InterruptIn::_irq_handler(intPtrTable[7].context); }
+static void pinInt08(void) { InterruptIn::_irq_handler(intPtrTable[8].context); }
+static void pinInt09(void) { InterruptIn::_irq_handler(intPtrTable[9].context); }
+static void pinInt10(void) { InterruptIn::_irq_handler(intPtrTable[10].context); }
+static void pinInt11(void) { InterruptIn::_irq_handler(intPtrTable[11].context); }
+static void pinInt12(void) { InterruptIn::_irq_handler(intPtrTable[12].context); }
+static void pinInt13(void) { InterruptIn::_irq_handler(intPtrTable[13].context); }
+static void pinInt14(void) { InterruptIn::_irq_handler(intPtrTable[14].context); }
+static void pinInt15(void) { InterruptIn::_irq_handler(intPtrTable[15].context); }
+static void pinInt16(void) { InterruptIn::_irq_handler(intPtrTable[16].context); }
+static void pinInt17(void) { InterruptIn::_irq_handler(intPtrTable[17].context); }
+static void pinInt18(void) { InterruptIn::_irq_handler(intPtrTable[18].context); }
+static void pinInt19(void) { InterruptIn::_irq_handler(intPtrTable[19].context); }
+static void pinInt20(void) { InterruptIn::_irq_handler(intPtrTable[20].context); }
+static void pinInt21(void) { InterruptIn::_irq_handler(intPtrTable[21].context); }
+static void pinInt22(void) { InterruptIn::_irq_handler(intPtrTable[22].context); }
+static void pinInt23(void) { InterruptIn::_irq_handler(intPtrTable[23].context); }
+static void pinInt24(void) { InterruptIn::_irq_handler(intPtrTable[24].context); }
+static void pinInt25(void) { InterruptIn::_irq_handler(intPtrTable[25].context); }
+static void pinInt26(void) { InterruptIn::_irq_handler(intPtrTable[26].context); }
+static void pinInt27(void) { InterruptIn::_irq_handler(intPtrTable[27].context); }
+static void pinInt28(void) { InterruptIn::_irq_handler(intPtrTable[28].context); }
+static void pinInt29(void) { InterruptIn::_irq_handler(intPtrTable[29].context); }
+static void pinInt30(void) { InterruptIn::_irq_handler(intPtrTable[30].context); }
+static void pinInt31(void) { InterruptIn::_irq_handler(intPtrTable[31].context); }
+static void pinInt32(void) { InterruptIn::_irq_handler(intPtrTable[32].context); }
+static void pinInt33(void) { InterruptIn::_irq_handler(intPtrTable[33].context); }
+static void pinInt34(void) { InterruptIn::_irq_handler(intPtrTable[34].context); }
+static void pinInt35(void) { InterruptIn::_irq_handler(intPtrTable[35].context); }
+static void pinInt36(void) { InterruptIn::_irq_handler(intPtrTable[36].context); }
+static void pinInt37(void) { InterruptIn::_irq_handler(intPtrTable[37].context); }
+static void pinInt38(void) { InterruptIn::_irq_handler(intPtrTable[38].context); }
+static void pinInt39(void) { InterruptIn::_irq_handler(intPtrTable[39].context); }
+static void pinInt40(void) { InterruptIn::_irq_handler(intPtrTable[40].context); }
+static void pinInt41(void) { InterruptIn::_irq_handler(intPtrTable[41].context); }
+static void pinInt42(void) { InterruptIn::_irq_handler(intPtrTable[42].context); }
+static void pinInt43(void) { InterruptIn::_irq_handler(intPtrTable[43].context); }
+static void pinInt44(void) { InterruptIn::_irq_handler(intPtrTable[44].context); }
+static void pinInt45(void) { InterruptIn::_irq_handler(intPtrTable[45].context); }
+static void pinInt46(void) { InterruptIn::_irq_handler(intPtrTable[46].context); }
+static void pinInt47(void) { InterruptIn::_irq_handler(intPtrTable[47].context); }
+
+
+
+
+void
+InterruptIn::rise(Callback<void()> func) {
+ if (_gpioPin >= MAX_MCU_PINS-1)
+ return;
+ if (func) {
+ _func = func;
+ intPtrTable[_gpioPin].context = this;
+ attachInterrupt(digitalPinToInterrupt(_gpioPin), intPtrTable[_gpioPin].func, RISING);
+ } else {
+ _func = InterruptIn::donothing;
+ intPtrTable[_gpioPin].context = NULL;
+ detachInterrupt(_gpioPin);
+ }
+};
+
+void
+InterruptIn::fall(Callback<void()> func) {
+ if (func) {
+ _func = func;
+ intPtrTable[_gpioPin].context = this;
+ attachInterrupt(digitalPinToInterrupt(_gpioPin), intPtrTable[_gpioPin].func, FALLING);
+ } else {
+ _func = InterruptIn::donothing;
+ intPtrTable[_gpioPin].context = NULL;
+ detachInterrupt(_gpioPin);
+ }
+}
+
+
+#define MAX_TIMEOUTS 10
+class Timeout;
+struct TimeoutVector {
+ Timeout *timer;
+ volatile uint32_t timeout; // us
+} TimeOuts[MAX_TIMEOUTS];
+
+
+#if defined(__SAMD21G18A__) || defined(__SAMD21J18A__)
+/*
+ * __SAMD21J18A__ is the SamD21 Explained Board
+ * __SAMD21G18A__ is Genuino Zero-Board (compatible with the LoRa board)
+ */
+
+/*
+ * see tcc.h included from
+ * Arduino15/packages/arduino/tools/CMSIS-Atmel/1.1.0/CMSIS/
+ * Device/ATMEL/samd21/include/component/tcc.h
+ */
+static const struct TCC_CONFIG {
+ Tcc *tcc_ptr;
+ IRQn_Type tcc_irq;
+ uint8_t nbits;
+} TCC_CONFIG[] {
+ { TCC0, TCC0_IRQn, 24 },
+ { TCC1, TCC1_IRQn, 24 },
+ { TCC2, TCC2_IRQn, 16 },
+};
+#define USE_TCC 0 // TCC0, TTC1, TTC2 are working using the Arduino D21
+
+
+static bool initTimerDone = false;
+
+static void initTimer() {
+ Tcc *TC = TCC_CONFIG[USE_TCC].tcc_ptr;
+
+ // Enable clock for TC, see gclk.h
+ if (TC == TCC0 || TC == TCC1) {
+ REG_GCLK_CLKCTRL = (uint16_t) (GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN_GCLK0 | GCLK_CLKCTRL_ID_TCC0_TCC1);
+ } else if (TC == TCC2) {
+ REG_GCLK_CLKCTRL = (uint16_t) (GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN_GCLK0 | GCLK_CLKCTRL_ID_TCC2_TC3_Val);
+ }
+ while (GCLK->STATUS.bit.SYNCBUSY == 1); // wait for sync
+
+ TC->CTRLA.reg &= ~TCC_CTRLA_ENABLE; // Disable TC
+ while (TC->SYNCBUSY.bit.ENABLE == 1); // wait for sync
+
+ TC->CTRLA.reg |= (TCC_CTRLA_PRESCALER_DIV1024 | TCC_CTRLA_RUNSTDBY); // Set perscaler
+
+ TC->WAVE.reg |= TCC_WAVE_WAVEGEN_NFRQ; // Set wave form configuration
+ while (TC->SYNCBUSY.bit.WAVE == 1); // wait for sync
+
+ TC->PER.bit.PER = 0xFFFFFF; // set counter top to max 24 bit
+ while (TC->SYNCBUSY.bit.PER == 1); // wait for sync
+
+ // the compare counter TC->CC[0].reg will be set in the startTimer
+ // after the timeout calculation is known.
+
+ // Interrupts
+ TC->INTENSET.reg = 0; // disable all interrupts
+ TC->INTENSET.bit.OVF = 1; // enable overfollow
+ TC->INTENSET.bit.MC0 = 1; // enable compare match to CC0
+
+ NVIC_EnableIRQ( TCC_CONFIG[USE_TCC].tcc_irq); // Enable InterruptVector
+ initTimerDone = true;
+}
+
+static void stopTimer(void)
+{
+ Tcc *TC = TCC_CONFIG[USE_TCC].tcc_ptr;
+
+ TC->CTRLA.reg &= ~TCC_CTRLA_ENABLE; // Disable TC
+ while (TC->SYNCBUSY.bit.ENABLE == 1); // wait for sync
+}
+
+static void startTimer(uint32_t delay_us)
+{
+ Tcc *TC = TCC_CONFIG[USE_TCC].tcc_ptr;
+
+ if (!initTimerDone)
+ initTimer(); // initial setup with stopped timer
+
+ stopTimer(); // avoid timer interrupts while calculating
+
+ /*
+ * every 21333 ns equals one tick (1/(48000000/1024))
+ * COUNT*DIVIDER*SECS until interrupt
+ * 48 Mhz = (65536*1024)/1.398636s
+ */
+ long long nclocks = delay_us * 1000; // ns;
+ nclocks = nclocks / 21333;
+ int nCounts = nclocks;
+
+ int bits = TCC_CONFIG[USE_TCC].nbits;
+ int maxCounts = (uint32_t)(1<<bits)-1;
+
+ if (nCounts > maxCounts) // if count exceeds timer capacity
+ nCounts = maxCounts; // set the largest posible count.
+ if (nCounts == 0)
+ nCounts = 1;
+ TC->CC[0].bit.CC = nCounts;
+ while (TC->SYNCBUSY.bit.CC0 == 1); // wait for sync
+
+ TC->CTRLA.reg |= TCC_CTRLA_ENABLE ; // Enable TC
+ while (TC->SYNCBUSY.bit.ENABLE == 1); // wait for sync
+#if 1
+ Serial.print(millis(), DEC);
+ Serial.print(" startTimer: nCounts=");
+ Serial.println(nCounts, DEC);
+#endif
+}
+
+
+
+#if USE_TCC == 0
+void TCC0_Handler()
+#elif USE_TCC == 1
+void TCC1_Handler()
+#elif USE_TCC == 2
+void TCC2_Handler()
+#endif
+{
+ static uint32_t last_usecs = 0;
+ Tcc *TC = TCC_CONFIG[USE_TCC].tcc_ptr;
+ uint32_t usecs = micros();
+ uint32_t u_offset = 0;
+
+ if (last_usecs && last_usecs < usecs) {
+ /*
+ * Problem is that the micros sometimes gives smaller values
+ * compared to previuos micros. As a workaround we all 1ms.
+ */
+ u_offset = 1000;
+ }
+ last_usecs = usecs;
+
+ /*
+ * Overflow means the max timer exeeded, we need restart the timer
+ * Interrupts and
+ */
+ if (TC->INTFLAG.bit.OVF == 1) { // A overflow caused the interrupt
+ Serial.print("OVF\r\n");
+ TC->INTFLAG.bit.OVF = 1; // writing a one clears the flag ovf flag
+ }
+
+ if (TC->INTFLAG.bit.MC0 == 1) { // A compare to cc0 caused the interrupt
+ //Serial.print("MC0\r\n");
+ TC->INTFLAG.bit.MC0 = 1; // writing a one clears the MCO (match capture) flag
+ }
+
+ TC->CTRLA.reg &= ~TCC_CTRLA_ENABLE; // Disable TC
+ while (TC->SYNCBUSY.bit.ENABLE == 1); // wait for sync
+
+ for (int i = 0; i < MAX_TIMEOUTS-1; i++) {
+ struct TimeoutVector *tvp = &TimeOuts[i];
+ if (tvp->timer && tvp->timeout && usecs + u_offset >= tvp->timeout) {
+ Timeout *saveTimer = tvp->timer;
+ tvp->timer = NULL;
+ tvp->timeout = 0;
+ Timeout::_irq_handler(saveTimer);
+ }
+ }
+ /*
+ * we need to restart the timer for remaining interrupts
+ * we provide the interrupt entry time in usecs which means
+ * we don't count the irq_hander duration or debug prints
+ */
+ Timeout::restart(usecs);
+}
+
+#endif // D21 TCC Timer
+
+void
+Timeout::insert(void)
+{
+ noInterrupts();
+ for (int i = 0; i < MAX_TIMEOUTS-1; i++) {
+ struct TimeoutVector *tvp = &TimeOuts[i];
+ if (tvp->timer == NULL) {
+ tvp->timeout = _timeout;
+ tvp->timer = this;
+ break;
+ }
+ }
+ interrupts();
+}
+
+void
+Timeout::remove(void)
+{
+ noInterrupts();
+ for (int i = 0; i < MAX_TIMEOUTS-1; i++) {
+ struct TimeoutVector *tvp = &TimeOuts[i];
+ if (tvp->timer == this) {
+ tvp->timer = NULL;
+ tvp->timeout = 0;
+ break;
+ }
+ }
+ interrupts();
+}
+
+
+void
+Timeout::restart(uint32_t usecs)
+{
+ uint32_t timeout = ~0;
+
+ /*
+ * find the lowest timeout value which is our the next timeout
+ * zero means stop the timer.
+ */
+ noInterrupts();
+ for (int i = 0; i < MAX_TIMEOUTS-1; i++) {
+ struct TimeoutVector *tvp = &TimeOuts[i];
+ if (tvp->timer && tvp->timeout > 0) {
+ if (tvp->timeout < timeout) {
+ timeout = tvp->timeout;
+ }
+ }
+ }
+ interrupts();
+
+ if (timeout == (uint32_t)~0) {
+ stopTimer();
+ return;
+ }
+ if (!usecs)
+ usecs = micros();
+
+ if (timeout > usecs) {
+ startTimer(timeout - usecs);
+ return;
+ } else {
+ startTimer(1); // just one usec to trigger interrrupt
+ }
+}
+#endif // ARDUINO
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sx1276/arduino-mbed.h Tue Jul 11 13:32:34 2017 +0200
@@ -0,0 +1,245 @@
+/*
+ * The file is Licensed under the Apache License, Version 2.0
+ * (c) 2017 Helmut Tschemernjak
+ * 30826 Garbsen (Hannover) Germany
+ */
+
+
+
+#ifdef ARDUINO
+#ifndef __ARDUINO_MBED_H__
+#define __ARDUINO_MBED_H__
+
+#include <arduino.h>
+#include "Callback-A.h"
+#include <SPI.h>
+#undef min
+#undef max
+#undef map
+
+
+typedef int PinName;
+#define NC -1
+#define wait_ms delay
+
+class DigitalInOut {
+public:
+ DigitalInOut(PinName pin) {
+ _gpioPin = pin;
+ }
+ void write(int value) {
+ digitalWrite(_gpioPin, value == 0 ? LOW : HIGH);
+ };
+
+ void output() {
+ pinMode(_gpioPin, OUTPUT);
+ };
+
+ void input() {
+ pinMode(_gpioPin, INPUT);
+ };
+
+ int read() {
+ if (digitalRead(_gpioPin) == HIGH)
+ return 1;
+ else
+ return 0;
+ };
+ operator int() {
+ return read();
+ };
+
+ DigitalInOut& operator= (int value) {
+ // Underlying write is thread safe
+ write(value);
+ return *this;
+ }
+
+ DigitalInOut& operator= (DigitalInOut& rhs) {
+ write(rhs.read());
+ return *this;
+ }
+
+private:
+ int _gpioPin;
+};
+
+class DigitalOut : public DigitalInOut {
+public:
+
+ DigitalOut(PinName pin) : DigitalInOut(pin) {
+ output();
+ }
+
+ DigitalOut& operator= (int value) {
+ write(value);
+ return *this;
+ }
+
+};
+
+class DigitalIn : public DigitalInOut {
+public:
+
+ DigitalIn(PinName pin) : DigitalInOut(pin) {
+ input();
+ }
+};
+
+class XSPI {
+public:
+ XSPI(PinName mosi, PinName miso, PinName sclk) {
+ _mosi = mosi;
+ _miso = miso;
+ _sclk = sclk;
+ if (mosi == PIN_SPI_MOSI && miso == PIN_SPI_MISO && sclk == PIN_SPI_SCK)
+ _spi = &SPI;
+#if SPI_INTERFACES_COUNT > 1
+ else if (mosi == PIN_SPI1_MOSI && miso == PIN_SPI1_MISO && sclk == PIN_SPI1_SCK)
+ _spi = &SPI1;
+#endif
+#if SPI_INTERFACES_COUNT > 2
+ else if (mosi == PIN_SPI2_MOSI && miso == PIN_SPI2_MISO && sclk == PIN_SPI2_SCK)
+ _spi = &SPI2;
+#endif
+ else {
+ _spi = NULL;
+ return;
+ }
+ _hz = 1000000;
+ _mode = SPI_MODE0;
+ _spi->beginTransaction(SPISettings(_hz, MSBFIRST, _mode));
+ _spi->endTransaction();
+ }
+
+ void format(int bits, int mode = 0) {
+ if (mode == 0)
+ _mode = SPI_MODE0;
+ else if (mode == 1)
+ _mode = SPI_MODE1;
+ else if (mode == 2)
+ _mode = SPI_MODE2;
+ else if (mode == 3)
+ _mode = SPI_MODE3;
+ else
+ _mode = SPI_MODE0;
+ _bits = bits;
+ _spi->beginTransaction(SPISettings(_hz, MSBFIRST, _mode));
+ _spi->endTransaction();
+ }
+ void frequency(int hz) {
+ _hz = hz;
+ _spi->beginTransaction(SPISettings(_hz, MSBFIRST, _mode));
+ _spi->endTransaction();
+ }
+
+ int write(int value) {
+ _spi->beginTransaction(SPISettings(_hz, MSBFIRST, _mode));
+ int ret = _spi->transfer(value);
+ _spi->endTransaction();
+ return ret;
+ }
+
+private:
+ SPIClass *_spi;
+ int _hz;
+ int _mode;
+ int _bits;
+ int _mosi, _miso, _sclk;
+};
+
+class InterruptIn {
+public:
+ static void donothing(void) {
+ }
+
+ InterruptIn(PinName pin) : _func() {
+ _gpioPin = pin;
+ _func = InterruptIn::donothing;
+ pinMode(_gpioPin, INPUT);
+ }
+
+ ~InterruptIn() {
+ detachInterrupt(digitalPinToInterrupt(_gpioPin));
+ };
+
+ static void _irq_handler(InterruptIn *id) {
+ if (id)
+ id->_func();
+ }
+
+ void rise(Callback<void()> func);
+
+ void fall(Callback<void()> func);
+
+private:
+ int _gpioPin;
+ Callback<void()> _func;
+};
+
+class Timer {
+public:
+ void start(void) {
+ _time = micros();
+ }
+ int read_ms(void) {
+ return (micros() - _time) / 1000;
+ }
+ int read_us(void) {
+ return micros() - _time;
+ }
+private:
+ uint32_t _time;
+};
+
+
+class Timeout {
+public:
+ Timeout() : _func() {
+ }
+ ~Timeout() {
+ detach();
+ }
+
+ void attach(Callback<void()> func, int msecs) {
+ if (msecs == 0)
+ return detach();
+ _func = func;
+ _timeout = micros() + (uint32_t)msecs * 1000;
+ insert();
+ restart();
+ }
+
+ void attach_us(Callback<void()> func, long usecs) {
+ if (usecs == 0)
+ return detach();
+ _func = func;
+ _timeout = micros() + usecs;
+ insert();
+ restart();
+ }
+
+ void detach() {
+ _func = NULL;
+ remove();
+ restart();
+ }
+
+ static void _irq_handler(Timeout *tp) {
+ if (tp) {
+ tp->_func();
+ }
+ }
+
+ static void restart(uint32_t usecs = 0);
+protected:
+ void insert(void);
+ void remove(void);
+private:
+ Callback<void()> _func;
+ uint32_t _timeout; // in us this lasts form 49 days.
+};
+
+#endif // __ARDUINO_MBED_H__
+
+#endif // ARDUINO
--- a/sx1276/sx1276-arduino-hal.cpp Fri Jun 30 16:08:05 2017 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,431 +0,0 @@
-
-/*
- * This file contains a copy of the master content sx1276-mbed-hal.h
- * with adaption for the Arduino environment
- * (c) 2017 Helmut Tschemernjak
- * 30826 Garbsen (Hannover) Germany
- */
-#ifdef ARDUINO
-
-/*
- (C) 2014 Semtech
- Description: -
- License: Revised BSD License, see LICENSE.TXT file include in the project
- Maintainers: Miguel Luis, Gregory Cristian and Nicolas Huguenin
- */
-
-/*
- * additional development to make it more generic across multiple OS versions
- * (c) 2017 Helmut Tschemernjak
- * 30826 Garbsen (Hannover) Germany
- */
-
-#include "sx1276-arduino-hal.h"
-
-
-
-SX1276Generic::SX1276Generic( RadioEvents_t *events, BoardType_t board,
- PinName mosi, PinName miso, PinName sclk, PinName nss, PinName reset,
- PinName dio0, PinName dio1, PinName dio2, PinName dio3, PinName dio4, PinName dio5,
- PinName antSwitch, PinName antSwitchTX, PinName antSwitchTXBoost, PinName tcxo)
-: SX1276( events)
-{
- this->RadioEvents = events;
- boardConnected = board;
-
- _antSwitch = NULL;
- _antSwitchTX = NULL;
- _antSwitchTXBoost = NULL;
-
- _tcxo = NULL;
- if (tcxo != NC)
- _tcxo = new DigitalOut(tcxo);
-
- switch(boardConnected) {
- case SX1276MB1MAS:
- case SX1276MB1LAS:
- _antSwitch = new DigitalOut(antSwitch);
- break;
- case RFM95_SX1276:
- break;
- case MURATA_SX1276:
- _antSwitch = new DigitalOut(antSwitch);
- _antSwitchTX = new DigitalOut(antSwitchTX);
- _antSwitchTXBoost = new DigitalOut(antSwitchTXBoost);
- break;
- default:
- break;
- }
- _spi = new SPI(mosi, miso, sclk );
- _nss = new DigitalOut(nss);
-
- _reset = new DigitalInOut(reset);
-
- _dio0 = NULL;
- _dio1 = NULL;
- _dio2 = NULL;
- _dio3 = NULL;
- _dio4 = NULL;
- _dio5 = NULL;
- if (dio0 != NC)
- _dio0 = new InterruptIn(dio0);
- if (dio1 != NC)
- _dio1 = new InterruptIn(dio1);
- if (dio2 != NC)
- _dio2 = new InterruptIn(dio2);
- if (dio3 != NC)
- _dio3 = new InterruptIn(dio3);
- if (dio4 != NC)
- _dio4 = new InterruptIn(dio4);
- if (dio5 != NC)
- _dio5 = new DigitalIn(dio5);
-
- Reset( );
-
- IoInit( );
-
- RxChainCalibration( );
-
- SetOpMode( RF_OPMODE_SLEEP );
-
- IoIrqInit( dioIrq );
-
- RadioRegistersInit( );
-
- SetModem( MODEM_FSK );
-}
-
-SX1276Generic::~SX1276Generic()
-{
- if (_antSwitch)
- delete _antSwitch;
- if (_antSwitchTX)
- delete _antSwitchTX;
- if (_antSwitchTXBoost)
- delete _antSwitchTXBoost;
-
- if (_tcxo) {
- *_tcxo = 0;
- delete (_tcxo);
- }
- delete _reset;
- delete _spi;
- delete _nss;
-
- if (_dio0)
- delete _dio0;
- if (_dio1)
- delete _dio1;
- if (_dio2)
- delete _dio2;
- if (_dio3)
- delete _dio3;
- if (_dio4)
- delete _dio4;
- if (_dio5)
- delete _dio5;
-}
-
-
-//-------------------------------------------------------------------------
-// Board relative functions
-//-------------------------------------------------------------------------
-uint8_t SX1276Generic::DetectBoardType( void )
-{
- return boardConnected;
-}
-
-void SX1276Generic::IoInit( void )
-{
- if (_tcxo)
- *_tcxo = 1;
- AntSwInit( );
- SpiInit( );
-}
-
-
-void SX1276Generic::SpiInit( void )
-{
- *_nss = 1;
- _spi->format( 8,0 );
- uint32_t frequencyToSet = 8000000;
- _spi->frequency( frequencyToSet );
- wait_ms(100);
-}
-
-void SX1276Generic::IoIrqInit( DioIrqHandler *irqHandlers )
-{
- if (_dio0)
- _dio0->rise(callback(this, static_cast< Trigger > ( irqHandlers[0] )));
- if (_dio1)
- _dio1->rise(callback(this, static_cast< Trigger > ( irqHandlers[1] )));
- if (_dio2)
- _dio2->rise(callback(this, static_cast< Trigger > ( irqHandlers[2] )));
- if (_dio3)
- _dio3->rise(callback(this, static_cast< Trigger > ( irqHandlers[3] )));
- if (_dio4)
- _dio4->rise(callback(this, static_cast< Trigger > ( irqHandlers[4] )));
-}
-
-void SX1276Generic::IoDeInit( void )
-{
- //nothing
-}
-
-void SX1276Generic::SetRfTxPower( int8_t power )
-{
- uint8_t paConfig = 0;
- uint8_t paDac = 0;
-
- paConfig = Read( REG_PACONFIG );
- paDac = Read( REG_PADAC );
-
- paConfig = ( paConfig & RF_PACONFIG_PASELECT_MASK ) | GetPaSelect( this->settings.Channel );
- paConfig = ( paConfig & RF_PACONFIG_MAX_POWER_MASK ) | 0x70;
-
- if( ( paConfig & RF_PACONFIG_PASELECT_PABOOST ) == RF_PACONFIG_PASELECT_PABOOST )
- {
- if( power > 17 )
- {
- paDac = ( paDac & RF_PADAC_20DBM_MASK ) | RF_PADAC_20DBM_ON;
- }
- else
- {
- paDac = ( paDac & RF_PADAC_20DBM_MASK ) | RF_PADAC_20DBM_OFF;
- }
- if( ( paDac & RF_PADAC_20DBM_ON ) == RF_PADAC_20DBM_ON )
- {
- if( power < 5 )
- {
- power = 5;
- }
- if( power > 20 )
- {
- power = 20;
- }
- paConfig = ( paConfig & RF_PACONFIG_OUTPUTPOWER_MASK ) | ( uint8_t )( ( uint16_t )( power - 5 ) & 0x0F );
- }
- else
- {
- if( power < 2 )
- {
- power = 2;
- }
- if( power > 17 )
- {
- power = 17;
- }
- paConfig = ( paConfig & RF_PACONFIG_OUTPUTPOWER_MASK ) | ( uint8_t )( ( uint16_t )( power - 2 ) & 0x0F );
- }
- }
- else
- {
- if( power < -1 )
- {
- power = -1;
- }
- if( power > 14 )
- {
- power = 14;
- }
- paConfig = ( paConfig & RF_PACONFIG_OUTPUTPOWER_MASK ) | ( uint8_t )( ( uint16_t )( power + 1 ) & 0x0F );
- }
- Write( REG_PACONFIG, paConfig );
- Write( REG_PADAC, paDac );
-}
-
-
-uint8_t SX1276Generic::GetPaSelect( uint32_t channel )
-{
- if( channel > RF_MID_BAND_THRESH )
- {
- if (boardConnected == SX1276MB1LAS || boardConnected == RFM95_SX1276 || boardConnected == MURATA_SX1276)
- {
- return RF_PACONFIG_PASELECT_PABOOST;
- }
- else
- {
- return RF_PACONFIG_PASELECT_RFO;
- }
- }
- else
- {
- return RF_PACONFIG_PASELECT_RFO;
- }
-}
-
-void SX1276Generic::SetAntSwLowPower( bool status )
-{
- if( isRadioActive != status )
- {
- isRadioActive = status;
-
- if( status == false )
- {
- AntSwInit( );
- }
- else
- {
- AntSwDeInit( );
- }
- }
-}
-
-void SX1276Generic::AntSwInit( void )
-{
- if (_antSwitch)
- *_antSwitch = 0;
- if (boardConnected == MURATA_SX1276) {
- *_antSwitchTX = 0;
- *_antSwitchTXBoost = 0;
- }
-}
-
-void SX1276Generic::AntSwDeInit( void )
-{
- if (_antSwitch)
- *_antSwitch = 0;
- if (boardConnected == MURATA_SX1276) {
- *_antSwitchTX = 0;
- *_antSwitchTXBoost = 0;
- }
-}
-
-
-void SX1276Generic::SetAntSw( uint8_t opMode )
-{
- switch( opMode )
- {
- case RFLR_OPMODE_TRANSMITTER:
- if (boardConnected == MURATA_SX1276) {
- *_antSwitch = 0;// Murata-RX
- if (Read( REG_PACONFIG) & RF_PACONFIG_PASELECT_PABOOST)
- *_antSwitchTXBoost = 1;
- else
- *_antSwitchTX = 1; // alternate: antSwitchTXBoost = 1
- } else {
- if (_antSwitch)
- *_antSwitch = 1;
- }
- break;
- case RFLR_OPMODE_RECEIVER:
- case RFLR_OPMODE_RECEIVER_SINGLE:
- case RFLR_OPMODE_CAD:
- if (boardConnected == MURATA_SX1276) {
- *_antSwitch = 1; // Murata-RX
- *_antSwitchTX = 0;
- *_antSwitchTXBoost = 0;
- } else {
- if (_antSwitch)
- _antSwitch = 0;
- }
- break;
- case RFLR_OPMODE_SLEEP:
- case RFLR_OPMODE_STANDBY:
- default:
- if (boardConnected == MURATA_SX1276) {
- *_antSwitch = 0; //Murata-RX
- *_antSwitchTX = 0;
- *_antSwitchTXBoost = 0;
- } else {
- if (_antSwitch)
- *_antSwitch = 0;
- }
- break;
- }
-}
-
-void SX1276Generic::SetTimeout(TimeoutTimer_t timer, timeoutFuncPtr func, int timeout_ms)
-{
- switch(timer) {
- case RXTimeoutTimer:
- if (func)
- rxTimeoutTimer.attach_us(callback(this, func), timeout_ms);
- else
- rxTimeoutTimer.detach();
- break;
- case TXTimeoutTimer:
- if (func)
- txTimeoutTimer.attach_us(callback(this, func), timeout_ms);
- else
- txTimeoutTimer.detach();
- break;
- case RXTimeoutSyncWordTimer:
- if (func)
- rxTimeoutSyncWord.attach_us(callback(this, func), timeout_ms);
- else
- rxTimeoutSyncWord.detach();
- break;
- }
-}
-
-bool SX1276Generic::CheckRfFrequency( uint32_t frequency )
-{
- // Implement check. Currently all frequencies are supported
- return true;
-}
-
-void SX1276Generic::Reset( void )
-{
- _reset->output();
- *_reset = 0;
- wait_ms( 1 );
- *_reset = 1;
- _reset->input(); // I don't know my input again, maybe to save power (Helmut T)
- wait_ms( 6 );
-}
-
-void SX1276Generic::Write( uint8_t addr, uint8_t data )
-{
- Write( addr, &data, 1 );
-}
-
-uint8_t SX1276Generic::Read( uint8_t addr )
-{
- uint8_t data;
- Read( addr, &data, 1 );
- return data;
-}
-
-void SX1276Generic::Write( uint8_t addr, void *buffer, uint8_t size )
-{
- uint8_t i;
- uint8_t *p = (uint8_t *)buffer;
-
- *_nss = 0; // what about SPI hold/release timing on fast MCUs? Helmut
- _spi->write( addr | 0x80 );
- for( i = 0; i < size; i++ )
- {
- _spi->write(*p++);
- }
- *_nss = 1;
-}
-
-void SX1276Generic::Read( uint8_t addr, void *buffer, uint8_t size )
-{
- uint8_t i;
- uint8_t *p = (uint8_t *)buffer;
-
- *_nss = 0; // what about SPI hold/release timing on fast MCUs? Helmut
- _spi->write( addr & 0x7F );
- for( i = 0; i < size; i++ )
- {
- *p++ = _spi->write( 0 );
- }
- *_nss = 1;
-}
-
-void SX1276Generic::WriteFifo( void *buffer, uint8_t size )
-{
- Write( 0, buffer, size );
-}
-
-void SX1276Generic::ReadFifo( void *buffer, uint8_t size )
-{
- Read( 0, buffer, size );
-}
-
-
-
-
-#endif // ARDUINO
--- a/sx1276/sx1276-arduino-hal.h Fri Jun 30 16:08:05 2017 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,240 +0,0 @@
-
-/*
- * This file contains a copy of the master content sx1276-mbed-hal.h
- * with adaption for the Arduino environment
- * (c) 2017 Helmut Tschemernjak
- * 30826 Garbsen (Hannover) Germany
- */
-#ifdef ARDUINO
-
-/*
- (C) 2014 Semtech
- Description: -
- License: Revised BSD License, see LICENSE.TXT file include in the project
- Maintainers: Miguel Luis, Gregory Cristian and Nicolas Huguenin
- */
-
-/*
- * additional development to make it more generic across multiple OS versions
- * (c) 2017 Helmut Tschemernjak
- * 30826 Garbsen (Hannover) Germany
- */
-
-#ifndef __SX1276_ARDUINO_HAL_H__
-#define __SX1276_ARDUINO_HAL_H__
-#include "sx1276.h"
-
-
-
-/*!
- * Actual implementation of a SX1276 radio, includes some modifications to make it compatible with the MB1 LAS board
- */
-class SX1276Generic : public SX1276
-{
-protected:
- /*!
- * Antenna switch GPIO pins objects
- */
- DigitalOut *_antSwitch;
- DigitalOut *_antSwitchTX;
- DigitalOut *_antSwitchTXBoost;
-
- /*!
- * SX1276 Reset pin
- */
- DigitalInOut *_reset;
-
- /*!
- * TCXO being used with the Murata Module
- */
- DigitalOut *_tcxo;
-
- /*!
- * SPI Interface
- */
- SPI *_spi; // mosi, miso, sclk
- DigitalOut *_nss;
-
- /*!
- * SX1276 DIO pins
- */
- InterruptIn *_dio0;
- InterruptIn *_dio1;
- InterruptIn *_dio2;
- InterruptIn *_dio3;
- InterruptIn *_dio4;
- DigitalIn *_dio5;
-
- /*!
- * Tx and Rx timers
- */
- Timeout txTimeoutTimer;
- Timeout rxTimeoutTimer;
- Timeout rxTimeoutSyncWord;
-
-
-private:
- /*!
- * triggers definition
- */
- typedef void (SX1276Generic::*Trigger)(void);
-
-
- public:
- SX1276Generic( RadioEvents_t *events, BoardType_t board,
- PinName mosi, PinName miso, PinName sclk, PinName nss, PinName reset,
- PinName dio0, PinName dio1, PinName dio2, PinName dio3, PinName dio4, PinName dio5,
- PinName antSwitch = NC, PinName antSwitchTX= NC, PinName antSwitchTXBoost = NC, PinName tcxo = NC);
-
-
- SX1276Generic( RadioEvents_t *events );
-
- virtual ~SX1276Generic();
-
-protected:
- /*!
- * @brief Initializes the radio I/Os pins interface
- */
- virtual void IoInit( void );
-
- /*!
- * @brief Initializes the radio SPI
- */
- virtual void SpiInit( void );
-
- /*!
- * @brief Initializes DIO IRQ handlers
- *
- * @param [IN] irqHandlers Array containing the IRQ callback functions
- */
- virtual void IoIrqInit( DioIrqHandler *irqHandlers );
-
- /*!
- * @brief De-initializes the radio I/Os pins interface.
- *
- * \remark Useful when going in MCU lowpower modes
- */
- virtual void IoDeInit( void );
-
- /*!
- * @brief Gets the board PA selection configuration
- *
- * @param [IN] channel Channel frequency in Hz
- * @retval PaSelect RegPaConfig PaSelect value
- */
- virtual uint8_t GetPaSelect( uint32_t channel );
-
- /*!
- * @brief Set the RF Switch I/Os pins in Low Power mode
- *
- * @param [IN] status enable or disable
- */
- virtual void SetAntSwLowPower( bool status );
-
- /*!
- * @brief Initializes the RF Switch I/Os pins interface
- */
- virtual void AntSwInit( void );
-
- /*!
- * @brief De-initializes the RF Switch I/Os pins interface
- *
- * @remark Needed to decrease the power consumption in MCU lowpower modes
- */
- virtual void AntSwDeInit( void );
-
- /*!
- * @brief Controls the antena switch if necessary.
- *
- * @remark see errata note
- *
- * @param [IN] opMode Current radio operating mode
- */
- virtual void SetAntSw( uint8_t opMode );
-
- /*
- * The the Timeout for a given Timer.
- */
- virtual void SetTimeout(TimeoutTimer_t timer, timeoutFuncPtr, int timeout_ms = 0);
-
- public:
-
- /*!
- * @brief Detect the board connected by reading the value of the antenna switch pin
- */
- virtual uint8_t DetectBoardType( void );
-
- /*!
- * @brief Checks if the given RF frequency is supported by the hardware
- *
- * @param [IN] frequency RF frequency to be checked
- * @retval isSupported [true: supported, false: unsupported]
- */
- virtual bool CheckRfFrequency( uint32_t frequency );
-
- /*!
- * @brief Writes the radio register at the specified address
- *
- * @param [IN]: addr Register address
- * @param [IN]: data New register value
- */
- virtual void Write ( uint8_t addr, uint8_t data ) ;
-
- /*!
- * @brief Reads the radio register at the specified address
- *
- * @param [IN]: addr Register address
- * @retval data Register value
- */
- virtual uint8_t Read ( uint8_t addr ) ;
-
- /*!
- * @brief Writes multiple radio registers starting at address
- *
- * @param [IN] addr First Radio register address
- * @param [IN] buffer Buffer containing the new register's values
- * @param [IN] size Number of registers to be written
- */
- virtual void Write( uint8_t addr, void *buffer, uint8_t size ) ;
-
- /*!
- * @brief Reads multiple radio registers starting at address
- *
- * @param [IN] addr First Radio register address
- * @param [OUT] buffer Buffer where to copy the registers data
- * @param [IN] size Number of registers to be read
- */
- virtual void Read ( uint8_t addr, void *buffer, uint8_t size ) ;
-
- /*!
- * @brief Writes the buffer contents to the SX1276 FIFO
- *
- * @param [IN] buffer Buffer containing data to be put on the FIFO.
- * @param [IN] size Number of bytes to be written to the FIFO
- */
- virtual void WriteFifo( void *buffer, uint8_t size ) ;
-
- /*!
- * @brief Reads the contents of the SX1276 FIFO
- *
- * @param [OUT] buffer Buffer where to copy the FIFO read data.
- * @param [IN] size Number of bytes to be read from the FIFO
- */
- virtual void ReadFifo( void *buffer, uint8_t size ) ;
-
- /*!
- * @brief Reset the SX1276
- */
- virtual void Reset( void );
-
- /*!
- * \brief Sets the radio output power.
- *
- * @param [IN] power Sets the RF output power
- */
- virtual void SetRfTxPower( int8_t power );
-
-};
-
-#endif // __SX1276_ARDUINO_HAL_H__
-#endif // ARDUINO
--- a/sx1276/sx1276-mbed-hal.cpp Fri Jun 30 16:08:05 2017 +0200
+++ b/sx1276/sx1276-mbed-hal.cpp Tue Jul 11 13:32:34 2017 +0200
@@ -19,6 +19,10 @@
* 30826 Garbsen (Hannover) Germany
*/
+#ifdef ARDUINO
+ #include "arduino-mbed.h"
+#endif
+
#include "sx1276-mbed-hal.h"
@@ -56,7 +60,7 @@
default:
break;
}
- _spi = new SPI(mosi, miso, sclk );
+ _spi = new XSPI(mosi, miso, sclk );
_nss = new DigitalOut(nss);
_reset = new DigitalInOut(reset);
@@ -371,6 +375,8 @@
bool SX1276Generic::CheckRfFrequency( uint32_t frequency )
{
+ if (frequency > 1200000)
+ return false;
// Implement check. Currently all frequencies are supported
return true;
}
--- a/sx1276/sx1276-mbed-hal.h Fri Jun 30 16:08:05 2017 +0200
+++ b/sx1276/sx1276-mbed-hal.h Tue Jul 11 13:32:34 2017 +0200
@@ -21,12 +21,19 @@
#ifndef __SX1276_MBED_HAL_H__
#define __SX1276_MBED_HAL_H__
+
+
#include "sx1276.h"
+#ifdef __MBED__
+#define XSPI SPI
+#endif
+
/*!
- * Actual implementation of a SX1276 radio, includes some modifications to make it compatible with the MB1 LAS board
+ * Actual implementation of a SX1276 radio, includes some modifications to make it
+ * compatible with the MB1 LAS board
*/
class SX1276Generic : public SX1276
{
@@ -51,7 +58,7 @@
/*!
* SPI Interface
*/
- SPI *_spi; // mosi, miso, sclk
+ XSPI *_spi; // mosi, miso, sclk
DigitalOut *_nss;
/*!
--- a/sx1276/sx1276.h Fri Jun 30 16:08:05 2017 +0200 +++ b/sx1276/sx1276.h Tue Jul 11 13:32:34 2017 +0200 @@ -23,8 +23,8 @@ #define __SX1276_H__ #include "radio.h" -#include "./registers/sx1276Regs-Fsk.h" -#include "./registers/sx1276Regs-LoRa.h" +#include "sx1276Regs-Fsk.h" +#include "sx1276Regs-LoRa.h"
