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:
107:414e9c822e99
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 107:414e9c822e99 1 /* mbed Microcontroller Library
mbed_official 107:414e9c822e99 2 * Copyright (c) 2006-2015 ARM Limited
mbed_official 107:414e9c822e99 3 *
mbed_official 107:414e9c822e99 4 * Licensed under the Apache License, Version 2.0 (the "License");
mbed_official 107:414e9c822e99 5 * you may not use this file except in compliance with the License.
mbed_official 107:414e9c822e99 6 * You may obtain a copy of the License at
mbed_official 107:414e9c822e99 7 *
mbed_official 107:414e9c822e99 8 * http://www.apache.org/licenses/LICENSE-2.0
mbed_official 107:414e9c822e99 9 *
mbed_official 107:414e9c822e99 10 * Unless required by applicable law or agreed to in writing, software
mbed_official 107:414e9c822e99 11 * distributed under the License is distributed on an "AS IS" BASIS,
mbed_official 107:414e9c822e99 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
mbed_official 107:414e9c822e99 13 * See the License for the specific language governing permissions and
mbed_official 107:414e9c822e99 14 * limitations under the License.
mbed_official 107:414e9c822e99 15 */
mbed_official 107:414e9c822e99 16 #include <stddef.h>
mbed_official 107:414e9c822e99 17 #include "us_ticker_api.h"
mbed_official 107:414e9c822e99 18 #include "cmsis.h"
mbed_official 107:414e9c822e99 19 #include "mbed_assert.h"
mbed_official 107:414e9c822e99 20 #include "compiler.h"
mbed_official 107:414e9c822e99 21 #include "sysclk.h"
mbed_official 107:414e9c822e99 22 #include "tc.h"
mbed_official 107:414e9c822e99 23
mbed_official 107:414e9c822e99 24 uint8_t us_ticker_inited = 0;
mbed_official 107:414e9c822e99 25 extern uint8_t g_sys_init;
mbed_official 107:414e9c822e99 26 volatile uint16_t us_ticker_16bit_counter;
mbed_official 107:414e9c822e99 27 volatile uint16_t us_ticker_interrupt_counter;
mbed_official 107:414e9c822e99 28 volatile uint16_t us_ticker_interrupt_offset;
mbed_official 107:414e9c822e99 29 volatile uint32_t overflow32bitcounter = 0;
mbed_official 107:414e9c822e99 30
mbed_official 107:414e9c822e99 31 #define TICKER_COUNTER_uS TC1
mbed_official 107:414e9c822e99 32
mbed_official 107:414e9c822e99 33 #define TICKER_COUNTER_CLK0 ID_TC3
mbed_official 107:414e9c822e99 34 #define TICKER_COUNTER_CLK1 ID_TC4
mbed_official 107:414e9c822e99 35
mbed_official 107:414e9c822e99 36 #define TICKER_COUNTER_CHANNEL0 0
mbed_official 107:414e9c822e99 37 #define TICKER_COUNTER_IRQn0 TC3_IRQn
mbed_official 107:414e9c822e99 38 #define TICKER_COUNTER_Handlr0 TC3_Handler
mbed_official 107:414e9c822e99 39
mbed_official 107:414e9c822e99 40 #define TICKER_COUNTER_CHANNEL1 1
mbed_official 107:414e9c822e99 41 #define TICKER_COUNTER_IRQn1 TC4_IRQn
mbed_official 107:414e9c822e99 42 #define TICKER_COUNTER_Handlr1 TC4_Handler
mbed_official 107:414e9c822e99 43
mbed_official 107:414e9c822e99 44 #define OVERFLOW_16bit_VALUE 0xFFFF
mbed_official 107:414e9c822e99 45
mbed_official 107:414e9c822e99 46
mbed_official 107:414e9c822e99 47 void TICKER_COUNTER_Handlr1(void)
mbed_official 107:414e9c822e99 48 {
mbed_official 107:414e9c822e99 49 uint32_t status=tc_get_status(TICKER_COUNTER_uS, TICKER_COUNTER_CHANNEL1);
mbed_official 107:414e9c822e99 50 uint32_t interrupmask=tc_get_interrupt_mask(TICKER_COUNTER_uS, TICKER_COUNTER_CHANNEL1);
mbed_official 107:414e9c822e99 51
mbed_official 107:414e9c822e99 52 if (((status & interrupmask) & TC_IER_CPCS)) {
mbed_official 107:414e9c822e99 53 if(us_ticker_interrupt_counter) {
mbed_official 107:414e9c822e99 54 us_ticker_interrupt_counter--;
mbed_official 107:414e9c822e99 55 } else {
mbed_official 107:414e9c822e99 56 if(us_ticker_interrupt_offset) {
mbed_official 107:414e9c822e99 57 us_ticker_interrupt_offset=0;
mbed_official 107:414e9c822e99 58 tc_stop(TICKER_COUNTER_uS, TICKER_COUNTER_CHANNEL1);
mbed_official 107:414e9c822e99 59 tc_write_rc(TICKER_COUNTER_uS, TICKER_COUNTER_CHANNEL1, (uint32_t)us_ticker_interrupt_offset);
mbed_official 107:414e9c822e99 60 tc_start(TICKER_COUNTER_uS, TICKER_COUNTER_CHANNEL1);
mbed_official 107:414e9c822e99 61 } else
mbed_official 107:414e9c822e99 62 us_ticker_irq_handler();
mbed_official 107:414e9c822e99 63 }
mbed_official 107:414e9c822e99 64 }
mbed_official 107:414e9c822e99 65 }
mbed_official 107:414e9c822e99 66
mbed_official 107:414e9c822e99 67 void TICKER_COUNTER_Handlr0(void)
mbed_official 107:414e9c822e99 68 {
mbed_official 107:414e9c822e99 69 uint32_t status=tc_get_status(TICKER_COUNTER_uS, TICKER_COUNTER_CHANNEL0);
mbed_official 107:414e9c822e99 70 uint32_t interrupmask=tc_get_interrupt_mask(TICKER_COUNTER_uS, TICKER_COUNTER_CHANNEL0);
mbed_official 107:414e9c822e99 71
mbed_official 107:414e9c822e99 72 if (((status & interrupmask) & TC_IER_COVFS)) {
mbed_official 107:414e9c822e99 73 us_ticker_16bit_counter++;
mbed_official 107:414e9c822e99 74 if(us_ticker_16bit_counter == 0xFFFF)
mbed_official 107:414e9c822e99 75 overflow32bitcounter++;
mbed_official 107:414e9c822e99 76 }
mbed_official 107:414e9c822e99 77 }
mbed_official 107:414e9c822e99 78
mbed_official 107:414e9c822e99 79 void us_ticker_init(void)
mbed_official 107:414e9c822e99 80 {
mbed_official 107:414e9c822e99 81 if (us_ticker_inited) return;
mbed_official 107:414e9c822e99 82 us_ticker_inited = 1;
mbed_official 107:414e9c822e99 83
mbed_official 107:414e9c822e99 84 us_ticker_16bit_counter=0;
mbed_official 107:414e9c822e99 85 us_ticker_interrupt_counter=0;
mbed_official 107:414e9c822e99 86 us_ticker_interrupt_offset=0;
mbed_official 107:414e9c822e99 87
mbed_official 107:414e9c822e99 88 if (g_sys_init == 0) {
mbed_official 107:414e9c822e99 89 sysclk_init();
mbed_official 107:414e9c822e99 90 system_board_init();
mbed_official 107:414e9c822e99 91 g_sys_init = 1;
mbed_official 107:414e9c822e99 92 }
mbed_official 107:414e9c822e99 93
mbed_official 107:414e9c822e99 94 /* Configure the PMC to enable the TC module. */
mbed_official 107:414e9c822e99 95 sysclk_enable_peripheral_clock(TICKER_COUNTER_CLK0);
mbed_official 107:414e9c822e99 96 sysclk_enable_peripheral_clock(TICKER_COUNTER_CLK1);
mbed_official 107:414e9c822e99 97
mbed_official 107:414e9c822e99 98 #if SAMG55
mbed_official 107:414e9c822e99 99 /* Enable PCK output */
mbed_official 107:414e9c822e99 100 pmc_disable_pck(PMC_PCK_3);
mbed_official 107:414e9c822e99 101 pmc_switch_pck_to_mck(PMC_PCK_3, PMC_PCK_PRES_CLK_1);
mbed_official 107:414e9c822e99 102 pmc_enable_pck(PMC_PCK_3);
mbed_official 107:414e9c822e99 103 #endif
mbed_official 107:414e9c822e99 104
mbed_official 107:414e9c822e99 105 /* Init TC to Counter mode. */
mbed_official 107:414e9c822e99 106 tc_init(TICKER_COUNTER_uS, TICKER_COUNTER_CHANNEL0, TC_CMR_TCCLKS_TIMER_CLOCK4);
mbed_official 107:414e9c822e99 107 tc_init(TICKER_COUNTER_uS, TICKER_COUNTER_CHANNEL1, TC_CMR_TCCLKS_TIMER_CLOCK4);
mbed_official 107:414e9c822e99 108
mbed_official 107:414e9c822e99 109
mbed_official 107:414e9c822e99 110 NVIC_DisableIRQ(TICKER_COUNTER_IRQn0);
mbed_official 107:414e9c822e99 111
mbed_official 107:414e9c822e99 112 NVIC_ClearPendingIRQ(TICKER_COUNTER_IRQn0);
mbed_official 107:414e9c822e99 113 NVIC_SetPriority(TICKER_COUNTER_IRQn0, 0);
mbed_official 107:414e9c822e99 114 NVIC_EnableIRQ(TICKER_COUNTER_IRQn0);
mbed_official 107:414e9c822e99 115 tc_enable_interrupt(TICKER_COUNTER_uS, TICKER_COUNTER_CHANNEL0, TC_IER_COVFS);
mbed_official 107:414e9c822e99 116
mbed_official 107:414e9c822e99 117 tc_start(TICKER_COUNTER_uS, TICKER_COUNTER_CHANNEL0);
mbed_official 107:414e9c822e99 118 }
mbed_official 107:414e9c822e99 119
mbed_official 107:414e9c822e99 120
mbed_official 107:414e9c822e99 121 uint32_t us_ticker_read()
mbed_official 107:414e9c822e99 122 {
mbed_official 107:414e9c822e99 123 if (!us_ticker_inited)
mbed_official 107:414e9c822e99 124 us_ticker_init();
mbed_official 107:414e9c822e99 125
mbed_official 107:414e9c822e99 126 uint32_t counter_value=0;
mbed_official 107:414e9c822e99 127 uint16_t tickerbefore=0;
mbed_official 107:414e9c822e99 128 do {
mbed_official 107:414e9c822e99 129 tickerbefore=us_ticker_16bit_counter;
mbed_official 107:414e9c822e99 130 counter_value=tc_read_cv(TICKER_COUNTER_uS, TICKER_COUNTER_CHANNEL0);
mbed_official 107:414e9c822e99 131 } while(tickerbefore!=us_ticker_16bit_counter);
mbed_official 107:414e9c822e99 132
mbed_official 107:414e9c822e99 133 return counter_value+(OVERFLOW_16bit_VALUE*us_ticker_16bit_counter);
mbed_official 107:414e9c822e99 134 }
mbed_official 107:414e9c822e99 135
mbed_official 107:414e9c822e99 136 void us_ticker_set_interrupt(timestamp_t timestamp)
mbed_official 107:414e9c822e99 137 {
mbed_official 107:414e9c822e99 138 uint32_t cur_time;
mbed_official 107:414e9c822e99 139 int32_t delta;
mbed_official 107:414e9c822e99 140
mbed_official 107:414e9c822e99 141 cur_time = us_ticker_read();
mbed_official 107:414e9c822e99 142 delta = (int32_t)((uint32_t)timestamp - cur_time);
mbed_official 107:414e9c822e99 143 if (delta < 0) {
mbed_official 107:414e9c822e99 144 /* Event already occurred in past */
mbed_official 107:414e9c822e99 145 us_ticker_irq_handler();
mbed_official 107:414e9c822e99 146 return;
mbed_official 107:414e9c822e99 147 }
mbed_official 107:414e9c822e99 148
mbed_official 107:414e9c822e99 149 uint16_t interruptat=0;
mbed_official 107:414e9c822e99 150
mbed_official 107:414e9c822e99 151 if(delta > OVERFLOW_16bit_VALUE) {
mbed_official 107:414e9c822e99 152 us_ticker_interrupt_counter= (delta/OVERFLOW_16bit_VALUE) -1;
mbed_official 107:414e9c822e99 153 us_ticker_interrupt_offset=delta%OVERFLOW_16bit_VALUE;
mbed_official 107:414e9c822e99 154 interruptat=OVERFLOW_16bit_VALUE;
mbed_official 107:414e9c822e99 155 } else {
mbed_official 107:414e9c822e99 156 us_ticker_interrupt_counter=0;
mbed_official 107:414e9c822e99 157 us_ticker_interrupt_offset=0;
mbed_official 107:414e9c822e99 158 interruptat=delta;
mbed_official 107:414e9c822e99 159 }
mbed_official 107:414e9c822e99 160
mbed_official 107:414e9c822e99 161 NVIC_DisableIRQ(TICKER_COUNTER_IRQn1);
mbed_official 107:414e9c822e99 162
mbed_official 107:414e9c822e99 163 tc_write_rc(TICKER_COUNTER_uS, TICKER_COUNTER_CHANNEL1, (uint32_t)interruptat);
mbed_official 107:414e9c822e99 164
mbed_official 107:414e9c822e99 165 NVIC_ClearPendingIRQ(TICKER_COUNTER_IRQn1);
mbed_official 107:414e9c822e99 166 NVIC_SetPriority(TICKER_COUNTER_IRQn1, 0);
mbed_official 107:414e9c822e99 167 NVIC_EnableIRQ(TICKER_COUNTER_IRQn1);
mbed_official 107:414e9c822e99 168 tc_enable_interrupt(TICKER_COUNTER_uS, TICKER_COUNTER_CHANNEL1, TC_IDR_CPCS );
mbed_official 107:414e9c822e99 169
mbed_official 107:414e9c822e99 170 tc_start(TICKER_COUNTER_uS, TICKER_COUNTER_CHANNEL1);
mbed_official 107:414e9c822e99 171 }
mbed_official 107:414e9c822e99 172
mbed_official 107:414e9c822e99 173 void us_ticker_disable_interrupt(void)
mbed_official 107:414e9c822e99 174 {
mbed_official 107:414e9c822e99 175 tc_stop(TICKER_COUNTER_uS, TICKER_COUNTER_CHANNEL1);
mbed_official 107:414e9c822e99 176 tc_disable_interrupt(TICKER_COUNTER_uS, TICKER_COUNTER_CHANNEL1, TC_IDR_CPCS);
mbed_official 107:414e9c822e99 177 NVIC_DisableIRQ(TICKER_COUNTER_IRQn1);
mbed_official 107:414e9c822e99 178 }
mbed_official 107:414e9c822e99 179
mbed_official 107:414e9c822e99 180 void us_ticker_clear_interrupt(void)
mbed_official 107:414e9c822e99 181 {
mbed_official 107:414e9c822e99 182 NVIC_ClearPendingIRQ(TICKER_COUNTER_IRQn1);
mbed_official 107:414e9c822e99 183 }