mbed library sources

Dependents:   Encrypted my_mbed lklk CyaSSL_DTLS_Cellular ... more

Superseded

This library was superseded by mbed-dev - https://os.mbed.com/users/mbed_official/code/mbed-dev/.

Development branch of the mbed library sources. This library is kept in synch with the latest changes from the mbed SDK and it is not guaranteed to work.

If you are looking for a stable and tested release, please import one of the official mbed library releases:

Import librarymbed

The official Mbed 2 C/C++ SDK provides the software platform and libraries to build your applications.

Committer:
mbed_official
Date:
Wed Sep 30 17:00:09 2015 +0100
Revision:
635:a11c0372f0ba
Parent:
390:35c2c1cf29cd
Synchronized with git revision d29c98dae61be0946ddf3a3c641c7726056f9452

Full URL: https://github.com/mbedmicro/mbed/commit/d29c98dae61be0946ddf3a3c641c7726056f9452/

Added support for SAMW25

Who changed what in which revision?

UserRevisionLine numberNew contents of line
mbed_official 390:35c2c1cf29cd 1 #include "cmsis.h"
mbed_official 390:35c2c1cf29cd 2 #if defined(NVIC_NUM_VECTORS)
mbed_official 390:35c2c1cf29cd 3
bogdanm 15:4892fe388435 4 #include "InterruptManager.h"
bogdanm 15:4892fe388435 5 #include <string.h>
bogdanm 15:4892fe388435 6
bogdanm 15:4892fe388435 7 #define CHAIN_INITIAL_SIZE 4
bogdanm 15:4892fe388435 8
bogdanm 15:4892fe388435 9 namespace mbed {
bogdanm 15:4892fe388435 10
bogdanm 15:4892fe388435 11 typedef void (*pvoidf)(void);
bogdanm 15:4892fe388435 12
mbed_official 262:85569914dbe0 13 InterruptManager* InterruptManager::_instance = (InterruptManager*)NULL;
bogdanm 15:4892fe388435 14
bogdanm 15:4892fe388435 15 InterruptManager* InterruptManager::get() {
bogdanm 15:4892fe388435 16 if (NULL == _instance)
bogdanm 15:4892fe388435 17 _instance = new InterruptManager();
bogdanm 15:4892fe388435 18 return _instance;
bogdanm 15:4892fe388435 19 }
bogdanm 15:4892fe388435 20
bogdanm 15:4892fe388435 21 InterruptManager::InterruptManager() {
bogdanm 15:4892fe388435 22 memset(_chains, 0, NVIC_NUM_VECTORS * sizeof(CallChain*));
bogdanm 15:4892fe388435 23 }
bogdanm 15:4892fe388435 24
bogdanm 15:4892fe388435 25 void InterruptManager::destroy() {
bogdanm 15:4892fe388435 26 // Not a good idea to call this unless NO interrupt at all
bogdanm 15:4892fe388435 27 // is under the control of the handler; otherwise, a system crash
bogdanm 15:4892fe388435 28 // is very likely to occur
bogdanm 15:4892fe388435 29 if (NULL != _instance) {
bogdanm 15:4892fe388435 30 delete _instance;
mbed_official 262:85569914dbe0 31 _instance = (InterruptManager*)NULL;
bogdanm 15:4892fe388435 32 }
bogdanm 15:4892fe388435 33 }
bogdanm 15:4892fe388435 34
bogdanm 15:4892fe388435 35 InterruptManager::~InterruptManager() {
bogdanm 15:4892fe388435 36 for(int i = 0; i < NVIC_NUM_VECTORS; i++)
bogdanm 15:4892fe388435 37 if (NULL != _chains[i])
bogdanm 15:4892fe388435 38 delete _chains[i];
bogdanm 15:4892fe388435 39 }
bogdanm 15:4892fe388435 40
bogdanm 15:4892fe388435 41 bool InterruptManager::must_replace_vector(IRQn_Type irq) {
bogdanm 15:4892fe388435 42 int irq_pos = get_irq_index(irq);
bogdanm 15:4892fe388435 43
bogdanm 15:4892fe388435 44 if (NULL == _chains[irq_pos]) {
bogdanm 15:4892fe388435 45 _chains[irq_pos] = new CallChain(CHAIN_INITIAL_SIZE);
bogdanm 15:4892fe388435 46 _chains[irq_pos]->add((pvoidf)NVIC_GetVector(irq));
bogdanm 15:4892fe388435 47 return true;
bogdanm 15:4892fe388435 48 }
bogdanm 15:4892fe388435 49 return false;
bogdanm 15:4892fe388435 50 }
bogdanm 15:4892fe388435 51
bogdanm 15:4892fe388435 52 pFunctionPointer_t InterruptManager::add_common(void (*function)(void), IRQn_Type irq, bool front) {
bogdanm 15:4892fe388435 53 int irq_pos = get_irq_index(irq);
bogdanm 15:4892fe388435 54 bool change = must_replace_vector(irq);
bogdanm 15:4892fe388435 55
bogdanm 15:4892fe388435 56 pFunctionPointer_t pf = front ? _chains[irq_pos]->add_front(function) : _chains[irq_pos]->add(function);
bogdanm 15:4892fe388435 57 if (change)
bogdanm 15:4892fe388435 58 NVIC_SetVector(irq, (uint32_t)&InterruptManager::static_irq_helper);
bogdanm 15:4892fe388435 59 return pf;
bogdanm 15:4892fe388435 60 }
bogdanm 15:4892fe388435 61
bogdanm 15:4892fe388435 62 bool InterruptManager::remove_handler(pFunctionPointer_t handler, IRQn_Type irq) {
bogdanm 15:4892fe388435 63 int irq_pos = get_irq_index(irq);
mbed_official 221:8276e3a4886f 64
bogdanm 15:4892fe388435 65 if (NULL == _chains[irq_pos])
bogdanm 15:4892fe388435 66 return false;
bogdanm 15:4892fe388435 67 if (!_chains[irq_pos]->remove(handler))
bogdanm 15:4892fe388435 68 return false;
bogdanm 15:4892fe388435 69 // If there's a single function left in the chain, swith the interrupt vector
bogdanm 15:4892fe388435 70 // to call that function directly. This way we save both time and space.
bogdanm 15:4892fe388435 71 if (_chains[irq_pos]->size() == 1 && NULL != _chains[irq_pos]->get(0)->get_function()) {
bogdanm 15:4892fe388435 72 NVIC_SetVector(irq, (uint32_t)_chains[irq_pos]->get(0)->get_function());
bogdanm 15:4892fe388435 73 delete _chains[irq_pos];
mbed_official 262:85569914dbe0 74 _chains[irq_pos] = (CallChain*) NULL;
bogdanm 15:4892fe388435 75 }
bogdanm 15:4892fe388435 76 return true;
bogdanm 15:4892fe388435 77 }
bogdanm 15:4892fe388435 78
bogdanm 15:4892fe388435 79 void InterruptManager::irq_helper() {
bogdanm 15:4892fe388435 80 _chains[__get_IPSR()]->call();
bogdanm 15:4892fe388435 81 }
bogdanm 15:4892fe388435 82
bogdanm 15:4892fe388435 83 int InterruptManager::get_irq_index(IRQn_Type irq) {
bogdanm 15:4892fe388435 84 return (int)irq + NVIC_USER_IRQ_OFFSET;
bogdanm 15:4892fe388435 85 }
bogdanm 15:4892fe388435 86
bogdanm 15:4892fe388435 87 void InterruptManager::static_irq_helper() {
bogdanm 15:4892fe388435 88 InterruptManager::get()->irq_helper();
bogdanm 15:4892fe388435 89 }
bogdanm 15:4892fe388435 90
bogdanm 15:4892fe388435 91 } // namespace mbed
bogdanm 15:4892fe388435 92
mbed_official 390:35c2c1cf29cd 93 #endif