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:
parent
0fed4c91f1
commit
94f9a56125
@ -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
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user