Reincarnate the sensinode/cc2430 port
This commit is contained in:
parent
c78b5bad5c
commit
b7674c3636
114 changed files with 10044 additions and 3068 deletions
|
@ -1,44 +1,83 @@
|
|||
#include <stdio.h>
|
||||
|
||||
#include "contiki.h"
|
||||
#include "sys/clock.h"
|
||||
#include "sys/autostart.h"
|
||||
|
||||
#include "dev/serial-line.h"
|
||||
#include "dev/slip.h"
|
||||
#include "dev/bus.h"
|
||||
#include "dev/leds.h"
|
||||
#include "dev/uart.h"
|
||||
#include "dev/uart1.h"
|
||||
#include "dev/dma.h"
|
||||
#include "dev/models.h"
|
||||
#include "dev/cc2430_rf.h"
|
||||
#include "net/mac/sicslowmac.h"
|
||||
#include "net/mac/frame802154.h"
|
||||
#include "dev/watchdog.h"
|
||||
#include "dev/lpm.h"
|
||||
#include "net/rime.h"
|
||||
#include "net/netstack.h"
|
||||
#include "net/mac/frame802154.h"
|
||||
#include "sensinode-debug.h"
|
||||
#include "dev/watchdog-cc2430.h"
|
||||
#include "dev/sensinode-sensors.h"
|
||||
#include "disco.h"
|
||||
#include "contiki-lib.h"
|
||||
#include "contiki-net.h"
|
||||
|
||||
volatile int i, a;
|
||||
unsigned short node_id = 0; /* Manually sets MAC address when > 0 */
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
print_processes(struct process * const processes[])
|
||||
{
|
||||
printf("Starting");
|
||||
while(*processes != NULL) {
|
||||
printf(" '%s'", (*processes)->name);
|
||||
processes++;
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
putchar(char c)
|
||||
{
|
||||
/* UART1 used for debugging on Sensinode products. */
|
||||
uart1_writeb(c);
|
||||
}
|
||||
#if VIZTOOL_CONF_ON
|
||||
PROCESS_NAME(viztool_process);
|
||||
#endif
|
||||
|
||||
#if BATMON_CONF_ON
|
||||
PROCESS_NAME(batmon_process);
|
||||
#endif
|
||||
|
||||
#if SHORTCUTS_CONF_NETSTACK
|
||||
static __data int len;
|
||||
#endif
|
||||
|
||||
#ifdef STARTUP_CONF_VERBOSE
|
||||
#define STARTUP_VERBOSE STARTUP_CONF_VERBOSE
|
||||
#else
|
||||
#define STARTUP_VERBOSE 0
|
||||
#endif
|
||||
|
||||
#if STARTUP_VERBOSE
|
||||
#define PUTSTRING(...) putstring(__VA_ARGS__)
|
||||
#define PUTHEX(...) puthex(__VA_ARGS__)
|
||||
#define PUTBIN(...) putbin(__VA_ARGS__)
|
||||
#define PUTCHAR(...) putchar(__VA_ARGS__)
|
||||
#else
|
||||
#define PUTSTRING(...) do {} while(0)
|
||||
#define PUTHEX(...) do {} while(0)
|
||||
#define PUTBIN(...) do {} while(0)
|
||||
#define PUTCHAR(...) do {} while(0)
|
||||
#endif
|
||||
|
||||
|
||||
#if !CLOCK_CONF_ACCURATE
|
||||
extern volatile __data clock_time_t count;
|
||||
/* accurate clock is stack hungry */
|
||||
extern volatile __bit sleep_flag;
|
||||
#endif
|
||||
|
||||
extern rimeaddr_t rimeaddr_node_addr;
|
||||
static __data int r;
|
||||
#if ENERGEST_CONF_ON
|
||||
static unsigned long irq_energest = 0;
|
||||
#define ENERGEST_IRQ_SAVE(a) do { \
|
||||
a = energest_type_time(ENERGEST_TYPE_IRQ); } while(0)
|
||||
#define ENERGEST_IRQ_RESTORE(a) do { \
|
||||
energest_type_set(ENERGEST_TYPE_IRQ, a); } while(0)
|
||||
#else
|
||||
#define ENERGEST_IRQ_SAVE(a) do {} while(0)
|
||||
#define ENERGEST_IRQ_RESTORE(a) do {} while(0)
|
||||
#endif
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static void
|
||||
fade(int l)
|
||||
{
|
||||
volatile int i, a;
|
||||
int k, j;
|
||||
for(k = 0; k < 400; ++k) {
|
||||
j = k > 200? 400 - k: k;
|
||||
|
@ -57,52 +96,86 @@ fade(int l)
|
|||
static void
|
||||
set_rime_addr(void)
|
||||
{
|
||||
rimeaddr_t addr;
|
||||
uint8_t ft_buffer[8];
|
||||
uint8_t *addr_long = NULL;
|
||||
uint16_t addr_short = 0;
|
||||
int i;
|
||||
char i;
|
||||
|
||||
/* TODO: This flash_read routine currently gets a different address
|
||||
* than nano_programmer -m... something broken or misconfigured...
|
||||
*/
|
||||
|
||||
flash_read(&ft_buffer[0], 0x1FFF8, 8);
|
||||
|
||||
printf("Read MAC from flash: %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n",
|
||||
ft_buffer[0], ft_buffer[1], ft_buffer[2], ft_buffer[3],
|
||||
ft_buffer[4], ft_buffer[5], ft_buffer[6], ft_buffer[7]);
|
||||
|
||||
memset(&addr, 0, sizeof(rimeaddr_t));
|
||||
|
||||
#if UIP_CONF_IPV6
|
||||
memcpy(addr.u8, ft_buffer, sizeof(addr.u8));
|
||||
#if SHORTCUTS_CONF_FLASH_READ
|
||||
__code unsigned char * macp;
|
||||
#else
|
||||
if(node_id == 0) {
|
||||
for(i = 0; i < sizeof(rimeaddr_t); ++i) {
|
||||
addr.u8[i] = ft_buffer[7 - i];
|
||||
}
|
||||
} else {
|
||||
printf("Setting manual address from node_id\n");
|
||||
addr.u8[1] = node_id >> 8;
|
||||
addr.u8[0] = node_id & 0xff;
|
||||
}
|
||||
static uint8_t ft_buffer[8];
|
||||
#endif
|
||||
|
||||
rimeaddr_set_node_addr(&addr);
|
||||
printf("Rime configured with address ");
|
||||
for(i = (sizeof(addr.u8)) - 1; i > 0; i--) {
|
||||
printf("%02x:", addr.u8[i]);
|
||||
PUTSTRING("Rime is 0x");
|
||||
PUTHEX(sizeof(rimeaddr_t));
|
||||
PUTSTRING(" bytes long\n");
|
||||
|
||||
if(node_id == 0) {
|
||||
PUTSTRING("Reading MAC from flash\n");
|
||||
#if SHORTCUTS_CONF_FLASH_READ
|
||||
/*
|
||||
* The MAC is always stored in 0x1FFF8 of our flash. This maps to address
|
||||
* 0xFFF8 of our CODE segment, when BANK3 is selected.
|
||||
* Switch to BANK3, read 8 bytes starting at 0xFFF8 and restore last BANK
|
||||
* Since we are called from main(), this MUST be BANK1 or something is very
|
||||
* wrong. This code can be used even without banking
|
||||
*/
|
||||
|
||||
/* Don't interrupt us to make sure no BANK switching happens while working */
|
||||
DISABLE_INTERRUPTS();
|
||||
|
||||
/* Switch to BANK3, map CODE: 0x8000 – 0xFFFF to FLASH: 0x18000 – 0x1FFFF */
|
||||
FMAP = 3;
|
||||
|
||||
/* Set our pointer to the correct address and fetch 8 bytes of MAC */
|
||||
macp = (__code unsigned char *) 0xFFF8;
|
||||
|
||||
for(i = (RIMEADDR_SIZE - 1); i >= 0; --i) {
|
||||
rimeaddr_node_addr.u8[i] = *macp;
|
||||
macp++;
|
||||
}
|
||||
|
||||
/* Remap 0x8000 – 0xFFFF to BANK1 */
|
||||
FMAP = 1;
|
||||
ENABLE_INTERRUPTS();
|
||||
#else
|
||||
/*
|
||||
* Or use the more generic flash_read() routine which can read from any
|
||||
* address of our flash
|
||||
*/
|
||||
flash_read(ft_buffer, 0x1FFF8, 8);
|
||||
|
||||
/* Flip the byte order and store MSB first */
|
||||
for(i = (RIMEADDR_SIZE - 1); i >= 0; --i) {
|
||||
rimeaddr_node_addr.u8[RIMEADDR_SIZE - 1 - i] = ft_buffer[i];
|
||||
}
|
||||
#endif
|
||||
|
||||
} else {
|
||||
PUTSTRING("Setting manual address from node_id\n");
|
||||
rimeaddr_node_addr.u8[RIMEADDR_SIZE - 1] = node_id >> 8;
|
||||
rimeaddr_node_addr.u8[RIMEADDR_SIZE - 2] = node_id & 0xff;
|
||||
}
|
||||
printf("%02x\n", addr.u8[i]);
|
||||
|
||||
/* Now the address is stored MSB first */
|
||||
#if STARTUP_VERBOSE
|
||||
PUTSTRING("Rime configured with address ");
|
||||
for(i = 0; i < RIMEADDR_SIZE - 1; i++) {
|
||||
PUTHEX(rimeaddr_node_addr.u8[i]);
|
||||
PUTCHAR(':');
|
||||
}
|
||||
PUTHEX(rimeaddr_node_addr.u8[i]);
|
||||
PUTCHAR('\n');
|
||||
#endif
|
||||
|
||||
/* Set the cc2430 RF addresses */
|
||||
if (sizeof(addr.u8) == 6)
|
||||
addr_long = (uint8_t *) addr.u8;
|
||||
else
|
||||
addr_short = (addr.u8[1] * 256) + addr.u8[0];
|
||||
|
||||
cc2430_rf_set_addr(0xffff, addr_short, addr_long);
|
||||
#if (RIMEADDR_SIZE==8)
|
||||
addr_short = (rimeaddr_node_addr.u8[6] * 256) + rimeaddr_node_addr.u8[7];
|
||||
addr_long = (uint8_t *) &rimeaddr_node_addr;
|
||||
#else
|
||||
addr_short = (rimeaddr_node_addr.u8[0] * 256) + rimeaddr_node_addr.u8[1];
|
||||
#endif
|
||||
cc2430_rf_set_addr(IEEE802154_PANID, addr_short, addr_long);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
int
|
||||
|
@ -111,37 +184,220 @@ main(void)
|
|||
|
||||
/* Hardware initialization */
|
||||
bus_init();
|
||||
rtimer_init();
|
||||
|
||||
/* model-specific h/w init. */
|
||||
model_init();
|
||||
|
||||
/* Init LEDs here */
|
||||
leds_init();
|
||||
fade(LEDS_GREEN);
|
||||
|
||||
uart1_init(115200);
|
||||
uart1_set_input(serial_line_input_byte);
|
||||
|
||||
/* initialize process manager. */
|
||||
process_init();
|
||||
|
||||
/* Init UART1 */
|
||||
uart1_init();
|
||||
|
||||
#if DMA_ON
|
||||
dma_init();
|
||||
#endif
|
||||
|
||||
#if SLIP_ARCH_CONF_ENABLE
|
||||
/* On cc2430, the argument is not used */
|
||||
slip_arch_init(0);
|
||||
#else
|
||||
uart1_set_input(serial_line_input_byte);
|
||||
serial_line_init();
|
||||
#endif
|
||||
|
||||
printf("\n" CONTIKI_VERSION_STRING " started\n");
|
||||
printf("model: " SENSINODE_MODEL "\n\n");
|
||||
PUTSTRING("##########################################\n");
|
||||
putstring(CONTIKI_VERSION_STRING "\n");
|
||||
putstring(SENSINODE_MODEL " (CC24");
|
||||
puthex(((CHIPID >> 3) | 0x20));
|
||||
putstring("-" FLASH_SIZE ")\n");
|
||||
|
||||
/* initialize the radio driver */
|
||||
#if STARTUP_VERBOSE
|
||||
#ifdef HAVE_SDCC_BANKING
|
||||
PUTSTRING(" With Banking.\n");
|
||||
#endif /* HAVE_SDCC_BANKING */
|
||||
#ifdef SDCC_MODEL_LARGE
|
||||
PUTSTRING(" --model-large\n");
|
||||
#endif /* SDCC_MODEL_LARGE */
|
||||
#ifdef SDCC_MODEL_HUGE
|
||||
PUTSTRING(" --model-huge\n");
|
||||
#endif /* SDCC_MODEL_HUGE */
|
||||
#ifdef SDCC_STACK_AUTO
|
||||
PUTSTRING(" --stack-auto\n");
|
||||
#endif /* SDCC_STACK_AUTO */
|
||||
|
||||
cc2430_rf_init();
|
||||
rime_init(sicslowmac_init(&cc2430_rf_driver));
|
||||
set_rime_addr();
|
||||
PUTCHAR('\n');
|
||||
|
||||
PUTSTRING(" Net: ");
|
||||
PUTSTRING(NETSTACK_NETWORK.name);
|
||||
PUTCHAR('\n');
|
||||
PUTSTRING(" MAC: ");
|
||||
PUTSTRING(NETSTACK_MAC.name);
|
||||
PUTCHAR('\n');
|
||||
PUTSTRING(" RDC: ");
|
||||
PUTSTRING(NETSTACK_RDC.name);
|
||||
PUTCHAR('\n');
|
||||
|
||||
PUTSTRING("##########################################\n");
|
||||
#endif
|
||||
|
||||
watchdog_init();
|
||||
|
||||
/* Initialise the cc2430 RNG engine. */
|
||||
random_init(0);
|
||||
|
||||
/* start services */
|
||||
process_start(&etimer_process, NULL);
|
||||
ctimer_init();
|
||||
|
||||
/* initialize the netstack */
|
||||
netstack_init();
|
||||
set_rime_addr();
|
||||
|
||||
#if BUTTON_SENSOR_ON || ADC_SENSOR_ON
|
||||
process_start(&sensors_process, NULL);
|
||||
sensinode_sensors_activate();
|
||||
#endif
|
||||
|
||||
#if UIP_CONF_IPV6
|
||||
memcpy(&uip_lladdr.addr, &rimeaddr_node_addr, sizeof(uip_lladdr.addr));
|
||||
queuebuf_init();
|
||||
process_start(&tcpip_process, NULL);
|
||||
|
||||
#if DISCO_ENABLED
|
||||
process_start(&disco_process, NULL);
|
||||
#endif /* DISCO_ENABLED */
|
||||
|
||||
#if VIZTOOL_CONF_ON
|
||||
process_start(&viztool_process, NULL);
|
||||
#endif
|
||||
|
||||
#if (!UIP_CONF_IPV6_RPL)
|
||||
{
|
||||
uip_ipaddr_t ipaddr;
|
||||
|
||||
uip_ip6addr(&ipaddr, 0x2001, 0x630, 0x301, 0x6453, 0, 0, 0, 0);
|
||||
uip_ds6_set_addr_iid(&ipaddr, &uip_lladdr);
|
||||
uip_ds6_addr_add(&ipaddr, 0, ADDR_TENTATIVE);
|
||||
}
|
||||
#endif /* UIP_CONF_IPV6_RPL */
|
||||
#endif /* UIP_CONF_IPV6 */
|
||||
|
||||
/*
|
||||
* Acknowledge the UART1 RX interrupt
|
||||
* now that we're sure we are ready to process it
|
||||
*/
|
||||
model_uart_intr_en();
|
||||
|
||||
energest_init();
|
||||
ENERGEST_ON(ENERGEST_TYPE_CPU);
|
||||
|
||||
fade(LEDS_RED);
|
||||
|
||||
#if BATMON_CONF_ON
|
||||
process_start(&batmon_process, NULL);
|
||||
#endif
|
||||
|
||||
autostart_start(autostart_processes);
|
||||
|
||||
watchdog_start();
|
||||
|
||||
while(1) {
|
||||
process_run();
|
||||
etimer_request_poll();
|
||||
do {
|
||||
/* Reset watchdog and handle polls and events */
|
||||
watchdog_periodic();
|
||||
|
||||
/**/
|
||||
#if !CLOCK_CONF_ACCURATE
|
||||
if(sleep_flag) {
|
||||
if(etimer_pending() &&
|
||||
(etimer_next_expiration_time() - count - 1) > MAX_TICKS) { /*core/sys/etimer.c*/
|
||||
etimer_request_poll();
|
||||
}
|
||||
sleep_flag = 0;
|
||||
}
|
||||
#endif
|
||||
r = process_run();
|
||||
} while(r > 0);
|
||||
#if SHORTCUTS_CONF_NETSTACK
|
||||
len = NETSTACK_RADIO.pending_packet();
|
||||
if(len) {
|
||||
packetbuf_clear();
|
||||
len = NETSTACK_RADIO.read(packetbuf_dataptr(), PACKETBUF_SIZE);
|
||||
if(len > 0) {
|
||||
packetbuf_set_datalen(len);
|
||||
NETSTACK_RDC.input();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if LPM_MODE
|
||||
#if (LPM_MODE==LPM_MODE_PM2)
|
||||
SLEEP &= ~OSC_PD; /* Make sure both HS OSCs are on */
|
||||
while(!(SLEEP & HFRC_STB)); /* Wait for RCOSC to be stable */
|
||||
CLKCON |= OSC; /* Switch to the RCOSC */
|
||||
while(!(CLKCON & OSC)); /* Wait till it's happened */
|
||||
SLEEP |= OSC_PD; /* Turn the other one off */
|
||||
#endif /* LPM_MODE==LPM_MODE_PM2 */
|
||||
|
||||
/*
|
||||
* Set MCU IDLE or Drop to PM1. Any interrupt will take us out of LPM
|
||||
* Sleep Timer will wake us up in no more than 7.8ms (max idle interval)
|
||||
*/
|
||||
SLEEP = (SLEEP & 0xFC) | (LPM_MODE - 1);
|
||||
|
||||
#if (LPM_MODE==LPM_MODE_PM2)
|
||||
/*
|
||||
* Wait 3 NOPs. Either an interrupt occurred and SLEEP.MODE was cleared or
|
||||
* no interrupt occurred and we can safely power down
|
||||
*/
|
||||
__asm
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
__endasm;
|
||||
|
||||
if (SLEEP & SLEEP_MODE0) {
|
||||
#endif /* LPM_MODE==LPM_MODE_PM2 */
|
||||
|
||||
ENERGEST_OFF(ENERGEST_TYPE_CPU);
|
||||
ENERGEST_ON(ENERGEST_TYPE_LPM);
|
||||
|
||||
/* We are only interested in IRQ energest while idle or in LPM */
|
||||
ENERGEST_IRQ_RESTORE(irq_energest);
|
||||
|
||||
/* Go IDLE or Enter PM1 */
|
||||
PCON |= IDLE;
|
||||
|
||||
/* First instruction upon exiting PM1 must be a NOP */
|
||||
__asm
|
||||
nop
|
||||
__endasm;
|
||||
|
||||
/* Remember energest IRQ for next pass */
|
||||
ENERGEST_IRQ_SAVE(irq_energest);
|
||||
|
||||
ENERGEST_ON(ENERGEST_TYPE_CPU);
|
||||
ENERGEST_OFF(ENERGEST_TYPE_LPM);
|
||||
|
||||
#if (LPM_MODE==LPM_MODE_PM2)
|
||||
SLEEP &= ~OSC_PD; /* Make sure both HS OSCs are on */
|
||||
while(!(SLEEP & XOSC_STB)); /* Wait for XOSC to be stable */
|
||||
CLKCON &= ~OSC; /* Switch to the XOSC */
|
||||
/*
|
||||
* On occasion the XOSC is reported stable when in reality it's not.
|
||||
* We need to wait for a safeguard of 64us or more before selecting it
|
||||
*/
|
||||
clock_delay(10);
|
||||
while(CLKCON & OSC); /* Wait till it's happened */
|
||||
}
|
||||
#endif /* LPM_MODE==LPM_MODE_PM2 */
|
||||
#endif /* LPM_MODE */
|
||||
}
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue