Merge pull request #13003 from benpicco/lpc2387-timer
This commit is contained in:
commit
45646a811d
@ -128,6 +128,11 @@ typedef struct {
|
|||||||
*/
|
*/
|
||||||
#define TIMER_CHANNEL_NUMOF (4U)
|
#define TIMER_CHANNEL_NUMOF (4U)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Prevent shared timer functions from being used
|
||||||
|
*/
|
||||||
|
#define PERIPH_TIMER_PROVIDES_SET
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Declare needed generic SPI functions
|
* @brief Declare needed generic SPI functions
|
||||||
* @{
|
* @{
|
||||||
|
|||||||
@ -21,6 +21,7 @@
|
|||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "irq.h"
|
||||||
#include "periph_conf.h"
|
#include "periph_conf.h"
|
||||||
#include "periph_cpu.h"
|
#include "periph_cpu.h"
|
||||||
#include "periph/timer.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;
|
dev->MR[channel] = value;
|
||||||
/* Match Interrupt */
|
/* Match Interrupt */
|
||||||
dev->MCR |= (1 << (channel * 3));
|
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;
|
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)
|
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)) {
|
if (is_oneshot(tim_num, chan_num)) {
|
||||||
dev->MCR &= ~(1 << (chan_num * 3));
|
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)
|
static inline void isr_handler(lpc23xx_timer_t *dev, int tim_num)
|
||||||
{
|
{
|
||||||
for (unsigned i = 0; i < TIMER_CHANNEL_NUMOF; ++i) {
|
uint32_t state = dev->IR;
|
||||||
chan_handler(dev, tim_num, i);
|
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 */
|
/* we must not forget to acknowledge the handling of the interrupt */
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user