Mbed SDK for XRange SX1272 LoRa module
Dependents: XRangePingPong XRange-LoRaWAN-lmic-app lora-transceiver
SX1272 LoRa RF module
https://www.netblocks.eu/xrange-sx1272-lora-datasheet/
common/InterruptManager.cpp@339:ac6f3fd999f3, 2016-01-07 (annotated)
- Committer:
- netblocks
- Date:
- Thu Jan 07 13:01:25 2016 +0000
- Revision:
- 339:ac6f3fd999f3
- Parent:
- 336:1e18a06a987b
HSE_VALUE set for XTAL 16Mhz
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
dudmuck | 336:1e18a06a987b | 1 | #include "cmsis.h" |
dudmuck | 336:1e18a06a987b | 2 | #if defined(NVIC_NUM_VECTORS) |
dudmuck | 336:1e18a06a987b | 3 | |
dudmuck | 336:1e18a06a987b | 4 | #include "InterruptManager.h" |
dudmuck | 336:1e18a06a987b | 5 | #include <string.h> |
dudmuck | 336:1e18a06a987b | 6 | |
dudmuck | 336:1e18a06a987b | 7 | #define CHAIN_INITIAL_SIZE 4 |
dudmuck | 336:1e18a06a987b | 8 | |
dudmuck | 336:1e18a06a987b | 9 | namespace mbed { |
dudmuck | 336:1e18a06a987b | 10 | |
dudmuck | 336:1e18a06a987b | 11 | typedef void (*pvoidf)(void); |
dudmuck | 336:1e18a06a987b | 12 | |
dudmuck | 336:1e18a06a987b | 13 | InterruptManager* InterruptManager::_instance = (InterruptManager*)NULL; |
dudmuck | 336:1e18a06a987b | 14 | |
dudmuck | 336:1e18a06a987b | 15 | InterruptManager* InterruptManager::get() { |
dudmuck | 336:1e18a06a987b | 16 | if (NULL == _instance) |
dudmuck | 336:1e18a06a987b | 17 | _instance = new InterruptManager(); |
dudmuck | 336:1e18a06a987b | 18 | return _instance; |
dudmuck | 336:1e18a06a987b | 19 | } |
dudmuck | 336:1e18a06a987b | 20 | |
dudmuck | 336:1e18a06a987b | 21 | InterruptManager::InterruptManager() { |
dudmuck | 336:1e18a06a987b | 22 | memset(_chains, 0, NVIC_NUM_VECTORS * sizeof(CallChain*)); |
dudmuck | 336:1e18a06a987b | 23 | } |
dudmuck | 336:1e18a06a987b | 24 | |
dudmuck | 336:1e18a06a987b | 25 | void InterruptManager::destroy() { |
dudmuck | 336:1e18a06a987b | 26 | // Not a good idea to call this unless NO interrupt at all |
dudmuck | 336:1e18a06a987b | 27 | // is under the control of the handler; otherwise, a system crash |
dudmuck | 336:1e18a06a987b | 28 | // is very likely to occur |
dudmuck | 336:1e18a06a987b | 29 | if (NULL != _instance) { |
dudmuck | 336:1e18a06a987b | 30 | delete _instance; |
dudmuck | 336:1e18a06a987b | 31 | _instance = (InterruptManager*)NULL; |
dudmuck | 336:1e18a06a987b | 32 | } |
dudmuck | 336:1e18a06a987b | 33 | } |
dudmuck | 336:1e18a06a987b | 34 | |
dudmuck | 336:1e18a06a987b | 35 | InterruptManager::~InterruptManager() { |
dudmuck | 336:1e18a06a987b | 36 | for(int i = 0; i < NVIC_NUM_VECTORS; i++) |
dudmuck | 336:1e18a06a987b | 37 | if (NULL != _chains[i]) |
dudmuck | 336:1e18a06a987b | 38 | delete _chains[i]; |
dudmuck | 336:1e18a06a987b | 39 | } |
dudmuck | 336:1e18a06a987b | 40 | |
dudmuck | 336:1e18a06a987b | 41 | bool InterruptManager::must_replace_vector(IRQn_Type irq) { |
dudmuck | 336:1e18a06a987b | 42 | int irq_pos = get_irq_index(irq); |
dudmuck | 336:1e18a06a987b | 43 | |
dudmuck | 336:1e18a06a987b | 44 | if (NULL == _chains[irq_pos]) { |
dudmuck | 336:1e18a06a987b | 45 | _chains[irq_pos] = new CallChain(CHAIN_INITIAL_SIZE); |
dudmuck | 336:1e18a06a987b | 46 | _chains[irq_pos]->add((pvoidf)NVIC_GetVector(irq)); |
dudmuck | 336:1e18a06a987b | 47 | return true; |
dudmuck | 336:1e18a06a987b | 48 | } |
dudmuck | 336:1e18a06a987b | 49 | return false; |
dudmuck | 336:1e18a06a987b | 50 | } |
dudmuck | 336:1e18a06a987b | 51 | |
dudmuck | 336:1e18a06a987b | 52 | pFunctionPointer_t InterruptManager::add_common(void (*function)(void), IRQn_Type irq, bool front) { |
dudmuck | 336:1e18a06a987b | 53 | int irq_pos = get_irq_index(irq); |
dudmuck | 336:1e18a06a987b | 54 | bool change = must_replace_vector(irq); |
dudmuck | 336:1e18a06a987b | 55 | |
dudmuck | 336:1e18a06a987b | 56 | pFunctionPointer_t pf = front ? _chains[irq_pos]->add_front(function) : _chains[irq_pos]->add(function); |
dudmuck | 336:1e18a06a987b | 57 | if (change) |
dudmuck | 336:1e18a06a987b | 58 | NVIC_SetVector(irq, (uint32_t)&InterruptManager::static_irq_helper); |
dudmuck | 336:1e18a06a987b | 59 | return pf; |
dudmuck | 336:1e18a06a987b | 60 | } |
dudmuck | 336:1e18a06a987b | 61 | |
dudmuck | 336:1e18a06a987b | 62 | bool InterruptManager::remove_handler(pFunctionPointer_t handler, IRQn_Type irq) { |
dudmuck | 336:1e18a06a987b | 63 | int irq_pos = get_irq_index(irq); |
dudmuck | 336:1e18a06a987b | 64 | |
dudmuck | 336:1e18a06a987b | 65 | if (NULL == _chains[irq_pos]) |
dudmuck | 336:1e18a06a987b | 66 | return false; |
dudmuck | 336:1e18a06a987b | 67 | if (!_chains[irq_pos]->remove(handler)) |
dudmuck | 336:1e18a06a987b | 68 | return false; |
dudmuck | 336:1e18a06a987b | 69 | // If there's a single function left in the chain, swith the interrupt vector |
dudmuck | 336:1e18a06a987b | 70 | // to call that function directly. This way we save both time and space. |
dudmuck | 336:1e18a06a987b | 71 | if (_chains[irq_pos]->size() == 1 && NULL != _chains[irq_pos]->get(0)->get_function()) { |
dudmuck | 336:1e18a06a987b | 72 | NVIC_SetVector(irq, (uint32_t)_chains[irq_pos]->get(0)->get_function()); |
dudmuck | 336:1e18a06a987b | 73 | delete _chains[irq_pos]; |
dudmuck | 336:1e18a06a987b | 74 | _chains[irq_pos] = (CallChain*) NULL; |
dudmuck | 336:1e18a06a987b | 75 | } |
dudmuck | 336:1e18a06a987b | 76 | return true; |
dudmuck | 336:1e18a06a987b | 77 | } |
dudmuck | 336:1e18a06a987b | 78 | |
dudmuck | 336:1e18a06a987b | 79 | void InterruptManager::irq_helper() { |
dudmuck | 336:1e18a06a987b | 80 | _chains[__get_IPSR()]->call(); |
dudmuck | 336:1e18a06a987b | 81 | } |
dudmuck | 336:1e18a06a987b | 82 | |
dudmuck | 336:1e18a06a987b | 83 | int InterruptManager::get_irq_index(IRQn_Type irq) { |
dudmuck | 336:1e18a06a987b | 84 | return (int)irq + NVIC_USER_IRQ_OFFSET; |
dudmuck | 336:1e18a06a987b | 85 | } |
dudmuck | 336:1e18a06a987b | 86 | |
dudmuck | 336:1e18a06a987b | 87 | void InterruptManager::static_irq_helper() { |
dudmuck | 336:1e18a06a987b | 88 | InterruptManager::get()->irq_helper(); |
dudmuck | 336:1e18a06a987b | 89 | } |
dudmuck | 336:1e18a06a987b | 90 | |
dudmuck | 336:1e18a06a987b | 91 | } // namespace mbed |
dudmuck | 336:1e18a06a987b | 92 | |
dudmuck | 336:1e18a06a987b | 93 | #endif |