Skip to content

Commit 62254c2

Browse files
mmahadevan108bulislaw
authored andcommitted
KW41Z: 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 95559ad commit 62254c2

File tree

6 files changed

+94
-55
lines changed

6 files changed

+94
-55
lines changed

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

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -46,9 +46,7 @@ typedef enum {
4646
PWM_3 = (0 << TPM_SHIFT) | (2), // TPM0 CH2
4747
PWM_4 = (0 << TPM_SHIFT) | (3), // TPM0 CH3
4848
PWM_5 = (1 << TPM_SHIFT) | (0), // TPM1 CH0
49-
PWM_6 = (1 << TPM_SHIFT) | (1), // TPM1 CH1
50-
PWM_7 = (2 << TPM_SHIFT) | (0), // TPM2 CH0
51-
PWM_8 = (2 << TPM_SHIFT) | (1), // TPM2 CH1
49+
PWM_6 = (1 << TPM_SHIFT) | (1) // TPM1 CH1
5250
} PWMName;
5351

5452
#define ADC_INSTANCE_SHIFT 8

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

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -132,12 +132,5 @@ const PinMap PinMap_PWM[] = {
132132
{PTB3, PWM_6, 5},
133133
{PTC4, PWM_5, 5},
134134
{PTC5, PWM_6, 5},
135-
/* TPM 2 */
136-
{PTA18, PWM_7, 5},
137-
{PTA19, PWM_8, 5},
138-
{PTB16, PWM_7, 5},
139-
{PTB17, PWM_8, 5},
140-
{PTC6, PWM_7, 5},
141-
{PTC7, PWM_8, 5},
142135
{NC , NC , 0}
143136
};

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

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

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

targets/TARGET_Freescale/TARGET_MCUXpresso_MCUS/TARGET_KW41Z/pwmout_api.c

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

3737
uint32_t pwm_base_clock;
3838

39-
/* Set the TPM clock source to be MCG FLL clock */
40-
CLOCK_SetTpmClock(1U);
41-
pwm_base_clock = CLOCK_GetFreq(kCLOCK_McgFllClk);
39+
/* TPM clock source is set to OSCERCLK during init */
40+
pwm_base_clock = CLOCK_GetFreq(kCLOCK_Osc0ErClk);
4241
float clkval = (float)pwm_base_clock / 1000000.0f;
4342
uint32_t clkdiv = 0;
4443
while (clkval > 1) {
Lines changed: 88 additions & 41 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,32 +17,58 @@
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+
1000000,
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);
@@ -55,53 +81,74 @@ void us_ticker_init(void)
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 32 to get 1MHz clock source for TPM */
89+
tpmConfig.prescale = kTPM_Prescale_Divide_32;
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
}

targets/targets.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -600,7 +600,7 @@
600600
"macros": ["CPU_MKW41Z512VHT4", "FSL_RTOS_MBED"],
601601
"inherits": ["Target"],
602602
"detect_code": ["0201"],
603-
"device_has": ["USTICKER", "ANALOGIN", "ANALOGOUT", "I2C", "I2CSLAVE", "INTERRUPTIN", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SERIAL", "SPI", "SPISLAVE", "TRNG", "STDIO_MESSAGES"],
603+
"device_has": ["USTICKER", "ANALOGIN", "ANALOGOUT", "I2C", "I2CSLAVE", "INTERRUPTIN", "PORTIN", "PORTINOUT", "PORTOUT", "PWMOUT", "RTC", "SERIAL", "SLEEP", "SPI", "SPISLAVE", "TRNG", "STDIO_MESSAGES"],
604604
"release_versions": ["2", "5"],
605605
"device_name": "MKW41Z512xxx4"
606606
},

0 commit comments

Comments
 (0)