Updated SPI config for faster SPI, split msp430/clock/spi into separate versions for MSP430/MSP430X
This commit is contained in:
parent
09082f02fe
commit
f4f84ffca4
|
@ -11,7 +11,11 @@ CONTIKI_CPU=$(CONTIKI)/cpu/msp430
|
||||||
|
|
||||||
### Define the source files we have in the MSP430 port
|
### Define the source files we have in the MSP430 port
|
||||||
|
|
||||||
CONTIKI_CPU_DIRS = . dev
|
ifneq (,$(findstring msp430x5,$(MCU)))
|
||||||
|
CONTIKI_CPU_DIRS = ${addprefix f5xxx/,. dev} . dev
|
||||||
|
else
|
||||||
|
CONTIKI_CPU_DIRS = ${addprefix f1xxx/,. dev} . dev
|
||||||
|
endif
|
||||||
|
|
||||||
MSP430 = msp430.c flash.c clock.c leds.c leds-arch.c \
|
MSP430 = msp430.c flash.c clock.c leds.c leds-arch.c \
|
||||||
watchdog.c lpm.c mtarch.c rtimer-arch.c
|
watchdog.c lpm.c mtarch.c rtimer-arch.c
|
||||||
|
|
|
@ -73,8 +73,10 @@ cc2520_arch_init(void)
|
||||||
CC2520_VREG_PORT(DIR) |= BV(CC2520_VREG_PIN);
|
CC2520_VREG_PORT(DIR) |= BV(CC2520_VREG_PIN);
|
||||||
CC2520_RESET_PORT(DIR) |= BV(CC2520_RESET_PIN);
|
CC2520_RESET_PORT(DIR) |= BV(CC2520_RESET_PIN);
|
||||||
|
|
||||||
P1DIR &= ~(BV(CC2520_FIFOP_PIN) | BV(CC2520_FIFO_PIN) | BV(CC2520_CCA_PIN));
|
CC2520_FIFOP_PORT(DIR) &= ~(BV(CC2520_FIFOP_PIN));
|
||||||
P2DIR &= ~(BV(CC2520_SFD_PIN));
|
CC2520_FIFO_PORT(DIR) &= ~(BV(CC2520_FIFO_PIN));
|
||||||
|
CC2520_CCA_PORT(DIR) &= ~(BV(CC2520_CCA_PIN));
|
||||||
|
CC2520_SFD_PORT(DIR) &= ~(BV(CC2520_SFD_PIN));
|
||||||
|
|
||||||
#if CONF_SFD_TIMESTAMPS
|
#if CONF_SFD_TIMESTAMPS
|
||||||
cc2520_arch_sfd_init();
|
cc2520_arch_sfd_init();
|
||||||
|
|
|
@ -27,11 +27,8 @@
|
||||||
* SUCH DAMAGE.
|
* SUCH DAMAGE.
|
||||||
*
|
*
|
||||||
* This file is part of the Contiki operating system.
|
* This file is part of the Contiki operating system.
|
||||||
*
|
|
||||||
* @(#)$Id: clock.c,v 1.26 2010/12/16 22:50:21 adamdunkels Exp $
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#include "contiki.h"
|
#include "contiki.h"
|
||||||
#include "sys/energest.h"
|
#include "sys/energest.h"
|
||||||
#include "sys/clock.h"
|
#include "sys/clock.h"
|
||||||
|
@ -49,60 +46,6 @@ static volatile clock_time_t count = 0;
|
||||||
/* last_tar is used for calculating clock_fine */
|
/* last_tar is used for calculating clock_fine */
|
||||||
static volatile uint16_t last_tar = 0;
|
static volatile uint16_t last_tar = 0;
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
#if CONTIKI_TARGET_WISMOTE
|
|
||||||
#ifdef __IAR_SYSTEMS_ICC__
|
|
||||||
#pragma vector=TIMER1_A1_VECTOR
|
|
||||||
__interrupt void
|
|
||||||
#else
|
|
||||||
interrupt(TIMER1_A1_VECTOR)
|
|
||||||
#endif
|
|
||||||
timera1 (void)
|
|
||||||
{
|
|
||||||
ENERGEST_ON(ENERGEST_TYPE_IRQ);
|
|
||||||
|
|
||||||
watchdog_start();
|
|
||||||
|
|
||||||
if(TA1IV == 2) { //CCR1
|
|
||||||
|
|
||||||
// HW timer bug fix: Interrupt handler called before TR==CCR.
|
|
||||||
// Occurrs when timer state is toggled between STOP and CONT.
|
|
||||||
while(TA1CTL & MC1 && TA1CCR1 - TA1R == 1);
|
|
||||||
|
|
||||||
// Make sure interrupt time is futures
|
|
||||||
do {
|
|
||||||
TA1CCR1 += INTERVAL;
|
|
||||||
++count;
|
|
||||||
|
|
||||||
/* Make sure the CLOCK_CONF_SECOND is a power of two, to ensure
|
|
||||||
that the modulo operation below becomes a logical and and not
|
|
||||||
an expensive divide. Algorithm from Wikipedia:
|
|
||||||
http://en.wikipedia.org/wiki/Power_of_two */
|
|
||||||
#if (CLOCK_CONF_SECOND & (CLOCK_CONF_SECOND - 1)) != 0
|
|
||||||
#error CLOCK_CONF_SECOND must be a power of two (i.e., 1, 2, 4, 8, 16, 32, 64, ...).
|
|
||||||
#error Change CLOCK_CONF_SECOND in contiki-conf.h.
|
|
||||||
#endif
|
|
||||||
if(count % CLOCK_CONF_SECOND == 0) {
|
|
||||||
++seconds;
|
|
||||||
energest_flush();
|
|
||||||
}
|
|
||||||
} while((TA1CCR1 - TA1R) > INTERVAL);
|
|
||||||
|
|
||||||
last_tar = TA1R;
|
|
||||||
|
|
||||||
if(etimer_pending() &&
|
|
||||||
(etimer_next_expiration_time() - count - 1) > MAX_TICKS) {
|
|
||||||
etimer_request_poll();
|
|
||||||
LPM4_EXIT;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
/*if(process_nevents() >= 0) {
|
|
||||||
LPM4_EXIT;
|
|
||||||
}*/
|
|
||||||
watchdog_stop();
|
|
||||||
ENERGEST_OFF(ENERGEST_TYPE_IRQ);
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
#ifdef __IAR_SYSTEMS_ICC__
|
#ifdef __IAR_SYSTEMS_ICC__
|
||||||
#pragma vector=TIMERA1_VECTOR
|
#pragma vector=TIMERA1_VECTOR
|
||||||
__interrupt void
|
__interrupt void
|
||||||
|
@ -118,7 +61,7 @@ timera1 (void)
|
||||||
if(TAIV == 2) {
|
if(TAIV == 2) {
|
||||||
|
|
||||||
/* HW timer bug fix: Interrupt handler called before TR==CCR.
|
/* HW timer bug fix: Interrupt handler called before TR==CCR.
|
||||||
* Occurrs when timer state is toggled between STOP and CONT. */
|
* Occurs when timer state is toggled between STOP and CONT. */
|
||||||
while(TACTL & MC1 && TACCR1 - TAR == 1);
|
while(TACTL & MC1 && TACCR1 - TAR == 1);
|
||||||
|
|
||||||
/* Make sure interrupt time is future */
|
/* Make sure interrupt time is future */
|
||||||
|
@ -157,7 +100,6 @@ timera1 (void)
|
||||||
|
|
||||||
ENERGEST_OFF(ENERGEST_TYPE_IRQ);
|
ENERGEST_OFF(ENERGEST_TYPE_IRQ);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
clock_time_t
|
clock_time_t
|
||||||
clock_time(void)
|
clock_time(void)
|
||||||
|
@ -173,13 +115,8 @@ clock_time(void)
|
||||||
void
|
void
|
||||||
clock_set(clock_time_t clock, clock_time_t fclock)
|
clock_set(clock_time_t clock, clock_time_t fclock)
|
||||||
{
|
{
|
||||||
#if CONTIKI_TARGET_WISMOTE
|
|
||||||
TA1R = fclock;
|
|
||||||
TA1CCR1 = fclock + INTERVAL;
|
|
||||||
#else
|
|
||||||
TAR = fclock;
|
TAR = fclock;
|
||||||
TACCR1 = fclock + INTERVAL;
|
TACCR1 = fclock + INTERVAL;
|
||||||
#endif
|
|
||||||
count = clock;
|
count = clock;
|
||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
|
@ -196,42 +133,14 @@ clock_fine(void)
|
||||||
/* Assign last_tar to local varible that can not be changed by interrupt */
|
/* Assign last_tar to local varible that can not be changed by interrupt */
|
||||||
t = last_tar;
|
t = last_tar;
|
||||||
/* perform calc based on t, TAR will not be changed during interrupt */
|
/* perform calc based on t, TAR will not be changed during interrupt */
|
||||||
#if CONTIKI_TARGET_WISMOTE
|
|
||||||
return (unsigned short) (TA1R - t);
|
|
||||||
#else
|
|
||||||
return (unsigned short) (TAR - t);
|
return (unsigned short) (TAR - t);
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
void
|
void
|
||||||
clock_init(void)
|
clock_init(void)
|
||||||
{
|
{
|
||||||
dint();
|
dint();
|
||||||
#if CONTIKI_TARGET_WISMOTE
|
|
||||||
/* Select SMCLK (2.4576MHz), clear TAR */
|
|
||||||
//TA1CTL = TASSEL1 | TACLR | ID_3;
|
|
||||||
|
|
||||||
/* Select ACLK clock, divide*/
|
|
||||||
/* TA1CTL = TASSEL0 | TACLR | ID_1; */
|
|
||||||
|
|
||||||
#if INTERVAL==32768/CLOCK_SECOND
|
|
||||||
TA1CTL = TASSEL0 | TACLR;
|
|
||||||
#elif INTERVAL==16384/CLOCK_SECOND
|
|
||||||
TA1CTL = TASSEL0 | TACLR | ID_1;
|
|
||||||
#else
|
|
||||||
#error NEED TO UPDATE clock.c to match interval!
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Initialize ccr1 to create the X ms interval. */
|
|
||||||
/* CCR1 interrupt enabled, interrupt occurs when timer equals CCR1. */
|
|
||||||
TA1CCTL1 = CCIE;
|
|
||||||
|
|
||||||
/* Interrupt after X ms. */
|
|
||||||
TA1CCR1 = INTERVAL;
|
|
||||||
|
|
||||||
/* Start Timer_A in continuous mode. */
|
|
||||||
TA1CTL |= MC1;
|
|
||||||
#else
|
|
||||||
/* Select SMCLK (2.4576MHz), clear TAR */
|
/* Select SMCLK (2.4576MHz), clear TAR */
|
||||||
/* TACTL = TASSEL1 | TACLR | ID_3; */
|
/* TACTL = TASSEL1 | TACLR | ID_3; */
|
||||||
|
|
||||||
|
@ -250,7 +159,7 @@ clock_init(void)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Initialize ccr1 to create the X ms interval. */
|
/* Initialize ccr1 to create the X ms interval. */
|
||||||
/* CCR1 interrupt enabled, interrupt occurs when timer equals CCR1. */
|
/* CCR1 interrupt enabled, interrupt occurs when timer equals CCR. */
|
||||||
TACCTL1 = CCIE;
|
TACCTL1 = CCIE;
|
||||||
|
|
||||||
/* Interrupt after X ms. */
|
/* Interrupt after X ms. */
|
||||||
|
@ -258,7 +167,7 @@ clock_init(void)
|
||||||
|
|
||||||
/* Start Timer_A in continuous mode. */
|
/* Start Timer_A in continuous mode. */
|
||||||
TACTL |= MC1;
|
TACTL |= MC1;
|
||||||
#endif
|
|
||||||
count = 0;
|
count = 0;
|
||||||
|
|
||||||
/* Enable interrupts. */
|
/* Enable interrupts. */
|
||||||
|
@ -293,7 +202,10 @@ clock_wait(int i)
|
||||||
void
|
void
|
||||||
clock_set_seconds(unsigned long sec)
|
clock_set_seconds(unsigned long sec)
|
||||||
{
|
{
|
||||||
|
int s;
|
||||||
|
s = splhigh();
|
||||||
|
seconds = sec;
|
||||||
|
splx(s);
|
||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
unsigned long
|
unsigned long
|
||||||
|
@ -310,10 +222,11 @@ clock_seconds(void)
|
||||||
rtimer_clock_t
|
rtimer_clock_t
|
||||||
clock_counter(void)
|
clock_counter(void)
|
||||||
{
|
{
|
||||||
#if CONTIKI_TARGET_WISMOTE
|
rtimer_clock_t t1, t2;
|
||||||
return TA1R;
|
do {
|
||||||
#else
|
t1 = TAR;
|
||||||
return TAR;
|
t2 = TAR;
|
||||||
#endif
|
} while(t1 != t2);
|
||||||
|
return t1;
|
||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
|
@ -28,18 +28,18 @@
|
||||||
*
|
*
|
||||||
* This file is part of the Contiki operating system.
|
* This file is part of the Contiki operating system.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "contiki.h"
|
#include "contiki.h"
|
||||||
#include "dev/watchdog.h"
|
#include "dev/watchdog.h"
|
||||||
|
|
||||||
#if DCOSYNCH_CONF_ENABLED
|
|
||||||
/* dco_required set to 1 will cause the CPU not to go into
|
/* dco_required set to 1 will cause the CPU not to go into
|
||||||
sleep modes where the DCO clock stopped */
|
sleep modes where the DCO clock stopped */
|
||||||
int msp430_dco_required;
|
int msp430_dco_required;
|
||||||
#endif /* DCOSYNCH_CONF_ENABLED */
|
|
||||||
|
|
||||||
#if defined(__MSP430__) && defined(__GNUC__)
|
#if defined(__MSP430__) && defined(__GNUC__)
|
||||||
#define asmv(arg) __asm__ __volatile__(arg)
|
#define asmv(arg) __asm__ __volatile__(arg)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
#if defined(__MSP430__) && defined(__GNUC__) && MSP430_MEMCPY_WORKAROUND
|
#if defined(__MSP430__) && defined(__GNUC__) && MSP430_MEMCPY_WORKAROUND
|
||||||
void *
|
void *
|
||||||
|
@ -71,27 +71,6 @@ w_memset(void *out, int value, size_t n)
|
||||||
void
|
void
|
||||||
msp430_init_dco(void)
|
msp430_init_dco(void)
|
||||||
{
|
{
|
||||||
#ifdef __MSP430X__
|
|
||||||
|
|
||||||
#ifdef __IAR_SYSTEMS_ICC__
|
|
||||||
__bis_SR_register(SCG0);
|
|
||||||
#else
|
|
||||||
asmv("bis %0, r2" : : "i" (SCG0));
|
|
||||||
#endif
|
|
||||||
|
|
||||||
UCSCTL0 = 0x0000;
|
|
||||||
UCSCTL1 = DCORSEL_4;
|
|
||||||
|
|
||||||
UCSCTL2 = MSP430_CPU_SPEED / 32768;
|
|
||||||
UCSCTL4 = 0x33; /* instead of 0x44 that is DCO/2 */
|
|
||||||
|
|
||||||
#ifdef __IAR_SYSTEMS_ICC__
|
|
||||||
__bic_SR_register(SCG0);
|
|
||||||
#else
|
|
||||||
asmv("bic %0, r2" : : "i" (SCG0));
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#else
|
|
||||||
/* This code taken from the FU Berlin sources and reformatted. */
|
/* This code taken from the FU Berlin sources and reformatted. */
|
||||||
#define DELTA ((MSP430_CPU_SPEED) / (32768 / 8))
|
#define DELTA ((MSP430_CPU_SPEED) / (32768 / 8))
|
||||||
|
|
||||||
|
@ -109,8 +88,8 @@ msp430_init_dco(void)
|
||||||
asm("nop");
|
asm("nop");
|
||||||
}
|
}
|
||||||
|
|
||||||
CCTL2 = CCIS0 + CM0 + CAP; // Define CCR2, CAP, ACLK
|
CCTL2 = CCIS0 + CM0 + CAP; /* Define CCR2, CAP, ACLK */
|
||||||
TACTL = TASSEL1 + TACLR + MC1; // SMCLK, continous mode
|
TACTL = TASSEL1 + TACLR + MC1; /* SMCLK, continous mode */
|
||||||
|
|
||||||
|
|
||||||
while(1) {
|
while(1) {
|
||||||
|
@ -141,15 +120,13 @@ msp430_init_dco(void)
|
||||||
TACTL = 0; /* Stop Timer_A */
|
TACTL = 0; /* Stop Timer_A */
|
||||||
|
|
||||||
BCSCTL1 &= ~(DIVA1 + DIVA0); /* remove /8 divisor from ACLK again */
|
BCSCTL1 &= ~(DIVA1 + DIVA0); /* remove /8 divisor from ACLK again */
|
||||||
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
static void
|
static void
|
||||||
init_ports(void)
|
init_ports(void)
|
||||||
{
|
{
|
||||||
/* Turn everything off, device drivers enable what is needed. */
|
/* Turn everything off, device drivers enable what is needed. */
|
||||||
|
|
||||||
/* All configured for digital I/O */
|
/* All configured for digital I/O */
|
||||||
#ifdef P1SEL
|
#ifdef P1SEL
|
||||||
P1SEL = 0;
|
P1SEL = 0;
|
||||||
|
@ -227,21 +204,17 @@ static char *cur_break = (char *)&_end;
|
||||||
void
|
void
|
||||||
msp430_add_lpm_req(int req)
|
msp430_add_lpm_req(int req)
|
||||||
{
|
{
|
||||||
#if DCOSYNCH_CONF_ENABLED
|
|
||||||
if(req <= MSP430_REQUIRE_LPM1) {
|
if(req <= MSP430_REQUIRE_LPM1) {
|
||||||
msp430_dco_required++;
|
msp430_dco_required++;
|
||||||
}
|
}
|
||||||
#endif /* DCOSYNCH_CONF_ENABLED */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
msp430_remove_lpm_req(int req)
|
msp430_remove_lpm_req(int req)
|
||||||
{
|
{
|
||||||
#if DCOSYNCH_CONF_ENABLED
|
|
||||||
if(req <= MSP430_REQUIRE_LPM1) {
|
if(req <= MSP430_REQUIRE_LPM1) {
|
||||||
msp430_dco_required--;
|
msp430_dco_required--;
|
||||||
}
|
}
|
||||||
#endif /* DCOSYNCH_CONF_ENABLED */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -258,14 +231,11 @@ msp430_cpu_init(void)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if DCOSYNCH_CONF_ENABLED
|
|
||||||
msp430_dco_required = 0;
|
msp430_dco_required = 0;
|
||||||
#endif /* DCOSYNCH_CONF_ENABLED */
|
|
||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
#define STACK_EXTRA 32
|
#define STACK_EXTRA 32
|
||||||
#define asmv(arg) __asm__ __volatile__(arg)
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Allocate memory from the heap. Check that we don't collide with the
|
* Allocate memory from the heap. Check that we don't collide with the
|
||||||
|
@ -357,13 +327,13 @@ msp430_sync_dco(void) {
|
||||||
/* start the timer */
|
/* start the timer */
|
||||||
TBCTL |= MC1;
|
TBCTL |= MC1;
|
||||||
|
|
||||||
// wait for next Capture
|
/* wait for next Capture */
|
||||||
TBCCTL6 &= ~CCIFG;
|
TBCCTL6 &= ~CCIFG;
|
||||||
while(!(TBCCTL6 & CCIFG));
|
while(!(TBCCTL6 & CCIFG));
|
||||||
last = TBCCR6;
|
last = TBCCR6;
|
||||||
|
|
||||||
TBCCTL6 &= ~CCIFG;
|
TBCCTL6 &= ~CCIFG;
|
||||||
// wait for next Capture - and calculate difference
|
/* wait for next Capture - and calculate difference */
|
||||||
while(!(TBCCTL6 & CCIFG));
|
while(!(TBCCTL6 & CCIFG));
|
||||||
diff = TBCCR6 - last;
|
diff = TBCCR6 - last;
|
||||||
|
|
|
@ -39,6 +39,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "contiki.h"
|
#include "contiki.h"
|
||||||
|
|
||||||
#include "sys/energest.h"
|
#include "sys/energest.h"
|
||||||
#include "sys/rtimer.h"
|
#include "sys/rtimer.h"
|
||||||
#include "sys/process.h"
|
#include "sys/process.h"
|
||||||
|
@ -53,32 +54,8 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
#if CONTIKI_TARGET_WISMOTE
|
|
||||||
#ifdef __IAR_SYSTEMS_ICC__
|
#ifdef __IAR_SYSTEMS_ICC__
|
||||||
#pragma vector=TIMER1_A0_VECTOR
|
#pragma vector=TIMERA0_VECTOR
|
||||||
__interrupt void
|
|
||||||
#else
|
|
||||||
interrupt(TIMER1_A0_VECTOR)
|
|
||||||
#endif
|
|
||||||
timera0 (void)
|
|
||||||
{
|
|
||||||
ENERGEST_ON(ENERGEST_TYPE_IRQ);
|
|
||||||
|
|
||||||
watchdog_start();
|
|
||||||
|
|
||||||
rtimer_run_next();
|
|
||||||
|
|
||||||
if(process_nevents() > 0) {
|
|
||||||
LPM4_EXIT;
|
|
||||||
}
|
|
||||||
|
|
||||||
watchdog_stop();
|
|
||||||
|
|
||||||
ENERGEST_OFF(ENERGEST_TYPE_IRQ);
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
#ifdef __IAR_SYSTEMS_ICC__
|
|
||||||
#pragma vector=TIMER1_A0_VECTOR
|
|
||||||
__interrupt void
|
__interrupt void
|
||||||
#else
|
#else
|
||||||
interrupt(TIMERA0_VECTOR)
|
interrupt(TIMERA0_VECTOR)
|
||||||
|
@ -99,7 +76,6 @@ timera0 (void)
|
||||||
|
|
||||||
ENERGEST_OFF(ENERGEST_TYPE_IRQ);
|
ENERGEST_OFF(ENERGEST_TYPE_IRQ);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
void
|
void
|
||||||
rtimer_arch_init(void)
|
rtimer_arch_init(void)
|
||||||
|
@ -107,11 +83,7 @@ rtimer_arch_init(void)
|
||||||
dint();
|
dint();
|
||||||
|
|
||||||
/* CCR0 interrupt enabled, interrupt occurs when timer equals CCR0. */
|
/* CCR0 interrupt enabled, interrupt occurs when timer equals CCR0. */
|
||||||
#if CONTIKI_TARGET_WISMOTE
|
|
||||||
TA1CCTL0 = CCIE;
|
|
||||||
#else
|
|
||||||
TACCTL0 = CCIE;
|
TACCTL0 = CCIE;
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Enable interrupts. */
|
/* Enable interrupts. */
|
||||||
eint();
|
eint();
|
||||||
|
@ -122,13 +94,8 @@ rtimer_arch_now(void)
|
||||||
{
|
{
|
||||||
rtimer_clock_t t1, t2;
|
rtimer_clock_t t1, t2;
|
||||||
do {
|
do {
|
||||||
#if CONTIKI_TARGET_WISMOTE
|
|
||||||
t1 = TA1R;
|
|
||||||
t2 = TA1R;
|
|
||||||
#else
|
|
||||||
t1 = TAR;
|
t1 = TAR;
|
||||||
t2 = TAR;
|
t2 = TAR;
|
||||||
#endif
|
|
||||||
} while(t1 != t2);
|
} while(t1 != t2);
|
||||||
return t1;
|
return t1;
|
||||||
}
|
}
|
||||||
|
@ -138,10 +105,6 @@ rtimer_arch_schedule(rtimer_clock_t t)
|
||||||
{
|
{
|
||||||
PRINTF("rtimer_arch_schedule time %u\n", t);
|
PRINTF("rtimer_arch_schedule time %u\n", t);
|
||||||
|
|
||||||
#if CONTIKI_TARGET_WISMOTE
|
|
||||||
TA1CCR0 = t;
|
|
||||||
#else
|
|
||||||
TACCR0 = t;
|
TACCR0 = t;
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
|
@ -30,6 +30,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "contiki.h"
|
#include "contiki.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This is SPI initialization code for the MSP430X architecture.
|
* This is SPI initialization code for the MSP430X architecture.
|
||||||
*
|
*
|
||||||
|
@ -66,10 +67,11 @@ spi_init(void)
|
||||||
// Clear pending interrupts before enable!!!
|
// Clear pending interrupts before enable!!!
|
||||||
IFG2 &= ~UCB0RXIFG;
|
IFG2 &= ~UCB0RXIFG;
|
||||||
IFG2 &= ~UCB0TXIFG;
|
IFG2 &= ~UCB0TXIFG;
|
||||||
|
/* UCB0IE &= ~UCRXIFG; */
|
||||||
|
/* UCB0IE &= ~UCTXIFG; */
|
||||||
UCB0CTL1 &= ~UCSWRST; // Remove RESET before enabling interrupts
|
UCB0CTL1 &= ~UCSWRST; // Remove RESET before enabling interrupts
|
||||||
|
|
||||||
//Enable UCB0 Interrupts
|
//Enable UCB0 Interrupts
|
||||||
//IE2 |= UCB0TXIE; // Enable USCI_B0 TX Interrupts
|
//IE2 |= UCB0TXIE; // Enable USCI_B0 TX Interrupts
|
||||||
//IE2 |= UCB0RXIE; // Enable USCI_B0 RX Interrupts
|
//IE2 |= UCB0RXIE; // Enable USCI_B0 RX Interrupts
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
229
cpu/msp430/f5xxx/clock.c
Normal file
229
cpu/msp430/f5xxx/clock.c
Normal file
|
@ -0,0 +1,229 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2011, Swedish Institute of Computer Science
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. Neither the name of the Institute nor the names of its contributors
|
||||||
|
* may be used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* This file is part of the Contiki operating system.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "contiki.h"
|
||||||
|
#include "sys/energest.h"
|
||||||
|
#include "sys/clock.h"
|
||||||
|
#include "sys/etimer.h"
|
||||||
|
#include "rtimer-arch.h"
|
||||||
|
#include "dev/watchdog.h"
|
||||||
|
|
||||||
|
#define INTERVAL (RTIMER_ARCH_SECOND / CLOCK_SECOND)
|
||||||
|
|
||||||
|
#define MAX_TICKS (~((clock_time_t)0) / 2)
|
||||||
|
|
||||||
|
static volatile unsigned long seconds;
|
||||||
|
|
||||||
|
static volatile clock_time_t count = 0;
|
||||||
|
/* last_tar is used for calculating clock_fine, last_ccr might be better? */
|
||||||
|
static volatile uint16_t last_tar = 0;
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
#ifdef __IAR_SYSTEMS_ICC__
|
||||||
|
#pragma vector=TIMER1_A1_VECTOR
|
||||||
|
__interrupt void
|
||||||
|
#else
|
||||||
|
interrupt(TIMER1_A1_VECTOR)
|
||||||
|
#endif
|
||||||
|
timera1 (void)
|
||||||
|
{
|
||||||
|
ENERGEST_ON(ENERGEST_TYPE_IRQ);
|
||||||
|
|
||||||
|
/* watchdog_start(); */
|
||||||
|
|
||||||
|
if(TA1IV == 2) {
|
||||||
|
|
||||||
|
/* HW timer bug fix: Interrupt handler called before TR==CCR.
|
||||||
|
* Occurs when timer state is toggled between STOP and CONT. */
|
||||||
|
while(TA1CTL & MC1 && TA1CCR1 - TA1R == 1);
|
||||||
|
|
||||||
|
/* Make sure interrupt time is future */
|
||||||
|
do {
|
||||||
|
TA1CCR1 += INTERVAL;
|
||||||
|
++count;
|
||||||
|
|
||||||
|
/* Make sure the CLOCK_CONF_SECOND is a power of two, to ensure
|
||||||
|
that the modulo operation below becomes a logical and and not
|
||||||
|
an expensive divide. Algorithm from Wikipedia:
|
||||||
|
http://en.wikipedia.org/wiki/Power_of_two */
|
||||||
|
#if (CLOCK_CONF_SECOND & (CLOCK_CONF_SECOND - 1)) != 0
|
||||||
|
#error CLOCK_CONF_SECOND must be a power of two (i.e., 1, 2, 4, 8, 16, 32, 64, ...).
|
||||||
|
#error Change CLOCK_CONF_SECOND in contiki-conf.h.
|
||||||
|
#endif
|
||||||
|
if(count % CLOCK_CONF_SECOND == 0) {
|
||||||
|
++seconds;
|
||||||
|
energest_flush();
|
||||||
|
}
|
||||||
|
} while((TA1CCR1 - TA1R) > INTERVAL);
|
||||||
|
|
||||||
|
last_tar = TA1R;
|
||||||
|
|
||||||
|
if(etimer_pending() &&
|
||||||
|
(etimer_next_expiration_time() - count - 1) > MAX_TICKS) {
|
||||||
|
etimer_request_poll();
|
||||||
|
LPM4_EXIT;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
/* if(process_nevents() >= 0) {
|
||||||
|
LPM4_EXIT;
|
||||||
|
}*/
|
||||||
|
|
||||||
|
/* watchdog_stop(); */
|
||||||
|
|
||||||
|
ENERGEST_OFF(ENERGEST_TYPE_IRQ);
|
||||||
|
}
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
clock_time_t
|
||||||
|
clock_time(void)
|
||||||
|
{
|
||||||
|
clock_time_t t1, t2;
|
||||||
|
do {
|
||||||
|
t1 = count;
|
||||||
|
t2 = count;
|
||||||
|
} while(t1 != t2);
|
||||||
|
return t1;
|
||||||
|
}
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
void
|
||||||
|
clock_set(clock_time_t clock, clock_time_t fclock)
|
||||||
|
{
|
||||||
|
TA1R = fclock;
|
||||||
|
TA1CCR1 = fclock + INTERVAL;
|
||||||
|
count = clock;
|
||||||
|
}
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
int
|
||||||
|
clock_fine_max(void)
|
||||||
|
{
|
||||||
|
return INTERVAL;
|
||||||
|
}
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
unsigned short
|
||||||
|
clock_fine(void)
|
||||||
|
{
|
||||||
|
unsigned short t;
|
||||||
|
/* Assign last_tar to local varible that can not be changed by interrupt */
|
||||||
|
t = last_tar;
|
||||||
|
/* perform calc based on t, TAR will not be changed during interrupt */
|
||||||
|
return (unsigned short) (TA1R - t);
|
||||||
|
}
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
void
|
||||||
|
clock_init(void)
|
||||||
|
{
|
||||||
|
dint();
|
||||||
|
|
||||||
|
/* Select SMCLK (2.4576MHz), clear TAR */
|
||||||
|
/* TACTL = TASSEL1 | TACLR | ID_3; */
|
||||||
|
|
||||||
|
/* Select ACLK 32768Hz clock, divide by 2 */
|
||||||
|
/* TA1CTL = TASSEL0 | TACLR | ID_1; */
|
||||||
|
|
||||||
|
#if INTERVAL==32768/CLOCK_SECOND
|
||||||
|
TA1CTL = TASSEL0 | TACLR;
|
||||||
|
#elif INTERVAL==16384/CLOCK_SECOND
|
||||||
|
TA1CTL = TASSEL0 | TACLR | ID_1;
|
||||||
|
#else
|
||||||
|
#error NEED TO UPDATE clock.c to match interval!
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Initialize ccr1 to create the X ms interval. */
|
||||||
|
/* CCR1 interrupt enabled, interrupt occurs when timer equals CCR1. */
|
||||||
|
TA1CCTL1 = CCIE;
|
||||||
|
|
||||||
|
/* Interrupt after X ms. */
|
||||||
|
TA1CCR1 = INTERVAL;
|
||||||
|
|
||||||
|
/* Start Timer_A in continuous mode. */
|
||||||
|
TA1CTL |= MC1;
|
||||||
|
|
||||||
|
count = 0;
|
||||||
|
|
||||||
|
/* Enable interrupts. */
|
||||||
|
eint();
|
||||||
|
|
||||||
|
}
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
/**
|
||||||
|
* Delay the CPU for a multiple of 2.83 us.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
clock_delay(unsigned int i)
|
||||||
|
{
|
||||||
|
while(i--) {
|
||||||
|
asm("nop");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
/**
|
||||||
|
* Wait for a multiple of 10 ms.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
clock_wait(int i)
|
||||||
|
{
|
||||||
|
clock_time_t start;
|
||||||
|
|
||||||
|
start = clock_time();
|
||||||
|
while(clock_time() - start < (clock_time_t)i);
|
||||||
|
}
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
void
|
||||||
|
clock_set_seconds(unsigned long sec)
|
||||||
|
{
|
||||||
|
int s;
|
||||||
|
s = splhigh();
|
||||||
|
seconds = sec;
|
||||||
|
splx(s);
|
||||||
|
}
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
unsigned long
|
||||||
|
clock_seconds(void)
|
||||||
|
{
|
||||||
|
unsigned long t1, t2;
|
||||||
|
do {
|
||||||
|
t1 = seconds;
|
||||||
|
t2 = seconds;
|
||||||
|
} while(t1 != t2);
|
||||||
|
return t1;
|
||||||
|
}
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
rtimer_clock_t
|
||||||
|
clock_counter(void)
|
||||||
|
{
|
||||||
|
rtimer_clock_t t1, t2;
|
||||||
|
do {
|
||||||
|
t1 = TA1R;
|
||||||
|
t2 = TA1R;
|
||||||
|
} while(t1 != t2);
|
||||||
|
return t1;
|
||||||
|
}
|
||||||
|
/*---------------------------------------------------------------------------*/
|
238
cpu/msp430/f5xxx/msp430.c
Normal file
238
cpu/msp430/f5xxx/msp430.c
Normal file
|
@ -0,0 +1,238 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2011, Swedish Institute of Computer Science
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. Neither the name of the Institute nor the names of its contributors
|
||||||
|
* may be used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* This file is part of the Contiki operating system.
|
||||||
|
*/
|
||||||
|
#include "contiki.h"
|
||||||
|
#include "dev/watchdog.h"
|
||||||
|
|
||||||
|
/* dco_required set to 1 will cause the CPU not to go into
|
||||||
|
sleep modes where the DCO clock stopped */
|
||||||
|
int msp430_dco_required;
|
||||||
|
|
||||||
|
#if defined(__MSP430__) && defined(__GNUC__)
|
||||||
|
#define asmv(arg) __asm__ __volatile__(arg)
|
||||||
|
#endif
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
void
|
||||||
|
msp430_init_dco(void)
|
||||||
|
{
|
||||||
|
#ifdef __IAR_SYSTEMS_ICC__
|
||||||
|
__bis_SR_register(SCG0);
|
||||||
|
#else
|
||||||
|
asmv("bis %0, r2" : : "i" (SCG0));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
UCSCTL0 = 0x0000;
|
||||||
|
UCSCTL1 = DCORSEL_4;
|
||||||
|
|
||||||
|
UCSCTL2 = MSP430_CPU_SPEED / 32768;
|
||||||
|
UCSCTL4 = 0x33; /* instead of 0x44 that is DCO/2 */
|
||||||
|
|
||||||
|
#ifdef __IAR_SYSTEMS_ICC__
|
||||||
|
__bic_SR_register(SCG0);
|
||||||
|
#else
|
||||||
|
asmv("bic %0, r2" : : "i" (SCG0));
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
static void
|
||||||
|
init_ports(void)
|
||||||
|
{
|
||||||
|
/* Turn everything off, device drivers enable what is needed. */
|
||||||
|
/* All configured for digital I/O */
|
||||||
|
#ifdef P1SEL
|
||||||
|
P1SEL = 0;
|
||||||
|
#endif
|
||||||
|
#ifdef P2SEL
|
||||||
|
P2SEL = 0;
|
||||||
|
#endif
|
||||||
|
#ifdef P3SEL
|
||||||
|
P3SEL = 0;
|
||||||
|
#endif
|
||||||
|
#ifdef P4SEL
|
||||||
|
P4SEL = 0;
|
||||||
|
#endif
|
||||||
|
#ifdef P5SEL
|
||||||
|
P5SEL = 0;
|
||||||
|
#endif
|
||||||
|
#ifdef P6SEL
|
||||||
|
P6SEL = 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* All available inputs */
|
||||||
|
#ifdef P1DIR
|
||||||
|
P1DIR = 0;
|
||||||
|
P1OUT = 0;
|
||||||
|
#endif
|
||||||
|
#ifdef P2DIR
|
||||||
|
P2DIR = 0;
|
||||||
|
P2OUT = 0;
|
||||||
|
#endif
|
||||||
|
#ifdef P3DIR
|
||||||
|
P3DIR = 0;
|
||||||
|
P3OUT = 0;
|
||||||
|
#endif
|
||||||
|
#ifdef P4DIR
|
||||||
|
P4DIR = 0;
|
||||||
|
P4OUT = 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef P5DIR
|
||||||
|
P5DIR = 0;
|
||||||
|
P5OUT = 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef P6DIR
|
||||||
|
P6DIR = 0;
|
||||||
|
P6OUT = 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef P7DIR
|
||||||
|
P7DIR = 0;
|
||||||
|
P7OUT = 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef P8DIR
|
||||||
|
P8DIR = 0;
|
||||||
|
P8OUT = 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
P1IE = 0;
|
||||||
|
P2IE = 0;
|
||||||
|
}
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
/* msp430-ld may align _end incorrectly. Workaround in cpu_init. */
|
||||||
|
#if defined(__MSP430__) && defined(__GNUC__)
|
||||||
|
extern int _end; /* Not in sys/unistd.h */
|
||||||
|
static char *cur_break = (char *)&_end;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
/* add/remove_lpm_req - for requiring a specific LPM mode. currently Contiki */
|
||||||
|
/* jumps to LPM3 to save power, but DMA will not work if DCO is not clocked */
|
||||||
|
/* so some modules might need to enter their LPM requirements */
|
||||||
|
/* NOTE: currently only works with LPM1 (e.g. DCO) requirements. */
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
void
|
||||||
|
msp430_add_lpm_req(int req)
|
||||||
|
{
|
||||||
|
if(req <= MSP430_REQUIRE_LPM1) {
|
||||||
|
msp430_dco_required++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
msp430_remove_lpm_req(int req)
|
||||||
|
{
|
||||||
|
if(req <= MSP430_REQUIRE_LPM1) {
|
||||||
|
msp430_dco_required--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
msp430_cpu_init(void)
|
||||||
|
{
|
||||||
|
dint();
|
||||||
|
watchdog_init();
|
||||||
|
init_ports();
|
||||||
|
msp430_init_dco();
|
||||||
|
eint();
|
||||||
|
#if defined(__MSP430__) && defined(__GNUC__)
|
||||||
|
if((uintptr_t)cur_break & 1) { /* Workaround for msp430-ld bug! */
|
||||||
|
cur_break++;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
msp430_dco_required = 0;
|
||||||
|
}
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#define STACK_EXTRA 32
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Allocate memory from the heap. Check that we don't collide with the
|
||||||
|
* stack right now (some other routine might later). A watchdog might
|
||||||
|
* be used to check if cur_break and the stack pointer meet during
|
||||||
|
* runtime.
|
||||||
|
*/
|
||||||
|
#if defined(__MSP430__) && defined(__GNUC__)
|
||||||
|
void *
|
||||||
|
sbrk(int incr)
|
||||||
|
{
|
||||||
|
char *stack_pointer;
|
||||||
|
|
||||||
|
asmv("mov r1, %0" : "=r" (stack_pointer));
|
||||||
|
stack_pointer -= STACK_EXTRA;
|
||||||
|
if(incr > (stack_pointer - cur_break))
|
||||||
|
return (void *)-1; /* ENOMEM */
|
||||||
|
|
||||||
|
void *old_break = cur_break;
|
||||||
|
cur_break += incr;
|
||||||
|
/*
|
||||||
|
* If the stack was never here then [old_break .. cur_break] should
|
||||||
|
* be filled with zeros.
|
||||||
|
*/
|
||||||
|
return old_break;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
/*
|
||||||
|
* Mask all interrupts that can be masked.
|
||||||
|
*/
|
||||||
|
int
|
||||||
|
splhigh_(void)
|
||||||
|
{
|
||||||
|
int sr;
|
||||||
|
/* Clear the GIE (General Interrupt Enable) flag. */
|
||||||
|
#ifdef __IAR_SYSTEMS_ICC__
|
||||||
|
sr = __get_SR_register();
|
||||||
|
__bic_SR_register(GIE);
|
||||||
|
#else
|
||||||
|
asmv("mov r2, %0" : "=r" (sr));
|
||||||
|
asmv("bic %0, r2" : : "i" (GIE));
|
||||||
|
#endif
|
||||||
|
return sr & GIE; /* Ignore other sr bits. */
|
||||||
|
}
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
#ifdef __IAR_SYSTEMS_ICC__
|
||||||
|
int __low_level_init(void)
|
||||||
|
{
|
||||||
|
/* turn off watchdog so that C-init will run */
|
||||||
|
WDTCTL = WDTPW + WDTHOLD;
|
||||||
|
/*
|
||||||
|
* Return value:
|
||||||
|
*
|
||||||
|
* 1 - Perform data segment initialization.
|
||||||
|
* 0 - Skip data segment initialization.
|
||||||
|
*/
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
/*---------------------------------------------------------------------------*/
|
107
cpu/msp430/f5xxx/rtimer-arch.c
Normal file
107
cpu/msp430/f5xxx/rtimer-arch.c
Normal file
|
@ -0,0 +1,107 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2011, Swedish Institute of Computer Science.
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
* 3. Neither the name of the Institute nor the names of its contributors
|
||||||
|
* may be used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* This file is part of the Contiki operating system.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \file
|
||||||
|
* MSP430-specific rtimer code for MSP430X
|
||||||
|
* \author
|
||||||
|
* Adam Dunkels <adam@sics.se>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "contiki.h"
|
||||||
|
#include "sys/energest.h"
|
||||||
|
#include "sys/rtimer.h"
|
||||||
|
#include "sys/process.h"
|
||||||
|
#include "dev/watchdog.h"
|
||||||
|
|
||||||
|
#define DEBUG 0
|
||||||
|
#if DEBUG
|
||||||
|
#include <stdio.h>
|
||||||
|
#define PRINTF(...) printf(__VA_ARGS__)
|
||||||
|
#else
|
||||||
|
#define PRINTF(...)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
#ifdef __IAR_SYSTEMS_ICC__
|
||||||
|
#pragma vector=TIMER1_A0_VECTOR
|
||||||
|
__interrupt void
|
||||||
|
#else
|
||||||
|
interrupt(TIMER1_A0_VECTOR)
|
||||||
|
#endif
|
||||||
|
timera0 (void)
|
||||||
|
{
|
||||||
|
ENERGEST_ON(ENERGEST_TYPE_IRQ);
|
||||||
|
|
||||||
|
watchdog_start();
|
||||||
|
|
||||||
|
rtimer_run_next();
|
||||||
|
|
||||||
|
if(process_nevents() > 0) {
|
||||||
|
LPM4_EXIT;
|
||||||
|
}
|
||||||
|
|
||||||
|
watchdog_stop();
|
||||||
|
|
||||||
|
ENERGEST_OFF(ENERGEST_TYPE_IRQ);
|
||||||
|
}
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
void
|
||||||
|
rtimer_arch_init(void)
|
||||||
|
{
|
||||||
|
dint();
|
||||||
|
|
||||||
|
/* CCR0 interrupt enabled, interrupt occurs when timer equals CCR0. */
|
||||||
|
TA1CCTL0 = CCIE;
|
||||||
|
|
||||||
|
/* Enable interrupts. */
|
||||||
|
eint();
|
||||||
|
}
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
rtimer_clock_t
|
||||||
|
rtimer_arch_now(void)
|
||||||
|
{
|
||||||
|
rtimer_clock_t t1, t2;
|
||||||
|
do {
|
||||||
|
t1 = TA1R;
|
||||||
|
t2 = TA1R;
|
||||||
|
} while(t1 != t2);
|
||||||
|
return t1;
|
||||||
|
}
|
||||||
|
/*---------------------------------------------------------------------------*/
|
||||||
|
void
|
||||||
|
rtimer_arch_schedule(rtimer_clock_t t)
|
||||||
|
{
|
||||||
|
PRINTF("rtimer_arch_schedule time %u\n", t);
|
||||||
|
|
||||||
|
TA1CCR0 = t;
|
||||||
|
}
|
||||||
|
/*---------------------------------------------------------------------------*/
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2011, Swedish Institute of Computer Science.
|
* Copyright (c) 2011, Swedish Institute of Computer Science
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
@ -42,19 +42,28 @@ unsigned char spi_busy = 0;
|
||||||
void
|
void
|
||||||
spi_init(void)
|
spi_init(void)
|
||||||
{
|
{
|
||||||
UCB0CTL1 |= UCSWRST; // Put state machine in reset
|
// Initialize ports for communication with SPI units.
|
||||||
UCB0CTL1 = UCSSEL0 | UCSSEL1; // Select ACLK
|
|
||||||
UCB0CTL0 |= UCCKPH | UCSYNC | UCMSB | UCMST; // 3-pin, 8-bit SPI master, rising edge capture
|
|
||||||
|
|
||||||
// 16 bit baud rate register
|
UCB0CTL1 |= UCSWRST; //reset usci
|
||||||
UCB0BR0 = 0x00; // MSB => 0
|
UCB0CTL1 |= UCSSEL_2; //smclk while usci is reset
|
||||||
UCB0BR1 = 0x08; // LSB => SMCLK / (UCxxBR0 + UCxxBR1 × 256)
|
UCB0CTL0 = ( UCMSB | UCMST | UCSYNC | UCCKPL); // MSB-first 8-bit, Master, Synchronous, 3 pin SPI master, no ste, watch-out for clock-phase UCCKPH
|
||||||
|
|
||||||
// Set MOSI and SCLK as OUT and MISO as IN ports
|
UCB0BR1 = 0x00;
|
||||||
P3SEL |= ( BIT1 + BIT2 + BIT3 ); // Port3 = SPI peripheral
|
UCB0BR0 = 0x02;
|
||||||
P3DIR |= ( BIT1 + BIT3 ); // MOSI and SCLK as Output
|
|
||||||
P3DIR &= ~BIT2; // Don't forget to configure MISO as Input
|
|
||||||
P3DIR |= BIT0;
|
|
||||||
|
|
||||||
UCB0CTL1 &= ~UCSWRST; // Initialize USCI state machine
|
// UCB0MCTL = 0; // Dont need modulation control.
|
||||||
|
|
||||||
|
P3SEL |= BV(SCK) | BV(MOSI) | BV(MISO); // Select Peripheral functionality
|
||||||
|
P3DIR |= BV(SCK) | BV(MISO); // Configure as outputs(SIMO,CLK).
|
||||||
|
|
||||||
|
//ME1 |= USPIE0; // Module enable ME1 --> U0ME? xxx/bg
|
||||||
|
|
||||||
|
// Clear pending interrupts before enable!!!
|
||||||
|
UCB0IE &= ~UCRXIFG;
|
||||||
|
UCB0IE &= ~UCTXIFG;
|
||||||
|
UCB0CTL1 &= ~UCSWRST; // Remove RESET before enabling interrupts
|
||||||
|
|
||||||
|
//Enable UCB0 Interrupts
|
||||||
|
//IE2 |= UCB0TXIE; // Enable USCI_B0 TX Interrupts
|
||||||
|
//IE2 |= UCB0RXIE; // Enable USCI_B0 RX Interrupts
|
||||||
}
|
}
|
|
@ -43,7 +43,11 @@
|
||||||
|
|
||||||
#include "sys/rtimer.h"
|
#include "sys/rtimer.h"
|
||||||
|
|
||||||
|
#ifdef RTIMER_CONF_SECOND
|
||||||
|
#define RTIMER_ARCH_SECOND RTIMER_CONF_SECOND
|
||||||
|
#else
|
||||||
#define RTIMER_ARCH_SECOND (4096U*8)
|
#define RTIMER_ARCH_SECOND (4096U*8)
|
||||||
|
#endif
|
||||||
|
|
||||||
rtimer_clock_t rtimer_arch_now(void);
|
rtimer_clock_t rtimer_arch_now(void);
|
||||||
|
|
||||||
|
|
|
@ -450,8 +450,6 @@ main(int argc, char **argv)
|
||||||
ENERGEST_ON(ENERGEST_TYPE_CPU);
|
ENERGEST_ON(ENERGEST_TYPE_CPU);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
/*---------------------------------------------------------------------------*/
|
/*---------------------------------------------------------------------------*/
|
||||||
#if LOG_CONF_ENABLED
|
#if LOG_CONF_ENABLED
|
||||||
|
|
|
@ -46,10 +46,11 @@
|
||||||
#define PLATFORM_HAS_BUTTON 1
|
#define PLATFORM_HAS_BUTTON 1
|
||||||
|
|
||||||
/* CPU target speed in Hz */
|
/* CPU target speed in Hz */
|
||||||
#define F_CPU 16000000uL /*2457600uL*/
|
#define F_CPU 16000000uL
|
||||||
|
|
||||||
/* Our clock resolution, this is the same as Unix HZ. */
|
/* Our clock resolution, this is the same as Unix HZ. */
|
||||||
#define CLOCK_CONF_SECOND 128UL
|
#define CLOCK_CONF_SECOND 128UL
|
||||||
|
#define RTIMER_CONF_SECOND (4096U*8)
|
||||||
|
|
||||||
#define BAUD2UBR(baud) ((F_CPU/baud))
|
#define BAUD2UBR(baud) ((F_CPU/baud))
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue