mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2024-12-29 04:50:03 +01:00
Merge pull request #14700 from fjmolinas/to_cc2538_enhance_rtt
cpu/cc2538: RTT: implement missing API functions
This commit is contained in:
commit
574676b150
@ -24,6 +24,9 @@
|
||||
#include "cpu.h"
|
||||
#include "periph/rtt.h"
|
||||
|
||||
#define ENABLE_DEBUG (0)
|
||||
#include "debug.h"
|
||||
|
||||
#define SMWDTHROSC_STLOAD_STLOAD_MASK (0x00000001)
|
||||
|
||||
/* allocate memory for alarm and overflow callbacks + args */
|
||||
@ -32,6 +35,14 @@ static void *alarm_arg;
|
||||
static rtt_cb_t overflow_cb = NULL;
|
||||
static void *overflow_arg;
|
||||
|
||||
static uint32_t rtt_alarm;
|
||||
static uint32_t rtt_offset;
|
||||
|
||||
static enum {
|
||||
RTT_ALARM,
|
||||
RTT_OVERFLOW
|
||||
} rtt_next_alarm;
|
||||
|
||||
static inline void _rtt_irq_enable(void)
|
||||
{
|
||||
NVIC_SetPriority(SM_TIMER_ALT_IRQn, RTT_IRQ_PRIO);
|
||||
@ -60,12 +71,38 @@ void rtt_init(void)
|
||||
rtt_poweron();
|
||||
}
|
||||
|
||||
static inline uint32_t _rtt_get_counter(void)
|
||||
{
|
||||
return ((SMWDTHROSC_ST0 & 0xFF)
|
||||
| ((SMWDTHROSC_ST1 & 0xFF) << 8)
|
||||
| ((SMWDTHROSC_ST2 & 0xFF) << 16)
|
||||
| ((SMWDTHROSC_ST3 & 0xFF) << 24));
|
||||
}
|
||||
|
||||
uint32_t rtt_get_counter(void)
|
||||
{
|
||||
return ((SMWDTHROSC_ST0 & 0xFF) |
|
||||
((SMWDTHROSC_ST1 & 0xFF) << 8) |
|
||||
((SMWDTHROSC_ST2 & 0xFF) << 16) |
|
||||
((SMWDTHROSC_ST3 & 0xFF) << 24));
|
||||
return _rtt_get_counter() - rtt_offset;
|
||||
}
|
||||
|
||||
void rtt_set_counter(uint32_t counter)
|
||||
{
|
||||
rtt_alarm -= rtt_offset;
|
||||
rtt_offset = _rtt_get_counter() + counter;
|
||||
rtt_alarm += rtt_offset;
|
||||
|
||||
/* re-set the overflow callback */
|
||||
if (overflow_cb) {
|
||||
rtt_set_overflow_cb(overflow_cb, overflow_arg);
|
||||
}
|
||||
}
|
||||
|
||||
static void _set_alarm(uint32_t alarm)
|
||||
{
|
||||
while (!(SMWDTHROSC_STLOAD & SMWDTHROSC_STLOAD_STLOAD_MASK)) {}
|
||||
SMWDTHROSC_ST3 = (alarm >> 24) & 0xFF;
|
||||
SMWDTHROSC_ST2 = (alarm >> 16) & 0xFF;
|
||||
SMWDTHROSC_ST1 = (alarm >> 8) & 0xFF;
|
||||
SMWDTHROSC_ST0 = alarm & 0xFF;
|
||||
}
|
||||
|
||||
void rtt_set_alarm(uint32_t alarm, rtt_cb_t cb, void *arg)
|
||||
@ -73,21 +110,30 @@ void rtt_set_alarm(uint32_t alarm, rtt_cb_t cb, void *arg)
|
||||
assert(cb && !(alarm & ~RTT_MAX_VALUE));
|
||||
|
||||
unsigned irq = irq_disable();
|
||||
|
||||
/* set alarm value */
|
||||
while (!(SMWDTHROSC_STLOAD & SMWDTHROSC_STLOAD_STLOAD_MASK)) {}
|
||||
SMWDTHROSC_ST3 = (alarm >> 24) & 0xFF;
|
||||
SMWDTHROSC_ST2 = (alarm >> 16) & 0xFF;
|
||||
SMWDTHROSC_ST1 = (alarm >> 8) & 0xFF;
|
||||
SMWDTHROSC_ST0 = alarm & 0xFF;
|
||||
rtt_alarm = alarm + rtt_offset;
|
||||
|
||||
/* set callback*/
|
||||
alarm_cb = cb;
|
||||
alarm_arg = arg;
|
||||
|
||||
DEBUG("rtt_set_alarm(%lu), alarm in %lu ticks, overflow in %lu ticks\n",
|
||||
alarm, rtt_alarm - _rtt_get_counter(),
|
||||
rtt_offset - _rtt_get_counter());
|
||||
|
||||
/* only set overflow alarm if it happens before the scheduled alarm */
|
||||
if (overflow_cb == NULL || (rtt_offset >= rtt_alarm )) {
|
||||
rtt_next_alarm = RTT_ALARM;
|
||||
_set_alarm(rtt_alarm);
|
||||
}
|
||||
|
||||
irq_restore(irq);
|
||||
}
|
||||
|
||||
uint32_t rtt_get_alarm(void)
|
||||
{
|
||||
return rtt_alarm - rtt_offset;
|
||||
}
|
||||
|
||||
void rtt_clear_alarm(void)
|
||||
{
|
||||
unsigned irq = irq_disable();
|
||||
@ -101,17 +147,16 @@ void rtt_set_overflow_cb(rtt_cb_t cb, void *arg)
|
||||
{
|
||||
unsigned irq = irq_disable();
|
||||
|
||||
/* set threshold to RTT_MAX_VALUE */
|
||||
while (!(SMWDTHROSC_STLOAD & SMWDTHROSC_STLOAD_STLOAD_MASK)) {}
|
||||
SMWDTHROSC_ST3 = (RTT_MAX_VALUE >> 24) & 0xFF;
|
||||
SMWDTHROSC_ST2 = (RTT_MAX_VALUE >> 16) & 0xFF;
|
||||
SMWDTHROSC_ST1 = (RTT_MAX_VALUE >> 8) & 0xFF;
|
||||
SMWDTHROSC_ST0 = RTT_MAX_VALUE & 0xFF;
|
||||
|
||||
/* set callback*/
|
||||
overflow_cb = cb;
|
||||
overflow_arg = arg;
|
||||
|
||||
/* only set overflow alarm if it happens before the scheduled alarm */
|
||||
if (alarm_cb == NULL || (rtt_alarm > rtt_offset)) {
|
||||
rtt_next_alarm = RTT_OVERFLOW;
|
||||
_set_alarm(rtt_offset);
|
||||
}
|
||||
|
||||
irq_restore(irq);
|
||||
}
|
||||
|
||||
@ -126,17 +171,40 @@ void rtt_clear_overflow_cb(void)
|
||||
|
||||
void isr_sleepmode(void)
|
||||
{
|
||||
if (alarm_cb) {
|
||||
rtt_cb_t tmp;
|
||||
bool both = (rtt_alarm == rtt_offset);
|
||||
|
||||
switch (rtt_next_alarm) {
|
||||
case RTT_ALARM:
|
||||
/* 'consume' the callback (as it might be set again in the cb) */
|
||||
rtt_cb_t tmp = alarm_cb;
|
||||
tmp = alarm_cb;
|
||||
alarm_cb = NULL;
|
||||
tmp(alarm_arg);
|
||||
}
|
||||
else if (overflow_cb) {
|
||||
|
||||
if (!both) {
|
||||
break;
|
||||
} /* fall-through */
|
||||
case RTT_OVERFLOW:
|
||||
/* 'consume' the callback (as it might be set again in the cb) */
|
||||
rtt_cb_t tmp = overflow_cb;
|
||||
tmp = overflow_cb;
|
||||
overflow_cb = NULL;
|
||||
tmp(overflow_arg);
|
||||
break;
|
||||
}
|
||||
|
||||
if (alarm_cb && (rtt_offset >= rtt_alarm)) {
|
||||
DEBUG("rtt: next alarm in %lu ticks (RTT)\n",
|
||||
rtt_alarm - _rtt_get_counter());
|
||||
|
||||
rtt_next_alarm = RTT_ALARM;
|
||||
_set_alarm(rtt_alarm);
|
||||
} else if (overflow_cb && (rtt_alarm > rtt_offset)) {
|
||||
DEBUG("rtt: next alarm in %lu ticks (OVERFLOW)\n",
|
||||
rtt_offset - _rtt_get_counter());
|
||||
|
||||
rtt_next_alarm = RTT_OVERFLOW;
|
||||
_set_alarm(rtt_offset);
|
||||
}
|
||||
|
||||
cortexm_isr_end();
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user