mbed-dev library fork for STM32F100R6 microcontroller (LQFP64, 24MHz, 32kB flash, 4kB ram, 2-channel DAC, HDMI CEC, very cheap) . Use in online compiler (instead mbed library) with selected platform Nucleo F103RB.
Fork of mbed-dev by
Tested and working:
- blink
- system frequency 24Mhz (with external xtal 8Mhz)
- stdio uart on pins PA_2-PA_3
- Serial on pins PA_9-PA_10
- AnalogOut on pins PA_4, PA_5 (DAC)
- AnalogIn on pins PA_0, PA_1, PA_2, PA_3, PA_4, PA_5, PA_6, PA_7, PB_0, PB_1, PC_0, PC_1, PC_2, PC_3, PC_5, PC_5
Notes:
- TIM2 is used for mbed needs (eq Timer, Ticker, wait etc. )
Simple test program:Import programtestF100R6
simple tests for STM32F100R6 microcontroller with dedicated library
Diff: common/InterruptManager.cpp
- Revision:
- 0:9b334a45a8ff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/common/InterruptManager.cpp Thu Oct 01 15:25:22 2015 +0300 @@ -0,0 +1,93 @@ +#include "cmsis.h" +#if defined(NVIC_NUM_VECTORS) + +#include "InterruptManager.h" +#include <string.h> + +#define CHAIN_INITIAL_SIZE 4 + +namespace mbed { + +typedef void (*pvoidf)(void); + +InterruptManager* InterruptManager::_instance = (InterruptManager*)NULL; + +InterruptManager* InterruptManager::get() { + if (NULL == _instance) + _instance = new InterruptManager(); + return _instance; +} + +InterruptManager::InterruptManager() { + memset(_chains, 0, NVIC_NUM_VECTORS * sizeof(CallChain*)); +} + +void InterruptManager::destroy() { + // Not a good idea to call this unless NO interrupt at all + // is under the control of the handler; otherwise, a system crash + // is very likely to occur + if (NULL != _instance) { + delete _instance; + _instance = (InterruptManager*)NULL; + } +} + +InterruptManager::~InterruptManager() { + for(int i = 0; i < NVIC_NUM_VECTORS; i++) + if (NULL != _chains[i]) + delete _chains[i]; +} + +bool InterruptManager::must_replace_vector(IRQn_Type irq) { + int irq_pos = get_irq_index(irq); + + if (NULL == _chains[irq_pos]) { + _chains[irq_pos] = new CallChain(CHAIN_INITIAL_SIZE); + _chains[irq_pos]->add((pvoidf)NVIC_GetVector(irq)); + return true; + } + return false; +} + +pFunctionPointer_t InterruptManager::add_common(void (*function)(void), IRQn_Type irq, bool front) { + int irq_pos = get_irq_index(irq); + bool change = must_replace_vector(irq); + + pFunctionPointer_t pf = front ? _chains[irq_pos]->add_front(function) : _chains[irq_pos]->add(function); + if (change) + NVIC_SetVector(irq, (uint32_t)&InterruptManager::static_irq_helper); + return pf; +} + +bool InterruptManager::remove_handler(pFunctionPointer_t handler, IRQn_Type irq) { + int irq_pos = get_irq_index(irq); + + if (NULL == _chains[irq_pos]) + return false; + if (!_chains[irq_pos]->remove(handler)) + return false; + // If there's a single function left in the chain, swith the interrupt vector + // to call that function directly. This way we save both time and space. + if (_chains[irq_pos]->size() == 1 && NULL != _chains[irq_pos]->get(0)->get_function()) { + NVIC_SetVector(irq, (uint32_t)_chains[irq_pos]->get(0)->get_function()); + delete _chains[irq_pos]; + _chains[irq_pos] = (CallChain*) NULL; + } + return true; +} + +void InterruptManager::irq_helper() { + _chains[__get_IPSR()]->call(); +} + +int InterruptManager::get_irq_index(IRQn_Type irq) { + return (int)irq + NVIC_USER_IRQ_OFFSET; +} + +void InterruptManager::static_irq_helper() { + InterruptManager::get()->irq_helper(); +} + +} // namespace mbed + +#endif