Skip to content

Commit a21d21e

Browse files
mmahadevan108bulislaw
authored andcommitted
KL43Z: Update usticker to use TPM instead of LPTMR for ticker
This will free up the LPTMR to be used as lpticker Signed-off-by: Mahesh Mahadevan <[email protected]>
1 parent 62254c2 commit a21d21e

File tree

5 files changed

+96
-58
lines changed

5 files changed

+96
-58
lines changed

targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_KL43Z/TARGET_FRDM/PeripheralNames.h

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -50,9 +50,7 @@ typedef enum {
5050
PWM_5 = (0 << TPM_SHIFT) | (4), // TPM0 CH4
5151
PWM_6 = (0 << TPM_SHIFT) | (5), // TPM0 CH5
5252
PWM_7 = (1 << TPM_SHIFT) | (0), // TPM1 CH0
53-
PWM_8 = (1 << TPM_SHIFT) | (1), // TPM1 CH1
54-
PWM_9 = (2 << TPM_SHIFT) | (0), // TPM2 CH0
55-
PWM_10 = (2 << TPM_SHIFT) | (1), // TPM2 CH1
53+
PWM_8 = (1 << TPM_SHIFT) | (1) // TPM1 CH1
5654
} PWMName;
5755

5856
#define ADC_INSTANCE_SHIFT 8

targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_KL43Z/TARGET_FRDM/PeripheralPins.c

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -137,21 +137,15 @@ const PinMap PinMap_SPI_SSEL[] = {
137137

138138
/************PWM***************/
139139
const PinMap PinMap_PWM[] = {
140-
{PTA0, PWM_6, 3}, // PTA0 , TPM0 CH5
141-
{PTA1, PWM_9 , 3}, // PTA1 , TPM2 CH0
142-
{PTA2, PWM_10, 3}, // PTA2 , TPM2 CH1
140+
{PTA0, PWM_6, 3}, // PTA0 , TPM0 CH5
143141
{PTA3, PWM_1, 3}, // PTA3 , TPM0 CH0
144142
{PTA4, PWM_2 , 3}, // PTA4 , TPM0 CH1
145143
{PTA5, PWM_3 , 3}, // PTA5 , TPM0 CH2
146144
{PTA12, PWM_7 , 3}, // PTA12, TPM1 CH0
147-
{PTA13, PWM_8 , 3}, // PTA13, TPM1 CH1
145+
{PTA13, PWM_8 , 3}, // PTA13, TPM1 CH1
148146

149147
{PTB0, PWM_7, 3}, // PTB0 , TPM1 CH0
150148
{PTB1, PWM_8, 3}, // PTB1 , TPM1 CH1
151-
{PTB2, PWM_9, 3}, // PTB2 , TPM2 CH0
152-
{PTB3, PWM_10, 3}, // PTB3 , TPM2 CH1
153-
{PTB18, PWM_9, 3}, // PTB18, TPM2 CH0
154-
{PTB19, PWM_10, 3}, // PTB18, TPM2 CH1
155149

156150
{PTC1, PWM_1, 4}, // PTC1 , TPM0 CH0
157151
{PTC2, PWM_2, 4}, // PTC2 , TPM0 CH1
@@ -161,14 +155,12 @@ const PinMap PinMap_PWM[] = {
161155
{PTD0, PWM_1 , 4}, // PTD0 , TPM0 CH0
162156
{PTD1, PWM_2 , 4}, // PTD0 , TPM0 CH1
163157
{PTD2, PWM_3 , 4}, // PTD2 , TPM0 CH2
164-
{PTD3, PWM_4 , 4}, // PTD3 , TPM0 CH3
158+
{PTD3, PWM_4 , 4}, // PTD3 , TPM0 CH3
165159
{PTD4, PWM_5 , 4}, // PTD4 , TPM0 CH4
166160
{PTD5, PWM_6 , 4}, // PTD5 , TPM0 CH5
167161

168162
{PTE20, PWM_7, 3}, // PTE20, TPM1 CH0
169163
{PTE21, PWM_8, 3}, // PTE21, TPM1 CH1
170-
{PTE22, PWM_9, 3}, // PTE22, TPM2 CH0
171-
{PTE23, PWM_10, 3}, // PTE23, TPM2 CH1
172164
{PTE24, PWM_1, 3}, // PTE24, TPM0 CH0
173165
{PTE25, PWM_2, 3}, // PTE25, TPM0 CH1
174166
{PTE29, PWM_3, 3}, // PTE29, TPM0 CH2

targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_KL43Z/TARGET_FRDM/mbed_overrides.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@
2222
void mbed_sdk_init()
2323
{
2424
BOARD_BootClockRUN();
25+
/* Set the TPM clock source to be IRC48M, do not change as TPM2 is used for the usticker */
26+
CLOCK_SetTpmClock(1U);
2527
}
2628

2729
// Enable the RTC oscillator if available on the board

targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_KL43Z/pwmout_api.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,7 @@ void pwmout_init(pwmout_t* obj, PinName pin)
3636

3737
uint32_t pwm_base_clock;
3838

39-
/* Set the TPM clock source to be IRC 48M */
40-
CLOCK_SetTpmClock(1U);
39+
/* TPM clock source is set to IRC48M during init */
4140
pwm_base_clock = CLOCK_GetFreq(kCLOCK_McgIrc48MClk);
4241
float clkval = (float)pwm_base_clock / 1000000.0f;
4342
uint32_t clkdiv = 0;
Lines changed: 89 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/* mbed Microcontroller Library
2-
* Copyright (c) 2006-2013 ARM Limited
2+
* Copyright (c) 2006-2018 ARM Limited
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -17,91 +17,138 @@
1717
#include "us_ticker_api.h"
1818
#include "PeripheralNames.h"
1919
#include "fsl_pit.h"
20-
#include "fsl_lptmr.h"
20+
#include "fsl_tpm.h"
2121
#include "fsl_clock_config.h"
2222

23-
static int us_ticker_inited = 0;
24-
25-
static void lptmr_isr(void)
23+
const ticker_info_t* us_ticker_get_info()
2624
{
27-
LPTMR_ClearStatusFlags(LPTMR0, kLPTMR_TimerCompareFlag);
28-
LPTMR_StopTimer(LPTMR0);
25+
static const ticker_info_t info = {
26+
3000000,
27+
32
28+
};
29+
return &info;
30+
}
31+
32+
static bool us_ticker_inited = false;
2933

30-
us_ticker_irq_handler();
34+
static uint32_t us_ticker_int_counter = 0;
35+
static uint16_t us_ticker_int_remainder = 0;
36+
37+
static void tpm_isr(void)
38+
{
39+
// Clear the TPM timer overflow flag
40+
TPM_ClearStatusFlags(TPM2, kTPM_TimeOverflowFlag);
41+
TPM_StopTimer(TPM2);
42+
43+
if (us_ticker_int_counter > 0) {
44+
TPM2->MOD = 0xFFFF;
45+
TPM_StartTimer(TPM2, kTPM_SystemClock);
46+
us_ticker_int_counter--;
47+
} else {
48+
if (us_ticker_int_remainder > 0) {
49+
TPM2->MOD = us_ticker_int_remainder;
50+
TPM_StartTimer(TPM2, kTPM_SystemClock);
51+
us_ticker_int_remainder = 0;
52+
} else {
53+
// This function is going to disable the interrupts if there are
54+
// no other events in the queue
55+
us_ticker_irq_handler();
56+
}
57+
}
3158
}
3259

3360
void us_ticker_init(void)
3461
{
62+
/* Common for ticker/timer. */
63+
uint32_t busClock;
64+
/* Structure to initialize PIT. */
65+
pit_config_t pitConfig;
66+
3567
if (us_ticker_inited) {
68+
/* calling init again should cancel current interrupt */
69+
TPM_DisableInterrupts(TPM2, kTPM_TimeOverflowInterruptEnable);
3670
return;
3771
}
38-
us_ticker_inited = 1;
39-
40-
//Timer uses PIT
41-
//Common for ticker/timer
42-
uint32_t busClock;
43-
44-
// Structure to initialize PIT
45-
pit_config_t pitConfig;
4672

4773
PIT_GetDefaultConfig(&pitConfig);
4874
PIT_Init(PIT, &pitConfig);
4975

5076
busClock = CLOCK_GetFreq(kCLOCK_BusClk);
5177

52-
PIT_SetTimerPeriod(PIT, kPIT_Chnl_0, busClock / 1000000 - 1);
78+
PIT_SetTimerPeriod(PIT, kPIT_Chnl_0, (busClock / 3000000) - 1);
5379
PIT_SetTimerPeriod(PIT, kPIT_Chnl_1, 0xFFFFFFFF);
5480
PIT_SetTimerChainMode(PIT, kPIT_Chnl_1, true);
5581
PIT_StartTimer(PIT, kPIT_Chnl_0);
5682
PIT_StartTimer(PIT, kPIT_Chnl_1);
5783

58-
//Ticker uses LPTMR
59-
lptmr_config_t lptmrConfig;
60-
LPTMR_GetDefaultConfig(&lptmrConfig);
61-
lptmrConfig.prescalerClockSource = kLPTMR_PrescalerClock_0;
62-
LPTMR_Init(LPTMR0, &lptmrConfig);
63-
64-
busClock = CLOCK_GetFreq(kCLOCK_McgInternalRefClk);
65-
LPTMR_SetTimerPeriod(LPTMR0, busClock / 1000000 - 1);
66-
/* Set interrupt handler */
67-
NVIC_SetVector(LPTMR0_IRQn, (uint32_t)lptmr_isr);
68-
NVIC_EnableIRQ(LPTMR0_IRQn);
84+
/* Configure interrupt generation counters and disable ticker interrupts. */
85+
tpm_config_t tpmConfig;
86+
87+
TPM_GetDefaultConfig(&tpmConfig);
88+
/* Set to Div 16 to get 3MHz clock source for TPM */
89+
tpmConfig.prescale = kTPM_Prescale_Divide_16;
90+
TPM_Init(TPM2, &tpmConfig);
91+
NVIC_SetVector(TPM2_IRQn, (uint32_t)tpm_isr);
92+
NVIC_EnableIRQ(TPM2_IRQn);
93+
94+
us_ticker_inited = true;
6995
}
7096

7197

7298
uint32_t us_ticker_read()
7399
{
74-
if (!us_ticker_inited) {
75-
us_ticker_init();
76-
}
77-
78100
return ~(PIT_GetCurrentTimerCount(PIT, kPIT_Chnl_1));
79101
}
80102

81103
void us_ticker_disable_interrupt(void)
82104
{
83-
LPTMR_DisableInterrupts(LPTMR0, kLPTMR_TimerInterruptEnable);
105+
TPM_DisableInterrupts(TPM2, kTPM_TimeOverflowInterruptEnable);
84106
}
85107

86108
void us_ticker_clear_interrupt(void)
87109
{
88-
LPTMR_ClearStatusFlags(LPTMR0, kLPTMR_TimerCompareFlag);
110+
TPM_ClearStatusFlags(TPM2, kTPM_TimeOverflowFlag);
89111
}
90112

91113
void us_ticker_set_interrupt(timestamp_t timestamp)
92114
{
93-
uint32_t now_us, delta_us;
115+
/* We get here absolute interrupt time which takes into account counter overflow.
116+
* Since we use additional count-down timer to generate interrupt we need to calculate
117+
* load value based on time-stamp.
118+
*/
119+
const uint32_t now_ticks = us_ticker_read();
120+
uint32_t delta_ticks =
121+
timestamp >= now_ticks ? timestamp - now_ticks : (uint32_t)((uint64_t) timestamp + 0xFFFFFFFF - now_ticks);
122+
123+
if (delta_ticks == 0) {
124+
/* The requested delay is less than the minimum resolution of this counter. */
125+
delta_ticks = 1;
126+
}
127+
128+
us_ticker_int_counter = (uint32_t)(delta_ticks >> 16);
129+
us_ticker_int_remainder = (uint16_t)(0xFFFF & delta_ticks);
94130

95-
now_us = us_ticker_read();
96-
delta_us = timestamp >= now_us ? timestamp - now_us : (uint32_t)((uint64_t)timestamp + 0xFFFFFFFF - now_us);
131+
TPM_StopTimer(TPM2);
132+
TPM2->CNT = 0;
97133

98-
LPTMR_StopTimer(LPTMR0);
99-
LPTMR_SetTimerPeriod(LPTMR0, (uint32_t)delta_us);
100-
LPTMR_EnableInterrupts(LPTMR0, kLPTMR_TimerInterruptEnable);
101-
LPTMR_StartTimer(LPTMR0);
134+
if (us_ticker_int_counter > 0) {
135+
TPM2->MOD = 0xFFFF;
136+
us_ticker_int_counter--;
137+
} else {
138+
TPM2->MOD = us_ticker_int_remainder;
139+
us_ticker_int_remainder = 0;
140+
}
141+
142+
/* Clear the count and set match value */
143+
TPM_ClearStatusFlags(TPM2, kTPM_TimeOverflowFlag);
144+
TPM_EnableInterrupts(TPM2, kTPM_TimeOverflowInterruptEnable);
145+
TPM_StartTimer(TPM2, kTPM_SystemClock);
102146
}
103147

104148
void us_ticker_fire_interrupt(void)
105149
{
106-
NVIC_SetPendingIRQ(LPTMR0_IRQn);
150+
us_ticker_int_counter = 0;
151+
us_ticker_int_remainder = 0;
152+
153+
NVIC_SetPendingIRQ(TPM2_IRQn);
107154
}

0 commit comments

Comments
 (0)