Merge pull request #13003 from benpicco/lpc2387-timer

This commit is contained in:
Kaspar Schleiser 2020-08-28 13:35:15 +02:00 committed by GitHub
commit 45646a811d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 46 additions and 9 deletions

View File

@ -128,6 +128,11 @@ typedef struct {
*/
#define TIMER_CHANNEL_NUMOF (4U)
/**
* @brief Prevent shared timer functions from being used
*/
#define PERIPH_TIMER_PROVIDES_SET
/**
* @brief Declare needed generic SPI functions
* @{

View File

@ -21,6 +21,7 @@
#include <stdint.h>
#include <string.h>
#include "irq.h"
#include "periph_conf.h"
#include "periph_cpu.h"
#include "periph/timer.h"
@ -167,6 +168,37 @@ int timer_set_absolute(tim_t tim, int channel, unsigned int value)
dev->MR[channel] = value;
/* Match Interrupt */
dev->MCR |= (1 << (channel * 3));
return 0;
}
int timer_set(tim_t tim, int channel, unsigned int timeout)
{
if (((unsigned) tim >= TIMER_NUMOF) || ((unsigned) channel >= TIMER_CHANNEL_NUMOF)) {
return -1;
}
/* Interrupt will only be generated on increment,
so a 0 timeout is not possible */
if (timeout == 0) {
timeout = 1;
}
lpc23xx_timer_t *dev = get_dev(tim);
unsigned state = irq_disable();
dev->TCR = 0;
unsigned absolute = timeout + dev->TC;
unsigned mask = 1 << (channel * 3);
dev->MR[channel] = absolute;
dev->MCR |= mask;
set_oneshot(tim, channel);
dev->TCR = 1;
irq_restore(state);
return 0;
}
@ -226,13 +258,6 @@ void timer_stop(tim_t tim)
static inline void chan_handler(lpc23xx_timer_t *dev, unsigned tim_num, unsigned chan_num)
{
const uint32_t mask = (1 << chan_num);
if ((dev->IR & mask) == 0) {
return;
}
dev->IR |= mask;
if (is_oneshot(tim_num, chan_num)) {
dev->MCR &= ~(1 << (chan_num * 3));
}
@ -242,8 +267,15 @@ static inline void chan_handler(lpc23xx_timer_t *dev, unsigned tim_num, unsigned
static inline void isr_handler(lpc23xx_timer_t *dev, int tim_num)
{
for (unsigned i = 0; i < TIMER_CHANNEL_NUMOF; ++i) {
chan_handler(dev, tim_num, i);
uint32_t state = dev->IR;
uint8_t chan = 0;
/* clear interrupt flags */
dev->IR = state;
while (state) {
state = bitarithm_test_and_clear(state, &chan);
chan_handler(dev, tim_num, chan);
}
/* we must not forget to acknowledge the handling of the interrupt */