Christopher Haster / mbed-hal

Dependencies:   target-freescale

Fork of mbed-hal by Morpheus

Committer:
screamer
Date:
Wed Mar 23 21:36:09 2016 +0000
Revision:
0:9c59db1fbc9e
Initial revision

Who changed what in which revision?

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