Skip to content

Commit cd7bdbb

Browse files
authored
Merge pull request #2294 from fpistm/HT_comp
feat(HardwareTimer): support regular and complementary channels
2 parents 7f5d45e + 9dfb520 commit cd7bdbb

File tree

2 files changed

+45
-82
lines changed

2 files changed

+45
-82
lines changed

Diff for: cores/arduino/HardwareTimer.h

+4-3
Original file line numberDiff line numberDiff line change
@@ -181,10 +181,11 @@ class HardwareTimer {
181181
int getLLChannel(uint32_t channel);
182182
int getIT(uint32_t channel);
183183
int getAssociatedChannel(uint32_t channel);
184-
#if defined(TIM_CCER_CC1NE)
185-
bool isComplementaryChannel[TIMER_CHANNELS];
186-
#endif
184+
187185
private:
186+
// Store for each channel if regular, complementary or both are used
187+
// High part for complementary (COMPLEMENTARY_CHAN_MASK), low part for regular (REGULAR_CHAN_MASK)
188+
uint8_t __ChannelsUsed[TIMER_CHANNELS];
188189
TimerModes_t _ChannelMode[TIMER_CHANNELS];
189190
timerObj_t _timerObj;
190191
callback_function_t callbacks[1 + TIMER_CHANNELS]; //Callbacks: 0 for update, 1-4 for channels. (channel5/channel6, if any, doesn't have interrupt)

Diff for: libraries/SrcWrapper/src/HardwareTimer.cpp

+41-79
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@
3131
/* Private Defines */
3232
#define PIN_NOT_USED 0xFF
3333
#define MAX_RELOAD ((1 << 16) - 1) // Currently even 32b timers are used as 16b to have generic behavior
34+
#define REGULAR_CHAN_MASK 0x01
35+
#define COMPLEMENTARY_CHAN_MASK 0x10
3436

3537
/* Private Variables */
3638
timerObj_t *HardwareTimer_Handle[TIMER_NUM] = {NULL};
@@ -73,9 +75,6 @@ HardwareTimer::HardwareTimer(TIM_TypeDef *instance)
7375
void HardwareTimer::setup(TIM_TypeDef *instance)
7476
{
7577
uint32_t index = get_timer_index(instance);
76-
if (index == UNKNOWN_TIMER) {
77-
Error_Handler();
78-
}
7978

8079
// Already initialized?
8180
if (_timerObj.handle.Instance) {
@@ -111,9 +110,7 @@ void HardwareTimer::setup(TIM_TypeDef *instance)
111110

112111
// Initialize channel mode and complementary
113112
for (int i = 0; i < TIMER_CHANNELS; i++) {
114-
#if defined(TIM_CCER_CC1NE)
115-
isComplementaryChannel[i] = false;
116-
#endif
113+
__ChannelsUsed[i] = 0x00;
117114
_ChannelMode[i] = TIMER_DISABLED;
118115
}
119116

@@ -174,14 +171,7 @@ void HardwareTimer::pauseChannel(uint32_t channel)
174171

175172
int timAssociatedInputChannel;
176173
int LLChannel = getLLChannel(channel);
177-
if (LLChannel == -1) {
178-
Error_Handler();
179-
}
180-
181174
int interrupt = getIT(channel);
182-
if (interrupt == -1) {
183-
Error_Handler();
184-
}
185175

186176
// Disable channel and corresponding interrupt
187177
__HAL_TIM_DISABLE_IT(&(_timerObj.handle), interrupt);
@@ -190,11 +180,11 @@ void HardwareTimer::pauseChannel(uint32_t channel)
190180
/* Starting from G4, new Channel state implementation prevents to restart a channel,
191181
if the channel has not been explicitly be stopped with HAL interface */
192182
#if defined(TIM_CHANNEL_N_STATE_SET)
193-
if (isComplementaryChannel[channel - 1]) {
183+
if (__ChannelsUsed[channel - 1] & COMPLEMENTARY_CHAN_MASK) {
194184
TIM_CHANNEL_N_STATE_SET(&(_timerObj.handle), getChannel(channel), HAL_TIM_CHANNEL_STATE_READY);
195-
} else
185+
}
196186
#endif
197-
{
187+
if (__ChannelsUsed[channel - 1] & REGULAR_CHAN_MASK) {
198188
TIM_CHANNEL_STATE_SET(&(_timerObj.handle), getChannel(channel), HAL_TIM_CHANNEL_STATE_READY);
199189
}
200190
#endif
@@ -234,11 +224,11 @@ void HardwareTimer::resume(void)
234224
/**
235225
* @brief Convert arduino channel into HAL channel
236226
* @param Arduino channel [1..4]
237-
* @retval HAL channel. return -1 if arduino channel is invalid
227+
* @retval HAL channel. Error handler called if arduino channel is invalid
238228
*/
239229
int HardwareTimer::getChannel(uint32_t channel)
240230
{
241-
uint32_t return_value;
231+
int return_value = -1;
242232

243233
switch (channel) {
244234
case 1:
@@ -254,21 +244,22 @@ int HardwareTimer::getChannel(uint32_t channel)
254244
return_value = TIM_CHANNEL_4;
255245
break;
256246
default:
257-
return_value = -1;
247+
Error_Handler();
258248
}
259249
return return_value;
260250
}
261251

262252
/**
263-
* @brief Convert arduino channel into LL channel
253+
* @brief Convert arduino channel into LL channels used (regular and/or complementary)
264254
* @param Arduino channel [1..4]
265-
* @retval LL channel. return -1 if arduino channel is invalid
255+
* @retval LL channel. Error handler called if arduino channel is invalid
266256
*/
267257
int HardwareTimer::getLLChannel(uint32_t channel)
268258
{
269-
uint32_t return_value;
259+
int return_value = 0;
260+
270261
#if defined(TIM_CCER_CC1NE)
271-
if (isComplementaryChannel[channel - 1]) {
262+
if (__ChannelsUsed[channel - 1] & COMPLEMENTARY_CHAN_MASK) {
272263
// Complementary channel
273264
switch (channel) {
274265
case 1:
@@ -288,38 +279,41 @@ int HardwareTimer::getLLChannel(uint32_t channel)
288279
default:
289280
return_value = -1;
290281
}
291-
} else
282+
}
292283
#endif
293-
{
284+
if ((return_value != -1) && (__ChannelsUsed[channel - 1] & REGULAR_CHAN_MASK)) {
294285
// Regular channel not complementary
295286
switch (channel) {
296287
case 1:
297-
return_value = LL_TIM_CHANNEL_CH1;
288+
return_value |= LL_TIM_CHANNEL_CH1;
298289
break;
299290
case 2:
300-
return_value = LL_TIM_CHANNEL_CH2;
291+
return_value |= LL_TIM_CHANNEL_CH2;
301292
break;
302293
case 3:
303-
return_value = LL_TIM_CHANNEL_CH3;
294+
return_value |= LL_TIM_CHANNEL_CH3;
304295
break;
305296
case 4:
306-
return_value = LL_TIM_CHANNEL_CH4;
297+
return_value |= LL_TIM_CHANNEL_CH4;
307298
break;
308299
default:
309300
return_value = -1;
310301
}
311302
}
303+
if (return_value == -1) {
304+
Error_Handler();
305+
}
312306
return return_value;
313307
}
314308

315309
/**
316310
* @brief Convert arduino channel into HAL Interrupt ID
317311
* @param Arduino channel [1..4]
318-
* @retval HAL channel. return -1 if arduino channel is invalid
312+
* @retval HAL channel. Error handler called if arduino channel is invalid
319313
*/
320314
int HardwareTimer::getIT(uint32_t channel)
321315
{
322-
uint32_t return_value;
316+
int return_value = -1;
323317

324318
switch (channel) {
325319
case 1:
@@ -335,7 +329,7 @@ int HardwareTimer::getIT(uint32_t channel)
335329
return_value = TIM_IT_CC4;
336330
break;
337331
default:
338-
return_value = -1;
332+
Error_Handler();
339333
}
340334
return return_value;
341335
}
@@ -377,19 +371,7 @@ void HardwareTimer::resumeChannel(uint32_t channel)
377371
{
378372
int timChannel = getChannel(channel);
379373
int timAssociatedInputChannel;
380-
if (timChannel == -1) {
381-
Error_Handler();
382-
}
383-
384374
int interrupt = getIT(channel);
385-
if (interrupt == -1) {
386-
Error_Handler();
387-
}
388-
389-
int LLChannel = getLLChannel(channel);
390-
if (LLChannel == -1) {
391-
Error_Handler();
392-
}
393375

394376
// Clear flag and enable IT
395377
if (callbacks[channel]) {
@@ -401,11 +383,11 @@ void HardwareTimer::resumeChannel(uint32_t channel)
401383
case TIMER_OUTPUT_COMPARE_PWM1:
402384
case TIMER_OUTPUT_COMPARE_PWM2: {
403385
#if defined(TIM_CCER_CC1NE)
404-
if (isComplementaryChannel[channel - 1]) {
386+
if (__ChannelsUsed[channel - 1] & COMPLEMENTARY_CHAN_MASK) {
405387
HAL_TIMEx_PWMN_Start(&(_timerObj.handle), timChannel);
406-
} else
388+
}
407389
#endif
408-
{
390+
if (__ChannelsUsed[channel - 1] & REGULAR_CHAN_MASK) {
409391
HAL_TIM_PWM_Start(&(_timerObj.handle), timChannel);
410392
}
411393
}
@@ -416,11 +398,11 @@ void HardwareTimer::resumeChannel(uint32_t channel)
416398
case TIMER_OUTPUT_COMPARE_FORCED_ACTIVE:
417399
case TIMER_OUTPUT_COMPARE_FORCED_INACTIVE: {
418400
#if defined(TIM_CCER_CC1NE)
419-
if (isComplementaryChannel[channel - 1]) {
401+
if (__ChannelsUsed[channel - 1] & COMPLEMENTARY_CHAN_MASK) {
420402
HAL_TIMEx_OCN_Start(&(_timerObj.handle), timChannel);
421-
} else
403+
}
422404
#endif
423-
{
405+
if (__ChannelsUsed[channel - 1] & REGULAR_CHAN_MASK) {
424406
HAL_TIM_OC_Start(&(_timerObj.handle), timChannel);
425407
}
426408
}
@@ -642,10 +624,6 @@ void HardwareTimer::setMode(uint32_t channel, TimerModes_t mode, PinName pin, Ch
642624
TIM_OC_InitTypeDef channelOC;
643625
TIM_IC_InitTypeDef channelIC;
644626

645-
if (timChannel == -1) {
646-
Error_Handler();
647-
}
648-
649627
/* Configure some default values. Maybe overwritten later */
650628
channelOC.OCMode = TIMER_NOT_USED;
651629
channelOC.Pulse = __HAL_TIM_GET_COMPARE(&(_timerObj.handle), timChannel); // keep same value already written in hardware register
@@ -724,13 +702,18 @@ void HardwareTimer::setMode(uint32_t channel, TimerModes_t mode, PinName pin, Ch
724702
HAL_TIM_IC_ConfigChannel(&(_timerObj.handle), &channelIC, timChannel);
725703
break;
726704
case TIMER_INPUT_FREQ_DUTY_MEASUREMENT:
705+
// Check if regular channel
706+
if (STM_PIN_INVERTED(pinmap_function(pin, PinMap_TIM))) {
707+
Error_Handler();
708+
}
727709
// Configure 1st channel
728710
channelIC.ICPolarity = TIM_INPUTCHANNELPOLARITY_RISING;
729711
channelIC.ICSelection = TIM_ICSELECTION_DIRECTTI;
730712
HAL_TIM_IC_ConfigChannel(&(_timerObj.handle), &channelIC, timChannel);
731713

732714
// Identify and configure 2nd associated channel
733715
timAssociatedInputChannel = getAssociatedChannel(channel);
716+
__ChannelsUsed[timAssociatedInputChannel - 1] |= REGULAR_CHAN_MASK;
734717
_ChannelMode[timAssociatedInputChannel - 1] = mode;
735718
channelIC.ICPolarity = TIM_INPUTCHANNELPOLARITY_FALLING;
736719
channelIC.ICSelection = TIM_ICSELECTION_INDIRECTTI;
@@ -759,9 +742,7 @@ void HardwareTimer::setMode(uint32_t channel, TimerModes_t mode, PinName pin, Ch
759742
Error_Handler();
760743
}
761744

762-
#if defined(TIM_CCER_CC1NE)
763-
isComplementaryChannel[channel - 1] = STM_PIN_INVERTED(pinmap_function(pin, PinMap_TIM));
764-
#endif
745+
__ChannelsUsed[channel - 1] |= (STM_PIN_INVERTED(pinmap_function(pin, PinMap_TIM))) ? COMPLEMENTARY_CHAN_MASK : REGULAR_CHAN_MASK;
765746
}
766747
}
767748

@@ -818,10 +799,6 @@ void HardwareTimer::setCaptureCompare(uint32_t channel, uint32_t compare, TimerC
818799
uint32_t Prescalerfactor = LL_TIM_GetPrescaler(_timerObj.handle.Instance) + 1;
819800
uint32_t CCR_RegisterValue;
820801

821-
if (timChannel == -1) {
822-
Error_Handler();
823-
}
824-
825802
switch (format) {
826803
case MICROSEC_COMPARE_FORMAT:
827804
CCR_RegisterValue = ((compare * (getTimerClkFreq() / 1000000)) / Prescalerfactor);
@@ -885,10 +862,6 @@ uint32_t HardwareTimer::getCaptureCompare(uint32_t channel, TimerCompareFormat_
885862
uint32_t Prescalerfactor = LL_TIM_GetPrescaler(_timerObj.handle.Instance) + 1;
886863
uint32_t return_value;
887864

888-
if (timChannel == -1) {
889-
Error_Handler();
890-
}
891-
892865
switch (format) {
893866
case MICROSEC_COMPARE_FORMAT:
894867
return_value = (uint32_t)((CCR_RegisterValue * Prescalerfactor * 1000000.0) / getTimerClkFreq());
@@ -1026,9 +999,6 @@ void HardwareTimer::detachInterrupt()
1026999
void HardwareTimer::attachInterrupt(uint32_t channel, callback_function_t callback)
10271000
{
10281001
int interrupt = getIT(channel);
1029-
if (interrupt == -1) {
1030-
Error_Handler();
1031-
}
10321002

10331003
if ((channel == 0) || (channel > (TIMER_CHANNELS + 1))) {
10341004
Error_Handler(); // only channel 1..4 have an interrupt
@@ -1055,9 +1025,6 @@ void HardwareTimer::attachInterrupt(uint32_t channel, callback_function_t callba
10551025
void HardwareTimer::detachInterrupt(uint32_t channel)
10561026
{
10571027
int interrupt = getIT(channel);
1058-
if (interrupt == -1) {
1059-
Error_Handler();
1060-
}
10611028

10621029
if ((channel == 0) || (channel > (TIMER_CHANNELS + 1))) {
10631030
Error_Handler(); // only channel 1..4 have an interrupt
@@ -1194,14 +1161,6 @@ bool HardwareTimer::isRunningChannel(uint32_t channel)
11941161
int interrupt = getIT(channel);
11951162
bool ret;
11961163

1197-
if (LLChannel == -1) {
1198-
Error_Handler();
1199-
}
1200-
1201-
if (interrupt == -1) {
1202-
Error_Handler();
1203-
}
1204-
12051164
// channel is running if: timer is running, and either output channel is
12061165
// enabled or interrupt is set
12071166
ret = LL_TIM_CC_IsEnabledChannel(_timerObj.handle.Instance, LLChannel)
@@ -1361,6 +1320,9 @@ timer_index_t get_timer_index(TIM_TypeDef *instance)
13611320
index = TIMER22_INDEX;
13621321
}
13631322
#endif
1323+
if (index == UNKNOWN_TIMER) {
1324+
Error_Handler();
1325+
}
13641326
return index;
13651327
}
13661328

0 commit comments

Comments
 (0)