Implement rtimers for ADuCRF101
This commit is contained in:
parent
c8716f4d57
commit
ad141b00fb
5 changed files with 96 additions and 15 deletions
|
@ -101,6 +101,7 @@ CONTIKI_CPU_DIRS += ../common/CMSIS
|
|||
|
||||
CONTIKI_CPU_DIRS += .
|
||||
CONTIKI_SOURCEFILES += slip-arch.c
|
||||
CONTIKI_SOURCEFILES += rtimer-arch.c
|
||||
|
||||
CONTIKI_CPU_DIRS += dev
|
||||
CONTIKI_SOURCEFILES += uart.c
|
||||
|
|
|
@ -45,8 +45,8 @@
|
|||
typedef uint32_t clock_time_t;
|
||||
typedef uint16_t uip_stats_t;
|
||||
|
||||
typedef unsigned long rtimer_clock_t;
|
||||
#define RTIMER_CLOCK_LT(a, b) ((signed long)((a) - (b)) < 0)
|
||||
typedef uint32_t rtimer_clock_t;
|
||||
#define RTIMER_CLOCK_LT(a, b) ((int32_t)((a) - (b)) < 0)
|
||||
rtimer_clock_t rtimer_arch_now(void);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -35,25 +35,104 @@
|
|||
* \author Jim Paris <jim.paris@rigado.com>
|
||||
*/
|
||||
|
||||
#include <contiki.h>
|
||||
#include "rtimer-arch.h"
|
||||
#include "aducrf101-contiki.h"
|
||||
|
||||
/* rtimer on the ADuCRF101 is implemented with the "wakeup" timer.
|
||||
(timer 2). It should be clocked from an external crystal,
|
||||
but if that doesn't seem to be present, this code will select the
|
||||
imprecise internal 32.768 KHz oscillator instead. */
|
||||
|
||||
static void
|
||||
_timer2_enable(int enable)
|
||||
{
|
||||
T2CON_ENABLE_BBA = enable;
|
||||
clock_time_t now = clock_time();
|
||||
while(T2STA_CON_BBA) {
|
||||
/* Synchronizing settings may fail if the chosen clock isn't running;
|
||||
wait no more than 1ms for it */
|
||||
if((clock_time() - now) > (CLOCK_SECOND / 1000)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
static uint32_t
|
||||
_timer2_val(void)
|
||||
{
|
||||
/* This is atomic because the FREEZE bit is set in T2CON. */
|
||||
uint32_t now;
|
||||
now = pADI_WUT->T2VAL0;
|
||||
now |= pADI_WUT->T2VAL1 << 16;
|
||||
return now;
|
||||
}
|
||||
static uint32_t
|
||||
_timer2_measure_freq(void)
|
||||
{
|
||||
const int test_usec = 10000;
|
||||
uint32_t now = _timer2_val();
|
||||
clock_delay_usec(test_usec);
|
||||
return (_timer2_val() - now) * (1000000 / test_usec);
|
||||
}
|
||||
void
|
||||
rtimer_arch_init(void)
|
||||
{
|
||||
uint32_t freq;
|
||||
const char *timer = "LFXTAL";
|
||||
|
||||
_timer2_enable(0);
|
||||
pADI_WUT->T2CON = T2CON_PRE_DIV1 | T2CON_MOD_FREERUN | T2CON_FREEZE_EN |
|
||||
T2CON_WUEN_EN;
|
||||
|
||||
/* Try 32.768 KHz crystal */
|
||||
pADI_WUT->T2CON |= T2CON_CLK_LFXTAL;
|
||||
_timer2_enable(1);
|
||||
freq = _timer2_measure_freq();
|
||||
|
||||
if(freq < 20000 || freq > 40000) {
|
||||
/* No good; use 32.768 KHz internal oscillator */
|
||||
_timer2_enable(0);
|
||||
pADI_WUT->T2CON &= ~T2CON_CLK_MSK;
|
||||
pADI_WUT->T2CON |= T2CON_CLK_LFOSC;
|
||||
_timer2_enable(1);
|
||||
freq = _timer2_measure_freq();
|
||||
timer = "LFOSC";
|
||||
}
|
||||
|
||||
printf("Using %s for rtimer (%ld Hz)\n", timer, freq);
|
||||
|
||||
/* Enable interrupt in NVIC, but disable in WUT for now. */
|
||||
pADI_WUT->T2IEN = 0;
|
||||
NVIC_EnableIRQ(WUT_IRQn);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
rtimer_arch_schedule(rtimer_clock_t t)
|
||||
{
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
rtimer_arch_set(rtimer_clock_t t)
|
||||
{
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
rtimer_clock_t
|
||||
rtimer_arch_now(void)
|
||||
{
|
||||
return 0;
|
||||
/* This is atomic because the FREEZE bit is set in T2CON. */
|
||||
return _timer2_val();
|
||||
}
|
||||
void
|
||||
rtimer_arch_schedule(rtimer_clock_t t)
|
||||
{
|
||||
uint32_t now = _timer2_val();
|
||||
|
||||
/* Minimum of 5 wakeup timer ticks */
|
||||
if((int32_t)(t - now) < 5) {
|
||||
t = now + 5;
|
||||
}
|
||||
|
||||
/* Set T2WUFB to match at target time */
|
||||
T2IEN_WUFB_BBA = 0;
|
||||
pADI_WUT->T2WUFB0 = (t & 0xffff);
|
||||
pADI_WUT->T2WUFB1 = (t >> 16);
|
||||
T2IEN_WUFB_BBA = 1;
|
||||
}
|
||||
void
|
||||
WakeUp_Int_Handler(void)
|
||||
{
|
||||
/* clear interrupt */
|
||||
T2CLRI_WUFB_BBA = 1;
|
||||
/* disable T2WUFB match */
|
||||
T2IEN_WUFB_BBA = 0;
|
||||
rtimer_run_next();
|
||||
}
|
||||
|
|
|
@ -40,7 +40,7 @@
|
|||
|
||||
#include <stdint.h>
|
||||
|
||||
#define RTIMER_ARCH_SECOND (1000)
|
||||
#define RTIMER_ARCH_SECOND (32768)
|
||||
|
||||
#include "sys/rtimer.h"
|
||||
|
||||
|
|
|
@ -132,6 +132,7 @@ main(int argc, char **argv)
|
|||
process_init();
|
||||
process_start(&etimer_process, NULL);
|
||||
ctimer_init();
|
||||
rtimer_init();
|
||||
|
||||
set_rime_addr();
|
||||
|
||||
|
|
Loading…
Reference in a new issue