mbed library sources. Supersedes mbed-src. Fixes analogIn and analogOut problems for TARGET_STM32F3. Tested on NUCLEO-F303K8, using 3 analogout and 7 analogin channels simultaneously. Added ability for STM32F334R8 and STM32F303K8 to use all three channels of DAC simultaneously. https://developer.mbed.org/users/StevieWray/code/mbed-dev/ Added ability for TARGET_STM32F3 to use more than one ADC simultaneously. https://developer.mbed.org/questions/67997/NUCLEO-F303K8ADC/

Fork of mbed-dev by mbed official

Committer:
neurofun
Date:
Tue Feb 23 21:59:35 2016 +0000
Revision:
70:b3a5af880266
Parent:
0:9b334a45a8ff
Edited DAC routines to allow for the simultaneous use of three channels from two DACs as seen on the STM32F334R8 and STM32F303K8. Edited ADC routines to allow for the simultaneous use of more than one ADC.

Who changed what in which revision?

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