New platform: TI cc2530 Development Kit
This commits adds support for TI's SmartRF05 Eval. Board with cc2530 EMs Some initial support for cc2531 USB dongles
This commit is contained in:
parent
b7674c3636
commit
ad256e5014
68 changed files with 6824 additions and 0 deletions
489
cpu/cc253x/dev/cc2530-rf.c
Normal file
489
cpu/cc253x/dev/cc2530-rf.c
Normal file
|
@ -0,0 +1,489 @@
|
|||
/*
|
||||
* Copyright (c) 2011, George Oikonomou - <oikonomou@users.sourceforge.net>
|
||||
* 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
|
||||
* Implementation of the cc2530 RF driver
|
||||
*
|
||||
* \author
|
||||
* George Oikonomou - <oikonomou@users.sourceforge.net>
|
||||
*/
|
||||
#include "contiki.h"
|
||||
#include "dev/radio.h"
|
||||
#include "dev/cc2530-rf.h"
|
||||
#include "cc253x.h"
|
||||
#include "sfr-bits.h"
|
||||
#include "sys/clock.h"
|
||||
#include "sys/rtimer.h"
|
||||
|
||||
#include "net/packetbuf.h"
|
||||
#include "net/rime/rimestats.h"
|
||||
#include "net/netstack.h"
|
||||
|
||||
#include <string.h>
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#define CHECKSUM_LEN 2
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#if CC2530_RF_CONF_LEDS
|
||||
#define CC2530_RF_LEDS CC2530_RF_CONF_LEDS
|
||||
#else
|
||||
#define CC2530_RF_LEDS 0
|
||||
#endif
|
||||
|
||||
#if CC2530_RF_LEDS
|
||||
#include "dev/leds.h"
|
||||
#define RF_RX_LED_ON() leds_on(LEDS_RED);
|
||||
#define RF_RX_LED_OFF() leds_off(LEDS_RED);
|
||||
#define RF_TX_LED_ON() leds_on(LEDS_GREEN);
|
||||
#define RF_TX_LED_OFF() leds_off(LEDS_GREEN);
|
||||
#else
|
||||
#define RF_RX_LED_ON()
|
||||
#define RF_RX_LED_OFF()
|
||||
#define RF_TX_LED_ON()
|
||||
#define RF_TX_LED_OFF()
|
||||
#endif
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#define DEBUG 0
|
||||
#if DEBUG
|
||||
#include "debug.h"
|
||||
#define PUTSTRING(...) putstring(__VA_ARGS__)
|
||||
#define PUTHEX(...) puthex(__VA_ARGS__)
|
||||
#else
|
||||
#define PUTSTRING(...)
|
||||
#define PUTHEX(...)
|
||||
#endif
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Local RF Flags */
|
||||
#define RX_ACTIVE 0x80
|
||||
#define WAS_OFF 0x10
|
||||
#define RF_ON 0x01
|
||||
|
||||
/* Bit Masks for the last byte in the RX FIFO */
|
||||
#define CRC_BIT_MASK 0x80
|
||||
#define LQI_BIT_MASK 0x7F
|
||||
|
||||
/* 192 ms, radio off -> on interval */
|
||||
#define ONOFF_TIME RTIMER_ARCH_SECOND / 3125
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#if CC2530_RF_CONF_HEXDUMP
|
||||
#include "uart0.h"
|
||||
static const uint8_t magic[] = { 0x53, 0x6E, 0x69, 0x66 }; /* Snif */
|
||||
#endif
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#ifdef CC2530_RF_CONF_AUTOACK
|
||||
#define CC2530_RF_AUTOACK CC2530_RF_CONF_AUTOACK
|
||||
#else
|
||||
#define CC2530_RF_AUTOACK 1
|
||||
#endif
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static uint8_t __data rf_flags;
|
||||
|
||||
static int on(void); /* prepare() needs our prototype */
|
||||
static int off(void); /* transmit() needs our prototype */
|
||||
static int channel_clear(void); /* transmit() needs our prototype */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
int8_t
|
||||
cc2530_rf_channel_set(uint8_t channel)
|
||||
{
|
||||
PUTSTRING("RF: Set Chan\n");
|
||||
|
||||
if((channel < CC2530_RF_CHANNEL_MIN) || (channel > CC2530_RF_CHANNEL_MAX)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Changes to FREQCTRL take effect after the next recalibration */
|
||||
off();
|
||||
FREQCTRL = (CC2530_RF_CHANNEL_MIN
|
||||
+ (channel - CC2530_RF_CHANNEL_MIN) * CC2530_RF_CHANNEL_SPACING);
|
||||
on();
|
||||
|
||||
return (int8_t) channel;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
uint8_t
|
||||
cc2530_rf_power_set(uint8_t new_power)
|
||||
{
|
||||
PUTSTRING("RF: Set Power\n");
|
||||
/* off() */
|
||||
TXPOWER = new_power;
|
||||
/* on() */
|
||||
|
||||
return TXPOWER;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
cc2530_rf_set_addr(uint16_t pan)
|
||||
{
|
||||
PAN_ID0 = pan & 0xFF;
|
||||
PAN_ID1 = pan >> 8;
|
||||
|
||||
SHORT_ADDR0 = ((uint8_t *)&X_IEEE_ADDR)[0];
|
||||
SHORT_ADDR1 = ((uint8_t *)&X_IEEE_ADDR)[1];
|
||||
|
||||
memcpy(&EXT_ADDR0, &X_IEEE_ADDR, 8);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Netstack API radio driver functions */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static int
|
||||
init(void)
|
||||
{
|
||||
PUTSTRING("RF: Init\n");
|
||||
|
||||
if(rf_flags & RF_ON) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CC2530_RF_LOW_POWER_RX
|
||||
/* Reduce RX power consumption current to 20mA at the cost of sensitivity */
|
||||
RXCTRL = 0x00;
|
||||
FSCTRL = 0x50;
|
||||
#else
|
||||
RXCTRL = 0x3F;
|
||||
FSCTRL = 0x55;
|
||||
#endif /* CC2530_RF_LOW_POWER_RX */
|
||||
|
||||
CCACTRL0 = CC2530_RF_CCA_THRES;
|
||||
|
||||
/*
|
||||
* According to the user guide, these registers must be updated from their
|
||||
* defaults for optimal performance
|
||||
*
|
||||
* Table 23-6, Sec. 23.15.1, p. 259
|
||||
*/
|
||||
TXFILTCFG = 0x09; /* TX anti-aliasing filter */
|
||||
AGCCTRL1 = 0x15; /* AGC target value */
|
||||
FSCAL1 = 0x00; /* Reduce the VCO leakage */
|
||||
|
||||
/* Auto ACKs and CRC calculation, default RX and TX modes with FIFOs */
|
||||
FRMCTRL0 = FRMCTRL0_AUTOCRC;
|
||||
#if CC2530_RF_AUTOACK
|
||||
FRMCTRL0 |= FRMCTRL0_AUTOACK;
|
||||
#endif
|
||||
|
||||
/* Disable source address matching and autopend */
|
||||
SRCMATCH = 0; /* investigate */
|
||||
|
||||
/* MAX FIFOP threshold */
|
||||
FIFOPCTRL = CC2530_RF_MAX_PACKET_LEN;
|
||||
|
||||
cc2530_rf_power_set(CC2530_RF_TX_POWER);
|
||||
cc2530_rf_channel_set(CC2530_RF_CHANNEL);
|
||||
|
||||
RF_TX_LED_OFF();
|
||||
RF_RX_LED_OFF();
|
||||
|
||||
rf_flags |= RF_ON;
|
||||
|
||||
return 1;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static int
|
||||
prepare(const void *payload, unsigned short payload_len)
|
||||
{
|
||||
uint8_t i;
|
||||
|
||||
PUTSTRING("RF: Prepare 0x");
|
||||
PUTHEX(payload_len + CHECKSUM_LEN);
|
||||
PUTSTRING(" bytes\n");
|
||||
|
||||
/*
|
||||
* When we transmit in very quick bursts, make sure previous transmission
|
||||
* is not still in progress before re-writing to the TX FIFO
|
||||
*/
|
||||
while(FSMSTAT1 & FSMSTAT1_TX_ACTIVE);
|
||||
|
||||
if((rf_flags & RX_ACTIVE) == 0) {
|
||||
on();
|
||||
}
|
||||
|
||||
CC2530_CSP_ISFLUSHTX();
|
||||
|
||||
PUTSTRING("RF: data = ");
|
||||
/* Send the phy length byte first */
|
||||
RFD = payload_len + CHECKSUM_LEN; /* Payload plus FCS */
|
||||
for(i = 0; i < payload_len; i++) {
|
||||
RFD = ((unsigned char*) (payload))[i];
|
||||
PUTHEX(((unsigned char*)(payload))[i]);
|
||||
}
|
||||
PUTSTRING("\n");
|
||||
|
||||
/* Leave space for the FCS */
|
||||
RFD = 0;
|
||||
RFD = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static int
|
||||
transmit(unsigned short transmit_len)
|
||||
{
|
||||
uint8_t counter;
|
||||
int ret = RADIO_TX_ERR;
|
||||
rtimer_clock_t t0;
|
||||
transmit_len; /* hush the warning */
|
||||
|
||||
if(!(rf_flags & RX_ACTIVE)) {
|
||||
t0 = RTIMER_NOW();
|
||||
on();
|
||||
rf_flags |= WAS_OFF;
|
||||
while (RTIMER_CLOCK_LT(RTIMER_NOW(), t0 + ONOFF_TIME));
|
||||
}
|
||||
|
||||
if(channel_clear() == CC2530_RF_CCA_BUSY) {
|
||||
RIMESTATS_ADD(contentiondrop);
|
||||
return RADIO_TX_COLLISION;
|
||||
}
|
||||
|
||||
/*
|
||||
* prepare() double checked that TX_ACTIVE is low. If SFD is high we are
|
||||
* receiving. Abort transmission and bail out with RADIO_TX_COLLISION
|
||||
*/
|
||||
if(FSMSTAT1 & FSMSTAT1_SFD) {
|
||||
RIMESTATS_ADD(contentiondrop);
|
||||
return RADIO_TX_COLLISION;
|
||||
}
|
||||
|
||||
/* Start the transmission */
|
||||
RF_TX_LED_ON();
|
||||
ENERGEST_OFF(ENERGEST_TYPE_LISTEN);
|
||||
ENERGEST_ON(ENERGEST_TYPE_TRANSMIT);
|
||||
|
||||
CC2530_CSP_ISTXON();
|
||||
|
||||
counter = 0;
|
||||
while(!(FSMSTAT1 & FSMSTAT1_TX_ACTIVE) && (counter++ < 3)) {
|
||||
clock_delay(10);
|
||||
}
|
||||
|
||||
if(!(FSMSTAT1 & FSMSTAT1_TX_ACTIVE)) {
|
||||
PUTSTRING("RF: TX never active.\n");
|
||||
CC2530_CSP_ISFLUSHTX();
|
||||
ret = RADIO_TX_ERR;
|
||||
} else {
|
||||
/* Wait for the transmission to finish */
|
||||
while(FSMSTAT1 & FSMSTAT1_TX_ACTIVE);
|
||||
ret = RADIO_TX_OK;
|
||||
}
|
||||
ENERGEST_OFF(ENERGEST_TYPE_TRANSMIT);
|
||||
ENERGEST_ON(ENERGEST_TYPE_LISTEN);
|
||||
|
||||
if(rf_flags & WAS_OFF){
|
||||
off();
|
||||
}
|
||||
|
||||
RIMESTATS_ADD(lltx);
|
||||
|
||||
RF_TX_LED_OFF();
|
||||
|
||||
/* OK, sent. We are now ready to send more */
|
||||
return ret;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static int
|
||||
send(void *payload, unsigned short payload_len)
|
||||
{
|
||||
prepare(payload, payload_len);
|
||||
return transmit(payload_len);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static int
|
||||
read(void *buf, unsigned short bufsize)
|
||||
{
|
||||
uint8_t i;
|
||||
uint8_t len;
|
||||
uint8_t crc_corr;
|
||||
int8_t rssi;
|
||||
|
||||
PUTSTRING("RF: Read\n");
|
||||
|
||||
/* Check the length */
|
||||
len = RFD;
|
||||
|
||||
/* Check for validity */
|
||||
if(len > CC2530_RF_MAX_PACKET_LEN) {
|
||||
/* Oops, we must be out of sync. */
|
||||
PUTSTRING("RF: bad sync\n");
|
||||
|
||||
RIMESTATS_ADD(badsynch);
|
||||
CC2530_CSP_ISFLUSHRX();
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(len <= CC2530_RF_MIN_PACKET_LEN) {
|
||||
PUTSTRING("RF: too short\n");
|
||||
|
||||
RIMESTATS_ADD(tooshort);
|
||||
CC2530_CSP_ISFLUSHRX();
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(len - CHECKSUM_LEN > bufsize) {
|
||||
PUTSTRING("RF: too long\n");
|
||||
|
||||
RIMESTATS_ADD(toolong);
|
||||
CC2530_CSP_ISFLUSHRX();
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if CC2530_RF_CONF_HEXDUMP
|
||||
/* If we reach here, chances are the FIFO is holding a valid frame */
|
||||
uart0_writeb(magic[0]);
|
||||
uart0_writeb(magic[1]);
|
||||
uart0_writeb(magic[2]);
|
||||
uart0_writeb(magic[3]);
|
||||
uart0_writeb(len);
|
||||
#endif
|
||||
|
||||
RF_RX_LED_ON();
|
||||
|
||||
PUTSTRING("RF: read (0x");
|
||||
PUTHEX(len);
|
||||
PUTSTRING(" bytes) = ");
|
||||
len -= CHECKSUM_LEN;
|
||||
for(i = 0; i < len; ++i) {
|
||||
((unsigned char*)(buf))[i] = RFD;
|
||||
#if CC2530_RF_CONF_HEXDUMP
|
||||
uart0_writeb(((unsigned char*)(buf))[i]);
|
||||
#endif
|
||||
PUTHEX(((unsigned char*)(buf))[i]);
|
||||
}
|
||||
PUTSTRING("\n");
|
||||
|
||||
/* Read the RSSI and CRC/Corr bytes */
|
||||
rssi = ((int8_t) RFD) - 45;
|
||||
crc_corr = RFD;
|
||||
|
||||
#if CC2530_RF_CONF_HEXDUMP
|
||||
uart0_writeb(rssi);
|
||||
uart0_writeb(crc_corr);
|
||||
#endif
|
||||
|
||||
/* MS bit CRC OK/Not OK, 7 LS Bits, Correlation value */
|
||||
if(crc_corr & CRC_BIT_MASK) {
|
||||
packetbuf_set_attr(PACKETBUF_ATTR_RSSI, rssi);
|
||||
packetbuf_set_attr(PACKETBUF_ATTR_LINK_QUALITY, crc_corr & LQI_BIT_MASK);
|
||||
RIMESTATS_ADD(llrx);
|
||||
} else {
|
||||
RIMESTATS_ADD(badcrc);
|
||||
CC2530_CSP_ISFLUSHRX();
|
||||
RF_RX_LED_OFF();
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* If FIFOP==1 and FIFO==0 then we had a FIFO overflow at some point. */
|
||||
if((FSMSTAT1 & (FSMSTAT1_FIFO | FSMSTAT1_FIFOP)) == FSMSTAT1_FIFOP) {
|
||||
/*
|
||||
* If we reach here means that there might be more intact packets in the
|
||||
* FIFO despite the overflow. This can happen with bursts of small packets.
|
||||
*
|
||||
* Only flush if the FIFO is actually empty. If not, then next pass we will
|
||||
* pick up one more packet or flush due to an error.
|
||||
*/
|
||||
if(!RXFIFOCNT) {
|
||||
CC2530_CSP_ISFLUSHRX();
|
||||
}
|
||||
}
|
||||
|
||||
RF_RX_LED_OFF();
|
||||
|
||||
return (len);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static int
|
||||
channel_clear(void)
|
||||
{
|
||||
if(FSMSTAT1 & FSMSTAT1_CCA) {
|
||||
return CC2530_RF_CCA_CLEAR;
|
||||
}
|
||||
return CC2530_RF_CCA_BUSY;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static int
|
||||
receiving_packet(void)
|
||||
{
|
||||
PUTSTRING("RF: Receiving\n");
|
||||
|
||||
/*
|
||||
* SFD high while transmitting and receiving.
|
||||
* TX_ACTIVE high only when transmitting
|
||||
*
|
||||
* FSMSTAT1 & (TX_ACTIVE | SFD) == SFD <=> receiving
|
||||
*/
|
||||
return (FSMSTAT1 & (FSMSTAT1_TX_ACTIVE | FSMSTAT1_SFD) == FSMSTAT1_SFD);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static int
|
||||
pending_packet(void)
|
||||
{
|
||||
return (FSMSTAT1 & FSMSTAT1_FIFOP);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static int
|
||||
on(void)
|
||||
{
|
||||
if(!(rf_flags & RX_ACTIVE)) {
|
||||
CC2530_CSP_ISFLUSHRX();
|
||||
CC2530_CSP_ISRXON();
|
||||
|
||||
rf_flags |= RX_ACTIVE;
|
||||
}
|
||||
|
||||
ENERGEST_ON(ENERGEST_TYPE_LISTEN);
|
||||
return 1;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
static int
|
||||
off(void)
|
||||
{
|
||||
CC2530_CSP_ISRFOFF();
|
||||
CC2530_CSP_ISFLUSHRX();
|
||||
|
||||
rf_flags = 0;
|
||||
|
||||
ENERGEST_OFF(ENERGEST_TYPE_LISTEN);
|
||||
return 1;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
const struct radio_driver cc2530_rf_driver =
|
||||
{
|
||||
init,
|
||||
prepare,
|
||||
transmit,
|
||||
send,
|
||||
read,
|
||||
channel_clear,
|
||||
receiving_packet,
|
||||
pending_packet,
|
||||
on,
|
||||
off,
|
||||
};
|
||||
/*---------------------------------------------------------------------------*/
|
127
cpu/cc253x/dev/cc2530-rf.h
Normal file
127
cpu/cc253x/dev/cc2530-rf.h
Normal file
|
@ -0,0 +1,127 @@
|
|||
/*
|
||||
* Copyright (c) 2011, George Oikonomou - <oikonomou@users.sourceforge.net>
|
||||
* 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
|
||||
* Implementation of the cc2530 RF driver
|
||||
*
|
||||
* \author
|
||||
* George Oikonomou - <oikonomou@users.sourceforge.net>
|
||||
*/
|
||||
#ifndef __CC2530_RF_H__
|
||||
#define __CC2530_RF_H__
|
||||
|
||||
#include "contiki.h"
|
||||
#include "dev/radio.h"
|
||||
#include "cc253x.h"
|
||||
/*---------------------------------------------------------------------------
|
||||
* RF Config
|
||||
*---------------------------------------------------------------------------*/
|
||||
#define CC2530_RF_TX_POWER_RECOMMENDED 0xD5
|
||||
#ifdef CC2530_RF_CONF_TX_POWER
|
||||
#define CC2530_RF_TX_POWER CC2530_RF_CONF_TX_POWER
|
||||
#else
|
||||
#define CC2530_RF_TX_POWER CC2530_RF_TX_POWER_RECOMMENDED
|
||||
#endif /* CC2530_RF_CONF_TX_POWER */
|
||||
|
||||
#ifdef CC2530_RF_CONF_CCA_THRES
|
||||
#define CC2530_RF_CCA_THRES CC2530_RF_CONF_CCA_THRES
|
||||
#else
|
||||
#define CC2530_RF_CCA_THRES CCA_THRES_USER_GUIDE /* User guide recommendation */
|
||||
#endif /* CC2530_RF_CONF_CCA_THRES */
|
||||
|
||||
#ifdef CC2530_RF_CONF_CHANNEL
|
||||
#define CC2530_RF_CHANNEL CC2530_RF_CONF_CHANNEL
|
||||
#else
|
||||
#define CC2530_RF_CHANNEL 18
|
||||
#endif /* CC2530_RF_CONF_CHANNEL */
|
||||
#define CC2530_RF_CHANNEL_MIN 11
|
||||
#define CC2530_RF_CHANNEL_MAX 26
|
||||
#define CC2530_RF_CHANNEL_SPACING 5
|
||||
|
||||
#ifdef CC2530_RF_CONF_AUTOACK
|
||||
#define CC2530_RF_AUTOACK CC2530_RF_CONF_AUTOACK
|
||||
#else
|
||||
#define CC2530_RF_AUTOACK 1
|
||||
#endif /* CC2530_RF_CONF_AUTOACK */
|
||||
|
||||
#ifdef CC2530_RF_CONF_LOW_POWER_RX
|
||||
#define CC2530_RF_LOW_POWER_RX CC2530_RF_CONF_LOW_POWER_RX
|
||||
#else
|
||||
#define CC2530_RF_LOW_POWER_RX 0
|
||||
#endif /* CC2530_RF_CONF_LOW_POWER_RX */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#define CCA_THRES_USER_GUIDE 0xF8
|
||||
#define CCA_THRES_ALONE 0xFC /* -4-76=-80dBm when CC2530 operated alone or with CC2591 in LGM */
|
||||
#define CCA_THR_HGM 0x06 /* 6-76=-70dBm when CC2530 operated with CC2591 in HGM */
|
||||
#define CORR_THR 0x14
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#define CC2530_RF_MAX_PACKET_LEN 127
|
||||
#define CC2530_RF_MIN_PACKET_LEN 4
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#define CC2530_RF_CCA_CLEAR 1
|
||||
#define CC2530_RF_CCA_BUSY 0
|
||||
|
||||
/* Wait for RSSI to be valid. */
|
||||
#define CC2530_RF_CCA_VALID_WAIT() while(!(RSSISTAT & RSSIST))
|
||||
/*---------------------------------------------------------------------------
|
||||
* Command Strobe Processor
|
||||
*---------------------------------------------------------------------------*/
|
||||
/* OPCODES */
|
||||
#define CSP_OP_ISRXON 0xE3
|
||||
#define CSP_OP_ISTXON 0xE9
|
||||
#define CSP_OP_ISTXONCCA 0xEA
|
||||
#define CSP_OP_ISRFOFF 0xEF
|
||||
#define CSP_OP_ISFLUSHRX 0xED
|
||||
#define CSP_OP_ISFLUSHTX 0xEE
|
||||
|
||||
#define CC2530_CSP_ISRXON() do { RFST = CSP_OP_ISRXON; } while(0)
|
||||
#define CC2530_CSP_ISTXON() do { RFST = CSP_OP_ISTXON; } while(0)
|
||||
#define CC2530_CSP_ISTXONCCA() do { RFST = CSP_OP_ISTXONCCA; } while(0)
|
||||
#define CC2530_CSP_ISRFOFF() do { RFST = CSP_OP_ISRFOFF; } while(0)
|
||||
|
||||
/* OP x 2 for flushes */
|
||||
#define CC2530_CSP_ISFLUSHRX() do { \
|
||||
RFST = CSP_OP_ISFLUSHRX; \
|
||||
RFST = CSP_OP_ISFLUSHRX; \
|
||||
} while(0)
|
||||
#define CC2530_CSP_ISFLUSHTX() do { \
|
||||
RFST = CSP_OP_ISFLUSHTX; \
|
||||
RFST = CSP_OP_ISFLUSHTX; \
|
||||
} while(0)
|
||||
/*---------------------------------------------------------------------------*/
|
||||
extern const struct radio_driver cc2530_rf_driver;
|
||||
/*---------------------------------------------------------------------------*/
|
||||
int8_t cc2530_rf_channel_set(uint8_t channel);
|
||||
uint8_t cc2530_rf_power_set(uint8_t new_power);
|
||||
void cc2530_rf_set_addr(uint16_t pan);
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#endif /* __CC2530_RF_H__ */
|
46
cpu/cc253x/dev/clock-isr.h
Normal file
46
cpu/cc253x/dev/clock-isr.h
Normal file
|
@ -0,0 +1,46 @@
|
|||
/*
|
||||
* Copyright (c) 2011, George Oikonomou - <oikonomou@users.sourceforge.net>
|
||||
* 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
|
||||
* Declaration of the Sleep timer ISR, used by the clock module
|
||||
* \author
|
||||
* George Oikonomou - <oikonomou@users.sourceforge.net>
|
||||
*/
|
||||
#ifndef __CLOCK_ISR_H__
|
||||
#define __CLOCK_ISR_H__
|
||||
|
||||
#include "contiki-conf.h"
|
||||
#include "cc253x.h"
|
||||
|
||||
void clock_isr(void) __interrupt(ST_VECTOR);
|
||||
|
||||
#endif /* __CLOCK_ISR_H__ */
|
182
cpu/cc253x/dev/clock.c
Normal file
182
cpu/cc253x/dev/clock.c
Normal file
|
@ -0,0 +1,182 @@
|
|||
/*
|
||||
* Copyright (c) 2009, 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.
|
||||
*
|
||||
* $Id: clock.c,v 1.1 2009/09/08 20:07:35 zdshelby Exp $
|
||||
*/
|
||||
|
||||
/**
|
||||
* \file
|
||||
* Implementation of the clock functions for the 8051 CPU
|
||||
* \author
|
||||
* Zach Shelby (zach@sensinode.com) - original
|
||||
* George Oikonomou - <oikonomou@users.sourceforge.net> - cc2530 port
|
||||
*/
|
||||
#include "sfr-bits.h"
|
||||
#include "sys/clock.h"
|
||||
#include "sys/etimer.h"
|
||||
#include "cc253x.h"
|
||||
#include "sys/energest.h"
|
||||
|
||||
/* Sleep timer runs on the 32k RC osc. */
|
||||
/* One clock tick is 7.8 ms */
|
||||
#define TICK_VAL (32768/128) /* 256 */
|
||||
|
||||
#define MAX_TICKS (~((clock_time_t)0) / 2)
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Do NOT remove the absolute address and do NOT remove the initialiser here */
|
||||
__xdata __at(0x0000) static unsigned long timer_value = 0;
|
||||
|
||||
static volatile __data clock_time_t count = 0; /* Uptime in ticks */
|
||||
static volatile __data clock_time_t seconds = 0; /* Uptime in secs */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/**
|
||||
* One delay is about 0.6 us, so this function delays for len * 0.6 us
|
||||
*/
|
||||
void
|
||||
clock_delay(unsigned int len)
|
||||
{
|
||||
unsigned int i;
|
||||
for(i = 0; i< len; i++) {
|
||||
ASM(nop);
|
||||
}
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/**
|
||||
* Wait for a multiple of ~8 ms (a tick)
|
||||
*/
|
||||
void
|
||||
clock_wait(int i)
|
||||
{
|
||||
clock_time_t start;
|
||||
|
||||
start = clock_time();
|
||||
while(clock_time() - start < (clock_time_t)i);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
CCIF clock_time_t
|
||||
clock_time(void)
|
||||
{
|
||||
return count;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
CCIF unsigned long
|
||||
clock_seconds(void)
|
||||
{
|
||||
return seconds;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/*
|
||||
* There is some ambiguity between TI cc2530 software examples and information
|
||||
* in the datasheet.
|
||||
*
|
||||
* TI examples appear to be writing to SLEEPCMD, initialising hardware in a
|
||||
* fashion semi-similar to cc2430
|
||||
*
|
||||
* However, the datasheet claims that those bits in SLEEPCMD are reserved
|
||||
*
|
||||
* The code here goes by the datasheet (ignore TI examples) and seems to work.
|
||||
*/
|
||||
void
|
||||
clock_init(void)
|
||||
{
|
||||
/* Make sure we know where we stand */
|
||||
CLKCONCMD = CLKCONCMD_OSC32K | CLKCONCMD_OSC;
|
||||
|
||||
/* Stay with 32 KHz RC OSC, Chance System Clock to 32 MHz */
|
||||
CLKCONCMD &= ~CLKCONCMD_OSC;
|
||||
while(CLKCONSTA & CLKCONCMD_OSC);
|
||||
|
||||
/* Tickspeed 500 kHz for timers[1-4] */
|
||||
CLKCONCMD |= CLKCONCMD_TICKSPD2 | CLKCONCMD_TICKSPD1;
|
||||
while(CLKCONSTA != CLKCONCMD);
|
||||
|
||||
/*Initialize tick value*/
|
||||
timer_value = ST0;
|
||||
timer_value += ((unsigned long int) ST1) << 8;
|
||||
timer_value += ((unsigned long int) ST2) << 16;
|
||||
timer_value += TICK_VAL;
|
||||
ST2 = (unsigned char) (timer_value >> 16);
|
||||
ST1 = (unsigned char) (timer_value >> 8);
|
||||
ST0 = (unsigned char) timer_value;
|
||||
|
||||
STIE = 1; /* IEN0.STIE interrupt enable */
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
clock_isr(void) __interrupt(ST_VECTOR)
|
||||
{
|
||||
DISABLE_INTERRUPTS();
|
||||
ENERGEST_ON(ENERGEST_TYPE_IRQ);
|
||||
|
||||
/*
|
||||
* If the Sleep timer throws an interrupt while we are powering down to
|
||||
* PM1, we need to abort the power down. Clear SLEEP.MODE, this will signal
|
||||
* main() to abort the PM1 transition
|
||||
*
|
||||
* On cc2430 this would be:
|
||||
* SLEEPCMD &= 0xFC;
|
||||
*/
|
||||
|
||||
/*
|
||||
* Read value of the ST0:ST1:ST2, add TICK_VAL and write it back.
|
||||
* Next interrupt occurs after the current time + TICK_VAL
|
||||
*/
|
||||
timer_value = ST0;
|
||||
timer_value += ((unsigned long int) ST1) << 8;
|
||||
timer_value += ((unsigned long int) ST2) << 16;
|
||||
timer_value += TICK_VAL;
|
||||
ST2 = (unsigned char) (timer_value >> 16);
|
||||
ST1 = (unsigned char) (timer_value >> 8);
|
||||
ST0 = (unsigned char) timer_value;
|
||||
|
||||
++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;
|
||||
}
|
||||
|
||||
if(etimer_pending()
|
||||
&& (etimer_next_expiration_time() - count - 1) > MAX_TICKS) {
|
||||
etimer_request_poll();
|
||||
}
|
||||
|
||||
STIF = 0; /* IRCON.STIF */
|
||||
ENERGEST_OFF(ENERGEST_TYPE_IRQ);
|
||||
ENABLE_INTERRUPTS();
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
69
cpu/cc253x/dev/dma.c
Normal file
69
cpu/cc253x/dev/dma.c
Normal file
|
@ -0,0 +1,69 @@
|
|||
/**
|
||||
* \file
|
||||
* Driver for the cc2430 DMA controller. Can be assigned to any bank
|
||||
*
|
||||
* \author
|
||||
* Original: Martti Huttunen <martti@sensinode.com>
|
||||
* Port: Zach Shelby <zach@sensinode.com>
|
||||
* Further Modifications:
|
||||
* George Oikonomou <oikonomou@users.sourceforge.net>
|
||||
*
|
||||
*/
|
||||
|
||||
#include "contiki.h"
|
||||
#include "dev/dma.h"
|
||||
#include "cc253x.h"
|
||||
|
||||
#if DMA_ON
|
||||
struct dma_config dma_conf[DMA_CHANNEL_COUNT]; /* DMA Descriptors */
|
||||
struct process * dma_callback[DMA_CHANNEL_COUNT];
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
dma_init(void)
|
||||
{
|
||||
uint16_t tmp_ptr;
|
||||
|
||||
memset(dma_conf, 0, 4 * sizeof(dma_config_t));
|
||||
|
||||
for(tmp_ptr = 0; tmp_ptr < DMA_CHANNEL_COUNT; tmp_ptr++) {
|
||||
dma_callback[tmp_ptr] = 0;
|
||||
}
|
||||
|
||||
/* The address of the descriptor for Channel 0 is configured separately */
|
||||
tmp_ptr = (uint16_t) &(dma_conf[0]);
|
||||
DMA0CFGH = tmp_ptr >> 8;
|
||||
DMA0CFGL = tmp_ptr;
|
||||
|
||||
/*
|
||||
* Descriptors for Channels 1-4 must be consecutive in RAM.
|
||||
* We write the address of the 1st one to the register and the rest are
|
||||
* derived by the SoC
|
||||
*/
|
||||
#if (DMA_CHANNEL_COUNT > 1)
|
||||
tmp_ptr = (uint16_t) &(dma_conf[1]);
|
||||
DMA1CFGH = tmp_ptr >> 8;
|
||||
DMA1CFGL = tmp_ptr;
|
||||
#endif
|
||||
|
||||
IEN1_DMAIE = 1; /* Enable DMA interrupts */
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/*
|
||||
* Associate process p with DMA channel c. When a transfer on that channel
|
||||
* completes, the ISR will poll this process.
|
||||
*/
|
||||
void
|
||||
dma_associate_process(struct process * p, uint8_t c)
|
||||
{
|
||||
if((!c) || (c >= DMA_CHANNEL_COUNT)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if(p) {
|
||||
dma_conf[c].inc_prio |= 8; /* Enable interrupt generation */
|
||||
IEN1_DMAIE = 1; /* Make sure DMA interrupts are acknowledged */
|
||||
}
|
||||
dma_callback[c] = p;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#endif
|
148
cpu/cc253x/dev/dma.h
Normal file
148
cpu/cc253x/dev/dma.h
Normal file
|
@ -0,0 +1,148 @@
|
|||
/**
|
||||
* \file
|
||||
* Header file for the cc2430 DMA controller
|
||||
*
|
||||
* \author
|
||||
* Original: Martti Huttunen <martti@sensinode.com>
|
||||
* Port: Zach Shelby <zach@sensinode.com>
|
||||
* Further Modifications:
|
||||
* George Oikonomou <oikonomou@users.sourceforge.net>
|
||||
*/
|
||||
|
||||
#ifndef __DMA_H
|
||||
#define __DMA_H
|
||||
#include "cc253x.h"
|
||||
|
||||
/* DMA triggers */
|
||||
#define DMA_T_NONE 0 /* None, DMAREQ.DMAREQx bits start transfer */
|
||||
#define DMA_T_PREV 1 /* completion of previous channel */
|
||||
#define DMA_T_T1_CH0 2 /* Timer 1, compare, channel 0 */
|
||||
#define DMA_T_T1_CH1 3 /* Timer 1, compare, channel 1 */
|
||||
#define DMA_T_T1_CH2 4 /* Timer 1, compare, channel 2 */
|
||||
#define DMA_T_T2_COMP 5 /* Timer 2, compare */
|
||||
#define DMA_T_T2_OVFL 6 /* Timer 2, overflow */
|
||||
#define DMA_T_T3_CH0 7 /* Timer 3, compare, channel 0 */
|
||||
#define DMA_T_T3_CH1 8 /* Timer 3, compare, channel 1 */
|
||||
#define DMA_T_T4_CH0 9 /* Timer 4, compare, channel 0 */
|
||||
#define DMA_T_T4_CH1 10 /* Timer 4, compare, channel 1 */
|
||||
#define DMA_T_ST 11 /* Sleep Timer compare */
|
||||
#define DMA_T_IOC_0 12 /* Port 0 I/O pin input transition */
|
||||
#define DMA_T_IOC_1 13 /* Port 1 I/O pin input transition */
|
||||
#define DMA_T_URX0 14 /* USART0 RX complete */
|
||||
#define DMA_T_UTX0 15 /* USART0 TX complete */
|
||||
#define DMA_T_URX1 16 /* USART1 RX complete */
|
||||
#define DMA_T_UTX1 17 /* USART1 TX complete */
|
||||
#define DMA_T_FLASH 18 /* Flash data write complete */
|
||||
#define DMA_T_RADIO 19 /* RF packet byte received/transmit */
|
||||
#define DMA_T_ADC_CHALL 20 /* ADC end of a conversion in a sequence */
|
||||
#define DMA_T_ADC_CH11 21 /* ADC end of conversion channel 0 in sequence */
|
||||
#define DMA_T_ADC_CH21 22 /* ADC end of conversion channel 1 in sequence */
|
||||
#define DMA_T_ADC_CH32 23 /* ADC end of conversion channel 2 in sequence */
|
||||
#define DMA_T_ADC_CH42 24 /* ADC end of conversion channel 3 in sequence */
|
||||
#define DMA_T_ADC_CH53 25 /* ADC end of conversion channel 4 in sequence */
|
||||
#define DMA_T_ADC_CH63 26 /* ADC end of conversion channel 5 in sequence */
|
||||
#define DMA_T_ADC_CH74 27 /* ADC end of conversion channel 6 in sequence */
|
||||
#define DMA_T_ADC_CH84 28 /* ADC end of conversion channel 7 in sequence */
|
||||
#define DMA_T_ENC_DW 29 /* AES processor requests download input data */
|
||||
#define DMA_T_ENC_UP 30 /* AES processor requests upload output data */
|
||||
|
||||
/* variable DMA length modes (VLEN) */
|
||||
#define DMA_VLEN_LEN (0 << 5) /* Use LEN for transfer count*/
|
||||
/*
|
||||
* Transfer the number of bytes/words specified by first byte/word + 1
|
||||
* (up to a maximum specified by LEN).
|
||||
* Thus transfer count excludes length byte/word.
|
||||
*/
|
||||
#define DMA_VLEN_N1 (1 << 5)
|
||||
/*
|
||||
* Transfer the number of bytes/words specified by first byte/word
|
||||
* (up to a maximum specified by LEN).
|
||||
* Thus transfer count includes length byte/word.
|
||||
*/
|
||||
#define DMA_VLEN_N (2 << 5)
|
||||
/*
|
||||
* Transfer the number of bytes/words specified by first byte/word + 2
|
||||
* (up to a maximum specified by LEN).
|
||||
*/
|
||||
#define DMA_VLEN_N2 (3 << 5)
|
||||
/*
|
||||
* Transfer the number of bytes/words specified by first byte/word + 3
|
||||
* (up to a maximum specified by LEN).
|
||||
*/
|
||||
#define DMA_VLEN_N3 (4 << 5)
|
||||
#define DMA_VLEN_RES1 (5 << 5) /* reserved */
|
||||
#define DMA_VLEN_RES2 (6 << 5) /* reserved */
|
||||
#define DMA_VLEN_LEN2 (7 << 5) /* Use LEN for transfer count */
|
||||
|
||||
/* Transfer Types (Byte 6 [6:5]) */
|
||||
#define DMA_SINGLE 0x00 /* Single */
|
||||
#define DMA_BLOCK 0x20 /* Block */
|
||||
#define DMA_RPT_SINGLE 0x40 /* Repeated single */
|
||||
#define DMA_RPT_BLOCK 0x60 /* Repeated block */
|
||||
|
||||
/* Source Increment Modes (Byte 7 [7:6])*/
|
||||
#define DMA_SRC_INC_NO 0x00 /* Source No increment */
|
||||
#define DMA_SRC_INC_1 0x40 /* Source Increment 1 */
|
||||
#define DMA_SRC_INC_2 0x80 /* Source Increment 2 */
|
||||
#define DMA_SRC_DEC 0xC0 /* Source Decrement 1 */
|
||||
/* Source Increment Modes (Byte 7 [5:4])*/
|
||||
#define DMA_DST_INC_NO 0x00 /* DestinationNo increment */
|
||||
#define DMA_DST_INC_1 0x10 /* Destination Increment 1 */
|
||||
#define DMA_DST_INC_2 0x20 /* Destination Increment 2 */
|
||||
#define DMA_DST_DEC 0x30 /* Destination Decrement 1 */
|
||||
|
||||
/* Descriptor Byte 7, Bits[3:0] */
|
||||
#define DMA_IRQ_MASK_ENABLE 0x08
|
||||
#define DMA_MODE_7_BIT 0x04
|
||||
#define DMA_PRIO_HIGHEST 0x03
|
||||
#define DMA_PRIO_HIGH 0x02
|
||||
#define DMA_PRIO_GUARANTEED 0x01
|
||||
#define DMA_PRIO_LOW 0x00
|
||||
|
||||
/** DMA configuration structure */
|
||||
typedef struct dma_config {
|
||||
uint8_t src_h; /* source address high byte*/
|
||||
uint8_t src_l; /* source address low byte*/
|
||||
uint8_t dst_h; /* dest. address high byte*/
|
||||
uint8_t dst_l; /* dest. address low byte*/
|
||||
uint8_t len_h; /* [7:5] VLEN, [4:0] length high byte, 5 lowest bits*/
|
||||
uint8_t len_l; /* length low byte*/
|
||||
uint8_t wtt; /* 7: wordsize, [6:5] transfer mode, [4:0] trigger */
|
||||
/* [7:6] src inc, [5:4] dst_inc, 3: IRQ, 2: M8(vlen), [1-0] prio */
|
||||
uint8_t inc_prio;
|
||||
} dma_config_t;
|
||||
|
||||
#ifdef DMA_CONF_ON
|
||||
#define DMA_ON DMA_CONF_ON
|
||||
#else
|
||||
#define DMA_ON 0
|
||||
#endif
|
||||
|
||||
/* Number of DMA Channels and their Descriptors */
|
||||
#if DMA_ON
|
||||
#define DMA_CHANNEL_COUNT 2
|
||||
extern dma_config_t dma_conf[DMA_CHANNEL_COUNT];
|
||||
#endif
|
||||
|
||||
/* DMA-Related Macros */
|
||||
#define DMA_ARM(c) (DMAARM |= (1 << c)) /* Arm DMA Channel C */
|
||||
#define DMA_TRIGGER(c) (DMAREQ |= (1 << c)) /* Trigger DMA Channel C */
|
||||
/*
|
||||
* Check Channel C for Transfer Status
|
||||
* 1: Complete, Pending Interrupt, 0: Incomplete
|
||||
*/
|
||||
#define DMA_STATUS(c) (DMAIRQ &(1 << c))
|
||||
/* Abort Ongoing DMA Transfers on Channel C */
|
||||
#define DMA_ABORT(c) (DMAARM = ABORT | (1 << c))
|
||||
#define DMA_ABORT_ALL() (DMAARM = 0x9F) /* Abort ALL Ongoing DMA Transfers */
|
||||
|
||||
/* Functions Declarations */
|
||||
void dma_init(void);
|
||||
void dma_associate_process (struct process * p, uint8_t c);
|
||||
|
||||
/* Only link the ISR when DMA_ON is .... on */
|
||||
#if DMA_ON
|
||||
void dma_isr( void ) __interrupt (DMA_VECTOR);
|
||||
#endif
|
||||
|
||||
#endif /*__DMA_H*/
|
68
cpu/cc253x/dev/dma_intr.c
Normal file
68
cpu/cc253x/dev/dma_intr.c
Normal file
|
@ -0,0 +1,68 @@
|
|||
/**
|
||||
* \file
|
||||
* DMA driver ISRs
|
||||
* \author
|
||||
* Original: Martti Huttunen <martti@sensinode.com>
|
||||
* Port: Zach Shelby <zach@sensinode.com>
|
||||
*
|
||||
* DMA interrupt routines, must be stored in HOME bank
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "contiki.h"
|
||||
|
||||
#include "dev/dma.h"
|
||||
#include "cc253x.h"
|
||||
|
||||
#if DMA_ON
|
||||
extern struct process * dma_callback[DMA_CHANNEL_COUNT];
|
||||
#endif
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#ifdef HAVE_RF_DMA
|
||||
extern void rf_dma_callback_isr(void);
|
||||
#endif
|
||||
#ifdef SPI_DMA_RX
|
||||
extern void spi_rx_dma_callback(void);
|
||||
#endif
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/**
|
||||
* DMA interrupt service routine.
|
||||
*
|
||||
* if callback defined a poll is made to that process
|
||||
*/
|
||||
void
|
||||
dma_isr(void) __interrupt (DMA_VECTOR)
|
||||
{
|
||||
#if DMA_ON
|
||||
uint8_t i;
|
||||
#endif
|
||||
EA=0;
|
||||
DMAIF = 0;
|
||||
#ifdef HAVE_RF_DMA
|
||||
if((DMAIRQ & 1) != 0) {
|
||||
DMAIRQ &= ~1;
|
||||
DMAARM=0x81;
|
||||
rf_dma_callback_isr();
|
||||
}
|
||||
#endif
|
||||
#ifdef SPI_DMA_RX
|
||||
if((DMAIRQ & 0x08) != 0) {
|
||||
DMAIRQ &= ~(1 << 3);
|
||||
spi_rx_dma_callback();
|
||||
}
|
||||
#endif
|
||||
#if DMA_ON
|
||||
for(i = 0; i < DMA_CHANNEL_COUNT; i++) {
|
||||
if((DMAIRQ & (1 << i)) != 0) {
|
||||
DMAIRQ &= ~(1 << i);
|
||||
if(dma_callback[i] != 0) {
|
||||
process_poll(dma_callback[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
EA = 1;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
57
cpu/cc253x/dev/lpm.h
Normal file
57
cpu/cc253x/dev/lpm.h
Normal file
|
@ -0,0 +1,57 @@
|
|||
/*
|
||||
* Copyright (c) 2010, Loughborough University - 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
|
||||
* Header file for the cc2430 Low Power Modes (LPM)
|
||||
* We currently support the following:
|
||||
* - Set MCU IDLE while in PM0. This is working as intended
|
||||
* - Drop to PM1. This results in incoming radio packet losses.
|
||||
*
|
||||
* \author
|
||||
* George Oikonomou - <oikonomou@users.sourceforge.net>
|
||||
*/
|
||||
#ifndef __LPM_H__
|
||||
#define __LPM_H__
|
||||
|
||||
#include "contiki-conf.h"
|
||||
|
||||
#define LPM_MODE_NONE 0 /* No LPM - Always on */
|
||||
#define LPM_MODE_IDLE 1 /* Set MCU Idle as part of the main loop */
|
||||
#define LPM_MODE_PM2 2 /* Drop to PM1 - causes radio packet losses for now */
|
||||
|
||||
#ifdef LPM_CONF_MODE
|
||||
#define LPM_MODE LPM_CONF_MODE
|
||||
#else
|
||||
#define LPM_MODE LPM_MODE_IDLE
|
||||
#endif /* LPM_CONF_MODE */
|
||||
|
||||
#endif /* __LPM_H__ */
|
145
cpu/cc253x/dev/port.h
Normal file
145
cpu/cc253x/dev/port.h
Normal file
|
@ -0,0 +1,145 @@
|
|||
/*
|
||||
* Copyright (c) 2011, George Oikonomou - <oikonomou@users.sourceforge.net>
|
||||
* 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
|
||||
*
|
||||
* \author
|
||||
* George Oikonomou - <oikonomou@users.sourceforge.net>
|
||||
*/
|
||||
|
||||
|
||||
#ifndef PORT_H_
|
||||
#define PORT_H_
|
||||
|
||||
#include "cc253x.h"
|
||||
#include "sfr-bits.h"
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Use these to configure your platform's hardware */
|
||||
#define PORT_FUNC_GPIO(port,pin) PORT_FUNC_GPIO_X(port,pin)
|
||||
#define PORT_FUNC_PER(port,pin) PORT_FUNC_PER_X(port,pin)
|
||||
#define PORT0_ANALOG_IO(pin) PORT0_ANALOG_IO_X(pin)
|
||||
#define PORT0_DIGITAL_IO(pin) PORT0_DIGITAL_IO_X(pin)
|
||||
#define PORT_SET(port,pin) PORT_SET_X(port,pin)
|
||||
#define PORT_CLEAR(port,pin) PORT_CLEAR_X(port,pin) PORT_CLEAR_X(port,pin)
|
||||
#define PORT_TOGGLE(port,pin) PORT_TOGGLE_X(port,pin) PORT_TOGGLE_X(port,pin)
|
||||
#define PORT_READ(port,pin) PORT_READ_X(port,pin)
|
||||
#define PORT_WRITE(port,pin,v) PORT_WRITE_X(port,pin,v)
|
||||
#define PORT_DIR_OUTPUT(port,pin) PORT_DIR_OUTPUT_X(port,pin)
|
||||
#define PORT_DIR_INPUT(port,pin) PORT_DIR_INPUT_X(port,pin)
|
||||
#define PORT_IRQ_ENABLE(port,pin) PORT_IRQ_ENABLE_X(port,pin)
|
||||
#define PORT_IRQ_DISABLE(port,pin) PORT_IRQ_DISABLE_X(port,pin)
|
||||
#define PORT_IRQ_ENABLED(port,pin) PORT_IRQ_ENABLED_X(port,pin)
|
||||
#define PORT_IRQ_CHECK(port,pin) PORT_IRQ_CHECK_X(port,pin)
|
||||
#define PORT_IRQ_EDGE_FALL(port,pin) PORT_IRQ_EDGE_FALL_X(port,pin)
|
||||
#define PORT_IRQ_EDGE_RISE(port,pin) PORT_IRQ_EDGE_RISE_X(port,pin)
|
||||
#define PORT_IRQ_FLAG_OFF(port,pin) PORT_IRQ_FLAG_OFF_X(port,pin)
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Second Round of Macro Substitutions. Normally, you can stop reading here */
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#define PORT_FUNC_GPIO_X(port,pin) do { P##port##SEL &= ~(1 << pin); } while(0)
|
||||
#define PORT_FUNC_PER_X(port,pin) do { P##port##SEL |= 1 << pin; } while(0)
|
||||
#define PORT0_ANALOG_IO_X(port,pin) do { APCFG |= 1 << pin; } while(0)
|
||||
#define PORT0_DIGITAL_IO_X(port,pin) do { APCFG &= ~(1 << pin); } while(0)
|
||||
#define PORT_SET_X(port,pin) do { P##port##_##pin = 1; } while(0)
|
||||
#define PORT_CLEAR_X(port,pin) do { P##port##_##pin = 0; } while(0)
|
||||
#define PORT_TOGGLE_X(port,pin) do { P##port##_##pin ^= 1; } while(0)
|
||||
#define PORT_READ_X(port,pin) (P##port##_##pin)
|
||||
#define PORT_WRITE_X(port,pin,v) do { P##port##_##pin = v;} while(0)
|
||||
#define PORT_DIR_OUTPUT_X(port,pin) do { P##port##DIR |= 1 << pin; } while(0)
|
||||
#define PORT_DIR_INPUT_X(port,pin) do { P##port##DIR &= ~(1 << pin); } while(0)
|
||||
#define PORT_IRQ_ENABLE_X(port,pin) do { \
|
||||
P##port##IEN |= 1 << pin; \
|
||||
PORT##port##_IRQ_ENABLE(); \
|
||||
} while(0)
|
||||
#define PORT_IRQ_DISABLE_X(port,pin) do { \
|
||||
P##port##IEN &= ~(1 << pin); \
|
||||
PORT##port##_IRQ_DISABLE(); \
|
||||
} while(0)
|
||||
#define PORT_IRQ_ENABLED_X(port,pin) (P##port##IEN & (1 << pin))
|
||||
#define PORT_IRQ_CHECK_X(port,pin) (P##port##IFG & (1 << pin))
|
||||
#define PORT_IRQ_EDGE_FALL_X(port,pin) PORT##port##_IRQ_EDGE_FALL(pin)
|
||||
#define PORT_IRQ_EDGE_RISE_X(port,pin) PORT##port##_IRQ_EDGE_RISE(pin)
|
||||
#define PORT_IRQ_FLAG_OFF_X(port,pin) do { \
|
||||
P##port##IFG &= ~(1 << pin); \
|
||||
P##port##IF = 0; \
|
||||
} while(0)
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* To handle SFR diversities
|
||||
* - P0IE is in IEN1, which is bit-addressable,
|
||||
* P1IE and P2IE are in IEN2, which is not bit-addressable
|
||||
* - Edge detection (rising / falling) config is uniform for all pins in
|
||||
* P0 and P2. For P1, low and high nibble bits are configured separately
|
||||
* - Pullup/Pulldown/Tristate is quite different for each port
|
||||
*
|
||||
* You won't have to invoke these macros directly
|
||||
*/
|
||||
#define PORT0_IRQ_ENABLE() do { P0IE = 1; } while(0)
|
||||
#define PORT0_IRQ_DISABLE() do { P0IE = 0; } while(0)
|
||||
#define PORT1_IRQ_ENABLE() PORT_IRQ_EN_X(1)
|
||||
#define PORT1_IRQ_DISABLE() PORT_IRQ_DIS_X(1)
|
||||
#define PORT2_IRQ_ENABLE() PORT_IRQ_EN_X(2)
|
||||
#define PORT2_IRQ_DISABLE() PORT_IRQ_DIS_X(2)
|
||||
|
||||
#define PORT_IRQ_EN_X(port) do { IEN2 |= IEN2_P##port##IE; } while(0)
|
||||
#define PORT_IRQ_DIS_X(port) do { IEN2 &= ~IEN2_P##port##IE; } while(0)
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#define PORT0_IRQ_EDGE_FALL(pin) PORT_IRQ_EDGE_F_X(0)
|
||||
#define PORT0_IRQ_EDGE_RISE(pin) PORT_IRQ_EDGE_R_X(0)
|
||||
#define PORT1_IRQ_EDGE_FALL(pin) PORT1_##pin##_IRQ_EDGE_F_X()
|
||||
#define PORT1_IRQ_EDGE_RISE(pin) PORT1_##pin##_IRQ_EDGE_R_X()
|
||||
#define PORT2_IRQ_EDGE_FALL(pin) PORT_IRQ_EDGE_F_X(2)
|
||||
#define PORT2_IRQ_EDGE_RISE(pin) PORT_IRQ_EDGE_R_X(2)
|
||||
|
||||
/* Ports 0 & 2 */
|
||||
#define PORT_IRQ_EDGE_F_X(port) do { PICTL |= PICTL_P##port##ICON; } while(0)
|
||||
#define PORT_IRQ_EDGE_R_X(port) do { PICTL &= ~PICTL_P##port##ICON; } while(0)
|
||||
/* Port 1 - High Nibble */
|
||||
#define PORT1_7_IRQ_EDGE_F_X() do { PICTL |= PICTL_P1ICONH; } while(0)
|
||||
#define PORT1_7_IRQ_EDGE_R_X() do { PICTL &= ~PICTL_P1ICONH; } while(0)
|
||||
#define PORT1_6_IRQ_EDGE_F_X() do { PICTL |= PICTL_P1ICONH; } while(0)
|
||||
#define PORT1_6_IRQ_EDGE_R_X() do { PICTL &= ~PICTL_P1ICONH; } while(0)
|
||||
#define PORT1_5_IRQ_EDGE_F_X() do { PICTL |= PICTL_P1ICONH; } while(0)
|
||||
#define PORT1_5_IRQ_EDGE_R_X() do { PICTL &= ~PICTL_P1ICONH; } while(0)
|
||||
#define PORT1_4_IRQ_EDGE_F_X() do { PICTL |= PICTL_P1ICONH; } while(0)
|
||||
#define PORT1_4_IRQ_EDGE_R_X() do { PICTL &= ~PICTL_P1ICONH; } while(0)
|
||||
/* Port 1 - Low Nibble */
|
||||
#define PORT1_3_IRQ_EDGE_F_X() do { PICTL |= PICTL_P1ICONL; } while(0)
|
||||
#define PORT1_3_IRQ_EDGE_R_X() do { PICTL &= ~PICTL_P1ICONL; } while(0)
|
||||
#define PORT1_2_IRQ_EDGE_F_X() do { PICTL |= PICTL_P1ICONL; } while(0)
|
||||
#define PORT1_2_IRQ_EDGE_R_X() do { PICTL &= ~PICTL_P1ICONL; } while(0)
|
||||
#define PORT1_1_IRQ_EDGE_F_X() do { PICTL |= PICTL_P1ICONL; } while(0)
|
||||
#define PORT1_1_IRQ_EDGE_R_X() do { PICTL &= ~PICTL_P1ICONL; } while(0)
|
||||
#define PORT1_0_IRQ_EDGE_F_X() do { PICTL |= PICTL_P1ICONL; } while(0)
|
||||
#define PORT1_0_IRQ_EDGE_R_X() do { PICTL &= ~PICTL_P1ICONL; } while(0)
|
||||
/*---------------------------------------------------------------------------*/
|
||||
|
||||
#endif /* __PORT_H__ */
|
111
cpu/cc253x/dev/random.c
Normal file
111
cpu/cc253x/dev/random.c
Normal file
|
@ -0,0 +1,111 @@
|
|||
/*
|
||||
* Copyright (c) 2011, George Oikonomou - <oikonomou@users.sourceforge.net>
|
||||
* 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
|
||||
* Random number generator routines exploiting the cc2530 hardware
|
||||
* capabilities.
|
||||
*
|
||||
* This file overrides core/lib/random.c.
|
||||
*
|
||||
* \author
|
||||
* George Oikonomou - <oikonomou@users.sourceforge.net>
|
||||
*/
|
||||
#include "cc253x.h"
|
||||
#include "sfr-bits.h"
|
||||
#include "dev/cc2530-rf.h"
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/**
|
||||
* \brief Generates a new random number using the cc253x RNG.
|
||||
* \return The random number.
|
||||
*/
|
||||
unsigned short
|
||||
random_rand(void)
|
||||
{
|
||||
/* Clock the RNG LSFR once */
|
||||
ADCCON1 |= ADCCON1_RCTRL0;
|
||||
|
||||
return (RNDL | (RNDH << 8));
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/**
|
||||
* \brief Seed the cc253x random number generator.
|
||||
* \param seed Ignored. It's here because the function prototype is in core.
|
||||
*
|
||||
* We form a seed for the RNG by sampling IF_ADC as
|
||||
* discussed in the user guide.
|
||||
* Seeding with this method should not be done during
|
||||
* normal radio operation. Thus, use this function before
|
||||
* initialising the network.
|
||||
*/
|
||||
void
|
||||
random_init(unsigned short seed)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* Make sure the RNG is on */
|
||||
ADCCON1 &= ~(ADCCON1_RCTRL1 | ADCCON1_RCTRL0);
|
||||
|
||||
/* Infinite RX */
|
||||
FRMCTRL0 = FRMCTRL0_RX_MODE1;
|
||||
|
||||
/* Turn RF on */
|
||||
CC2530_CSP_ISRXON();
|
||||
|
||||
/* Wait until (user guide sec. 23.12, p 239) "the chip has been in RX long
|
||||
* enough for the transients to have died out. A convenient way to do this is
|
||||
* to wait for the RSSI-valid signal to go high." */
|
||||
while(!(RSSISTAT & RSSISTAT_RSSI_VALID));
|
||||
|
||||
/*
|
||||
* Form the seed by concatenating bits from IF_ADC in the RF receive path.
|
||||
* Keep sampling until we have read at least 16 bits AND the seed is valid
|
||||
*
|
||||
* Invalid seeds are 0x0000 and 0x8003 - User Guide (sec. 14.2.2 p. 146):
|
||||
* "Note that a seed value of 0x0000 or 0x8003 always leads to an unchanged
|
||||
* value in the LFSR after clocking, as no values are pushed in via in_bit
|
||||
* (see Figure 14-1); hence, neither of these seed values should not be used
|
||||
* for random-number generation."
|
||||
*/
|
||||
i = 0;
|
||||
while(i < 16 || (seed == 0x0000 || seed == 0x8003)) {
|
||||
seed = (seed << 1) | (RFRND & RFRND_IRND);
|
||||
seed <<= 1;
|
||||
i++;
|
||||
}
|
||||
|
||||
/* High byte first */
|
||||
RNDL = seed >> 8;
|
||||
RNDL = seed & 0xFF;
|
||||
|
||||
/* RF Off. NETSTACK_RADIO.init() will sort out normal RF operation */
|
||||
CC2530_CSP_ISRFOFF();
|
||||
}
|
70
cpu/cc253x/dev/uart-intr.c
Normal file
70
cpu/cc253x/dev/uart-intr.c
Normal file
|
@ -0,0 +1,70 @@
|
|||
/**
|
||||
* \file
|
||||
*
|
||||
* uart write routines
|
||||
*
|
||||
* \author
|
||||
*
|
||||
* Anthony "Asterisk" Ambuehl
|
||||
*
|
||||
* interrupt routines which must be in HOME bank. handles received data from UART.
|
||||
*
|
||||
*/
|
||||
#include "cc253x.h"
|
||||
|
||||
#include "dev/uart0.h"
|
||||
#include "dev/uart1.h"
|
||||
#include "sys/energest.h"
|
||||
#include "dev/leds.h"
|
||||
|
||||
#if UART0_ENABLE
|
||||
static int (*uart0_input_handler)(unsigned char c);
|
||||
#endif
|
||||
#if UART1_ENABLE
|
||||
static int (*uart1_input_handler)(unsigned char c);
|
||||
#endif
|
||||
|
||||
#if UART0_ENABLE
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
uart0_set_input(int (*input)(unsigned char c))
|
||||
{
|
||||
uart0_input_handler = input;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#if UART0_CONF_WITH_INPUT
|
||||
void
|
||||
uart0_rx_isr(void) __interrupt (URX0_VECTOR)
|
||||
{
|
||||
ENERGEST_ON(ENERGEST_TYPE_IRQ);
|
||||
leds_toggle(LEDS_YELLOW);
|
||||
URX0IF = 0;
|
||||
if(uart0_input_handler != NULL) {
|
||||
uart0_input_handler(U0DBUF);
|
||||
}
|
||||
ENERGEST_OFF(ENERGEST_TYPE_IRQ);
|
||||
}
|
||||
#endif
|
||||
#endif /* UART0_ENABLE */
|
||||
#if UART1_ENABLE
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
uart1_set_input(int (*input)(unsigned char c))
|
||||
{
|
||||
uart1_input_handler = input;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#if UART_ONE_CONF_WITH_INPUT
|
||||
void
|
||||
uart1_rx_isr(void) __interrupt (URX1_VECTOR)
|
||||
{
|
||||
ENERGEST_ON(ENERGEST_TYPE_IRQ);
|
||||
URX1IF = 0;
|
||||
if(uart1_input_handler != NULL) {
|
||||
uart1_input_handler(U1DBUF);
|
||||
}
|
||||
ENERGEST_OFF(ENERGEST_TYPE_IRQ);
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#endif /* UART_ONE_CONF_WITH_INPUT */
|
||||
#endif /* UART1_ENABLE */
|
43
cpu/cc253x/dev/uart.h
Normal file
43
cpu/cc253x/dev/uart.h
Normal file
|
@ -0,0 +1,43 @@
|
|||
#ifndef UART_H
|
||||
#define UART_H
|
||||
|
||||
#include "contiki-conf.h"
|
||||
|
||||
#include "cc253x.h"
|
||||
#include "8051def.h"
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* UART BAUD Rates */
|
||||
/*
|
||||
* Macro to set speed of UART N by setting the UnBAUD SFR to M and the
|
||||
* UnGCR SRF to E. See the cc2530 datasheet for possible values of M and E
|
||||
*/
|
||||
#define UART_SET_SPEED(N, M, E) do{ U##N##BAUD = M; U##N##GCR = E; } while(0)
|
||||
|
||||
/*
|
||||
* Sample Values for M and E in the macro above to achieve some common BAUD
|
||||
* rates. For more values, see the cc2430 datasheet
|
||||
*/
|
||||
/* 2000000 - cc2430 theoretical MAX when using the 32MHz clock */
|
||||
#define UART_2K_M 0
|
||||
#define UART_2K_E 16
|
||||
/* 1000000 - cc2430 theoretical MAX when using the 16MHz clock */
|
||||
#define UART_1K_M 0
|
||||
#define UART_1K_E 15
|
||||
/* 921600 */
|
||||
#define UART_921_M 216
|
||||
#define UART_921_E 14
|
||||
/* 460800 Higher values lead to problems when the node needs to RX */
|
||||
#define UART_460_M 216
|
||||
#define UART_460_E 13
|
||||
/* 115200 */
|
||||
#define UART_115_M 216
|
||||
#define UART_115_E 11
|
||||
/* 38400 */
|
||||
#define UART_38_M 59
|
||||
#define UART_38_E 10
|
||||
/* 9600 */
|
||||
#define UART_9_M 59
|
||||
#define UART_9_E 8
|
||||
|
||||
#endif /* UART_H */
|
75
cpu/cc253x/dev/uart0.c
Normal file
75
cpu/cc253x/dev/uart0.c
Normal file
|
@ -0,0 +1,75 @@
|
|||
/**
|
||||
* \file
|
||||
*
|
||||
* uart0 write routines
|
||||
*
|
||||
* \author
|
||||
*
|
||||
* Anthony "Asterisk" Ambuehl
|
||||
*
|
||||
*/
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "cc253x.h"
|
||||
#include "sfr-bits.h"
|
||||
#include "dev/uart0.h"
|
||||
|
||||
#if UART0_ENABLE
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
uart0_init()
|
||||
{
|
||||
#if UART0_CONF_HIGH_SPEED
|
||||
UART_SET_SPEED(0, UART_460_M, UART_460_E);
|
||||
#else
|
||||
UART_SET_SPEED(0, UART_115_M, UART_115_E);
|
||||
#endif
|
||||
|
||||
#ifdef UART0_ALTERNATIVE_2
|
||||
PERCFG |= PERCFG_U0CFG; / *alternative port 2 = P1.5-2 */
|
||||
#ifdef UART0_RTSCTS
|
||||
P1SEL |= 0x3C; /* peripheral select for TX and RX, RTS, CTS */
|
||||
#else
|
||||
P1SEL |= 0x30; /* peripheral select for TX and RX */
|
||||
P1 &= ~0x08; /* RTS down */
|
||||
#endif
|
||||
P1DIR |= 0x28; /* RTS, TX out */
|
||||
P1DIR &= ~0x14; /* CTS & RX in */
|
||||
#else
|
||||
PERCFG &= ~PERCFG_U0CFG; /* alternative port 1 = P0.5-2 */
|
||||
#ifdef UART0_RTSCTS
|
||||
P0SEL |= 0x20 | 0x10; /* peripheral select for TX and RX */
|
||||
#else
|
||||
P0SEL |= 0x0C; /* peripheral select for TX and RX */
|
||||
P0 &= ~0x20; /* RTS down */
|
||||
#endif
|
||||
P0DIR |= 0x28; /* RTS, TX out */
|
||||
P0DIR &= ~0x14; /* CTS, RX in */
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef UART0_RTSCTS
|
||||
U0UCR = 0x42; /*defaults: 8N1, RTS/CTS, high stop bit*/
|
||||
#else
|
||||
U0UCR = 0x02; /*defaults: 8N1, no flow control, high stop bit*/
|
||||
#endif
|
||||
|
||||
U0CSR = UCSR_MODE; /* UART mode */
|
||||
U0UCR = 0x80; /* Flush */
|
||||
UART0_RX_EN();
|
||||
|
||||
UART0_RX_INT(1);
|
||||
U0DBUF = 0;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Write one byte over the UART. */
|
||||
void
|
||||
uart0_writeb(uint8_t byte)
|
||||
{
|
||||
UTX0IF = 0;
|
||||
U0DBUF = byte;
|
||||
while(!UTX0IF); /* Wait until byte has been transmitted. */
|
||||
UTX0IF = 0;
|
||||
}
|
||||
#endif
|
41
cpu/cc253x/dev/uart0.h
Normal file
41
cpu/cc253x/dev/uart0.h
Normal file
|
@ -0,0 +1,41 @@
|
|||
#ifndef UART_0_H
|
||||
#define UART_0_H
|
||||
|
||||
#include "contiki-conf.h"
|
||||
|
||||
#include "cc253x.h"
|
||||
#include "8051def.h"
|
||||
#include "uart.h"
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* UART0 Enable - Disable */
|
||||
#ifdef UART0_CONF_ENABLE
|
||||
#define UART0_ENABLE UART0_CONF_ENABLE
|
||||
#else
|
||||
#define UART0_ENABLE 0
|
||||
#endif
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* UART0 Function Declarations */
|
||||
#if UART0_ENABLE
|
||||
void uart0_init();
|
||||
void uart0_writeb(uint8_t byte);
|
||||
|
||||
void uart0_set_input(int (*input)(unsigned char c));
|
||||
|
||||
#if UART0_CONF_WITH_INPUT
|
||||
void uart0_rx_isr( void ) __interrupt (URX0_VECTOR);
|
||||
/* Macro to turn on / off UART RX Interrupt */
|
||||
#define UART0_RX_INT(v) do { URX0IE = v; } while(0)
|
||||
#define UART0_RX_EN() do { U0CSR |= UCSR_RE; } while(0)
|
||||
#else
|
||||
#define UART0_RX_INT(v)
|
||||
#define UART0_RX_EN()
|
||||
#endif /* UART0_CONF_WITH_INPUT */
|
||||
#else
|
||||
#define uart0_init(...)
|
||||
#define uart0_writeb(...)
|
||||
#define uart0_set_input(...)
|
||||
#define UART0_RX_INT(v)
|
||||
#define UART0_RX_EN()
|
||||
#endif /* UART0_ENABLE */
|
||||
#endif /* UART_0_H */
|
74
cpu/cc253x/dev/uart1.c
Normal file
74
cpu/cc253x/dev/uart1.c
Normal file
|
@ -0,0 +1,74 @@
|
|||
/**
|
||||
* \file
|
||||
*
|
||||
* uart1 write routines
|
||||
*
|
||||
* \author
|
||||
*
|
||||
* Anthony "Asterisk" Ambuehl
|
||||
*
|
||||
*/
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "cc253x.h"
|
||||
#include "dev/uart1.h"
|
||||
|
||||
#if UART1_ENABLE
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* UART1 initialization */
|
||||
void
|
||||
uart1_init()
|
||||
{
|
||||
#ifdef UART1_ALTERNATIVE_1
|
||||
PERCFG &= ~PERCFG_U1CFG; /*alternative port 1 = P0.5-2*/
|
||||
#ifdef UART1_RTSCTS
|
||||
P0SEL |= 0x3C; /*peripheral select for TX and RX, RTS, CTS*/
|
||||
#else
|
||||
P0SEL |= 0x30; /*peripheral select for TX and RX*/
|
||||
P0 &= ~0x08; /*RTS down*/
|
||||
#endif
|
||||
P0DIR |= 0x18; /*RTS, TX out*/
|
||||
P0DIR &= ~0x24; /*CTS, RX in*/
|
||||
#else
|
||||
PERCFG |= PERCFG_U1CFG; /*alternative port 2 = P1.7-4*/
|
||||
#ifdef UART1_RTSCTS
|
||||
P1SEL |= 0xF0; /*peripheral select for TX and RX*/
|
||||
#else
|
||||
P1SEL |= 0xC0; /*peripheral select for TX and RX*/
|
||||
P1 &= ~0x20; /*RTS down*/
|
||||
#endif
|
||||
P1DIR |= 0x60; /*RTS, TX out*/
|
||||
P1DIR &= ~0x90; /*CTS, RX in*/
|
||||
#endif
|
||||
|
||||
#if UART_ONE_CONF_HIGH_SPEED
|
||||
UART_SET_SPEED(1, UART_460_M, UART_460_E);
|
||||
#else
|
||||
UART_SET_SPEED(1, UART_115_M, UART_115_E);
|
||||
#endif
|
||||
|
||||
#ifdef UART1_RTSCTS
|
||||
U1UCR = 0x42; /*defaults: 8N1, RTS/CTS, high stop bit*/
|
||||
#else
|
||||
U1UCR = 0x02; /*defaults: 8N1, no flow control, high stop bit*/
|
||||
#endif
|
||||
|
||||
U1CSR = UCSR_MODE; /* UART mode */
|
||||
U1UCR = 0x80; /* Flush */
|
||||
|
||||
UART1_RX_INT(1);
|
||||
U0DBUF = 0;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* Write one byte over the UART. */
|
||||
void
|
||||
uart1_writeb(uint8_t byte)
|
||||
{
|
||||
UTX1IF = 0;
|
||||
U1DBUF = byte;
|
||||
while(!UTX1IF); /* Wait until byte has been transmitted. */
|
||||
UTX1IF = 0;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
#endif
|
38
cpu/cc253x/dev/uart1.h
Normal file
38
cpu/cc253x/dev/uart1.h
Normal file
|
@ -0,0 +1,38 @@
|
|||
#ifndef UART_1_H
|
||||
#define UART_1_H
|
||||
|
||||
#include "contiki-conf.h"
|
||||
|
||||
#include "cc253x.h"
|
||||
#include "8051def.h"
|
||||
#include "uart.h"
|
||||
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* UART1 Enable - Disable */
|
||||
#ifdef UART1_CONF_ENABLE
|
||||
#define UART1_ENABLE UART1_CONF_ENABLE
|
||||
#else
|
||||
#define UART1_ENABLE 0
|
||||
#endif
|
||||
/*---------------------------------------------------------------------------*/
|
||||
/* UART1 Function Declarations */
|
||||
#if UART1_ENABLE
|
||||
void uart1_init();
|
||||
void uart1_writeb(uint8_t byte);
|
||||
|
||||
void uart1_set_input(int (*input)(unsigned char c));
|
||||
#if UART1_CONF_WITH_INPUT
|
||||
void uart1_rx_isr( void ) __interrupt (URX1_VECTOR);
|
||||
/* Macro to turn on / off UART RX Interrupt */
|
||||
#define UART1_RX_INT(v) do { URX1IE = v; } while(0)
|
||||
#else
|
||||
#define UART1_RX_INT(v)
|
||||
#endif /* UART1_CONF_WITH_INPUT */
|
||||
#else
|
||||
#define uart1_init(...)
|
||||
#define uart1_writeb(...)
|
||||
#define uart1_set_input(...)
|
||||
#define UART1_RX_INT(v)
|
||||
#endif /* UART1_ENABLE */
|
||||
|
||||
#endif /* UART_1_H */
|
88
cpu/cc253x/dev/watchdog.c
Normal file
88
cpu/cc253x/dev/watchdog.c
Normal file
|
@ -0,0 +1,88 @@
|
|||
/*
|
||||
* Copyright (c) 2010, Loughborough University - 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
|
||||
* Hardware-dependent functions for the cc253x watchdog.
|
||||
*
|
||||
* This file contains an ISR and must reside in the HOME bank.
|
||||
*
|
||||
* \author
|
||||
* George Oikonomou - <oikonomou@users.sourceforge.net>
|
||||
*/
|
||||
|
||||
#include "sys/energest.h"
|
||||
#include "cc253x.h"
|
||||
#include "sfr-bits.h"
|
||||
#include "contiki-conf.h"
|
||||
|
||||
#define WDT_TIMEOUT_MIN (WDCTL_INT1 | WDCTL_INT0)
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
watchdog_init(void)
|
||||
{
|
||||
WDCTL = 0; /* IDLE, Max Interval */
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
watchdog_start(void)
|
||||
{
|
||||
WDCTL |= WDCTL_MODE1; /* Start in Watchdog mode */
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
watchdog_periodic(void)
|
||||
{
|
||||
/* Write the 'clear' sequence while maintaining mode and interval setting */
|
||||
WDCTL = (WDCTL & 0x0F) | WDCTL_CLR3 | WDCTL_CLR1;
|
||||
WDCTL = (WDCTL & 0x0F) | WDCTL_CLR2 | WDCTL_CLR0;
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
watchdog_stop(void)
|
||||
{
|
||||
/* In watchdog mode, stopping is impossible so we just reset the timer */
|
||||
watchdog_periodic();
|
||||
}
|
||||
/*---------------------------------------------------------------------------*/
|
||||
void
|
||||
watchdog_reboot(void)
|
||||
{
|
||||
WDCTL = WDT_TIMEOUT_MIN;
|
||||
/* Dis-acknowledge all interrupts while we wait for the dog to bark */
|
||||
DISABLE_INTERRUPTS();
|
||||
/* NOP till the dog barks... */
|
||||
while(1) {
|
||||
__asm
|
||||
nop
|
||||
__endasm;
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue