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:
64:41a834223ea3
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
mbed_official 15:a81a8d6c1dfe 1 /* mbed Microcontroller Library
mbed_official 15:a81a8d6c1dfe 2 * Copyright (c) 2006-2015 ARM Limited
mbed_official 15:a81a8d6c1dfe 3 *
mbed_official 15:a81a8d6c1dfe 4 * Licensed under the Apache License, Version 2.0 (the "License");
mbed_official 15:a81a8d6c1dfe 5 * you may not use this file except in compliance with the License.
mbed_official 15:a81a8d6c1dfe 6 * You may obtain a copy of the License at
mbed_official 15:a81a8d6c1dfe 7 *
mbed_official 15:a81a8d6c1dfe 8 * http://www.apache.org/licenses/LICENSE-2.0
mbed_official 15:a81a8d6c1dfe 9 *
mbed_official 15:a81a8d6c1dfe 10 * Unless required by applicable law or agreed to in writing, software
mbed_official 15:a81a8d6c1dfe 11 * distributed under the License is distributed on an "AS IS" BASIS,
mbed_official 15:a81a8d6c1dfe 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
mbed_official 15:a81a8d6c1dfe 13 * See the License for the specific language governing permissions and
mbed_official 15:a81a8d6c1dfe 14 * limitations under the License.
mbed_official 15:a81a8d6c1dfe 15 */
mbed_official 15:a81a8d6c1dfe 16 #include <stddef.h>
mbed_official 15:a81a8d6c1dfe 17 #include "us_ticker_api.h"
mbed_official 15:a81a8d6c1dfe 18 #include "cmsis.h"
mbed_official 15:a81a8d6c1dfe 19 #include "mbed_assert.h"
mbed_official 15:a81a8d6c1dfe 20 #include "ins_gclk.h"
mbed_official 15:a81a8d6c1dfe 21 #include "compiler.h"
mbed_official 15:a81a8d6c1dfe 22 #include "system.h"
mbed_official 15:a81a8d6c1dfe 23 #include "tc.h"
mbed_official 15:a81a8d6c1dfe 24 #include "tc_interrupt.h"
mbed_official 15:a81a8d6c1dfe 25
mbed_official 18:da299f395b9e 26 #if (SAMD21) || (SAMR21)
mbed_official 15:a81a8d6c1dfe 27 #define TICKER_COUNTER_uS TC4
mbed_official 15:a81a8d6c1dfe 28 #define TICKER_COUNTER_IRQn TC4_IRQn
mbed_official 15:a81a8d6c1dfe 29 #define TICKER_COUNTER_Handlr TC4_Handler
mbed_official 18:da299f395b9e 30 #elif (SAML21) /*SAML21 TCC4 does not support 32 bit counter operations*/
mbed_official 18:da299f395b9e 31 #define TICKER_COUNTER_uS TC0
mbed_official 18:da299f395b9e 32 #define TICKER_COUNTER_IRQn TC0_IRQn
mbed_official 18:da299f395b9e 33 #define TICKER_COUNTER_Handlr TC0_Handler
mbed_official 18:da299f395b9e 34 #endif
mbed_official 15:a81a8d6c1dfe 35
mbed_official 15:a81a8d6c1dfe 36 static int us_ticker_inited = 0;
mbed_official 15:a81a8d6c1dfe 37 extern uint8_t g_sys_init;
mbed_official 15:a81a8d6c1dfe 38
mbed_official 15:a81a8d6c1dfe 39 struct tc_module us_ticker_module;
mbed_official 15:a81a8d6c1dfe 40
mbed_official 15:a81a8d6c1dfe 41
mbed_official 15:a81a8d6c1dfe 42 static inline void tc_clear_interrupt(
mbed_official 15:a81a8d6c1dfe 43 struct tc_module *const module,
mbed_official 15:a81a8d6c1dfe 44 const enum tc_callback callback_type)
mbed_official 15:a81a8d6c1dfe 45 {
mbed_official 15:a81a8d6c1dfe 46 /* Sanity check arguments */
mbed_official 15:a81a8d6c1dfe 47 MBED_ASSERT(module);
mbed_official 15:a81a8d6c1dfe 48
mbed_official 15:a81a8d6c1dfe 49 /* Clear interrupt flags */
mbed_official 15:a81a8d6c1dfe 50 if (callback_type == TC_CALLBACK_CC_CHANNEL0) {
mbed_official 15:a81a8d6c1dfe 51 module->hw->COUNT8.INTENCLR.reg = TC_INTFLAG_MC(1);
mbed_official 15:a81a8d6c1dfe 52 } else if (callback_type == TC_CALLBACK_CC_CHANNEL1) {
mbed_official 15:a81a8d6c1dfe 53 module->hw->COUNT8.INTENCLR.reg = TC_INTFLAG_MC(2);
mbed_official 15:a81a8d6c1dfe 54 } else {
mbed_official 15:a81a8d6c1dfe 55 module->hw->COUNT8.INTENCLR.reg = (1 << callback_type);
mbed_official 15:a81a8d6c1dfe 56 }
mbed_official 15:a81a8d6c1dfe 57 }
mbed_official 15:a81a8d6c1dfe 58
mbed_official 15:a81a8d6c1dfe 59 void us_ticker_irq_handler_internal(struct tc_module* us_tc_module)
mbed_official 15:a81a8d6c1dfe 60 {
mbed_official 15:a81a8d6c1dfe 61 uint32_t status_flags;
mbed_official 15:a81a8d6c1dfe 62
mbed_official 15:a81a8d6c1dfe 63 /* Clear TC capture overflow and TC count overflow */
mbed_official 15:a81a8d6c1dfe 64 status_flags = TC_STATUS_CAPTURE_OVERFLOW | TC_STATUS_COUNT_OVERFLOW;
mbed_official 15:a81a8d6c1dfe 65 tc_clear_status(&us_ticker_module, status_flags);
mbed_official 15:a81a8d6c1dfe 66
mbed_official 15:a81a8d6c1dfe 67 us_ticker_irq_handler();
mbed_official 15:a81a8d6c1dfe 68 }
mbed_official 15:a81a8d6c1dfe 69
mbed_official 15:a81a8d6c1dfe 70 void us_ticker_init(void)
mbed_official 15:a81a8d6c1dfe 71 {
mbed_official 15:a81a8d6c1dfe 72 uint32_t cycles_per_us;
mbed_official 15:a81a8d6c1dfe 73 uint32_t prescaler = 0;
mbed_official 15:a81a8d6c1dfe 74 struct tc_config config_tc;
mbed_official 15:a81a8d6c1dfe 75
mbed_official 15:a81a8d6c1dfe 76 if (us_ticker_inited) return;
mbed_official 15:a81a8d6c1dfe 77 us_ticker_inited = 1;
mbed_official 15:a81a8d6c1dfe 78
mbed_official 15:a81a8d6c1dfe 79 if (g_sys_init == 0) {
mbed_official 15:a81a8d6c1dfe 80 system_init();
mbed_official 15:a81a8d6c1dfe 81 g_sys_init = 1;
mbed_official 15:a81a8d6c1dfe 82 }
mbed_official 15:a81a8d6c1dfe 83
mbed_official 15:a81a8d6c1dfe 84 tc_get_config_defaults(&config_tc);
mbed_official 15:a81a8d6c1dfe 85
mbed_official 15:a81a8d6c1dfe 86 cycles_per_us = system_gclk_gen_get_hz(config_tc.clock_source) / 1000000;
mbed_official 15:a81a8d6c1dfe 87 MBED_ASSERT(cycles_per_us > 0);
mbed_official 15:a81a8d6c1dfe 88 /*while((cycles_per_us & 1) == 0 && prescaler <= 10) {
mbed_official 15:a81a8d6c1dfe 89 cycles_per_us = cycles_per_us >> 1;
mbed_official 15:a81a8d6c1dfe 90 prescaler++;
mbed_official 15:a81a8d6c1dfe 91 }*/
mbed_official 15:a81a8d6c1dfe 92 while((cycles_per_us > 1) && (prescaler <= 10)) {
mbed_official 15:a81a8d6c1dfe 93 cycles_per_us = cycles_per_us >> 1;
mbed_official 15:a81a8d6c1dfe 94 prescaler++;
mbed_official 15:a81a8d6c1dfe 95 }
mbed_official 15:a81a8d6c1dfe 96 if (prescaler >= 9) {
mbed_official 15:a81a8d6c1dfe 97 prescaler = 7;
mbed_official 15:a81a8d6c1dfe 98 } else if (prescaler >= 7) {
mbed_official 15:a81a8d6c1dfe 99 prescaler = 6;
mbed_official 15:a81a8d6c1dfe 100 } else if (prescaler >= 5) {
mbed_official 15:a81a8d6c1dfe 101 prescaler = 5;
mbed_official 15:a81a8d6c1dfe 102 }
mbed_official 15:a81a8d6c1dfe 103
mbed_official 64:41a834223ea3 104 config_tc.clock_prescaler = (enum tc_clock_prescaler)TC_CTRLA_PRESCALER(prescaler);
mbed_official 15:a81a8d6c1dfe 105 config_tc.counter_size = TC_COUNTER_SIZE_32BIT;
mbed_official 15:a81a8d6c1dfe 106 config_tc.run_in_standby = true;
mbed_official 15:a81a8d6c1dfe 107 config_tc.counter_32_bit.value = 0;
mbed_official 15:a81a8d6c1dfe 108 config_tc.counter_32_bit.compare_capture_channel[TC_COMPARE_CAPTURE_CHANNEL_0] = 0xFFFFFFFF;
mbed_official 15:a81a8d6c1dfe 109
mbed_official 15:a81a8d6c1dfe 110 /* Initialize the timer */
mbed_official 64:41a834223ea3 111 tc_init(&us_ticker_module, TICKER_COUNTER_uS, &config_tc);
mbed_official 15:a81a8d6c1dfe 112
mbed_official 15:a81a8d6c1dfe 113 /* Register callback function */
mbed_official 15:a81a8d6c1dfe 114 tc_register_callback(&us_ticker_module, (tc_callback_t)us_ticker_irq_handler_internal, TC_CALLBACK_CC_CHANNEL0);
mbed_official 15:a81a8d6c1dfe 115
mbed_official 15:a81a8d6c1dfe 116 /* Enable the timer module */
mbed_official 15:a81a8d6c1dfe 117 tc_enable(&us_ticker_module);
mbed_official 15:a81a8d6c1dfe 118 }
mbed_official 15:a81a8d6c1dfe 119
mbed_official 15:a81a8d6c1dfe 120 uint32_t us_ticker_read()
mbed_official 15:a81a8d6c1dfe 121 {
mbed_official 15:a81a8d6c1dfe 122 if (!us_ticker_inited)
mbed_official 15:a81a8d6c1dfe 123 us_ticker_init();
mbed_official 15:a81a8d6c1dfe 124
mbed_official 15:a81a8d6c1dfe 125 return tc_get_count_value(&us_ticker_module);
mbed_official 15:a81a8d6c1dfe 126 }
mbed_official 15:a81a8d6c1dfe 127
mbed_official 15:a81a8d6c1dfe 128 void us_ticker_set_interrupt(timestamp_t timestamp)
mbed_official 15:a81a8d6c1dfe 129 {
mbed_official 15:a81a8d6c1dfe 130 uint32_t cur_time;
mbed_official 15:a81a8d6c1dfe 131 int32_t delta;
mbed_official 15:a81a8d6c1dfe 132
mbed_official 15:a81a8d6c1dfe 133 cur_time = us_ticker_read();
mbed_official 15:a81a8d6c1dfe 134 delta = (int32_t)((uint32_t)timestamp - cur_time);
mbed_official 15:a81a8d6c1dfe 135 if (delta < 0) {
mbed_official 15:a81a8d6c1dfe 136 /* Event already occurred in past */
mbed_official 15:a81a8d6c1dfe 137 us_ticker_irq_handler();
mbed_official 15:a81a8d6c1dfe 138 return;
mbed_official 15:a81a8d6c1dfe 139 }
mbed_official 15:a81a8d6c1dfe 140
mbed_official 15:a81a8d6c1dfe 141 NVIC_DisableIRQ(TICKER_COUNTER_IRQn);
mbed_official 15:a81a8d6c1dfe 142 NVIC_SetVector(TICKER_COUNTER_IRQn, (uint32_t)TICKER_COUNTER_Handlr);
mbed_official 15:a81a8d6c1dfe 143
mbed_official 15:a81a8d6c1dfe 144 /* Enable the callback */
mbed_official 15:a81a8d6c1dfe 145 tc_enable_callback(&us_ticker_module, TC_CALLBACK_CC_CHANNEL0);
mbed_official 15:a81a8d6c1dfe 146 tc_set_compare_value(&us_ticker_module, TC_COMPARE_CAPTURE_CHANNEL_0, (uint32_t)timestamp);
mbed_official 15:a81a8d6c1dfe 147
mbed_official 15:a81a8d6c1dfe 148 NVIC_EnableIRQ(TICKER_COUNTER_IRQn);
mbed_official 15:a81a8d6c1dfe 149 }
mbed_official 15:a81a8d6c1dfe 150
mbed_official 15:a81a8d6c1dfe 151 void us_ticker_disable_interrupt(void)
mbed_official 15:a81a8d6c1dfe 152 {
mbed_official 15:a81a8d6c1dfe 153 /* Disable the callback */
mbed_official 15:a81a8d6c1dfe 154 tc_disable_callback(&us_ticker_module, TC_CALLBACK_CC_CHANNEL0);
mbed_official 15:a81a8d6c1dfe 155 NVIC_DisableIRQ(TICKER_COUNTER_IRQn);
mbed_official 15:a81a8d6c1dfe 156 }
mbed_official 15:a81a8d6c1dfe 157
mbed_official 15:a81a8d6c1dfe 158 void us_ticker_clear_interrupt(void)
mbed_official 15:a81a8d6c1dfe 159 {
mbed_official 15:a81a8d6c1dfe 160 uint32_t status_flags;
mbed_official 15:a81a8d6c1dfe 161
mbed_official 15:a81a8d6c1dfe 162 /* Clear TC channel 0 match */
mbed_official 15:a81a8d6c1dfe 163 status_flags = TC_STATUS_CHANNEL_0_MATCH;
mbed_official 15:a81a8d6c1dfe 164 tc_clear_status(&us_ticker_module, status_flags);
mbed_official 15:a81a8d6c1dfe 165
mbed_official 15:a81a8d6c1dfe 166 /* Clear the interrupt */
mbed_official 15:a81a8d6c1dfe 167 tc_clear_interrupt(&us_ticker_module, TC_CALLBACK_CC_CHANNEL0);
mbed_official 15:a81a8d6c1dfe 168 NVIC_ClearPendingIRQ(TICKER_COUNTER_IRQn);
mbed_official 64:41a834223ea3 169 }