Modification of mbed-src library only for STM32F030F4, very cheap microcontroller in 20-Pin TSSOP package, with 16Kbytes of Flash and 4Kbytes of Ram. **Target for online compilator must be Nucleo 32F030R8.** 01.02.2018 Acosinwork: Fork of mbed-STM32F030F4 library. Support for Troyka GPIO expander by Amperka. http://amperka.ru/product/troyka-gpio-expander

Fork of mbed-STM32F030F4 by Nothing Special

Committer:
acosinwork
Date:
Thu Feb 01 10:37:10 2018 +0000
Revision:
12:6f07dd7cbe47
Parent:
0:38ccae254a29
Change pin mapping and set internall oscillator as default. Fork to support Troyka GPIO expander (I2C I/O); http://amperka.ru/product/troyka-gpio-expander

Who changed what in which revision?

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