added prescaler for 16 bit pwm in LPC1347 target

Fork of mbed-dev by mbed official

Committer:
JojoS
Date:
Sat Sep 10 15:32:04 2016 +0000
Revision:
147:ba84b7dc41a7
Parent:
144:ef7eb2e8f9f7
added prescaler for 16 bit timers (solution as in LPC11xx), default prescaler 31 for max 28 ms period time

Who changed what in which revision?

UserRevisionLine numberNew contents of line
<> 144:ef7eb2e8f9f7 1 #include "cmsis.h"
<> 144:ef7eb2e8f9f7 2 #if defined(NVIC_NUM_VECTORS)
<> 144:ef7eb2e8f9f7 3
<> 144:ef7eb2e8f9f7 4 #include "InterruptManager.h"
<> 144:ef7eb2e8f9f7 5 #include "critical.h"
<> 144:ef7eb2e8f9f7 6 #include <string.h>
<> 144:ef7eb2e8f9f7 7
<> 144:ef7eb2e8f9f7 8 #define CHAIN_INITIAL_SIZE 4
<> 144:ef7eb2e8f9f7 9
<> 144:ef7eb2e8f9f7 10 namespace mbed {
<> 144:ef7eb2e8f9f7 11
<> 144:ef7eb2e8f9f7 12 typedef void (*pvoidf)(void);
<> 144:ef7eb2e8f9f7 13
<> 144:ef7eb2e8f9f7 14 InterruptManager* InterruptManager::_instance = (InterruptManager*)NULL;
<> 144:ef7eb2e8f9f7 15
<> 144:ef7eb2e8f9f7 16 InterruptManager* InterruptManager::get() {
<> 144:ef7eb2e8f9f7 17
<> 144:ef7eb2e8f9f7 18 if (NULL == _instance) {
<> 144:ef7eb2e8f9f7 19 InterruptManager* temp = new InterruptManager();
<> 144:ef7eb2e8f9f7 20
<> 144:ef7eb2e8f9f7 21 // Atomically set _instance
<> 144:ef7eb2e8f9f7 22 core_util_critical_section_enter();
<> 144:ef7eb2e8f9f7 23 if (NULL == _instance) {
<> 144:ef7eb2e8f9f7 24 _instance = temp;
<> 144:ef7eb2e8f9f7 25 }
<> 144:ef7eb2e8f9f7 26 core_util_critical_section_exit();
<> 144:ef7eb2e8f9f7 27
<> 144:ef7eb2e8f9f7 28 // Another thread got there first so delete ours
<> 144:ef7eb2e8f9f7 29 if (temp != _instance) {
<> 144:ef7eb2e8f9f7 30 delete temp;
<> 144:ef7eb2e8f9f7 31 }
<> 144:ef7eb2e8f9f7 32
<> 144:ef7eb2e8f9f7 33 }
<> 144:ef7eb2e8f9f7 34 return _instance;
<> 144:ef7eb2e8f9f7 35 }
<> 144:ef7eb2e8f9f7 36
<> 144:ef7eb2e8f9f7 37 InterruptManager::InterruptManager() {
<> 144:ef7eb2e8f9f7 38 // No mutex needed in constructor
<> 144:ef7eb2e8f9f7 39 memset(_chains, 0, NVIC_NUM_VECTORS * sizeof(CallChain*));
<> 144:ef7eb2e8f9f7 40 }
<> 144:ef7eb2e8f9f7 41
<> 144:ef7eb2e8f9f7 42 void InterruptManager::destroy() {
<> 144:ef7eb2e8f9f7 43 // Not a good idea to call this unless NO interrupt at all
<> 144:ef7eb2e8f9f7 44 // is under the control of the handler; otherwise, a system crash
<> 144:ef7eb2e8f9f7 45 // is very likely to occur
<> 144:ef7eb2e8f9f7 46 if (NULL != _instance) {
<> 144:ef7eb2e8f9f7 47 delete _instance;
<> 144:ef7eb2e8f9f7 48 _instance = (InterruptManager*)NULL;
<> 144:ef7eb2e8f9f7 49 }
<> 144:ef7eb2e8f9f7 50 }
<> 144:ef7eb2e8f9f7 51
<> 144:ef7eb2e8f9f7 52 InterruptManager::~InterruptManager() {
<> 144:ef7eb2e8f9f7 53 for(int i = 0; i < NVIC_NUM_VECTORS; i++)
<> 144:ef7eb2e8f9f7 54 if (NULL != _chains[i])
<> 144:ef7eb2e8f9f7 55 delete _chains[i];
<> 144:ef7eb2e8f9f7 56 }
<> 144:ef7eb2e8f9f7 57
<> 144:ef7eb2e8f9f7 58 bool InterruptManager::must_replace_vector(IRQn_Type irq) {
<> 144:ef7eb2e8f9f7 59 lock();
<> 144:ef7eb2e8f9f7 60
<> 144:ef7eb2e8f9f7 61 int ret = false;
<> 144:ef7eb2e8f9f7 62 int irq_pos = get_irq_index(irq);
<> 144:ef7eb2e8f9f7 63 if (NULL == _chains[irq_pos]) {
<> 144:ef7eb2e8f9f7 64 _chains[irq_pos] = new CallChain(CHAIN_INITIAL_SIZE);
<> 144:ef7eb2e8f9f7 65 _chains[irq_pos]->add((pvoidf)NVIC_GetVector(irq));
<> 144:ef7eb2e8f9f7 66 ret = true;
<> 144:ef7eb2e8f9f7 67 }
<> 144:ef7eb2e8f9f7 68 unlock();
<> 144:ef7eb2e8f9f7 69 return ret;
<> 144:ef7eb2e8f9f7 70 }
<> 144:ef7eb2e8f9f7 71
<> 144:ef7eb2e8f9f7 72 pFunctionPointer_t InterruptManager::add_common(void (*function)(void), IRQn_Type irq, bool front) {
<> 144:ef7eb2e8f9f7 73 lock();
<> 144:ef7eb2e8f9f7 74 int irq_pos = get_irq_index(irq);
<> 144:ef7eb2e8f9f7 75 bool change = must_replace_vector(irq);
<> 144:ef7eb2e8f9f7 76
<> 144:ef7eb2e8f9f7 77 pFunctionPointer_t pf = front ? _chains[irq_pos]->add_front(function) : _chains[irq_pos]->add(function);
<> 144:ef7eb2e8f9f7 78 if (change)
<> 144:ef7eb2e8f9f7 79 NVIC_SetVector(irq, (uint32_t)&InterruptManager::static_irq_helper);
<> 144:ef7eb2e8f9f7 80 unlock();
<> 144:ef7eb2e8f9f7 81 return pf;
<> 144:ef7eb2e8f9f7 82 }
<> 144:ef7eb2e8f9f7 83
<> 144:ef7eb2e8f9f7 84 bool InterruptManager::remove_handler(pFunctionPointer_t handler, IRQn_Type irq) {
<> 144:ef7eb2e8f9f7 85 int irq_pos = get_irq_index(irq);
<> 144:ef7eb2e8f9f7 86 bool ret = false;
<> 144:ef7eb2e8f9f7 87
<> 144:ef7eb2e8f9f7 88 lock();
<> 144:ef7eb2e8f9f7 89 if (_chains[irq_pos] != NULL) {
<> 144:ef7eb2e8f9f7 90 if (_chains[irq_pos]->remove(handler)) {
<> 144:ef7eb2e8f9f7 91 ret = true;
<> 144:ef7eb2e8f9f7 92 }
<> 144:ef7eb2e8f9f7 93 }
<> 144:ef7eb2e8f9f7 94 unlock();
<> 144:ef7eb2e8f9f7 95
<> 144:ef7eb2e8f9f7 96 return ret;
<> 144:ef7eb2e8f9f7 97 }
<> 144:ef7eb2e8f9f7 98
<> 144:ef7eb2e8f9f7 99 void InterruptManager::irq_helper() {
<> 144:ef7eb2e8f9f7 100 _chains[__get_IPSR()]->call();
<> 144:ef7eb2e8f9f7 101 }
<> 144:ef7eb2e8f9f7 102
<> 144:ef7eb2e8f9f7 103 int InterruptManager::get_irq_index(IRQn_Type irq) {
<> 144:ef7eb2e8f9f7 104 // Pure function - no lock needed
<> 144:ef7eb2e8f9f7 105 return (int)irq + NVIC_USER_IRQ_OFFSET;
<> 144:ef7eb2e8f9f7 106 }
<> 144:ef7eb2e8f9f7 107
<> 144:ef7eb2e8f9f7 108 void InterruptManager::static_irq_helper() {
<> 144:ef7eb2e8f9f7 109 InterruptManager::get()->irq_helper();
<> 144:ef7eb2e8f9f7 110 }
<> 144:ef7eb2e8f9f7 111
<> 144:ef7eb2e8f9f7 112 void InterruptManager::lock() {
<> 144:ef7eb2e8f9f7 113 _mutex.lock();
<> 144:ef7eb2e8f9f7 114 }
<> 144:ef7eb2e8f9f7 115
<> 144:ef7eb2e8f9f7 116 void InterruptManager::unlock() {
<> 144:ef7eb2e8f9f7 117 _mutex.unlock();
<> 144:ef7eb2e8f9f7 118 }
<> 144:ef7eb2e8f9f7 119
<> 144:ef7eb2e8f9f7 120 } // namespace mbed
<> 144:ef7eb2e8f9f7 121
<> 144:ef7eb2e8f9f7 122 #endif