1
0
mirror of https://github.com/RIOT-OS/RIOT.git synced 2024-12-29 04:50:03 +01:00

cpu/qn908x/periph_timer: Implement timer_set()

This fixes test failures in tests/periph_timer_short_relative_set.

Note: This differs a bit from the implementation in e.g. nRF5x or STM32
in that it always briefly pauses the timer. The issue is that when
running the timer can take a few ticks to actually react to the new
compare target. So even if the previously written target is still in
the future, the timer may not fire anyway. Pausing the timer while
setting and setting the target at least one higher than the current
count reliably triggers the IRQ.
This commit is contained in:
Marian Buschsieweke 2023-01-03 22:35:11 +01:00
parent 0fed4c91f1
commit 94f9a56125
No known key found for this signature in database
GPG Key ID: CB8E3238CE715A94
2 changed files with 29 additions and 0 deletions

View File

@ -335,6 +335,10 @@ typedef uint16_t adc_conf_t;
*/
#define TIMER_CHANNELS (4)
#define TIMER_MAX_VALUE (0xffffffff)
/**
* @brief The nRF5x periph_timer implements timer_set()
*/
#define PERIPH_TIMER_PROVIDES_SET 1
/** @} */
/**

View File

@ -112,6 +112,31 @@ int timer_set_absolute(tim_t tim, int channel, unsigned int value)
return 0;
}
int timer_set(tim_t tim, int channel, unsigned int value)
{
DEBUG("timer_set(%u, %u, %u)\n", tim, channel, value);
if ((tim >= TIMER_NUMOF) || (channel >= TIMER_CHANNELS)) {
return -1;
}
CTIMER_Type* const dev = ctimers[tim];
/* no IRQ will be generated on value == 0, so bump it here */
value = (value != 0) ? value : 1;
unsigned irq_state = irq_disable();
/* briefly pause timer */
ctimers[tim]->TCR &= ~CTIMER_TCR_CEN_MASK;
/* set absolute timeout based on given value and enable IRQ */
dev->MR[channel] = dev->TC + value;
dev->MCR |= (CTIMER_MCR_MR0I_MASK << (channel * 3));
/* and resume timer */
ctimers[tim]->TCR |= CTIMER_TCR_CEN_MASK;
irq_restore(irq_state);
return 0;
}
int timer_clear(tim_t tim, int channel)
{
DEBUG("timer_clear(%u, %d)\n", tim, channel);