mbed library for slider v2

Dependents:   kl46z_slider_v2

Committer:
mturner5
Date:
Wed Sep 14 07:04:27 2016 +0000
Revision:
0:b7116bd48af6
Tried to use the timer.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
mturner5 0:b7116bd48af6 1 #ifndef MBED_INTERRUPTMANAGER_H
mturner5 0:b7116bd48af6 2 #define MBED_INTERRUPTMANAGER_H
mturner5 0:b7116bd48af6 3
mturner5 0:b7116bd48af6 4 #include "cmsis.h"
mturner5 0:b7116bd48af6 5 #include "CallChain.h"
mturner5 0:b7116bd48af6 6 #include "PlatformMutex.h"
mturner5 0:b7116bd48af6 7 #include <string.h>
mturner5 0:b7116bd48af6 8
mturner5 0:b7116bd48af6 9 namespace mbed {
mturner5 0:b7116bd48af6 10
mturner5 0:b7116bd48af6 11 /** Use this singleton if you need to chain interrupt handlers.
mturner5 0:b7116bd48af6 12 *
mturner5 0:b7116bd48af6 13 * @Note Synchronization level: Thread safe
mturner5 0:b7116bd48af6 14 *
mturner5 0:b7116bd48af6 15 * Example (for LPC1768):
mturner5 0:b7116bd48af6 16 * @code
mturner5 0:b7116bd48af6 17 * #include "InterruptManager.h"
mturner5 0:b7116bd48af6 18 * #include "mbed.h"
mturner5 0:b7116bd48af6 19 *
mturner5 0:b7116bd48af6 20 * Ticker flipper;
mturner5 0:b7116bd48af6 21 * DigitalOut led1(LED1);
mturner5 0:b7116bd48af6 22 * DigitalOut led2(LED2);
mturner5 0:b7116bd48af6 23 *
mturner5 0:b7116bd48af6 24 * void flip(void) {
mturner5 0:b7116bd48af6 25 * led1 = !led1;
mturner5 0:b7116bd48af6 26 * }
mturner5 0:b7116bd48af6 27 *
mturner5 0:b7116bd48af6 28 * void handler(void) {
mturner5 0:b7116bd48af6 29 * led2 = !led1;
mturner5 0:b7116bd48af6 30 * }
mturner5 0:b7116bd48af6 31 *
mturner5 0:b7116bd48af6 32 * int main() {
mturner5 0:b7116bd48af6 33 * led1 = led2 = 0;
mturner5 0:b7116bd48af6 34 * flipper.attach(&flip, 1.0);
mturner5 0:b7116bd48af6 35 * InterruptManager::get()->add_handler(handler, TIMER3_IRQn);
mturner5 0:b7116bd48af6 36 * }
mturner5 0:b7116bd48af6 37 * @endcode
mturner5 0:b7116bd48af6 38 */
mturner5 0:b7116bd48af6 39 class InterruptManager {
mturner5 0:b7116bd48af6 40 public:
mturner5 0:b7116bd48af6 41 /** Return the only instance of this class
mturner5 0:b7116bd48af6 42 */
mturner5 0:b7116bd48af6 43 static InterruptManager* get();
mturner5 0:b7116bd48af6 44
mturner5 0:b7116bd48af6 45 /** Destroy the current instance of the interrupt manager
mturner5 0:b7116bd48af6 46 */
mturner5 0:b7116bd48af6 47 static void destroy();
mturner5 0:b7116bd48af6 48
mturner5 0:b7116bd48af6 49 /** Add a handler for an interrupt at the end of the handler list
mturner5 0:b7116bd48af6 50 *
mturner5 0:b7116bd48af6 51 * @param function the handler to add
mturner5 0:b7116bd48af6 52 * @param irq interrupt number
mturner5 0:b7116bd48af6 53 *
mturner5 0:b7116bd48af6 54 * @returns
mturner5 0:b7116bd48af6 55 * The function object created for 'function'
mturner5 0:b7116bd48af6 56 */
mturner5 0:b7116bd48af6 57 pFunctionPointer_t add_handler(void (*function)(void), IRQn_Type irq) {
mturner5 0:b7116bd48af6 58 // Underlying call is thread safe
mturner5 0:b7116bd48af6 59 return add_common(function, irq);
mturner5 0:b7116bd48af6 60 }
mturner5 0:b7116bd48af6 61
mturner5 0:b7116bd48af6 62 /** Add a handler for an interrupt at the beginning of the handler list
mturner5 0:b7116bd48af6 63 *
mturner5 0:b7116bd48af6 64 * @param function the handler to add
mturner5 0:b7116bd48af6 65 * @param irq interrupt number
mturner5 0:b7116bd48af6 66 *
mturner5 0:b7116bd48af6 67 * @returns
mturner5 0:b7116bd48af6 68 * The function object created for 'function'
mturner5 0:b7116bd48af6 69 */
mturner5 0:b7116bd48af6 70 pFunctionPointer_t add_handler_front(void (*function)(void), IRQn_Type irq) {
mturner5 0:b7116bd48af6 71 // Underlying call is thread safe
mturner5 0:b7116bd48af6 72 return add_common(function, irq, true);
mturner5 0:b7116bd48af6 73 }
mturner5 0:b7116bd48af6 74
mturner5 0:b7116bd48af6 75 /** Add a handler for an interrupt at the end of the handler list
mturner5 0:b7116bd48af6 76 *
mturner5 0:b7116bd48af6 77 * @param tptr pointer to the object that has the handler function
mturner5 0:b7116bd48af6 78 * @param mptr pointer to the actual handler function
mturner5 0:b7116bd48af6 79 * @param irq interrupt number
mturner5 0:b7116bd48af6 80 *
mturner5 0:b7116bd48af6 81 * @returns
mturner5 0:b7116bd48af6 82 * The function object created for 'tptr' and 'mptr'
mturner5 0:b7116bd48af6 83 */
mturner5 0:b7116bd48af6 84 template<typename T>
mturner5 0:b7116bd48af6 85 pFunctionPointer_t add_handler(T* tptr, void (T::*mptr)(void), IRQn_Type irq) {
mturner5 0:b7116bd48af6 86 // Underlying call is thread safe
mturner5 0:b7116bd48af6 87 return add_common(tptr, mptr, irq);
mturner5 0:b7116bd48af6 88 }
mturner5 0:b7116bd48af6 89
mturner5 0:b7116bd48af6 90 /** Add a handler for an interrupt at the beginning of the handler list
mturner5 0:b7116bd48af6 91 *
mturner5 0:b7116bd48af6 92 * @param tptr pointer to the object that has the handler function
mturner5 0:b7116bd48af6 93 * @param mptr pointer to the actual handler function
mturner5 0:b7116bd48af6 94 * @param irq interrupt number
mturner5 0:b7116bd48af6 95 *
mturner5 0:b7116bd48af6 96 * @returns
mturner5 0:b7116bd48af6 97 * The function object created for 'tptr' and 'mptr'
mturner5 0:b7116bd48af6 98 */
mturner5 0:b7116bd48af6 99 template<typename T>
mturner5 0:b7116bd48af6 100 pFunctionPointer_t add_handler_front(T* tptr, void (T::*mptr)(void), IRQn_Type irq) {
mturner5 0:b7116bd48af6 101 // Underlying call is thread safe
mturner5 0:b7116bd48af6 102 return add_common(tptr, mptr, irq, true);
mturner5 0:b7116bd48af6 103 }
mturner5 0:b7116bd48af6 104
mturner5 0:b7116bd48af6 105 /** Remove a handler from an interrupt
mturner5 0:b7116bd48af6 106 *
mturner5 0:b7116bd48af6 107 * @param handler the function object for the handler to remove
mturner5 0:b7116bd48af6 108 * @param irq the interrupt number
mturner5 0:b7116bd48af6 109 *
mturner5 0:b7116bd48af6 110 * @returns
mturner5 0:b7116bd48af6 111 * true if the handler was found and removed, false otherwise
mturner5 0:b7116bd48af6 112 */
mturner5 0:b7116bd48af6 113 bool remove_handler(pFunctionPointer_t handler, IRQn_Type irq);
mturner5 0:b7116bd48af6 114
mturner5 0:b7116bd48af6 115 private:
mturner5 0:b7116bd48af6 116 InterruptManager();
mturner5 0:b7116bd48af6 117 ~InterruptManager();
mturner5 0:b7116bd48af6 118
mturner5 0:b7116bd48af6 119 void lock();
mturner5 0:b7116bd48af6 120 void unlock();
mturner5 0:b7116bd48af6 121
mturner5 0:b7116bd48af6 122 // We declare the copy contructor and the assignment operator, but we don't
mturner5 0:b7116bd48af6 123 // implement them. This way, if someone tries to copy/assign our instance,
mturner5 0:b7116bd48af6 124 // he will get an error at compile time.
mturner5 0:b7116bd48af6 125 InterruptManager(const InterruptManager&);
mturner5 0:b7116bd48af6 126 InterruptManager& operator =(const InterruptManager&);
mturner5 0:b7116bd48af6 127
mturner5 0:b7116bd48af6 128 template<typename T>
mturner5 0:b7116bd48af6 129 pFunctionPointer_t add_common(T *tptr, void (T::*mptr)(void), IRQn_Type irq, bool front=false) {
mturner5 0:b7116bd48af6 130 _mutex.lock();
mturner5 0:b7116bd48af6 131 int irq_pos = get_irq_index(irq);
mturner5 0:b7116bd48af6 132 bool change = must_replace_vector(irq);
mturner5 0:b7116bd48af6 133
mturner5 0:b7116bd48af6 134 pFunctionPointer_t pf = front ? _chains[irq_pos]->add_front(tptr, mptr) : _chains[irq_pos]->add(tptr, mptr);
mturner5 0:b7116bd48af6 135 if (change)
mturner5 0:b7116bd48af6 136 NVIC_SetVector(irq, (uint32_t)&InterruptManager::static_irq_helper);
mturner5 0:b7116bd48af6 137 _mutex.unlock();
mturner5 0:b7116bd48af6 138 return pf;
mturner5 0:b7116bd48af6 139 }
mturner5 0:b7116bd48af6 140
mturner5 0:b7116bd48af6 141 pFunctionPointer_t add_common(void (*function)(void), IRQn_Type irq, bool front=false);
mturner5 0:b7116bd48af6 142 bool must_replace_vector(IRQn_Type irq);
mturner5 0:b7116bd48af6 143 int get_irq_index(IRQn_Type irq);
mturner5 0:b7116bd48af6 144 void irq_helper();
mturner5 0:b7116bd48af6 145 void add_helper(void (*function)(void), IRQn_Type irq, bool front=false);
mturner5 0:b7116bd48af6 146 static void static_irq_helper();
mturner5 0:b7116bd48af6 147
mturner5 0:b7116bd48af6 148 CallChain* _chains[NVIC_NUM_VECTORS];
mturner5 0:b7116bd48af6 149 static InterruptManager* _instance;
mturner5 0:b7116bd48af6 150 PlatformMutex _mutex;
mturner5 0:b7116bd48af6 151 };
mturner5 0:b7116bd48af6 152
mturner5 0:b7116bd48af6 153 } // namespace mbed
mturner5 0:b7116bd48af6 154
mturner5 0:b7116bd48af6 155 #endif
mturner5 0:b7116bd48af6 156