diff --git a/core/dev/cc2520.c b/core/dev/cc2520.c new file mode 100644 index 000000000..f3e97a060 --- /dev/null +++ b/core/dev/cc2520.c @@ -0,0 +1,926 @@ +/* + * 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. + */ +/* + * This code is almost device independent and should be easy to port. + */ + +#include + +#include "contiki.h" + +#if defined(__AVR__) +#include +#endif + +#include "dev/leds.h" +#include "dev/spi.h" +#include "dev/cc2520.h" +#include "dev/cc2520_const.h" + +#include "net/packetbuf.h" +#include "net/rime/rimestats.h" +#include "net/netstack.h" + +#include "sys/timetable.h" + +#define WITH_SEND_CCA 1 + +#define FOOTER_LEN 2 + +#ifndef CC2520_CONF_CHECKSUM +#define CC2520_CONF_CHECKSUM 0 +#endif /* CC2520_CONF_CHECKSUM */ + +#ifndef CC2520_CONF_AUTOACK +#define CC2520_CONF_AUTOACK 0 +#endif /* CC2520_CONF_AUTOACK */ + +#if CC2520_CONF_CHECKSUM +#include "lib/crc16.h" +#define CHECKSUM_LEN 2 +#else +#define CHECKSUM_LEN 0 +#endif /* CC2520_CONF_CHECKSUM */ + +#define AUX_LEN (CHECKSUM_LEN + FOOTER_LEN) + + +#define FOOTER1_CRC_OK 0x80 +#define FOOTER1_CORRELATION 0x7f + +#define DEBUG 1 +#if DEBUG +#include +#define PRINTF(...) printf(__VA_ARGS__) +#else +#define PRINTF(...) +#endif + +#define DEBUG_LEDS DEBUG +#undef LEDS_ON +#undef LEDS_OFF +#if DEBUG_LEDS +#define LEDS_ON(x) leds_on(x) +#define LEDS_OFF(x) leds_off(x) +#else +#define LEDS_ON(x) +#define LEDS_OFF(x) +#endif + +void cc2520_arch_init(void); + +/* XXX hack: these will be made as Chameleon packet attributes */ +rtimer_clock_t cc2520_time_of_arrival, cc2520_time_of_departure; + +int cc2520_authority_level_of_sender; + +int cc2520_packets_seen, cc2520_packets_read; + +static uint8_t volatile pending; + +#define BUSYWAIT_UNTIL(cond, max_time) \ + do { \ + rtimer_clock_t t0; \ + t0 = RTIMER_NOW(); \ + while(!(cond) && RTIMER_CLOCK_LT(RTIMER_NOW(), t0 + (max_time))); \ + } while(0) + +volatile uint8_t cc2520_sfd_counter; +volatile uint16_t cc2520_sfd_start_time; +volatile uint16_t cc2520_sfd_end_time; + +static volatile uint16_t last_packet_timestamp; +/*---------------------------------------------------------------------------*/ +PROCESS(cc2520_process, "CC2520 driver"); +/*---------------------------------------------------------------------------*/ + + +int cc2520_on(void); +int cc2520_off(void); + +static int cc2520_read(void *buf, unsigned short bufsize); + +static int cc2520_prepare(const void *data, unsigned short len); +static int cc2520_transmit(unsigned short len); +static int cc2520_send(const void *data, unsigned short len); + +static int cc2520_receiving_packet(void); +static int pending_packet(void); +static int cc2520_cca(void); +/* static int detected_energy(void); */ + +signed char cc2520_last_rssi; +uint8_t cc2520_last_correlation; + +const struct radio_driver cc2520_driver = + { + cc2520_init, + cc2520_prepare, + cc2520_transmit, + cc2520_send, + cc2520_read, + /* cc2520_set_channel, */ + /* detected_energy, */ + cc2520_cca, + cc2520_receiving_packet, + pending_packet, + cc2520_on, + cc2520_off, + + }; + +static uint8_t receive_on; + +static int channel; + +/*---------------------------------------------------------------------------*/ + +static void +getrxdata(void *buf, int len) +{ + CC2520_READ_FIFO_BUF(buf, len); +} +static void +getrxbyte(uint8_t *byte) +{ + CC2520_READ_FIFO_BYTE(*byte); +} +static void +flushrx(void) +{ + uint8_t dummy; + + CC2520_READ_FIFO_BYTE(dummy); + CC2520_STROBE(CC2520_INS_SFLUSHRX); + CC2520_STROBE(CC2520_INS_SFLUSHRX); +} +/*---------------------------------------------------------------------------*/ +static void strobe(uint8_t regname) +{ + CC2520_STROBE(regname); +} +/*---------------------------------------------------------------------------*/ +static unsigned int +status(void) +{ + uint8_t status; + CC2520_GET_STATUS(status); + return status; +} +/*---------------------------------------------------------------------------*/ +static uint8_t locked, lock_on, lock_off; + +static void +on(void) +{ + ENERGEST_ON(ENERGEST_TYPE_LISTEN); + CC2520_ENABLE_FIFOP_INT(); + strobe(CC2520_INS_SRXON); + //BUSYWAIT_UNTIL(status() & (BV(CC2520_XOSC16M_STABLE)), RTIMER_SECOND / 100); + + receive_on = 1; +} +static void +off(void) +{ + /* PRINTF("off\n");*/ + receive_on = 0; + + /* Wait for transmission to end before turning radio off. */ + //BUSYWAIT_UNTIL(!(status() & BV(CC2520_TX_ACTIVE)), RTIMER_SECOND / 10); + //while(status() & BV(CC2520_TX_ACTIVE)); + + strobe(CC2520_INS_SRFOFF); + CC2520_DISABLE_FIFOP_INT(); + ENERGEST_OFF(ENERGEST_TYPE_LISTEN); + + if(!CC2520_FIFOP_IS_1) { + flushrx(); + } +} +/*---------------------------------------------------------------------------*/ +#define GET_LOCK() locked++ +static void RELEASE_LOCK(void) { + if(locked == 1) { + if(lock_on) { + on(); + lock_on = 0; + } + if(lock_off) { + off(); + lock_off = 0; + } + } + locked--; +} +/*---------------------------------------------------------------------------*/ +static uint8_t +getreg(unsigned regname) +{ + uint8_t reg; + CC2520_READ_REG(regname, reg); + return reg; +} +/*---------------------------------------------------------------------------*/ +static void +setreg(unsigned regname, unsigned value) +{ + CC2520_WRITE_REG(regname, value); +} +/*---------------------------------------------------------------------------*/ +static void +set_txpower(uint8_t power) +{ + uint16_t reg; + + reg = getreg(CC2520_TXCTRL); + reg = (reg & 0xffe0) | (power & 0x1f); + setreg(CC2520_TXCTRL, reg); +} +/*---------------------------------------------------------------------------*/ +#define AUTOACK (1 << 4) +#define ADR_DECODE (1 << 11) +#define RXFIFO_PROTECTION (1 << 9) +#define CORR_THR(n) (((n) & 0x1f) << 6) +#define FIFOP_THR(n) ((n) & 0x7f) +#define RXBPF_LOCUR (1 << 13); +/*---------------------------------------------------------------------------*/ +int temp_data; +int +cc2520_init(void) +{ + unsigned stat1; + + { + int s = splhigh(); + cc2520_arch_init(); /* Initalize ports and SPI. */ + CC2520_DISABLE_FIFOP_INT(); + CC2520_FIFOP_INT_INIT(); + splx(s); + } + /* Turn on voltage regulator and reset. */ + SET_VREG_INACTIVE(); + clock_delay(250); + SET_VREG_ACTIVE(); + clock_delay(250); + SET_RESET_ACTIVE(); + clock_delay(127); + SET_RESET_INACTIVE(); + clock_delay(125); + strobe(CC2520_INS_SXOSCON); // Turn on the crystal oscillator. + clock_delay(125); + + stat1 = status(); + while(!(stat1 & 0x80)) + stat1 = status(); + + /* Change default values as recommended in the data sheet, */ + /* correlation threshold = 20, RX bandpass filter = 1.3uA.*/ + + setreg(CC2520_TXCTRL, 0x94); + setreg(CC2520_TXPOWER, 0x13); // Output power 1 dBm + + /* + + valeurs de TXPOWER + 0x03 -> -18 dBm + 0x2C -> -7 dBm + 0x88 -> -4 dBm + 0x81 -> -2 dBm + 0x32 -> 0 dBm + 0x13 -> 1 dBm + 0x32 -> 0 dBm + 0x13 -> 1 dBm + 0xAB -> 2 dBm + 0xF2 -> 3 dBm + 0xF7 -> 5 dBm + */ + setreg(CC2520_CCACTRL0, 0xF8); // CCA treshold -80dBm + + // Recommended RX settings + setreg(CC2520_MDMCTRL0, 0x84); // Controls modem + setreg(CC2520_MDMCTRL1, 0x14); // Controls modem + setreg(CC2520_RXCTRL, 0x3F); // Adjust currents in RX related analog modules + setreg(CC2520_FSCTRL, 0x5A); // Adjust currents in synthesizer. + setreg(CC2520_FSCAL1, 0x2B); // Adjust currents in VCO + setreg(CC2520_AGCCTRL1, 0x11); // Adjust target value for AGC control loop + setreg(CC2520_AGCCTRL2, 0xEB); + + // Disable filter on @ (remove if you want to address specific wismote) + setreg(CC2520_FRMFILT0, 0x00); + + // Disable external clock + setreg(CC2520_EXTCLOCK, 0x00); + + // Tune ADC performance + setreg(CC2520_ADCTEST0, 0x10); + setreg(CC2520_ADCTEST1, 0x0E); + setreg(CC2520_ADCTEST2, 0x03); + + // Set auto CRC on frame + setreg(CC2520_FRMCTRL0, 0x60); + setreg(CC2520_FIFOPCTRL, 0x0F); + + cc2520_set_pan_addr(0xbabe, 0x0000, NULL); + cc2520_set_channel(15); + + flushrx(); + + process_start(&cc2520_process, NULL); + return 1; +} +/*---------------------------------------------------------------------------*/ +static int +cc2520_transmit(unsigned short payload_len) +{ + int i, txpower; + uint8_t total_len; +#if CC2520_CONF_CHECKSUM + uint16_t checksum; +#endif /* CC2520_CONF_CHECKSUM */ + + GET_LOCK(); +#if (DEBUG == 1) + P8OUT &= ~BIT6; // TODO LED FLASH for the debug on transmission +#endif + txpower = 0; + if(packetbuf_attr(PACKETBUF_ATTR_RADIO_TXPOWER) > 0) { + /* Remember the current transmission power */ + txpower = cc2520_get_txpower(); + /* Set the specified transmission power */ + //TODOset_txpower(packetbuf_attr(PACKETBUF_ATTR_RADIO_TXPOWER) - 1); + } + + total_len = payload_len + AUX_LEN; + + /* The TX FIFO can only hold one packet. Make sure to not overrun + * FIFO by waiting for transmission to start here and synchronizing + * with the CC2520_TX_ACTIVE check in cc2520_send. + * + * Note that we may have to wait up to 320 us (20 symbols) before + * transmission starts. + */ +#ifndef CC2520_CONF_SYMBOL_LOOP_COUNT +#error CC2520_CONF_SYMBOL_LOOP_COUNT needs to be set!!! +#else +#define LOOP_20_SYMBOLS CC2520_CONF_SYMBOL_LOOP_COUNT +#endif + +#if WITH_SEND_CCA + strobe(CC2520_INS_SRXON); + //BUSYWAIT_UNTIL(status() & BV(CC2520_TX_ACTIVE) , RTIMER_SECOND / 100); + strobe(CC2520_INS_STXONCCA); +#else /* WITH_SEND_CCA */ + strobe(CC2520_INS_STXON); +#endif /* WITH_SEND_CCA */ + for(i = LOOP_20_SYMBOLS; i > 0; i--) { + if(CC2520_SFD_IS_1) { + { + rtimer_clock_t sfd_timestamp; + sfd_timestamp = cc2520_sfd_start_time; + if(packetbuf_attr(PACKETBUF_ATTR_PACKET_TYPE) == + PACKETBUF_ATTR_PACKET_TYPE_TIMESTAMP) { + /* Write timestamp to last two bytes of packet in TXFIFO. */ + CC2520_WRITE_RAM(&sfd_timestamp, CC2520RAM_TXFIFO + payload_len - 1, 2); + } + } + + if(!(status() & BV(CC2520_TX_ACTIVE))) { + /* SFD went high but we are not transmitting. This means that + we just started receiving a packet, so we drop the + transmission. */ + RELEASE_LOCK(); + return RADIO_TX_COLLISION; + } + if(receive_on) { + ENERGEST_OFF(ENERGEST_TYPE_LISTEN); + } + ENERGEST_ON(ENERGEST_TYPE_TRANSMIT); + /* We wait until transmission has ended so that we get an + accurate measurement of the transmission time.*/ + //BUSYWAIT_UNTIL(getreg(CC2520_EXCFLAG0) & TX_FRM_DONE , RTIMER_SECOND / 100); + //BUSYWAIT_UNTIL(!(status() & BV(CC2520_TX_ACTIVE)), RTIMER_SECOND / 10); + +#ifdef ENERGEST_CONF_LEVELDEVICE_LEVELS + ENERGEST_OFF_LEVEL(ENERGEST_TYPE_TRANSMIT,cc2520_get_txpower()); +#endif + ENERGEST_OFF(ENERGEST_TYPE_TRANSMIT); + if(receive_on) { + ENERGEST_ON(ENERGEST_TYPE_LISTEN); + } else { + /* We need to explicitly turn off the radio, + * since STXON[CCA] -> TX_ACTIVE -> RX_ACTIVE */ + off(); + } + + if(packetbuf_attr(PACKETBUF_ATTR_RADIO_TXPOWER) > 0) { + /* Restore the transmission power */ + set_txpower(txpower & 0xff); + } + + RELEASE_LOCK(); + if (getreg(CC2520_EXCFLAG0) & TX_FRM_DONE ) + return RADIO_TX_OK; + else + return RADIO_TX_COLLISION; + } + } + + /* If we are using WITH_SEND_CCA, we get here if the packet wasn't + transmitted because of other channel activity. */ + RIMESTATS_ADD(contentiondrop); + PRINTF("cc2520: do_send() transmission never started\n"); + + if(packetbuf_attr(PACKETBUF_ATTR_RADIO_TXPOWER) > 0) { + /* Restore the transmission power */ + set_txpower(txpower & 0xff); + } + + RELEASE_LOCK(); + return RADIO_TX_COLLISION; +} +/*---------------------------------------------------------------------------*/ +static int +cc2520_prepare(const void *payload, unsigned short payload_len) +{ + uint8_t total_len; +#if CC2520_CONF_CHECKSUM + uint16_t checksum; +#endif /* CC2520_CONF_CHECKSUM */ + GET_LOCK(); + + PRINTF("cc2520: sending %d bytes\n", payload_len); + /*int i; + for(i = 0; i < payload_len;i++) + printf("%x",((uint8_t *) payload)[i]); + printf("\n");*/ + RIMESTATS_ADD(lltx); + + /* Wait for any previous transmission to finish. */ + /* while(status() & BV(CC2520_TX_ACTIVE));*/ + + /* Write packet to TX FIFO. */ + strobe(CC2520_INS_SFLUSHTX); + +#if CC2520_CONF_CHECKSUM + checksum = crc16_data(payload, payload_len, 0); +#endif /* CC2520_CONF_CHECKSUM */ + total_len = payload_len + AUX_LEN; + CC2520_WRITE_FIFO_BUF(&total_len, 1); + CC2520_WRITE_FIFO_BUF(payload, payload_len); +#if CC2520_CONF_CHECKSUM + CC2520_WRITE_FIFO_BUF(&checksum, CHECKSUM_LEN); +#endif /* CC2520_CONF_CHECKSUM */ + + RELEASE_LOCK(); + return 0; +} +/*---------------------------------------------------------------------------*/ +static int +cc2520_send(const void *payload, unsigned short payload_len) +{ + + cc2520_prepare(payload, payload_len); + return cc2520_transmit(payload_len); +} +/*---------------------------------------------------------------------------*/ +int +cc2520_off(void) +{ + /* Don't do anything if we are already turned off. */ + if(receive_on == 0) { + return 1; + } + + /* If we are called when the driver is locked, we indicate that the + radio should be turned off when the lock is unlocked. */ + if(locked) { + /* ("Off when locked (%d)\n", locked);*/ + lock_off = 1; + return 1; + } + + GET_LOCK(); + /* If we are currently receiving a packet (indicated by SFD == 1), + we don't actually switch the radio off now, but signal that the + driver should switch off the radio once the packet has been + received and processed, by setting the 'lock_off' variable. */ + if(status() & BV(CC2520_TX_ACTIVE)) { + lock_off = 1; + } else { + off(); + } + RELEASE_LOCK(); + return 1; +} +/*---------------------------------------------------------------------------*/ +int +cc2520_on(void) +{ + if(receive_on) { + return 1; + } + if(locked) { + lock_on = 1; + return 1; + } + + GET_LOCK(); + on(); + RELEASE_LOCK(); + return 1; +} +/*---------------------------------------------------------------------------*/ +int +cc2520_get_channel(void) +{ + return channel; +} +/*---------------------------------------------------------------------------*/ +int +cc2520_set_channel(int c) +{ + uint16_t f; + + GET_LOCK(); + /* + * Subtract the base channel (11), multiply by 5, which is the + * channel spacing. 357 is 2405-2048 and 0x4000 is LOCK_THR = 1. + */ + + channel = c; + + f = MIN_CHANNEL + ((channel - MIN_CHANNEL) * CHANNEL_SPACING); + /* + * Writing RAM requires crystal oscillator to be stable. + */ + while(!(status() & (BV(CC2520_XOSC16M_STABLE)))); + + /* Wait for any transmission to end. */ + while(status() & BV(CC2520_TX_ACTIVE)); + + // Define radio channel (between 11 and 25) + setreg(CC2520_FREQCTRL, f ); + + /* If we are in receive mode, we issue an SRXON command to ensure + that the VCO is calibrated. */ + if(receive_on) { + strobe(CC2520_INS_SRXON); + } + + RELEASE_LOCK(); + return 1; +} +/*---------------------------------------------------------------------------*/ +void +cc2520_set_pan_addr(unsigned pan, + unsigned addr, + const uint8_t *ieee_addr) +{ + uint8_t tmp[2]; + + GET_LOCK(); + + /* + * Writing RAM requires crystal oscillator to be stable. + */ + //BUSYWAIT_UNTIL(status() & (BV(CC2520_XOSC16M_STABLE)), RTIMER_SECOND / 10); + + tmp[0] = pan & 0xff; + tmp[1] = pan >> 8; + CC2520_WRITE_RAM(&tmp, CC2520RAM_PANID, 2); + + + tmp[0] = addr & 0xff; + tmp[1] = addr >> 8; + CC2520_WRITE_RAM(&tmp, CC2520RAM_SHORTADDR, 2); + /* + if(ieee_addr != NULL) { + uint8_t tmp_addr[8]; + // LSB first, MSB last for 802.15.4 addresses in CC2520 + for (f = 0; f < 8; f++) { + tmp_addr[7 - f] = ieee_addr[f]; + } + CC2520_WRITE_RAM(tmp_addr, CC2520RAM_IEEEADDR, 8); + }*/ + RELEASE_LOCK(); +} +/*---------------------------------------------------------------------------*/ +/* + * Interrupt leaves frame intact in FIFO. + */ +#if CC2520_TIMETABLE_PROFILING +#define cc2520_timetable_size 16 +TIMETABLE(cc2520_timetable); +TIMETABLE_AGGREGATE(aggregate_time, 10); +#endif /* CC2520_TIMETABLE_PROFILING */ +int +cc2520_interrupt(void) +{ + CC2520_CLEAR_FIFOP_INT(); + process_poll(&cc2520_process); +#if CC2520_TIMETABLE_PROFILING + timetable_clear(&cc2520_timetable); + TIMETABLE_TIMESTAMP(cc2520_timetable, "interrupt"); +#endif /* CC2520_TIMETABLE_PROFILING */ + + last_packet_timestamp = cc2520_sfd_start_time; + pending++; + cc2520_packets_seen++; + return 1; +} +/*---------------------------------------------------------------------------*/ +PROCESS_THREAD(cc2520_process, ev, data) +{ + int len; + PROCESS_BEGIN(); + + PRINTF("cc2520_process: started\n"); + + while(1) { + PROCESS_YIELD_UNTIL(ev == PROCESS_EVENT_POLL); +#if CC2520_TIMETABLE_PROFILING + TIMETABLE_TIMESTAMP(cc2520_timetable, "poll"); +#endif /* CC2520_TIMETABLE_PROFILING */ + + PRINTF("cc2520_process: calling receiver callback\n"); + + packetbuf_clear(); + packetbuf_set_attr(PACKETBUF_ATTR_TIMESTAMP, last_packet_timestamp); + len = cc2520_read(packetbuf_dataptr(), PACKETBUF_SIZE); + + packetbuf_set_datalen(len); + + NETSTACK_RDC.input(); + flushrx(); +#if CC2520_TIMETABLE_PROFILING + TIMETABLE_TIMESTAMP(cc2520_timetable, "end"); + timetable_aggregate_compute_detailed(&aggregate_time, + &cc2520_timetable); + timetable_clear(&cc2520_timetable); +#endif /* CC2520_TIMETABLE_PROFILING */ + } + + PROCESS_END(); +} +/*---------------------------------------------------------------------------*/ +static int +cc2520_read(void *buf, unsigned short bufsize) +{ + uint8_t footer[2]; + uint8_t len; +#if CC2520_CONF_CHECKSUM + uint16_t checksum; +#endif /* CC2520_CONF_CHECKSUM */ + + if((!CC2520_FIFOP_IS_1) & !(getreg(CC2520_EXCFLAG1) & RX_FRM_DONE)) { + return 0; + } +#if (DEBUG == 1) + P2OUT &= ~BIT4; // TODO LED FLASH for the debug on reception +#endif + + //BUSYWAIT_UNTIL( (status() & BV(CC2520_RX_ACTIVE)) , RTIMER_SECOND / 100); + //BUSYWAIT_UNTIL(getreg(CC2520_EXCFLAG1) & RX_FRM_DONE , RTIMER_SECOND / 100); + /* if(!pending) { + return 0; + }*/ + + pending = 0; + + GET_LOCK(); + + cc2520_packets_read++; + + getrxbyte(&len); + + if(len > CC2520_MAX_PACKET_LEN) { + /* Oops, we must be out of sync. */ + flushrx(); + RIMESTATS_ADD(badsynch); + RELEASE_LOCK(); + return 0; + } + + if(len <= AUX_LEN) { + flushrx(); + RIMESTATS_ADD(tooshort); + RELEASE_LOCK(); + return 0; + } + + if(len - AUX_LEN > bufsize) { + flushrx(); + RIMESTATS_ADD(toolong); + RELEASE_LOCK(); + return 0; + } + + getrxdata(buf, len - AUX_LEN); + +#if CC2520_CONF_CHECKSUM + getrxdata(&checksum, CHECKSUM_LEN); +#endif /* CC2520_CONF_CHECKSUM */ + getrxdata(footer, FOOTER_LEN); + +#if CC2520_CONF_CHECKSUM + if(checksum != crc16_data(buf, len - AUX_LEN, 0)) { + PRINTF("checksum failed 0x%04x != 0x%04x\n", + checksum, crc16_data(buf, len - AUX_LEN, 0)); + } + + if(footer[1] & FOOTER1_CRC_OK && + checksum == crc16_data(buf, len - AUX_LEN, 0)) { +#else + if(footer[1] & FOOTER1_CRC_OK) { +#endif /* CC2520_CONF_CHECKSUM */ + cc2520_last_rssi = footer[0]; + cc2520_last_correlation = footer[1] & FOOTER1_CORRELATION; + + + packetbuf_set_attr(PACKETBUF_ATTR_RSSI, cc2520_last_rssi); + packetbuf_set_attr(PACKETBUF_ATTR_LINK_QUALITY, cc2520_last_correlation); + + RIMESTATS_ADD(llrx); + + } else { + RIMESTATS_ADD(badcrc); + len = AUX_LEN; + } + + if(CC2520_FIFOP_IS_1) { + if(!CC2520_FIFO_IS_1) { + /* Clean up in case of FIFO overflow! This happens for every + * full length frame and is signaled by FIFOP = 1 and FIFO = + * 0. */ + flushrx(); + } else { + /* Another packet has been received and needs attention. */ + process_poll(&cc2520_process); + } + } + + RELEASE_LOCK(); + + if(len < AUX_LEN) { + return 0; + } + + return len - AUX_LEN; +} +/*---------------------------------------------------------------------------*/ +void +cc2520_set_txpower(uint8_t power) +{ + GET_LOCK(); + set_txpower(power); + RELEASE_LOCK(); +} +/*---------------------------------------------------------------------------*/ +int +cc2520_get_txpower(void) +{ + int power; + GET_LOCK(); + power = (int)(getreg(CC2520_TXCTRL) & 0x001f); + RELEASE_LOCK(); + return power; +} +/*---------------------------------------------------------------------------*/ +int +cc2520_rssi(void) +{ + int rssi; + int radio_was_off = 0; + + if(locked) { + return 0; + } + + GET_LOCK(); + + if(!receive_on) { + radio_was_off = 1; + cc2520_on(); + } + //BUSYWAIT_UNTIL(status() & BV(CC2520_RSSI_VALID), RTIMER_SECOND / 100); + + rssi = (int)((signed char)getreg(CC2520_RSSI)); + + if(radio_was_off) { + cc2520_off(); + } + RELEASE_LOCK(); + return rssi; +} +/*---------------------------------------------------------------------------*/ +/* +static int +detected_energy(void) +{ + return cc2520_rssi(); +} +*/ +/*---------------------------------------------------------------------------*/ +int +cc2520_cca_valid(void) +{ + int valid; + if(locked) { + return 1; + } + GET_LOCK(); + valid = !!(status() & BV(CC2520_RSSI_VALID)); + RELEASE_LOCK(); + return valid; +} +/*---------------------------------------------------------------------------*/ +static int +cc2520_cca(void) +{ + int cca; + int radio_was_off = 0; + + /* If the radio is locked by an underlying thread (because we are + being invoked through an interrupt), we preted that the coast is + clear (i.e., no packet is currently being transmitted by a + neighbor). */ + if(locked) { + return 1; + } + + GET_LOCK(); + if(!receive_on) { + radio_was_off = 1; + cc2520_on(); + } + + /* Make sure that the radio really got turned on. */ + if(!receive_on) { + RELEASE_LOCK(); + if(radio_was_off) { + cc2520_off(); + } + return 1; + } + + //BUSYWAIT_UNTIL(status() & BV(CC2520_RSSI_VALID), RTIMER_SECOND / 100); + + cca = CC2520_CCA_IS_1; + + if(radio_was_off) { + cc2520_off(); + } + RELEASE_LOCK(); + return cca; +} +/*---------------------------------------------------------------------------*/ +int +cc2520_receiving_packet(void) +{ + return CC2520_SFD_IS_1; +} +/*---------------------------------------------------------------------------*/ +static int +pending_packet(void) +{ + return CC2520_FIFOP_IS_1; +} +/*---------------------------------------------------------------------------*/ +void +cc2520_set_cca_threshold(int value) +{ + uint16_t shifted = value << 8; + GET_LOCK(); + setreg(CC2520_RSSI, shifted); + RELEASE_LOCK(); +} +/*---------------------------------------------------------------------------*/ diff --git a/core/dev/cc2520.h b/core/dev/cc2520.h new file mode 100644 index 000000000..b247f567b --- /dev/null +++ b/core/dev/cc2520.h @@ -0,0 +1,199 @@ +/* + * 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 + * CC2520 driver header file + * \author + * Adam Dunkels + * Joakim Eriksson + */ + +#ifndef __CC2520_H__ +#define __CC2520_H__ + +#include "contiki.h" +#include "dev/spi.h" +#include "dev/radio.h" +#include "dev/cc2520_const.h" + +int cc2520_init(void); + +#define CC2520_MAX_PACKET_LEN 127 + +int cc2520_set_channel(int channel); +int cc2520_get_channel(void); + +void cc2520_set_pan_addr(unsigned pan, + unsigned addr, + const uint8_t *ieee_addr); + +extern signed char cc2520_last_rssi; +extern uint8_t cc2520_last_correlation; + +int cc2520_rssi(void); + +extern const struct radio_driver cc2520_driver; + +/** + * \param power Between 1 and 31. + */ +void cc2520_set_txpower(uint8_t power); +int cc2520_get_txpower(void); +#define CC2520_TXPOWER_MAX 31 +#define CC2520_TXPOWER_MIN 0 + +/** + * Interrupt function, called from the simple-cc2520-arch driver. + * + */ +int cc2520_interrupt(void); + +/* XXX hack: these will be made as Chameleon packet attributes */ +extern rtimer_clock_t cc2520_time_of_arrival, + cc2520_time_of_departure; +extern int cc2520_authority_level_of_sender; + +int cc2520_on(void); +int cc2520_off(void); + +void cc2520_set_cca_threshold(int value); + +/************************************************************************/ +/* Additional SPI Macros for the CC2520 */ +/************************************************************************/ +/* Send a strobe to the CC2520 */ +#define CC2520_STROBE(s) \ + do { \ + CC2520_SPI_ENABLE(); \ + SPI_WRITE(s); \ + CC2520_SPI_DISABLE(); \ + } while (0) + +/* Write to a register in the CC2520 */ +/* Note: the SPI_WRITE(0) seems to be needed for getting the */ +/* write reg working on the Z1 / MSP430X platform */ +#define CC2520_WRITE_REG(adr,data) \ + do { \ + CC2520_SPI_ENABLE(); \ + SPI_WRITE_FAST(CC2520_INS_MEMWR | ((adr>>8)&0xFF)); \ + SPI_WRITE_FAST(adr & 0xff); \ + SPI_WRITE_FAST((u8_t) data); \ + SPI_WAITFORTx_ENDED(); \ + CC2520_SPI_DISABLE(); \ + } while(0) + + +/* Read a register in the CC2520 */ +#define CC2520_READ_REG(adr,data) \ + do { \ + CC2520_SPI_ENABLE(); \ + SPI_WRITE((CC2520_INS_MEMRD | ((adr>>8)&0xFF))); \ + SPI_WRITE((adr & 0xFF)); \ + SPI_READ(data); \ + data = SPI_RXBUF; \ + CC2520_SPI_DISABLE(); \ + } while(0) + +#define CC2520_READ_FIFO_BYTE(data) \ + do { \ + CC2520_SPI_ENABLE(); \ + SPI_WRITE(CC2520_INS_RXBUF); \ + (void)SPI_RXBUF; \ + SPI_READ(data); \ + clock_delay(1); \ + CC2520_SPI_DISABLE(); \ + } while(0) + +#define CC2520_READ_FIFO_BUF(buffer,count) \ + do { \ + uint8_t i; \ + CC2520_SPI_ENABLE(); \ + SPI_WRITE(CC2520_INS_RXBUF); \ + (void)SPI_RXBUF; \ + for(i = 0; i < (count); i++) { \ + SPI_READ(((uint8_t *)(buffer))[i]); \ + } \ + clock_delay(1); \ + CC2520_SPI_DISABLE(); \ + } while(0) + +#define CC2520_WRITE_FIFO_BUF(buffer,count) \ + do { \ + uint8_t i; \ + CC2520_SPI_ENABLE(); \ + SPI_WRITE_FAST(CC2520_INS_TXBUF); \ + for(i = 0; i < (count); i++) { \ + SPI_WRITE_FAST(((uint8_t *)(buffer))[i]); \ + SPI_WAITFORTxREADY(); \ + } \ + SPI_WAITFORTx_ENDED(); \ + CC2520_SPI_DISABLE(); \ + } while(0) + +/* Write to RAM in the CC2520 */ +#define CC2520_WRITE_RAM(buffer,adr,count) \ + do { \ + uint8_t i; \ + CC2520_SPI_ENABLE(); \ + SPI_WRITE_FAST(CC2520_INS_MEMWR | (((adr)>>8) & 0xFF)); \ + SPI_WRITE_FAST(((adr) & 0xFF)); \ + for(i = 0; i < (count); i++) { \ + SPI_WRITE_FAST(((uint8_t*)(buffer))[i]); \ + } \ + SPI_WAITFORTx_ENDED(); \ + CC2520_SPI_DISABLE(); \ + } while(0) + +/* Read from RAM in the CC2520 */ +#define CC2520_READ_RAM(buffer,adr,count) \ + do { \ + uint8_t i; \ + CC2520_SPI_ENABLE(); \ + SPI_WRITE(CC2520_INS_MEMRD | (((adr)>>8) & 0xFF)); \ + SPI_WRITE(((adr) & 0xFF)); \ + SPI_RXBUF; \ + for(i = 0; i < (count); i++) { \ + SPI_READ(((uint8_t*)(buffer))[i]); \ + } \ + CC2520_SPI_DISABLE(); \ + } while(0) + +/* Read status of the CC2520 */ +#define CC2520_GET_STATUS(s) \ + do { \ + CC2520_SPI_ENABLE(); \ + SPI_WRITE(CC2520_INS_SNOP); \ + s = SPI_RXBUF; \ + CC2520_SPI_DISABLE(); \ + } while (0) + +#endif /* __CC2520_H__ */ diff --git a/core/dev/cc2520_const.h b/core/dev/cc2520_const.h new file mode 100644 index 000000000..c77d05d1a --- /dev/null +++ b/core/dev/cc2520_const.h @@ -0,0 +1,215 @@ +/* + * 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. + * + */ + +#ifndef CC2520_CONST_H +#define CC2520_CONST_H + +/* + * All constants are from the Chipcon cc2520 Data Sheet that at one + * point in time could be found at + * http://www.chipcon.com/files/cc2520_Data_Sheet_1_4.pdf + * + * The page numbers below refer to pages in this document. + */ + +/* Page 27. */ +enum cc2520_status_byte { + CC2520_XOSC16M_STABLE = 7, + CC2520_RSSI_VALID = 6, + CC2520_EXCEPTION_CHA = 5, + CC2520_EXCEPTION_CHB = 4, + CC2520_DPU_H = 3, + CC2520_DPU_L = 2, + CC2520_TX_ACTIVE = 1, + CC2520_RX_ACTIVE = 0, + +}; +#define TX_FRM_DONE 0x02 +#define RX_FRM_DONE 0x01 +#define RX_FRM_ABORTED 0x20 + +/* Page 27. */ +enum cc2520_memory_size { + CC2520_RAM_SIZE = 640, + CC2520_FIFO_SIZE = 128, +}; + +/* Page 29. */ +enum cc2520_address { + CC2520RAM_TXFIFO = 0x100, + CC2520RAM_RXFIFO = 0x180, + CC2520RAM_IEEEADDR = 0x3EA, + CC2520RAM_PANID = 0x3F2, + CC2520RAM_SHORTADDR = 0x3F4, +}; + +// IEEE 802.15.4 defined constants (2.4 GHz logical channels) +#define MIN_CHANNEL 11 // 2405 MHz +#define MAX_CHANNEL 26 // 2480 MHz +#define CHANNEL_SPACING 5 // MHz + +// FREG definitions (BSET/BCLR supported) +#define CC2520_FRMFILT0 0x000 +#define CC2520_FRMFILT1 0x001 +#define CC2520_SRCMATCH 0x002 +#define CC2520_SRCSHORTEN0 0x004 +#define CC2520_SRCSHORTEN1 0x005 +#define CC2520_SRCSHORTEN2 0x006 +#define CC2520_SRCEXTEN0 0x008 +#define CC2520_SRCEXTEN1 0x009 +#define CC2520_SRCEXTEN2 0x00A +#define CC2520_FRMCTRL0 0x00C +#define CC2520_FRMCTRL1 0x00D +#define CC2520_RXENABLE0 0x00E +#define CC2520_RXENABLE1 0x00F +#define CC2520_EXCFLAG0 0x010 +#define CC2520_EXCFLAG1 0x011 +#define CC2520_EXCFLAG2 0x012 +#define CC2520_EXCMASKA0 0x014 +#define CC2520_EXCMASKA1 0x015 +#define CC2520_EXCMASKA2 0x016 +#define CC2520_EXCMASKB0 0x018 +#define CC2520_EXCMASKB1 0x019 +#define CC2520_EXCMASKB2 0x01A +#define CC2520_EXCBINDX0 0x01C +#define CC2520_EXCBINDX1 0x01D +#define CC2520_EXCBINDY0 0x01E +#define CC2520_EXCBINDY1 0x01F +#define CC2520_GPIOCTRL0 0x020 +#define CC2520_GPIOCTRL1 0x021 +#define CC2520_GPIOCTRL2 0x022 +#define CC2520_GPIOCTRL3 0x023 +#define CC2520_GPIOCTRL4 0x024 +#define CC2520_GPIOCTRL5 0x025 +#define CC2520_GPIOPOLARITY 0x026 +#define CC2520_GPIOCTRL 0x028 +#define CC2520_DPUCON 0x02A +#define CC2520_DPUSTAT 0x02C +#define CC2520_FREQCTRL 0x02E +#define CC2520_FREQTUNE 0x02F +#define CC2520_TXPOWER 0x030 +#define CC2520_TXCTRL 0x031 +#define CC2520_FSMSTAT0 0x032 +#define CC2520_FSMSTAT1 0x033 +#define CC2520_FIFOPCTRL 0x034 +#define CC2520_FSMCTRL 0x035 +#define CC2520_CCACTRL0 0x036 +#define CC2520_CCACTRL1 0x037 +#define CC2520_RSSI 0x038 +#define CC2520_RSSISTAT 0x039 +#define CC2520_TXFIFO_BUF 0x03A +#define CC2520_RXFIRST 0x03C +#define CC2520_RXFIFOCNT 0x03E +#define CC2520_TXFIFOCNT 0x03F + +// SREG definitions (BSET/BCLR unsupported) +#define CC2520_CHIPID 0x040 +#define CC2520_VERSION 0x042 +#define CC2520_EXTCLOCK 0x044 +#define CC2520_MDMCTRL0 0x046 +#define CC2520_MDMCTRL1 0x047 +#define CC2520_FREQEST 0x048 +#define CC2520_RXCTRL 0x04A +#define CC2520_FSCTRL 0x04C +#define CC2520_FSCAL0 0x04E +#define CC2520_FSCAL1 0x04F +#define CC2520_FSCAL2 0x050 +#define CC2520_FSCAL3 0x051 +#define CC2520_AGCCTRL0 0x052 +#define CC2520_AGCCTRL1 0x053 +#define CC2520_AGCCTRL2 0x054 +#define CC2520_AGCCTRL3 0x055 +#define CC2520_ADCTEST0 0x056 +#define CC2520_ADCTEST1 0x057 +#define CC2520_ADCTEST2 0x058 +#define CC2520_MDMTEST0 0x05A +#define CC2520_MDMTEST1 0x05B +#define CC2520_DACTEST0 0x05C +#define CC2520_DACTEST1 0x05D +#define CC2520_ATEST 0x05E +#define CC2520_DACTEST2 0x05F +#define CC2520_PTEST0 0x060 +#define CC2520_PTEST1 0x061 +#define CC2520_RESERVED 0x062 +#define CC2520_DPUBIST 0x07A +#define CC2520_ACTBIST 0x07C +#define CC2520_RAMBIST 0x07E + +// Instruction implementation +#define CC2520_INS_SNOP 0x00 +#define CC2520_INS_IBUFLD 0x02 +#define CC2520_INS_SIBUFEX 0x03 +#define CC2520_INS_SSAMPLECCA 0x04 +#define CC2520_INS_SRES 0x0F +#define CC2520_INS_MEMRD 0x10 +#define CC2520_INS_MEMWR 0x20 +#define CC2520_INS_RXBUF 0x30 +#define CC2520_INS_RXBUFCP 0x38 +#define CC2520_INS_RXBUFMOV 0x32 +#define CC2520_INS_TXBUF 0x3A +#define CC2520_INS_TXBUFCP 0x3E +#define CC2520_INS_RANDOM 0x3C +#define CC2520_INS_SXOSCON 0x40 +#define CC2520_INS_STXCAL 0x41 +#define CC2520_INS_SRXON 0x42 +#define CC2520_INS_STXON 0x43 +#define CC2520_INS_STXONCCA 0x44 +#define CC2520_INS_SRFOFF 0x45 +#define CC2520_INS_SXOSCOFF 0x46 +#define CC2520_INS_SFLUSHRX 0x47 +#define CC2520_INS_SFLUSHTX 0x48 +#define CC2520_INS_SACK 0x49 +#define CC2520_INS_SACKPEND 0x4A +#define CC2520_INS_SNACK 0x4B +#define CC2520_INS_SRXMASKBITSET 0x4C +#define CC2520_INS_SRXMASKBITCLR 0x4D +#define CC2520_INS_RXMASKAND 0x4E +#define CC2520_INS_RXMASKOR 0x4F +#define CC2520_INS_MEMCP 0x50 +#define CC2520_INS_MEMCPR 0x52 +#define CC2520_INS_MEMXCP 0x54 +#define CC2520_INS_MEMXWR 0x56 +#define CC2520_INS_BCLR 0x58 +#define CC2520_INS_BSET 0x59 +#define CC2520_INS_CTR 0x60 +#define CC2520_INS_CBCMAC 0x64 +#define CC2520_INS_UCBCMAC 0x66 +#define CC2520_INS_CCM 0x68 +#define CC2520_INS_UCCM 0x6A +#define CC2520_INS_ECB 0x70 +#define CC2520_INS_ECBO 0x72 +#define CC2520_INS_ECBX 0x74 +#define CC2520_INS_ECBXO 0x76 +#define CC2520_INS_INC 0x78 +#define CC2520_INS_ABORT 0x7F +#define CC2520_INS_REGRD 0x80 +#define CC2520_INS_REGWR 0xC0 + +#endif /* CC2520_CONST_H */ diff --git a/cpu/msp430/Makefile.msp430 b/cpu/msp430/Makefile.msp430 index 8649233b0..328089406 100644 --- a/cpu/msp430/Makefile.msp430 +++ b/cpu/msp430/Makefile.msp430 @@ -82,12 +82,13 @@ ifdef WERROR CFLAGSWERROR=-Werror endif -CFLAGS += $(CFLAGSNO) -fno-strict-aliasing +CFLAGS += $(CFLAGSNO) ### These flags can reduce the code size and RAM usage with up to 10% ifdef SMALL CFLAGS += -ffunction-sections +# CFLAGS += -fdata-sections LDFLAGS += -Wl,--gc-sections,--undefined=_reset_vector__,--undefined=InterruptVectors,--undefined=_copy_data_init__,--undefined=_clear_bss_init__,--undefined=_end_of_init__ endif # SMALL diff --git a/cpu/msp430/cc2520-arch-sfd.c b/cpu/msp430/cc2520-arch-sfd.c new file mode 100644 index 000000000..e24090d09 --- /dev/null +++ b/cpu/msp430/cc2520-arch-sfd.c @@ -0,0 +1,80 @@ +/* + * 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. + */ + +#include "contiki.h" +#include "dev/spi.h" +#include "dev/cc2520.h" + +extern volatile uint8_t cc2520_sfd_counter; +extern volatile uint16_t cc2520_sfd_start_time; +extern volatile uint16_t cc2520_sfd_end_time; + +/*---------------------------------------------------------------------------*/ +/* SFD interrupt for timestamping radio packets */ +#ifdef __IAR_SYSTEMS_ICC__ +#pragma vector=TIMERB1_VECTOR +__interrupt void +#else +interrupt(TIMERB1_VECTOR) +#endif +cc2520_timerb1_interrupt(void) +{ + int tbiv; + ENERGEST_ON(ENERGEST_TYPE_IRQ); + /* always read TBIV to clear IFG */ + tbiv = TBIV; + if(CC2520_SFD_IS_1) { + cc2520_sfd_counter++; + cc2520_sfd_start_time = TBCCR1; + } else { + cc2520_sfd_counter = 0; + cc2520_sfd_end_time = TBCCR1; + } + ENERGEST_OFF(ENERGEST_TYPE_IRQ); +} +/*---------------------------------------------------------------------------*/ +void +cc2520_arch_sfd_init(void) +{ + /* Need to select the special function! */ + P4SEL = BV(CC2520_SFD_PIN); + + /* start timer B - 32768 ticks per second */ + TBCTL = TBSSEL_1 | TBCLR; + + /* CM_3 = capture mode - capture on both edges */ + TBCCTL1 = CM_3 | CAP | SCS; + TBCCTL1 |= CCIE; + + /* Start Timer_B in continuous mode. */ + TBCTL |= MC1; + + TBR = RTIMER_NOW(); +} +/*---------------------------------------------------------------------------*/ diff --git a/cpu/msp430/cc2520-arch-sfd.h b/cpu/msp430/cc2520-arch-sfd.h new file mode 100644 index 000000000..ce6257ab2 --- /dev/null +++ b/cpu/msp430/cc2520-arch-sfd.h @@ -0,0 +1,38 @@ +/* + * 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. + */ +#ifndef CC2520_ARCH_SFD_H +#define CC2520_ARCH_SFD_H + +extern volatile uint8_t cc2520_arch_sfd_counter; +extern volatile uint16_t cc2520_arch_sfd_start_time; +extern volatile uint16_t cc2520_arch_sfd_end_time; + +void cc2520_arch_sfd_init(void); + +#endif /* CC2520_ARCH_SFD_H */ diff --git a/cpu/msp430/cc2520-arch.c b/cpu/msp430/cc2520-arch.c new file mode 100644 index 000000000..be73a9ab5 --- /dev/null +++ b/cpu/msp430/cc2520-arch.c @@ -0,0 +1,85 @@ +/* + * 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. + */ + +#include "contiki.h" +#include "contiki-net.h" + +#include "dev/spi.h" +#include "dev/cc2520.h" + +#ifdef CC2520_CONF_SFD_TIMESTAMPS +#define CONF_SFD_TIMESTAMPS CC2520_CONF_SFD_TIMESTAMPS +#endif /* CC2520_CONF_SFD_TIMESTAMPS */ + +#ifndef CONF_SFD_TIMESTAMPS +#define CONF_SFD_TIMESTAMPS 0 +#endif /* CONF_SFD_TIMESTAMPS */ + +#ifdef CONF_SFD_TIMESTAMPS +#include "cc2520-arch-sfd.h" +#endif + +/*---------------------------------------------------------------------------*/ +#ifdef __IAR_SYSTEMS_ICC__ +#pragma vector=CC2520_IRQ_VECTOR +__interrupt void +#else +interrupt(CC2520_IRQ_VECTOR) +#endif +cc2520_port1_interrupt(void) +{ + ENERGEST_ON(ENERGEST_TYPE_IRQ); + + if(cc2520_interrupt()) { + LPM4_EXIT; + } + + ENERGEST_OFF(ENERGEST_TYPE_IRQ); +} +/*---------------------------------------------------------------------------*/ +void +cc2520_arch_init(void) +{ + spi_init(); + + /* all input by default, set these as output */ + CC2520_CSN_PORT(DIR) |= BV(CC2520_CSN_PIN); + CC2520_VREG_PORT(DIR) |= BV(CC2520_VREG_PIN); + CC2520_RESET_PORT(DIR) |= BV(CC2520_RESET_PIN); + + P1DIR &= ~(BV(CC2520_FIFOP_PIN) | BV(CC2520_FIFO_PIN) | BV(CC2520_CCA_PIN)); + P2DIR &= ~(BV(CC2520_SFD_PIN)); + +#if CONF_SFD_TIMESTAMPS + cc2520_arch_sfd_init(); +#endif + + CC2520_SPI_DISABLE(); /* Unselect radio. */ +} +/*---------------------------------------------------------------------------*/ diff --git a/cpu/msp430/clock.c b/cpu/msp430/clock.c index fb54cbf73..06c737d2f 100644 --- a/cpu/msp430/clock.c +++ b/cpu/msp430/clock.c @@ -37,7 +37,7 @@ #include "sys/clock.h" #include "sys/etimer.h" #include "rtimer-arch.h" -#include "watchdog.h" +#include "dev/watchdog.h" #define INTERVAL (RTIMER_ARCH_SECOND / CLOCK_SECOND) @@ -49,13 +49,68 @@ static volatile clock_time_t count = 0; /* last_tar is used for calculating clock_fine */ 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__ #pragma vector=TIMERA1_VECTOR __interrupt void #else interrupt(TIMERA1_VECTOR) #endif -timera1 (void) { +timera1 (void) +{ ENERGEST_ON(ENERGEST_TYPE_IRQ); watchdog_start(); @@ -102,6 +157,7 @@ timera1 (void) { ENERGEST_OFF(ENERGEST_TYPE_IRQ); } +#endif /*---------------------------------------------------------------------------*/ clock_time_t clock_time(void) @@ -117,8 +173,13 @@ clock_time(void) void clock_set(clock_time_t clock, clock_time_t fclock) { +#if CONTIKI_TARGET_WISMOTE + TA1R = fclock; + TA1CCR1 = fclock + INTERVAL; +#else TAR = fclock; TACCR1 = fclock + INTERVAL; +#endif count = clock; } /*---------------------------------------------------------------------------*/ @@ -135,22 +196,58 @@ clock_fine(void) /* 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 */ +#if CONTIKI_TARGET_WISMOTE + return (unsigned short) (TA1R - t); +#else return (unsigned short) (TAR - t); +#endif } /*---------------------------------------------------------------------------*/ void clock_init(void) { 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 */ /* TACTL = TASSEL1 | TACLR | ID_3; */ - + /* Select ACLK 32768Hz clock, divide by 2 */ /* TACTL = TASSEL0 | TACLR | ID_1;*/ /* Select ACLK 32768Hz clock */ + /* TACTL = TASSEL0 | TACLR; */ + +#if INTERVAL==32768/CLOCK_SECOND TACTL = TASSEL0 | TACLR; +#elif INTERVAL==16384/CLOCK_SECOND + TACTL = 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. */ @@ -161,7 +258,7 @@ clock_init(void) /* Start Timer_A in continuous mode. */ TACTL |= MC1; - +#endif count = 0; /* Enable interrupts. */ @@ -221,6 +318,10 @@ clock_seconds(void) rtimer_clock_t clock_counter(void) { +#if CONTIKI_TARGET_WISMOTE + return TA1R; +#else return TAR; +#endif } /*---------------------------------------------------------------------------*/ diff --git a/cpu/msp430/dev/uart1.c b/cpu/msp430/dev/uart1.c index 5d8faaa81..cfc624bed 100644 --- a/cpu/msp430/dev/uart1.c +++ b/cpu/msp430/dev/uart1.c @@ -33,7 +33,6 @@ * Machine dependent MSP430 UART1 code. */ -#include #include "contiki.h" #include "sys/energest.h" #include "dev/uart1.h" @@ -93,7 +92,11 @@ handle_rxdma_timer(void *ptr) uint8_t uart1_active(void) { +#if CONTIKI_TARGET_WISMOTE + return rx_in_progress | transmitting; +#else return ((~ UTCTL1) & TXEPT) | rx_in_progress | transmitting; +#endif } /*---------------------------------------------------------------------------*/ void @@ -123,16 +126,21 @@ uart1_writeb(unsigned char c) /* Loop until the transmission buffer is available. */ /*while((IFG2 & UTXIFG1) == 0);*/ - TXBUF1 = ringbuf_get(&txbuf); + UCA1TXBUF = ringbuf_get(&txbuf); } #else /* TX_WITH_INTERRUPT */ +#if CONTIKI_TARGET_WISMOTE + while(!(UCA1IFG & UCTXIFG)); // USCI_A1 TX buffer ready? + UCA1TXBUF = c; +#else /* Loop until the transmission buffer is available. */ while((IFG2 & UTXIFG1) == 0); /* Transmit the data. */ TXBUF1 = c; +#endif #endif /* TX_WITH_INTERRUPT */ } /*---------------------------------------------------------------------------*/ @@ -143,6 +151,35 @@ uart1_writeb(unsigned char c) void uart1_init(unsigned long ubr) { +#if CONTIKI_TARGET_WISMOTE + P4DIR |= BIT5; + P4OUT |= BIT5 ; + P5SEL |= BIT6|BIT7; // P5.6,7 = USCI_A1 TXD/RXD + + P4SEL |= BIT7; + P4DIR |= BIT7; + + UCA1CTL1 |= UCSWRST; // **Put state machine in reset** + UCA1CTL1 |= UCSSEL_2; // SMCLK + UCA1BR0 = 139;//69; // Baudrate 57600 (see User's Guide) + UCA1BR1 = 0; // + UCA1MCTL |= UCBRS_2 + UCBRF_0; // Modulation UCBRFx=0 + UCA1CTL1 &= ~UCSWRST; // **Initialize USCI state machine** + + UCA1IE |= UCRXIE; + UCA1IFG &= ~UCRXIFG; + //UCA1IFG &= ~UCTXIFG; + + // UCA1TCTL1 |= URXSE; + + rx_in_progress = 0; + transmitting = 0; +#if TX_WITH_INTERRUPT + ringbuf_init(&txbuf, txbuf_data, sizeof(txbuf_data)); + UCA1IE |= UCTXIE; + //UCA1IFG &= ~UCTXIFG; +#endif /* TX_WITH_INTERRUPT */ +#else /* RS232 */ P3DIR &= ~0x80; /* Select P37 for input (UART1RX) */ P3DIR |= 0x40; /* Select P36 for output (UART1TX) */ @@ -151,7 +188,7 @@ uart1_init(unsigned long ubr) UCTL1 = SWRST | CHAR; /* 8-bit character, UART mode */ #if 0 - U1RCTL &= ~URXEIE; /* even erroneous characters trigger interrupts */ + U1RCTL &= ~URXEIE; /* even erroneous characters trigger interrupts */ #endif UTCTL1 = SSEL1; /* UCLK = MCLK */ @@ -235,10 +272,52 @@ uart1_init(unsigned long ubr) msp430_add_lpm_req(MSP430_REQUIRE_LPM1); #endif /* RX_WITH_DMA */ +#endif } /*---------------------------------------------------------------------------*/ +#if CONTIKI_TARGET_WISMOTE +#ifdef __IAR_SYSTEMS_ICC__ +#pragma vector=USCI_A1_VECTOR +__interrupt void +#else +interrupt(USCI_A1_VECTOR) +#endif +uart1_rx_interrupt(void) +{ + uint8_t c; + ENERGEST_ON(ENERGEST_TYPE_IRQ); + + if(UCRXIFG & UCA1IFG) { + rx_in_progress = 0; + // Check status register for receive errors. + if(UCA1STAT & UCRXERR) { + c = UCA1RXBUF; // Clear error flags by forcing a dummy read. + } else { + c = UCA1RXBUF; + if(uart1_input_handler != NULL) { + if(uart1_input_handler(c)) { + LPM4_EXIT; + } + } + } + UCA1IFG &= ~UCRXIFG; + } +#if TX_WITH_INTERRUPT + if(UCTXIFG & UCA1IFG) { + if(ringbuf_elements(&txbuf) == 0) { + transmitting = 0; + } else { + UCA1TXBUF = ringbuf_get(&txbuf); + } + UCA1IFG &= ~UCTXIFG; + } +#endif + //UCA1IFG &= 0x00; + ENERGEST_OFF(ENERGEST_TYPE_IRQ); +} +#else #if !RX_WITH_DMA #ifdef __IAR_SYSTEMS_ICC__ #pragma vector=UART1RX_VECTOR @@ -277,7 +356,12 @@ uart1_rx_interrupt(void) #endif /* !RX_WITH_DMA */ /*---------------------------------------------------------------------------*/ #if TX_WITH_INTERRUPT +#ifdef __IAR_SYSTEMS_ICC__ +#pragma vector=UART1TX_VECTOR +__interrupt void +#else interrupt(UART1TX_VECTOR) +#endif uart1_tx_interrupt(void) { ENERGEST_ON(ENERGEST_TYPE_IRQ); @@ -291,4 +375,5 @@ uart1_tx_interrupt(void) ENERGEST_OFF(ENERGEST_TYPE_IRQ); } #endif /* TX_WITH_INTERRUPT */ +#endif /*---------------------------------------------------------------------------*/ diff --git a/cpu/msp430/msp430.c b/cpu/msp430/msp430.c index 1eff4e261..3f67bbd70 100644 --- a/cpu/msp430/msp430.c +++ b/cpu/msp430/msp430.c @@ -27,12 +27,9 @@ * SUCH DAMAGE. * * This file is part of the Contiki operating system. - * - * @(#)$Id: msp430.c,v 1.15 2011/01/05 13:36:38 joxe Exp $ */ #include "contiki.h" #include "dev/watchdog.h" -#include "net/uip.h" /* dco_required set to 1 will cause the CPU not to go into sleep modes where the DCO clock stopped */ @@ -69,13 +66,34 @@ w_memset(void *out, int value, size_t n) void msp430_init_dco(void) { - /* This code taken from the FU Berlin sources and reformatted. */ +#if CONTIKI_TARGET_WISMOTE + // Stop watchdog + WDTCTL = WDTPW + WDTHOLD; + + /** Configure XTAL **/ + P7SEL |= BIT0 + BIT1; // Activate XT1 + UCSCTL6 &= ~XT1OFF; // Set XT1 On + + UCSCTL6 |= XT1DRIVE_2 | XTS | XT2OFF; // Max drive strength, adjust + UCSCTL6 &= ~XT1DRIVE_1; + + do { + UCSCTL7 &= ~(XT2OFFG + XT1LFOFFG + XT1HFOFFG + DCOFFG); + // Clear XT2,XT1,DCO fault flags + SFRIFG1 &= ~OFIFG; // Clear fault flags + }while (SFRIFG1&OFIFG); // Test oscillator fault flag + + UCSCTL2 = FLLD0 + FLLD2; + UCSCTL5 |= DIVA__2 + DIVS__2+ DIVM__2;//DIVPA__32 + DIVA__32 + DIVS__2+ DIVM__2; + UCSCTL4 = SELA__DCOCLKDIV + SELS__XT1CLK + SELM__XT1CLK; // Set MCLCK = XT1/2 , SMCLK = XT1/2 , ACLK = XT1/2 + +#else + /* This code taken from the FU Berlin sources and reformatted. */ #define DELTA ((MSP430_CPU_SPEED) / (32768 / 8)) unsigned int compare, oldcapture = 0; unsigned int i; - BCSCTL1 = 0xa4; /* ACLK is devided by 4. RSEL=6 no division for MCLK and SSMCLK. XT2 is off. */ @@ -119,6 +137,8 @@ msp430_init_dco(void) TACTL = 0; /* Stop Timer_A */ BCSCTL1 &= ~(DIVA1 + DIVA0); /* remove /8 divisor from ACLK again */ + +#endif } /*---------------------------------------------------------------------------*/ @@ -234,6 +254,7 @@ msp430_cpu_init(void) * runtime. */ #if defined(__MSP430__) && defined(__GNUC__) +#define asmv(arg) __asm__ __volatile__(arg) void * sbrk(int incr) { @@ -286,6 +307,7 @@ splhigh_(void) /* #endif */ /* } */ /*---------------------------------------------------------------------------*/ +#if DCOSYNCH_CONF_ENABLED /* this code will always start the TimerB if not already started */ void msp430_sync_dco(void) { @@ -332,4 +354,5 @@ msp430_sync_dco(void) { } } } +#endif /* DCOSYNCH_CONF_ENABLED */ /*---------------------------------------------------------------------------*/ diff --git a/cpu/msp430/msp430def.h b/cpu/msp430/msp430def.h index f4614efcf..b07a0514e 100644 --- a/cpu/msp430/msp430def.h +++ b/cpu/msp430/msp430def.h @@ -38,7 +38,6 @@ #include #define dint() __disable_interrupt() #define eint() __enable_interrupt() -#define __MSP430F1611__ 1 #define __MSP430__ 1 #define CC_CONF_INLINE #define BV(x) (1 << x) diff --git a/cpu/msp430/rtimer-arch.c b/cpu/msp430/rtimer-arch.c index fab65e418..50e6a2c76 100644 --- a/cpu/msp430/rtimer-arch.c +++ b/cpu/msp430/rtimer-arch.c @@ -39,7 +39,6 @@ */ #include "contiki.h" - #include "sys/energest.h" #include "sys/rtimer.h" #include "sys/process.h" @@ -54,13 +53,15 @@ #endif /*---------------------------------------------------------------------------*/ +#if CONTIKI_TARGET_WISMOTE #ifdef __IAR_SYSTEMS_ICC__ -#pragma vector=TIMERA0_VECTOR +#pragma vector=TIMER1_A0_VECTOR __interrupt void #else -interrupt(TIMERA0_VECTOR) +interrupt(TIMER1_A0_VECTOR) #endif -timera0 (void) { +timera0 (void) +{ ENERGEST_ON(ENERGEST_TYPE_IRQ); watchdog_start(); @@ -75,6 +76,30 @@ timera0 (void) { ENERGEST_OFF(ENERGEST_TYPE_IRQ); } +#else +#ifdef __IAR_SYSTEMS_ICC__ +#pragma vector=TIMER1_A0_VECTOR +__interrupt void +#else +interrupt(TIMERA0_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); +} +#endif /*---------------------------------------------------------------------------*/ void rtimer_arch_init(void) @@ -82,7 +107,11 @@ rtimer_arch_init(void) dint(); /* CCR0 interrupt enabled, interrupt occurs when timer equals CCR0. */ +#if CONTIKI_TARGET_WISMOTE + TA1CCTL0 = CCIE; +#else TACCTL0 = CCIE; +#endif /* Enable interrupts. */ eint(); @@ -93,8 +122,13 @@ rtimer_arch_now(void) { rtimer_clock_t t1, t2; do { +#if CONTIKI_TARGET_WISMOTE + t1 = TA1R; + t2 = TA1R; +#else t1 = TAR; t2 = TAR; +#endif } while(t1 != t2); return t1; } @@ -104,6 +138,10 @@ rtimer_arch_schedule(rtimer_clock_t t) { PRINTF("rtimer_arch_schedule time %u\n", t); +#if CONTIKI_TARGET_WISMOTE + TA1CCR0 = t; +#else TACCR0 = t; +#endif } /*---------------------------------------------------------------------------*/ diff --git a/cpu/msp430/watchdog.c b/cpu/msp430/watchdog.c index 89e816fe0..6ac86994c 100644 --- a/cpu/msp430/watchdog.c +++ b/cpu/msp430/watchdog.c @@ -112,9 +112,13 @@ watchdog_init(void) initialization. */ counter = 0; watchdog_stop(); - +#if CONTIKI_TARGET_WISMOTE + SFRIFG1 &= ~WDTIFG; + SFRIE1 |= WDTIE; +#else IFG1 &= ~WDTIFG; IE1 |= WDTIE; +#endif } /*---------------------------------------------------------------------------*/ void diff --git a/platform/sky/Makefile.common b/platform/sky/Makefile.common index 3a4510580..066cad86b 100644 --- a/platform/sky/Makefile.common +++ b/platform/sky/Makefile.common @@ -14,10 +14,6 @@ ifdef UIP_CONF_IPV6 CFLAGS += -DWITH_UIP6=1 endif -ifdef GCC -CFLAGS+=-Os -g -endif - ifdef IAR CFLAGS += -D__MSP430F1611__=1 -e --vla -Ohz --multiplier=16s --core=430 --double=32 CFLAGSNO = --dlib_config "$(IAR_PATH)/LIB/DLIB/dl430fn.h" $(CFLAGSWERROR) diff --git a/platform/wismote/Makefile.wismote b/platform/wismote/Makefile.wismote new file mode 100644 index 000000000..cb5e620b8 --- /dev/null +++ b/platform/wismote/Makefile.wismote @@ -0,0 +1,57 @@ +CONTIKI_TARGET_SOURCEFILES += contiki-wismote-platform.c \ + sht11.c sht11-sensor.c light-sensor.c battery-sensor.c \ + button-sensor.c radio-sensor.c + +#ARCH=spi.c ds2411.c xmem.c i2c.c node-id.c sensors.c cfs-coffee.c \ + cc2520.c cc2520-arch.c cc2520-arch-sfd.c \ + sky-sensors.c uip-ipchksum.c \ + checkpoint-arch.c uart1.c slip_uart1.c uart1-putchar.c + +ARCH=spix.c i2c.c node-id.c sensors.c cfs-coffee.c sht15.c \ + cc2520.c cc2520-arch.c cc2520-arch-sfd.c \ + sky-sensors.c uip-ipchksum.c \ + checkpoint-arch.c uart1.c slip_uart1.c uart1-putchar.c + + +CONTIKI_TARGET_DIRS = . dev apps net +ifndef CONTIKI_TARGET_MAIN +CONTIKI_TARGET_MAIN = contiki-wismote-main.c +endif + +ifdef UIP_CONF_IPV6 +CFLAGS += -DWITH_UIP6=1 +endif + +ifdef IAR +CFLAGS += -D__MSP430F5437__=1 -e --vla -Ohz --multiplier=32 --multiplier_location=4C0 --hw_workaround=CPU40 --core=430X --data_model small --double=32 +else +SMALL=1 +endif + +CFLAGS += -D__MSP430X__ + +CONTIKI_TARGET_SOURCEFILES += $(ARCH) $(UIPDRIVERS) + +MCU=msp430x5437 +include $(CONTIKI)/cpu/msp430/Makefile.msp430 + +ifdef IAR +LDFLAGS += -B -xm "$(IAR_PATH)/lib/dlib/dl430xsfn.r43" -f "$(IAR_PATH)/config/lnk430f5437.xcl" -l contiki-$(TARGET).map -Fintel-extended -s __program_start -D_STACK_SIZE=80 -D_DATA16_HEAP_SIZE=80 -D_DATA20_HEAP_SIZE=80 +endif + +contiki-$(TARGET).a: ${addprefix $(OBJECTDIR)/,symbols.o} +# $(AR) rcf $@ $^ + +ifdef IAR +%.hex: %.$(TARGET) + mv $< $@ +else +%.hex: %.ihex + mv $< $@ +endif + +%.upload: %.hex + msp430flasher -n msp430x5437 -e ERASE_MAIN -w $< -v -z [VCC] + +%.upload-clean: %.hex + msp430flasher -n msp430x5437 -w $< -v -z [VCC] diff --git a/platform/wismote/cfs-coffee-arch.h b/platform/wismote/cfs-coffee-arch.h new file mode 100644 index 000000000..1381ac66e --- /dev/null +++ b/platform/wismote/cfs-coffee-arch.h @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2008, 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 + * Coffee architecture-dependent header for the Tmote Sky platform. + * \author + * Nicolas Tsiftes + */ + +#ifndef CFS_COFFEE_ARCH_H +#define CFS_COFFEE_ARCH_H + +#include "contiki-conf.h" +#include "dev/xmem.h" +#include "dev/watchdog.h" + +/* Coffee configuration parameters. */ +#define COFFEE_SECTOR_SIZE 65536UL +#define COFFEE_PAGE_SIZE 256UL +#define COFFEE_START COFFEE_SECTOR_SIZE +#define COFFEE_SIZE (1024UL * 1024UL - COFFEE_START) +#define COFFEE_NAME_LENGTH 16 +#define COFFEE_MAX_OPEN_FILES 6 +#define COFFEE_FD_SET_SIZE 8 +#define COFFEE_LOG_TABLE_LIMIT 256 +#define COFFEE_DYN_SIZE 4*1024 +#define COFFEE_LOG_SIZE 1024 + +#define COFFEE_MICRO_LOGS 1 + +#define COFFEE_WATCHDOG_START() watchdog_start() +#define COFFEE_WATCHDOG_STOP() watchdog_stop() + +/* Flash operations. */ +#define COFFEE_WRITE(buf, size, offset) \ + xmem_pwrite((char *)(buf), (size), COFFEE_START + (offset)) + +#define COFFEE_READ(buf, size, offset) \ + xmem_pread((char *)(buf), (size), COFFEE_START + (offset)) + +#define COFFEE_ERASE(sector) \ + xmem_erase(COFFEE_SECTOR_SIZE, COFFEE_START + (sector) * COFFEE_SECTOR_SIZE) + +/* Coffee types. */ +typedef int16_t coffee_page_t; + +#endif /* !COFFEE_ARCH_H */ diff --git a/platform/wismote/checkpoint-arch.c b/platform/wismote/checkpoint-arch.c new file mode 100644 index 000000000..12f71bb89 --- /dev/null +++ b/platform/wismote/checkpoint-arch.c @@ -0,0 +1,370 @@ +/* + * 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. + * + */ + +/** + * \file + * Checkpoint library implementation for the Tmote Sky platform. + * \author + * Fredrik Osterlind + */ + +#include "contiki.h" +#include "lib/checkpoint.h" + +#include "sys/rtimer.h" +#include "sys/mt.h" +#include "cfs/cfs.h" +#include "cfs/cfs-coffee.h" +#include "dev/leds.h" +#include "dev/watchdog.h" + +#include + +#define DEBUG 0 +#if DEBUG +#define PRINTF(...) printf(__VA_ARGS__) +#else +#define PRINTF(...) +#endif + +#define COMMAND_ROLLBACK 1 +#define COMMAND_CHECKPOINT 2 +#define COMMAND_TBR 3 + +#define DATA_AS_HEX 0 /* If false, store binary data */ + +#define INCLUDE_RAM 1 /* Less then 10240 bytes */ +#define INCLUDE_TIMERS 1 /* 16 bytes */ +#define INCLUDE_LEDS 1 /* 1 bytes */ + +/* 10kb memory */ +#define RAM_START 0x1100 +#define RAM_END 0x3900 + +#define STOP_TIMERS() TACTL &= ~(MC1); TBCTL &= ~(MC1); watchdog_stop(); +#define START_TIMERS() watchdog_start(); TACTL |= MC1; TBCTL |= MC1; + +static struct mt_thread checkpoint_thread; +static uint8_t preset_cmd; +static int preset_fd; + +typedef union { + unsigned char u8[2]; + unsigned short u16; +} word_union_t; + +/*---------------------------------------------------------------------------*/ +static void +write_byte(int fd, uint8_t c) +{ +#if DATA_AS_HEX + uint8_t hex[2]; + sprintf(hex, "%02x", c); + if(cfs_write(fd, hex, 2) != 2) { + printf("err #1\n"); + } +#else /* DATA_AS_HEX */ + if(cfs_write(fd, &c, 1) != 1) { + printf("err #2\n"); + } +#endif /* DATA_AS_HEX */ +}/*---------------------------------------------------------------------------*/ +#if 0 +static void +write_array(int fd, unsigned char *mem, uint16_t len) +{ +#if DATA_AS_HEX + int i; + for(i = 0; i < len; i++) { + write_byte(fd, mem[i]); + } +#else /* DATA_AS_HEX */ + cfs_write(fd, mem, len); +#endif /* DATA_AS_HEX */ +} +#endif /* 0 */ +/*---------------------------------------------------------------------------*/ +static void +write_word(int fd, uint16_t w) +{ + word_union_t tmp; + tmp.u16 = w; + write_byte(fd, tmp.u8[0]); + write_byte(fd, tmp.u8[1]); +} +/*---------------------------------------------------------------------------*/ +static uint8_t +read_byte(int fd) +{ +#if DATA_AS_HEX + uint8_t hex[2]; + + cfs_read(fd, hex, 2); + + if(hex[0] >= 'A' && hex[0] <= 'F') { + hex[0] = (hex[0] - 'A' + 0xa); + } else if(hex[0] >= 'a' && hex[0] <= 'f') { + hex[0] = (hex[0] - 'a' + 0xa); + } else { + hex[0] = (hex[0] - '0'); + } + if(hex[1] >= 'A' && hex[1] <= 'F') { + hex[1] = (hex[1] - 'A' + 0xa); + } else if(hex[1] >= 'a' && hex[1] <= 'f') { + hex[1] = (hex[1] - 'a' + 0xa); + } else { + hex[1] = (hex[1] - '0'); + } + return (uint8_t)((hex[0]<<4)&0xf0) | (hex[1]&0x0f); +#else /* DATA_AS_HEX */ + uint8_t c; + cfs_read(fd, &c, 1); + return c; +#endif /* DATA_AS_HEX */ +} +/*---------------------------------------------------------------------------*/ +static uint16_t +read_word(int fd) +{ + word_union_t tmp; + tmp.u8[0] = read_byte(fd); + tmp.u8[1] = read_byte(fd); + return tmp.u16; +} +/*---------------------------------------------------------------------------*/ +static void +thread_checkpoint(int fd) +{ +#if INCLUDE_RAM + unsigned char *addr; + uint16_t size = 0; + unsigned char *thread_mem_start = (unsigned char *)&checkpoint_thread.thread.stack; + unsigned char *thread_mem_end = thread_mem_start + sizeof(checkpoint_thread.thread.stack) - 1; + unsigned char *coffee_mem_start = cfs_coffee_get_protected_mem(&size); + unsigned char *coffee_mem_end = coffee_mem_start + size - 1; +#endif /* INCLUDE_RAM */ + + /*printf("protected thread memory: %u, size=%u\n", (uint16_t) thread_mem_start, sizeof(checkpoint_thread.thread.stack));*/ + /*printf("protected coffee memory: %u, size=%u\n", (uint16_t) coffee_mem_start, size);*/ + + /* RAM */ +#if INCLUDE_RAM + for(addr = (unsigned char *)RAM_START; + addr < (unsigned char *)RAM_END; + addr++) { + + if((addr >= thread_mem_start && addr <= thread_mem_end)) { + /* Writing dummy memory */ + /*write_byte(fd, 1);*/ + continue; + } + + if((addr >= coffee_mem_start && addr <= coffee_mem_end)) { + /* Writing dummy memory */ + /*write_byte(fd, 2);*/ + continue; + } + + /* TODO Use write_array() */ + write_byte(fd, *addr); + + if(((int)addr % 512) == 0) { + PRINTF("."); + } + } + +#endif /* INCLUDE_RAM */ + + /* Timers */ +#if INCLUDE_TIMERS +/* write_word(fd, TACTL); + write_word(fd, TACCTL1); + write_word(fd, TACCR1); + write_word(fd, TAR); + + write_word(fd, TBCTL); + write_word(fd, TBCCTL1); + write_word(fd, TBCCR1); + write_word(fd, TBR);*/ +#endif /* INCLUDE_TIMERS */ + + /* LEDs */ +#if INCLUDE_LEDS + write_byte(fd, leds_arch_get()); +#endif /* INCLUDE_LEDS */ + + /* Radio */ + /* ADC */ + /* ... */ + + write_byte(fd, -1); /* Coffee padding byte */ +} +/*---------------------------------------------------------------------------*/ +static void +thread_rollback(int fd) +{ +#if INCLUDE_RAM + unsigned char *addr; + uint16_t size = 0; + unsigned char *thread_mem_start = (unsigned char *)&checkpoint_thread.thread.stack; + unsigned char *thread_mem_end = thread_mem_start + sizeof(checkpoint_thread.thread.stack) - 1; + unsigned char *coffee_mem_start = cfs_coffee_get_protected_mem(&size); + unsigned char *coffee_mem_end = coffee_mem_start + size - 1; +#endif /* INCLUDE_RAM */ + + /*printf("protected thread memory: %u, size=%u\n", (uint16_t) thread_mem_start, sizeof(checkpoint_thread.thread.stack));*/ + /*printf("protected coffee memory: %u, size=%u\n", (uint16_t) coffee_mem_start, size);*/ + + /* RAM */ +#if INCLUDE_RAM + for(addr = (unsigned char *)RAM_START; + addr < (unsigned char *)RAM_END; + addr++) { + if((addr >= thread_mem_start && addr <= thread_mem_end)) { + /* Ignoring incoming memory */ + /*read_byte(fd);*/ + continue; + } + + if((addr >= coffee_mem_start && addr <= coffee_mem_end)) { + /* Ignoring incoming memory */ + /*read_byte(fd);*/ + continue; + } + + *addr = read_byte(fd); + + if(((int)addr % 512) == 0) { + PRINTF("."); + } + } + +#endif /* INCLUDE_RAM */ + + /* Timers */ +#if INCLUDE_TIMERS +/* TACTL = read_word(fd); + TACCTL1 = read_word(fd); + TACCR1 = read_word(fd); + TAR = read_word(fd); + + TBCTL = read_word(fd); + TBCCTL1 = read_word(fd); + TBCCR1 = read_word(fd); + TBR = read_word(fd);*/ +#endif /* INCLUDE_TIMERS */ + + /* LEDs */ +#if INCLUDE_LEDS + leds_arch_set(read_byte(fd)); +#endif /* INCLUDE_LEDS */ + + /* Radio */ + /* ADC */ + /* ... */ + + read_byte(fd); /* Coffee padding byte */ +} +/*---------------------------------------------------------------------------*/ +static void +thread_loop(void *data) +{ + uint8_t cmd; + int fd; + + while(1) { + /* Store command and file descriptor on stack */ + cmd = preset_cmd; + fd = preset_fd; + + /* Handle command */ + if(cmd == COMMAND_ROLLBACK) { + PRINTF("Rolling back"); + thread_rollback(fd); + PRINTF(" done!\n"); + } else if(cmd == COMMAND_CHECKPOINT) { + PRINTF("Checkpointing"); + thread_checkpoint(fd); + PRINTF(" done!\n"); + } else if(cmd == COMMAND_TBR) { + PRINTF("Writing TBR"); + // write_word(fd, TBR); + PRINTF(" done!\n"); + } else { + printf("Error: unknown command: %u\n", cmd); + } + + /* Return to main Contiki thread */ + mt_yield(); + } +} +/*---------------------------------------------------------------------------*/ +int +checkpoint_arch_size() +{ + return 10258; +} +/*---------------------------------------------------------------------------*/ +void +checkpoint_arch_checkpoint(int fd) +{ +// STOP_TIMERS(); + + preset_cmd = COMMAND_CHECKPOINT; + preset_fd = fd; + mt_exec(&checkpoint_thread); + +// START_TIMERS(); +} +/*---------------------------------------------------------------------------*/ +void +checkpoint_arch_rollback(int fd) +{ + //STOP_TIMERS(); + + preset_cmd = COMMAND_ROLLBACK; + preset_fd = fd; + mt_exec(&checkpoint_thread); + + //START_TIMERS(); +} +/*---------------------------------------------------------------------------*/ +void +checkpoint_arch_init(void) +{ + mt_init(); + mt_start(&checkpoint_thread, thread_loop, NULL); + + /*mt_stop(&checkpoint_thread);*/ + /*mt_remove();*/ +} +/*---------------------------------------------------------------------------*/ diff --git a/platform/wismote/contiki-conf.h b/platform/wismote/contiki-conf.h new file mode 100644 index 000000000..9b3b138cc --- /dev/null +++ b/platform/wismote/contiki-conf.h @@ -0,0 +1,210 @@ +/* -*- C -*- */ + +#ifndef CONTIKI_CONF_H +#define CONTIKI_CONF_H + +#include "platform-conf.h" + +#ifndef NETSTACK_CONF_MAC +/* #define NETSTACK_CONF_MAC csma_driver */ +#define NETSTACK_CONF_MAC nullmac_driver +#endif /* NETSTACK_CONF_MAC */ + +#ifndef NETSTACK_CONF_RDC +/* #define NETSTACK_CONF_RDC contikimac_driver */ +#define NETSTACK_CONF_RDC nullrdc_driver +#endif /* NETSTACK_CONF_RDC */ + +#ifndef NETSTACK_CONF_RDC_CHANNEL_CHECK_RATE +#define NETSTACK_CONF_RDC_CHANNEL_CHECK_RATE 8 +#endif /* NETSTACK_CONF_RDC_CHANNEL_CHECK_RATE */ + +#ifndef NETSTACK_CONF_RADIO +#define NETSTACK_CONF_RADIO cc2520_driver +#endif /* NETSTACK_CONF_RADIO */ + +#ifndef NETSTACK_CONF_FRAMER +#define NETSTACK_CONF_FRAMER framer_802154 +#endif /* NETSTACK_CONF_FRAMER */ + +#ifndef CC2520_CONF_AUTOACK +#define CC2520_CONF_AUTOACK 1 +#endif /* CC2520_CONF_AUTOACK */ + + +#if WITH_UIP6 +/* Network setup for IPv6 */ +#define NETSTACK_CONF_NETWORK sicslowpan_driver + +/* Specify a minimum packet size for 6lowpan compression to be + enabled. This is needed for ContikiMAC, which needs packets to be + larger than a specified size, if no ContikiMAC header should be + used. */ +#define SICSLOWPAN_CONF_COMPRESSION_THRESHOLD 63 +#define CONTIKIMAC_CONF_WITH_CONTIKIMAC_HEADER 0 + +#define CXMAC_CONF_ANNOUNCEMENTS 0 +#define XMAC_CONF_ANNOUNCEMENTS 0 + +#ifndef QUEUEBUF_CONF_NUM +#define QUEUEBUF_CONF_NUM 8 +#endif + +#else /* WITH_UIP6 */ + +/* Network setup for non-IPv6 (rime). */ + +#define NETSTACK_CONF_NETWORK rime_driver + +#define COLLECT_CONF_ANNOUNCEMENTS 1 +#define CXMAC_CONF_ANNOUNCEMENTS 0 +#define XMAC_CONF_ANNOUNCEMENTS 0 +#define CONTIKIMAC_CONF_ANNOUNCEMENTS 0 + +#define CONTIKIMAC_CONF_COMPOWER 1 +#define XMAC_CONF_COMPOWER 1 +#define CXMAC_CONF_COMPOWER 1 + +#ifndef COLLECT_NEIGHBOR_CONF_MAX_COLLECT_NEIGHBORS +#define COLLECT_NEIGHBOR_CONF_MAX_COLLECT_NEIGHBORS 32 +#endif /* COLLECT_NEIGHBOR_CONF_MAX_COLLECT_NEIGHBORS */ + +#ifndef QUEUEBUF_CONF_NUM +#define QUEUEBUF_CONF_NUM 16 +#endif /* QUEUEBUF_CONF_NUM */ + +#ifndef TIMESYNCH_CONF_ENABLED +#define TIMESYNCH_CONF_ENABLED 0 +#endif /* TIMESYNCH_CONF_ENABLED */ + +#if TIMESYNCH_CONF_ENABLED +/* CC2520 SDF timestamps must be on if timesynch is enabled. */ +#undef CC2520_CONF_SFD_TIMESTAMPS +#define CC2520_CONF_SFD_TIMESTAMPS 1 +#endif /* TIMESYNCH_CONF_ENABLED */ + +#endif /* WITH_UIP6 */ + +#define PACKETBUF_CONF_ATTRS_INLINE 1 + +#ifndef RF_CHANNEL +#define RF_CHANNEL 26 +#endif /* RF_CHANNEL */ + +#define CONTIKIMAC_CONF_BROADCAST_RATE_LIMIT 0 + +#define IEEE802154_CONF_PANID 0xABCD + +#define SHELL_VARS_CONF_RAM_BEGIN 0x1100 +#define SHELL_VARS_CONF_RAM_END 0x2000 + +#define PROFILE_CONF_ON 0 +#define ENERGEST_CONF_ON 1 + +#define ELFLOADER_CONF_TEXT_IN_ROM 0 +#ifndef ELFLOADER_CONF_DATAMEMORY_SIZE +#define ELFLOADER_CONF_DATAMEMORY_SIZE 0x400 +#endif /* ELFLOADER_CONF_DATAMEMORY_SIZE */ +#ifndef ELFLOADER_CONF_TEXTMEMORY_SIZE +#define ELFLOADER_CONF_TEXTMEMORY_SIZE 0x800 +#endif /* ELFLOADER_CONF_TEXTMEMORY_SIZE */ + + +#define AODV_COMPLIANCE +#define AODV_NUM_RT_ENTRIES 32 + +#define WITH_ASCII 1 + +#define PROCESS_CONF_NUMEVENTS 8 +#define PROCESS_CONF_STATS 1 +/*#define PROCESS_CONF_FASTPOLL 4*/ + +#ifdef WITH_UIP6 + +#define RIMEADDR_CONF_SIZE 8 + +#define UIP_CONF_LL_802154 1 +#define UIP_CONF_LLH_LEN 0 + +#define UIP_CONF_ROUTER 1 +#ifndef UIP_CONF_IPV6_RPL +#define UIP_CONF_IPV6_RPL 1 +#endif /* UIP_CONF_IPV6_RPL */ + +/* configure number of neighbors and routes */ +#ifndef UIP_CONF_DS6_NBR_NBU +#define UIP_CONF_DS6_NBR_NBU 30 +#endif /* UIP_CONF_DS6_NBR_NBU */ +#ifndef UIP_CONF_DS6_ROUTE_NBU +#define UIP_CONF_DS6_ROUTE_NBU 30 +#endif /* UIP_CONF_DS6_ROUTE_NBU */ + +#define UIP_CONF_ND6_SEND_RA 0 +#define UIP_CONF_ND6_REACHABLE_TIME 600000 +#define UIP_CONF_ND6_RETRANS_TIMER 10000 + +#define UIP_CONF_IPV6 1 +#ifndef UIP_CONF_IPV6_QUEUE_PKT +#define UIP_CONF_IPV6_QUEUE_PKT 0 +#endif /* UIP_CONF_IPV6_QUEUE_PKT */ +#define UIP_CONF_IPV6_CHECKS 1 +#define UIP_CONF_IPV6_REASSEMBLY 0 +#define UIP_CONF_NETIF_MAX_ADDRESSES 3 +#define UIP_CONF_ND6_MAX_PREFIXES 3 +#define UIP_CONF_ND6_MAX_NEIGHBORS 4 +#define UIP_CONF_ND6_MAX_DEFROUTERS 2 +#define UIP_CONF_IP_FORWARD 0 +#ifndef UIP_CONF_BUFFER_SIZE +#define UIP_CONF_BUFFER_SIZE 240 +#endif + +#define SICSLOWPAN_CONF_COMPRESSION_IPV6 0 +#define SICSLOWPAN_CONF_COMPRESSION_HC1 1 +#define SICSLOWPAN_CONF_COMPRESSION_HC01 2 +#define SICSLOWPAN_CONF_COMPRESSION SICSLOWPAN_COMPRESSION_HC06 +#ifndef SICSLOWPAN_CONF_FRAG +#define SICSLOWPAN_CONF_FRAG 1 +#define SICSLOWPAN_CONF_MAXAGE 8 +#endif /* SICSLOWPAN_CONF_FRAG */ +#define SICSLOWPAN_CONF_CONVENTIONAL_MAC 1 +#define SICSLOWPAN_CONF_MAX_ADDR_CONTEXTS 2 +#ifndef SICSLOWPAN_CONF_MAX_MAC_TRANSMISSIONS +#define SICSLOWPAN_CONF_MAX_MAC_TRANSMISSIONS 5 +#endif /* SICSLOWPAN_CONF_MAX_MAC_TRANSMISSIONS */ +#else /* WITH_UIP6 */ +#define UIP_CONF_IP_FORWARD 1 +#define UIP_CONF_BUFFER_SIZE 108 +#endif /* WITH_UIP6 */ + +#define UIP_CONF_ICMP_DEST_UNREACH 1 + +#define UIP_CONF_DHCP_LIGHT +#define UIP_CONF_LLH_LEN 0 +#ifndef UIP_CONF_RECEIVE_WINDOW +#define UIP_CONF_RECEIVE_WINDOW 48 +#endif +#ifndef UIP_CONF_TCP_MSS +#define UIP_CONF_TCP_MSS 48 +#endif +#define UIP_CONF_MAX_CONNECTIONS 4 +#define UIP_CONF_MAX_LISTENPORTS 8 +#define UIP_CONF_UDP_CONNS 12 +#define UIP_CONF_FWCACHE_SIZE 30 +#define UIP_CONF_BROADCAST 1 +#define UIP_ARCH_IPCHKSUM 1 +#define UIP_CONF_UDP 1 +#define UIP_CONF_UDP_CHECKSUMS 1 +#define UIP_CONF_PINGADDRCONF 0 +#define UIP_CONF_LOGGING 0 + +#define UIP_CONF_TCP_SPLIT 0 + + + +/* include the project config */ +/* PROJECT_CONF_H might be defined in the project Makefile */ +#ifdef PROJECT_CONF_H +#include PROJECT_CONF_H +#endif /* PROJECT_CONF_H */ + +#endif /* CONTIKI_CONF_H */ diff --git a/platform/wismote/contiki-wismote-main.c b/platform/wismote/contiki-wismote-main.c new file mode 100644 index 000000000..5aff6d108 --- /dev/null +++ b/platform/wismote/contiki-wismote-main.c @@ -0,0 +1,470 @@ +/* + * 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. + * + */ + +#include "contiki.h" +#include +#include + +#include "dev/cc2520.h" +//#include "dev/ds2411.h" +#include "dev/leds.h" +#include "dev/serial-line.h" +#include "dev/slip.h" +#include "dev/uart1.h" +#include "dev/watchdog.h" +#include "dev/xmem.h" +#include "lib/random.h" +#include "net/netstack.h" +#include "net/mac/frame802154.h" + +#if WITH_UIP6 +#include "net/uip-ds6.h" +#endif /* WITH_UIP6 */ + +#include "net/rime.h" + +#include "node-id.h" +#include "sys/autostart.h" +#include "sys/profile.h" + +#if UIP_CONF_ROUTER + +#ifndef UIP_ROUTER_MODULE +#ifdef UIP_CONF_ROUTER_MODULE +#define UIP_ROUTER_MODULE UIP_CONF_ROUTER_MODULE +#else /* UIP_CONF_ROUTER_MODULE */ +#define UIP_ROUTER_MODULE rimeroute +#endif /* UIP_CONF_ROUTER_MODULE */ +#endif /* UIP_ROUTER_MODULE */ + +extern const struct uip_router UIP_ROUTER_MODULE; +#endif /* UIP_CONF_ROUTER */ + +#ifndef WITH_UIP +#define WITH_UIP 0 +#endif + +#if WITH_UIP +#include "net/uip.h" +#include "net/uip-fw.h" +#include "net/uip-fw-drv.h" +#include "net/uip-over-mesh.h" +static struct uip_fw_netif slipif = + {UIP_FW_NETIF(192,168,1,2, 255,255,255,255, slip_send)}; +static struct uip_fw_netif meshif = + {UIP_FW_NETIF(172,16,0,0, 255,255,0,0, uip_over_mesh_send)}; + +#endif /* WITH_UIP */ + +#define UIP_OVER_MESH_CHANNEL 8 +#if WITH_UIP +static uint8_t is_gateway; +#endif /* WITH_UIP */ + +#ifdef EXPERIMENT_SETUP +#include "experiment-setup.h" +#endif + +void init_platform(void); + +/*---------------------------------------------------------------------------*/ +#if 0 +int +force_float_inclusion() +{ + extern int __fixsfsi; + extern int __floatsisf; + extern int __mulsf3; + extern int __subsf3; + + return __fixsfsi + __floatsisf + __mulsf3 + __subsf3; +} +#endif +/*---------------------------------------------------------------------------*/ +void uip_log(char *msg) { puts(msg); } +/*---------------------------------------------------------------------------*/ +#ifndef RF_CHANNEL +#define RF_CHANNEL 26 +#endif +/*---------------------------------------------------------------------------*/ +#if 0 +void +force_inclusion(int d1, int d2) +{ + snprintf(NULL, 0, "%d", d1 % d2); +} +#endif +/*---------------------------------------------------------------------------*/ +#ifndef NODE_ID +#define NODE_ID 0x03 +#endif /* NODE_ID */ +static void +set_rime_addr(void) +{ + rimeaddr_t n_addr; + int i; + + memset(&n_addr, 0, sizeof(rimeaddr_t)); + + // Set node address +#if UIP_CONF_IPV6 + //memcpy(addr.u8, ds2411_id, sizeof(addr.u8)); + n_addr.u8[7] = NODE_ID & 0xff; + n_addr.u8[6] = NODE_ID >> 8; + + // n_addr.u8[7] = node_id & 0xff; + // n_addr.u8[6] = node_id >> 8; + +#else + /* if(node_id == 0) { + for(i = 0; i < sizeof(rimeaddr_t); ++i) { + addr.u8[i] = ds2411_id[7 - i]; + } + } else { + addr.u8[0] = node_id & 0xff; + addr.u8[1] = node_id >> 8; + }*/ + n_addr.u8[0] = NODE_ID >> 8; + n_addr.u8[1] = NODE_ID & 0xff; +#endif + + rimeaddr_set_node_addr(&n_addr); + printf("Rime started with address "); + for(i = 0; i < sizeof(n_addr.u8) - 1; i++) { + printf("%d.", n_addr.u8[i]); + } + printf("%d\n", n_addr.u8[i]); +} +/*---------------------------------------------------------------------------*/ +static void +print_processes(struct process * const processes[]) +{ + /* const struct process * const * p = processes;*/ + printf("Starting"); + while(*processes != NULL) { + printf(" '%s'", (*processes)->name); + processes++; + } + putchar('\n'); +} +/*--------------------------------------------------------------------------*/ +#if WITH_UIP +static void +set_gateway(void) +{ + if(!is_gateway) { + leds_on(LEDS_RED); + //printf("%d.%d: making myself the IP network gateway.\n\n", + // rimeaddr_node_addr.u8[0], rimeaddr_node_addr.u8[1]); + //printf("IPv4 address of the gateway: %d.%d.%d.%d\n\n", + // uip_ipaddr_to_quad(&uip_hostaddr)); + uip_over_mesh_set_gateway(&rimeaddr_node_addr); + uip_over_mesh_make_announced_gateway(); + is_gateway = 1; + } +} +#endif /* WITH_UIP */ +/*---------------------------------------------------------------------------*/ +int +main(int argc, char **argv) +{ + /* + * Initalize hardware. + */ + + msp430_cpu_init(); + clock_init(); + leds_init(); + + leds_on(LEDS_ALL); + + uart1_init(BAUD2UBR(115200)); /* Must come before first printf */ + +#if WITH_UIP + slip_arch_init(BAUD2UBR(115200)); +#endif /* WITH_UIP */ + + //ds2411_init(); + + /* XXX hack: Fix it so that the 802.15.4 MAC address is compatible + with an Ethernet MAC address - byte 0 (byte 2 in the DS ID) + cannot be odd. */ + //ds2411_id[2] &= 0xfe; + + //xmem_init(); + + rtimer_init(); + /* + * Hardware initialization done! + */ + + + /* Restore node id if such has been stored in external mem */ + //node_id_restore(); + + /* for setting "hardcoded" IEEE 802.15.4 MAC addresses */ +#ifdef IEEE_802154_MAC_ADDRESS + { + uint8_t ieee[] = IEEE_802154_MAC_ADDRESS; + //memcpy(ds2411_id, ieee, sizeof(uip_lladdr.addr)); + //ds2411_id[7] = node_id & 0xff; + } +#endif + + //random_init(ds2411_id[0] + node_id); + + leds_off(LEDS_BLUE); + /* + * Initialize Contiki and our processes. + */ + process_init(); + process_start(&etimer_process, NULL); + + ctimer_init(); + + init_platform(); + + set_rime_addr(); + + cc2520_init(); + { + uint8_t longaddr[8]; + uint16_t shortaddr; + + shortaddr = (rimeaddr_node_addr.u8[0] << 8) + + rimeaddr_node_addr.u8[1]; + memset(longaddr, 0, sizeof(longaddr)); + rimeaddr_copy((rimeaddr_t *)&longaddr, &rimeaddr_node_addr); + + printf("MAC %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x ", + longaddr[0], longaddr[1], longaddr[2], longaddr[3], + longaddr[4], longaddr[5], longaddr[6], longaddr[7]); + + cc2520_set_pan_addr(IEEE802154_PANID, shortaddr, longaddr); + } + cc2520_set_channel(RF_CHANNEL); + + printf(CONTIKI_VERSION_STRING " started. "); + if(node_id > 0) { + printf("Node id is set to %u.\n", node_id); + } else { + printf("Node id is not set.\n"); + } + +#if WITH_UIP6 + //memcpy(&uip_lladdr.addr, ds2411_id, sizeof(uip_lladdr.addr)); + + for(i =0;iipaddr.u8[i * 2], + lladdr->ipaddr.u8[i * 2 + 1]); + } + printf("%02x%02x\n", lladdr->ipaddr.u8[14], lladdr->ipaddr.u8[15]); + } + + if(!UIP_CONF_IPV6_RPL) { + uip_ipaddr_t ipaddr; + int i; + uip_ip6addr(&ipaddr, 0xaaaa, 0, 0, 0, 0, 0, 0, 0); + uip_ds6_set_addr_iid(&ipaddr, &uip_lladdr); + uip_ds6_addr_add(&ipaddr, 0, ADDR_TENTATIVE); + printf("Tentative global IPv6 address "); + for(i = 0; i < 7; ++i) { + printf("%02x%02x:", + ipaddr.u8[i * 2], ipaddr.u8[i * 2 + 1]); + } + printf("%02x%02x\n", + ipaddr.u8[7 * 2], ipaddr.u8[7 * 2 + 1]); + } + +#else /* WITH_UIP6 */ + + NETSTACK_RDC.init(); + NETSTACK_MAC.init(); + NETSTACK_NETWORK.init(); + + printf("%s %s, channel check rate %lu Hz, radio channel %u\n", + NETSTACK_MAC.name, NETSTACK_RDC.name, + CLOCK_SECOND / (NETSTACK_RDC.channel_check_interval() == 0? 1: + NETSTACK_RDC.channel_check_interval()), + RF_CHANNEL); +#endif /* WITH_UIP6 */ + +#if !WITH_UIP && !WITH_UIP6 + uart1_set_input(serial_line_input_byte); + serial_line_init(); +#endif + +#if PROFILE_CONF_ON + profile_init(); +#endif /* PROFILE_CONF_ON */ + + leds_off(LEDS_GREEN); + +#if TIMESYNCH_CONF_ENABLED + timesynch_init(); + timesynch_set_authority_level((rimeaddr_node_addr.u8[0] << 4) + 16); +#endif /* TIMESYNCH_CONF_ENABLED */ + +#if WITH_UIP + process_start(&tcpip_process, NULL); + process_start(&uip_fw_process, NULL); /* Start IP output */ + process_start(&slip_process, NULL); + + slip_set_input_callback(set_gateway); + + { + uip_ipaddr_t hostaddr, netmask; + + uip_init(); + + uip_ipaddr(&hostaddr, 172,16, + rimeaddr_node_addr.u8[0],rimeaddr_node_addr.u8[1]); + uip_ipaddr(&netmask, 255,255,0,0); + uip_ipaddr_copy(&meshif.ipaddr, &hostaddr); + + uip_sethostaddr(&hostaddr); + uip_setnetmask(&netmask); + uip_over_mesh_set_net(&hostaddr, &netmask); + /* uip_fw_register(&slipif);*/ + uip_over_mesh_set_gateway_netif(&slipif); + uip_fw_default(&meshif); + uip_over_mesh_init(UIP_OVER_MESH_CHANNEL); + printf("uIP started with IP address %d.%d.%d.%d\n", + uip_ipaddr_to_quad(&hostaddr)); + } +#endif /* WITH_UIP */ + + energest_init(); + ENERGEST_ON(ENERGEST_TYPE_CPU); + + watchdog_start(); + + print_processes(autostart_processes); + autostart_start(autostart_processes); + + // LED Low Init + P2DIR |= BIT4;//TODO + P8DIR |= BIT6; + P2OUT |= BIT4; + P8OUT |= BIT6; + + /* + * This is the scheduler loop. + */ + while(1) { + + int r; +#if PROFILE_CONF_ON + profile_episode_start(); +#endif /* PROFILE_CONF_ON */ + do { + /* Reset watchdog. */ + watchdog_periodic(); + r = process_run(); + } while(r > 0); +#if PROFILE_CONF_ON + profile_episode_end(); +#endif /* PROFILE_CONF_ON */ + + /* + * Idle processing. + */ + int s = splhigh(); /* Disable interrupts. */ + /* uart1_active is for avoiding LPM3 when still sending or receiving */ + if(process_nevents() != 0 || uart1_active()) { + splx(s); /* Re-enable interrupts. */ + } else { + static unsigned long irq_energest = 0; + + /* Re-enable interrupts and go to sleep atomically. */ + ENERGEST_OFF(ENERGEST_TYPE_CPU); + ENERGEST_ON(ENERGEST_TYPE_LPM); + /* We only want to measure the processing done in IRQs when we + are asleep, so we discard the processing time done when we + were awake. */ + energest_type_set(ENERGEST_TYPE_IRQ, irq_energest); + watchdog_stop(); + _BIS_SR(GIE | SCG0 | SCG1 | CPUOFF); /* LPM3 sleep. This + statement will block + until the CPU is + woken up by an + interrupt that sets + the wake up flag. */ + + /* We get the current processing time for interrupts that was + done during the LPM and store it for next time around. */ + dint(); + irq_energest = energest_type_time(ENERGEST_TYPE_IRQ); + eint(); + watchdog_start(); + ENERGEST_OFF(ENERGEST_TYPE_LPM); + ENERGEST_ON(ENERGEST_TYPE_CPU); + + /* P8OUT |= BIT6; */ + /* P2OUT |= BIT4; */ + } + } + + return 0; +} +/*---------------------------------------------------------------------------*/ +#if LOG_CONF_ENABLED +void +log_message(char *m1, char *m2) +{ + printf("%s%s\n", m1, m2); +} +#endif /* LOG_CONF_ENABLED */ diff --git a/platform/wismote/contiki-wismote-platform.c b/platform/wismote/contiki-wismote-platform.c new file mode 100644 index 000000000..4c9fcb5c3 --- /dev/null +++ b/platform/wismote/contiki-wismote-platform.c @@ -0,0 +1,42 @@ +/* + * 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. + * + * Author: Niclas Finne , Joakim Eriksson + */ + +#include "dev/button-sensor.h" + +SENSORS(&button_sensor); + +void +init_platform(void) +{ + process_start(&sensors_process, NULL); +} diff --git a/platform/wismote/dev/acc-sensor.c b/platform/wismote/dev/acc-sensor.c new file mode 100644 index 000000000..6817b7de6 --- /dev/null +++ b/platform/wismote/dev/acc-sensor.c @@ -0,0 +1,129 @@ +/* + * Copyright (c) 2010, 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. + * + * $Id: acc-sensor.c,v 1.6 2010/01/14 20:01:18 nifi Exp $ + * + * ----------------------------------------------------------------- + * + * Author : Adam Dunkels, Joakim Eriksson, Niclas Finne + * Created : 2005-11-01 + * Updated : $Date: 2010/01/14 20:01:18 $ + * $Revision: 1.6 $ + */ + +#include "dev/acc-sensor.h" + +const struct sensors_sensor acc_sensor; +static uint8_t active; + +/*---------------------------------------------------------------------------*/ +static void +activate(void) +{ + /* This assumes that some other sensor system already did setup the ADC + /* (in the case of the sky platform it is sensors_light_init that does it) + + P6SEL |= 0x70; + P6DIR = 0x00; + P6OUT = 0x00; + + P2DIR |= 0x48; + P2OUT |= 0x48; + + + /* stop converting immediately + ADC12CTL0 &= ~ENC; + ADC12CTL1 &= ~CONSEQ_3; + + /* Configure ADC12_2 to sample channel 11 (voltage) and use + /* the Vref+ as reference (SREF_1) since it is a stable reference + ADC12MCTL2 = (INCH_4 + SREF_1); + ADC12MCTL3 = (INCH_5 + SREF_1); + ADC12MCTL4 = (INCH_6 + SREF_1); + /* internal temperature can be read as value(3) + ADC12MCTL5 = (INCH_10 + SREF_1); + + ADC12CTL1 |= CONSEQ_3; + ADC12CTL0 |= ENC | ADC12SC; + + /* Irq_adc12_activate(&acc_sensor, 6, (INCH_11 + SREF_1)); */ + active = 1; +} +/*---------------------------------------------------------------------------*/ +static void +deactivate(void) +{ + /* irq_adc12_deactivate(&acc_sensor, 6); + acc_value = 0;*/ + active = 0; +} +/*---------------------------------------------------------------------------*/ +static int +value(int type) +{ +/* + switch(type) { + case 0: + return ADC12MEM2; + case 1: + return ADC12MEM3; + case 2: + return ADC12MEM4; + case 3: + return ADC12MEM5; + }*/ + return 0; +} +/*---------------------------------------------------------------------------*/ +static int +configure(int type, int c) +{ + switch(type) { + case SENSORS_ACTIVE: + if (c) { + activate(); + } else { + deactivate(); + } + } + return 0; +} +/*---------------------------------------------------------------------------*/ +static int +status(int type) +{ + switch (type) { + case SENSORS_ACTIVE: + case SENSORS_READY: + return active; + } + return 0; +} +/*---------------------------------------------------------------------------*/ +SENSORS_SENSOR(acc_sensor, ACC_SENSOR, + value, configure, status); diff --git a/platform/wismote/dev/acc-sensor.h b/platform/wismote/dev/acc-sensor.h new file mode 100644 index 000000000..b10ae214a --- /dev/null +++ b/platform/wismote/dev/acc-sensor.h @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2006, 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. + * + * $Id: acc-sensor.h,v 1.1 2009/01/15 21:06:02 adamdunkels Exp $ + * + * ----------------------------------------------------------------- + * + * Author : Adam Dunkels, Joakim Eriksson, Niclas Finne + * Created : 2005-11-01 + * Updated : $Date: 2009/01/15 21:06:02 $ + * $Revision: 1.1 $ + */ + +#ifndef __ACC_SENSOR_H__ +#define __ACC_SENSOR_H__ + +#include "lib/sensors.h" + +extern const struct sensors_sensor acc_sensor; + +#define ACC_SENSOR "Acc" + +#endif /* __ACC_SENSOR_H__ */ diff --git a/platform/wismote/dev/battery-sensor.c b/platform/wismote/dev/battery-sensor.c new file mode 100644 index 000000000..d40ff7d35 --- /dev/null +++ b/platform/wismote/dev/battery-sensor.c @@ -0,0 +1,96 @@ +/* + * Copyright (c) 2006, 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. + * + * $Id: battery-sensor.c,v 1.10 2010/02/03 20:30:07 nifi Exp $ + * + * ----------------------------------------------------------------- + * + * Author : Adam Dunkels, Joakim Eriksson, Niclas Finne + * Created : 2005-11-01 + * Updated : $Date: 2010/02/03 20:30:07 $ + * $Revision: 1.10 $ + */ + +#include "dev/battery-sensor.h" +#include "dev/sky-sensors.h" + +const struct sensors_sensor battery_sensor; +static uint8_t active; +/*---------------------------------------------------------------------------*/ +static void +activate(void) +{ + /* Configure ADC12_2 to sample channel 11 (voltage) and use */ + /* the Vref+ as reference (SREF_1) since it is a stable reference */ +// ADC12MCTL2 = (INCH_11 + SREF_1); + +// sky_sensors_activate(0x80); + + active = 1; +} +/*---------------------------------------------------------------------------*/ +static void +deactivate(void) +{ +// sky_sensors_deactivate(0x80); + active = 0; +} +/*---------------------------------------------------------------------------*/ +static int +value(int type) +{ + return 0;//ADC12MEM2/*battery_value*/; +} +/*---------------------------------------------------------------------------*/ +static int +configure(int type, int c) +{ + switch(type) { + case SENSORS_ACTIVE: + if(c) { + activate(); + } else { + deactivate(); + } + } + return 0; +} +/*---------------------------------------------------------------------------*/ +static int +status(int type) +{ + switch(type) { + case SENSORS_ACTIVE: + case SENSORS_READY: + return active; + } + return 0; +} +/*---------------------------------------------------------------------------*/ +SENSORS_SENSOR(battery_sensor, BATTERY_SENSOR, + value, configure, status); diff --git a/platform/wismote/dev/button-sensor.c b/platform/wismote/dev/button-sensor.c new file mode 100644 index 000000000..0456356ba --- /dev/null +++ b/platform/wismote/dev/button-sensor.c @@ -0,0 +1,106 @@ +/* + * 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 "lib/sensors.h" +#include "dev/hwconf.h" +#include "dev/button-sensor.h" + +const struct sensors_sensor button_sensor; + +static struct timer debouncetimer; +static int status(int type); + +HWCONF_PIN(BUTTON, 2, 7); +HWCONF_IRQ(BUTTON, 2, 7); + +/*---------------------------------------------------------------------------*/ +#ifdef __IAR_SYSTEMS_ICC__ +#pragma vector=PORT2_VECTOR +__interrupt void +#else +interrupt(PORT2_VECTOR) +#endif + irq_p2(void) +{ + ENERGEST_ON(ENERGEST_TYPE_IRQ); + + if(BUTTON_CHECK_IRQ()) { + if(timer_expired(&debouncetimer)) { + timer_set(&debouncetimer, CLOCK_SECOND / 4); + sensors_changed(&button_sensor); + LPM4_EXIT; + } + } + P2IFG = 0x00; + ENERGEST_OFF(ENERGEST_TYPE_IRQ); +} +/*---------------------------------------------------------------------------*/ +static int +value(int type) +{ + return BUTTON_READ() || !timer_expired(&debouncetimer); +} +/*---------------------------------------------------------------------------*/ +static int +configure(int type, int c) +{ + switch (type) { + case SENSORS_ACTIVE: + if (c) { + if(!status(SENSORS_ACTIVE)) { + timer_set(&debouncetimer, 0); + BUTTON_IRQ_EDGE_SELECTD(); + + BUTTON_SELECT(); + BUTTON_MAKE_INPUT(); + + BUTTON_ENABLE_IRQ(); + } + } else { + BUTTON_DISABLE_IRQ(); + } + return 1; + } + return 0; +} +/*---------------------------------------------------------------------------*/ +static int +status(int type) +{ + switch (type) { + case SENSORS_ACTIVE: + case SENSORS_READY: + return BUTTON_IRQ_ENABLED(); + } + return 0; +} +/*---------------------------------------------------------------------------*/ +SENSORS_SENSOR(button_sensor, BUTTON_SENSOR, + value, configure, status); diff --git a/platform/wismote/dev/ext-sensor.c b/platform/wismote/dev/ext-sensor.c new file mode 100644 index 000000000..42a8e7ed1 --- /dev/null +++ b/platform/wismote/dev/ext-sensor.c @@ -0,0 +1,105 @@ +/* + * Copyright (c) 2006, 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. + * + * $Id: ext-sensor.c,v 1.3 2010/02/13 11:20:48 joxe Exp $ + * + * ----------------------------------------------------------------- + * + * Author : Adam Dunkels, Joakim Eriksson, Niclas Finne, Marcus Lundén, + * Jesper Karlsson + * Created : 2005-11-01 + * Updated : $Date: 2010/02/13 11:20:48 $ + * $Revision: 1.3 $ + */ + +#include "contiki.h" +#include "dev/ext-sensor.h" +#include "dev/sky-sensors.h" + +const struct sensors_sensor ext_sensor; +static uint8_t active; +/*---------------------------------------------------------------------------*/ +static int +value(int type) +{ + /* ADC0 corresponds to the port under the logo, ADC1 to the port over the logo, + ADC2 and ADC3 corresponds to port on the JCreate bottom expansion port) + switch(type) { + case ADC0: + return ADC12MEM6; + case ADC1: + return ADC12MEM7; + case ADC2: + return ADC12MEM8; + case ADC3: + return ADC12MEM9; + }*/ + return 0; +} +/*---------------------------------------------------------------------------*/ +static int +status(int type) +{ + switch(type) { + case SENSORS_ACTIVE: + case SENSORS_READY: + return active; + } + return 0; +} +/*---------------------------------------------------------------------------*/ +static int +configure(int type, int c) +{ + switch(type) { + case SENSORS_ACTIVE: + if(c) { + if(!status(SENSORS_ACTIVE)) { + /* SREF_1 is Vref+ + /* MemReg6 == P6.0/A0 == port "under" logo + ADC12MCTL6 = (INCH_0 + SREF_0); + /* MemReg7 == P6.1/A1 == port "over" logo + ADC12MCTL7 = (INCH_1 + SREF_0); + /* MemReg8 == P6.2/A2, bottom expansion port + ADC12MCTL8 = (INCH_2 + SREF_0); + /* MemReg9 == P6.1/A3, bottom expansion port, End Of (ADC-)Sequence + ADC12MCTL9 = (INCH_3 + SREF_0); + */ + sky_sensors_activate(0x0F); + active = 1; + } + } else { + sky_sensors_deactivate(0x0F); + active = 0; + } + } + return 0; +} +/*---------------------------------------------------------------------------*/ +SENSORS_SENSOR(ext_sensor, "Ext", + value, configure, status); diff --git a/platform/wismote/dev/ext-sensor.h b/platform/wismote/dev/ext-sensor.h new file mode 100644 index 000000000..8fed8b59f --- /dev/null +++ b/platform/wismote/dev/ext-sensor.h @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2006, 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. + * + * $Id: ext-sensor.h,v 1.2 2010/02/13 11:20:48 joxe Exp $ + * + * ----------------------------------------------------------------- + * + * Author : Marcus Lundén + * Created : 2005-11-01 + * Updated : $Date: 2010/02/13 11:20:48 $ + * $Revision: 1.2 $ + */ + +#ifndef __EXT_SENSOR_H__ +#define __EXT_SENSOR_H__ + +#include "lib/sensors.h" + +#define ADC0 0 +#define ADC1 1 +#define ADC2 2 +#define ADC3 3 + +extern const struct sensors_sensor ext_sensor; + +#define EXT_SENSOR "Ext" + +#endif /* __EXT_SENSOR_H__ */ diff --git a/platform/wismote/dev/i2c.c b/platform/wismote/dev/i2c.c new file mode 100644 index 000000000..17a786d7a --- /dev/null +++ b/platform/wismote/dev/i2c.c @@ -0,0 +1,223 @@ +/* + * Copyright (c) 2006, 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. + */ + +/* + * Small and portable implementation of a bit-banging I2C bus master. + * + * The code should port really easily to platforms other than the + * msp430 but has some hardcoded constants in it. + * + * More info at: + * http://i2c-bus.org/ + * http://www.esacademy.com/faq/i2c/ + */ + +#include +#include +#include + +#include "dev/i2c.h" + +/* + * On the Tmote sky access to I2C/SPI/UART0 must always be exclusive. + */ + +void i2c_enable(void); +void i2c_disable(void); +int i2c_start(void); +unsigned i2c_read(int send_ack); +int i2c_write(unsigned); +void i2c_stop(void); + +#define I2C_PxDIR P3DIR +#define I2C_PxIN P3IN +#define I2C_PxOUT P3OUT +#define I2C_PxSEL P3SEL +/* + * SDA == P3.1 + * SCL == P3.3 + */ +#define SDA 1 +#define SCL 3 + +#define SDA_0() (I2C_PxDIR |= BV(SDA)) /* SDA Output */ +#define SDA_1() (I2C_PxDIR &= ~BV(SDA)) /* SDA Input */ +#define SDA_IS_1 (I2C_PxIN & BV(SDA)) + +#define SCL_0() (I2C_PxDIR |= BV(SCL)) /* SCL Output */ +#define SCL_1() (I2C_PxDIR &= ~BV(SCL)) /* SCL Input */ +#define SCL_IS_1 (I2C_PxIN & BV(SCL)) + +/* + * Should avoid infinite looping while waiting for SCL_IS_1. xxx/bg + */ +#define SCL_WAIT_FOR_1() do{}while (!SCL_IS_1) + +#define delay_4_7us() do{ _NOP(); _NOP(); _NOP(); _NOP(); \ + _NOP(); _NOP(); _NOP(); _NOP(); \ + _NOP(); _NOP(); _NOP(); _NOP(); }while(0) + +#define delay_4us() do{ _NOP(); _NOP(); _NOP(); _NOP(); \ + _NOP(); _NOP(); _NOP(); _NOP(); \ + _NOP(); _NOP(); }while(0) + +static unsigned char old_pxsel, old_pxout, old_pxdir; + +/* + * Grab SDA and SCL pins for exclusive use but remember old + * configuration so that it may be restored when we are done. + */ +void +i2c_enable(void) +{ + unsigned char sda_scl = BV(SDA)|BV(SCL); + + old_pxsel = I2C_PxSEL & sda_scl; + old_pxout = I2C_PxOUT & sda_scl; + old_pxdir = I2C_PxDIR & sda_scl; + + spi_busy = 1; + + I2C_PxSEL &= ~sda_scl; + + I2C_PxOUT &= ~sda_scl; + + I2C_PxDIR |= BV(SCL); /* SCL Output */ + I2C_PxDIR &= ~BV(SDA); /* SDA Input */ +} + +/* + * Restore bus to what it was before i2c_enable. + * + */ +void +i2c_disable(void) +{ + unsigned char not_sda_scl = ~(BV(SDA)|BV(SCL)); + + I2C_PxDIR = (I2C_PxDIR & not_sda_scl) | old_pxdir; + I2C_PxOUT = (I2C_PxOUT & not_sda_scl) | old_pxout; + I2C_PxSEL = (I2C_PxSEL & not_sda_scl) | old_pxsel; + + spi_busy = 0; +} + +int +i2c_start(void) +{ + SDA_1(); + SCL_1(); +#if 1 + SCL_WAIT_FOR_1(); +#else + { + unsigned long n; + for (n = 0; n < 100000 && !SCL_IS_1; n++) + ; + if (!SCL_IS_1) + return -1; + } +#endif + delay_4_7us(); + SDA_0(); + delay_4us(); + SCL_0(); + return 0; +} + +void +i2c_stop(void) +{ + SDA_0(); + delay_4us(); + SCL_1(); + SCL_WAIT_FOR_1(); + SDA_1(); +} + +/* + * Return true if we received an ACK. + */ +int +i2c_write(unsigned _c) +{ + unsigned char c = _c; + unsigned long n; + int i; + int ret; + + for (i = 0; i < 8; i++, c <<= 1) { + if (c & 0x80) + SDA_1(); + else + SDA_0(); + SCL_1(); + SCL_WAIT_FOR_1(); + SCL_0(); + } + + SDA_1(); + SCL_1(); + ret = 0; /* Loop waiting for an ACK to arrive. */ + for (n = 0; n < 250000; n++) { + if (!SDA_IS_1) { + ret = 1; + break; + } + } + SCL_WAIT_FOR_1(); /* clock stretching? */ + SCL_0(); + + return ret; +} + +unsigned +i2c_read(int send_ack) +{ + int i; + unsigned char c = 0x00; + + SDA_1(); + for (i = 0; i < 8; i++) { + c <<= 1; + SCL_1(); + SCL_WAIT_FOR_1(); + if (SDA_IS_1) + c |= 0x1; + SCL_0(); + } + + if (send_ack) + SDA_0(); + SCL_1(); + SCL_WAIT_FOR_1(); + SCL_0(); + + return c; +} diff --git a/platform/wismote/dev/i2c.h b/platform/wismote/dev/i2c.h new file mode 100644 index 000000000..74cd361e2 --- /dev/null +++ b/platform/wismote/dev/i2c.h @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2006, 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. + + */ + +#ifndef I2C_H +#define I2C_H + +/* + * On the Tmote sky access to I2C/SPI/UART0 must always be exclusive. + */ +#define I2C_ENABLE() (i2c_enable()) +#define I2C_DISABLE() (i2c_disable()) + +void i2c_enable(void); +void i2c_disable(void); +int i2c_start(void); +void i2c_stop(void); + +int i2c_write(unsigned); +unsigned i2c_read(int send_ack); + +#endif /* I2C_H */ diff --git a/platform/wismote/dev/light-sensor.c b/platform/wismote/dev/light-sensor.c new file mode 100644 index 000000000..cb9814e26 --- /dev/null +++ b/platform/wismote/dev/light-sensor.c @@ -0,0 +1,89 @@ +/* + * Copyright (c) 2005-2010, 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 "lib/sensors.h" +#include "dev/sky-sensors.h" +#include "dev/light-sensor.h" + +const struct sensors_sensor light_sensor; + +/*---------------------------------------------------------------------------*/ +static int +value(int type) +{ + /* switch(type) { */ + /* case LIGHT_SENSOR_PHOTOSYNTHETIC: */ + /* /\* Photosynthetically Active Radiation. *\/ */ + /* return ADC12MEM0; */ + /* case LIGHT_SENSOR_TOTAL_SOLAR: */ + /* /\* Total Solar Radiation. *\/ */ + /* return ADC12MEM1; */ + /* } */ + return 0; +} +/*---------------------------------------------------------------------------*/ +static int +status(int type) +{ +/* + switch(type) { + case SENSORS_ACTIVE: + case SENSORS_READY: + return (ADC12CTL0 & (ADC12ON + REFON)) == (ADC12ON + REFON); + } +*/ + return 0; +} + +/*---------------------------------------------------------------------------*/ +static int +configure(int type, int c) +{ + switch(type) { + case SENSORS_ACTIVE: + if(c) { + if(!status(SENSORS_ACTIVE)) { + +// ADC12MCTL0 = (INCH_4 + SREF_0); // photodiode 1 (P64) +// ADC12MCTL1 = (INCH_5 + SREF_0); // photodiode 2 (P65) + + sky_sensors_activate(0x30); + } + } else { + sky_sensors_deactivate(0x30); + } + } + return 0; +} +/*---------------------------------------------------------------------------*/ +SENSORS_SENSOR(light_sensor, "Light", + value, configure, status); diff --git a/platform/wismote/dev/light-sensor.h b/platform/wismote/dev/light-sensor.h new file mode 100644 index 000000000..467fec667 --- /dev/null +++ b/platform/wismote/dev/light-sensor.h @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2010, 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. + * + * + * $Id: light-sensor.h,v 1.2 2010/01/14 20:23:02 adamdunkels Exp $ + * + * ----------------------------------------------------------------- + * + * Author : Adam Dunkels, Joakim Eriksson, Niclas Finne + * Created : 2010-01-08 + * Updated : $Date: 2010/01/14 20:23:02 $ + * $Revision: 1.2 $ + */ + +#ifndef __LIGHT_SENSOR_H__ +#define __LIGHT_SENSOR_H__ + +#include "lib/sensors.h" + +extern const struct sensors_sensor light_sensor; + +#define LIGHT_SENSOR_PHOTOSYNTHETIC 0 +#define LIGHT_SENSOR_TOTAL_SOLAR 1 + + +#endif /* __LIGHT-SENSOR_H__ */ diff --git a/platform/wismote/dev/light.c b/platform/wismote/dev/light.c new file mode 100644 index 000000000..ab7d708d0 --- /dev/null +++ b/platform/wismote/dev/light.c @@ -0,0 +1,127 @@ +/* + * Copyright (c) 2005, 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: light.c,v 1.1 2006/08/02 14:44:46 bg- Exp $ + */ + +#include "contiki.h" +#include "dev/light.h" +#include + +/* + * Initialize periodic readings from the 2 photo diodes. The most + * recent readings will be stored in ADC internal registers/memory. + */ +void +sensors_light_init(void) +{ + P6SEL |= 0x30; + P6DIR = 0xff; + P6OUT = 0x00; + + /* Set up the ADC. */ + ADC12CTL0 = REF2_5V + SHT0_6 + SHT1_6 + MSC; // Setup ADC12, ref., sampling time + ADC12CTL1 = SHP + CONSEQ_3 + CSTARTADD_0; // Use sampling timer, repeat-sequenc-of-channels + + ADC12MCTL0 = (INCH_4 + SREF_0); // photodiode 1 (P64) + ADC12MCTL1 = (INCH_5 + SREF_0); // photodiode 2 (P65) + + ADC12CTL0 |= ADC12ON + REFON; + + ADC12CTL0 |= ENC; // enable conversion + ADC12CTL0 |= ADC12SC; // sample & convert +} + +/* Photosynthetically Active Radiation. */ +unsigned +sensors_light1(void) +{ + return ADC12MEM0; +} + +/* Total Solar Radiation. */ +unsigned +sensors_light2(void) +{ + return ADC12MEM1; +} + +/* + * Most of this information taken from + * http://www.moteiv.com/community/Getting_Data_from_Tmote_Sky%27s_Sensors + * + * The Photosynthetically Active Radiation (PAR) sensor as well as the + * Total Solar Radiation (TSR) sensor uses the 2.5V reference voltage + * to produce the raw ADC value. + + * The voltage across each sensor is: + * + * VsensorPAR = ADCValuePAR/4096 * Vref (1a) + * VsensorTSR = ADCValueTSR/4096 * Vref (1b) + * where Vref = 2.5V + * + * This voltage creates a current through a resistor R=100KOhm and this + * current has a linear relationship with the light intensity in Lux. + * IPAR = VsensorPAR / 100,000 (2a) + * ITSR = VsensorTSR / 100,000 (2b) + * + * S1087 (PAR) lx = 1e6 * IPAR * 1000 (3a) + * S1087-01 (TSR) lx = 1e5 * ITSR * 1000 (3b) + * + * lxPAR = 10e9 * ADCValuePAR *(1/4096)* Vref * 10e-5 or + * lxPAR = 3125* ADCvaluePAR / 512 + * and + * lxTSR = 10e8 * ADCValueTSR *(1/4096)* Vref * 10e-5 or + * lxTSR = 625* ADCvalueTSR / 1024 +*/ + +#if 0 +/* Photosynthetically Active Radiation in Lux units. */ +unsigned +sensors_light1_lux(void) +{ + unsigned temp; + temp = (uint32_t)ADC12MEM0; + + temp = (temp*3125)>> 9; + return (uint16_t)(temp & 0xFFFF); +} + +/* Total Solar Radiation in Lux units. */ +unsigned +sensors_light2_lux(void) +{ + unsigned temp; + temp = (uint32_t)ADC12MEM1; + + temp = (temp*625)>> 10; + return (uint16_t)(temp & 0xFFFF); +} +#endif diff --git a/platform/wismote/dev/light.h b/platform/wismote/dev/light.h new file mode 100644 index 000000000..09423c628 --- /dev/null +++ b/platform/wismote/dev/light.h @@ -0,0 +1,41 @@ +/* + * Copyright (c) 2005, 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: light.h,v 1.1 2006/08/02 14:44:46 bg- Exp $ + */ +#ifndef __LIGHT_H__ +#define __LIGHT_H__ + +void sensors_light_init(void); + +unsigned sensors_light1(void); +unsigned sensors_light2(void); + +#endif /* __LIGHT_H__ */ diff --git a/platform/wismote/dev/radio-sensor.c b/platform/wismote/dev/radio-sensor.c new file mode 100644 index 000000000..a12055730 --- /dev/null +++ b/platform/wismote/dev/radio-sensor.c @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2005, 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: radio-sensor.c,v 1.6 2010/01/14 20:01:19 nifi Exp $ + */ + +#include "lib/sensors.h" +#include "dev/cc2520.h" +#include "dev/radio-sensor.h" + +const struct sensors_sensor radio_sensor; + +/*---------------------------------------------------------------------------*/ +static int +value(int type) +{ + switch(type) { + case RADIO_SENSOR_LAST_PACKET: + return cc2520_last_correlation; + case RADIO_SENSOR_LAST_VALUE: + default: + return cc2520_last_rssi; + } +} +/*---------------------------------------------------------------------------*/ +static int +configure(int type, int c) +{ + return 0; +} +/*---------------------------------------------------------------------------*/ +static int +status(int type) +{ + return 0; +} +/*---------------------------------------------------------------------------*/ +SENSORS_SENSOR(radio_sensor, RADIO_SENSOR, + value, configure, status); diff --git a/platform/wismote/dev/sht11-arch.h b/platform/wismote/dev/sht11-arch.h new file mode 100644 index 000000000..8df629f65 --- /dev/null +++ b/platform/wismote/dev/sht11-arch.h @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2007, 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 + * Architecture-specific definitions for the SHT11 sensor on Tmote Sky. + * \author + * Niclas Finne + */ + +#ifndef SHT11_ARCH_H +#define SHT11_ARCH_H + +#define SHT11_ARCH_SDA 5 /* P1.5 */ +#define SHT11_ARCH_SCL 6 /* P1.6 */ +#define SHT11_ARCH_PWR 7 /* P1.7 */ + +#define SHT11_PxDIR P1DIR +#define SHT11_PxIN P1IN +#define SHT11_PxOUT P1OUT +#define SHT11_PxSEL P1SEL + +#endif diff --git a/platform/wismote/dev/sht15.c b/platform/wismote/dev/sht15.c new file mode 100644 index 000000000..6fa90a7e8 --- /dev/null +++ b/platform/wismote/dev/sht15.c @@ -0,0 +1,320 @@ +/* Copyright (c) 2009 ARAGO SYSTEMS + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * 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. + * Neither the name of the copyright holders nor the names of + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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. +*/ +/* + $Id: v 0.1 2011/02/15 tchapelle Exp $ +*/ +#include "dev/sht15.h" + +/*********************************************************************************** +* @fn halMcuWaitUs +* +* @brief Busy wait function. Waits the specified number of microseconds. Use +* assumptions about number of clock cycles needed for the various +* instructions. The duration of one cycle depends on MCLK. In this HAL +* , it is set to 8 MHz, thus 8 cycles per usec. +* +* NB! This function is highly dependent on architecture and compiler! +* +* @param uint16 usec - number of microseconds delay +* +* @return none +*/ + +#pragma optimize=none +void halMcuWaitUs(uint16_t usec) // 5 cycles for calling +{ + // The least we can wait is 3 usec: + // ~1 usec for call, 1 for first compare and 1 for return + while(usec > 3) // 2 cycles for compare + { // 2 cycles for jump + nop(); // 1 cycles for nop + nop(); // 1 cycles for nop + nop(); // 1 cycles for nop + nop(); // 1 cycles for nop + nop(); // 1 cycles for nop + nop(); // 1 cycles for nop + nop(); // 1 cycles for nop + nop(); // 1 cycles for nop + usec -= 2; // 1 cycles for optimized decrement + } +} // 4 cycles for returning + + +/** + SHT15/75 Driver + + !!! be advise that the SHT15 and SHT75 are not i2C compliant sensors + they are just designed to not disturb i2C devices on a 2 wire bus + this driver allow to drive the sensor with GPIO and delay +*/ + +/*********************************************************************************** +* @fn sht15_send_start +* +* @brief This function perform the start sequence asked by SHT15 and SHT75 +* +* +* +* @param none +* +* @return none +*/ +void sht15_send_start() +{ + // Sequence is to set data line to 1 then clock line to 1 + // then set data line to 0, clock line to 0 + // then set clock line to 1 and data line to 1 +// ___________ ________ +// data line : _____/ \___________/ +// ___________ ____________ +// clock line : _________/ \___/ + + DATA_OUT(); + DATA_SET(); + SCK_SET(); + DATA_CLR(); + SCK_CLR(); + SCK_SET(); + DATA_SET(); + SCK_CLR(); +} +/*********************************************************************************** +* @fn sht15_read16() +* +* @brief +* +* +* +* @param none +* +* @return uint16_t +*/ +uint16_t sht15_read16() +{ +uint16_t i; +DATA_IN(); + +SCK_CLR(); +uint16_t val = 0; + + for(i = 0; i < 18; i++) + { + if((i != 8) && (i != 17)) + { + SCK_SET(); + if(DATA_VAL()) + val |= 1; + + val <<= 1; + SCK_CLR(); + } + else if(i == 8) // Wait for first ACK from SHT15 + { + DATA_OUT(); + + DATA_CLR(); + + SCK_SET(); + SCK_CLR(); + + DATA_IN(); + } + else if(i == 17) // Wait for second ACK from SHT15 + { + DATA_OUT(); + + DATA_SET(); + + SCK_SET(); + SCK_CLR(); + } + } + return val; +} +/*********************************************************************************** +* @fn sht15_write8 +* +* @brief +* +* +* +* @param uint8 val +* +* @return none +*/ +void sht15_write8(uint8_t val) +{ + uint16_t i; + + DATA_OUT(); + + for(i = 0; i < 8; i++) + { + halMcuWaitUs(4); + SCK_CLR(); + + if(val & 0x80) + { + DATA_SET(); + } + else + { + DATA_CLR(); + } + val <<= 1; + + SCK_SET(); + } + + DATA_IN(); + + SCK_CLR(); + + while(DATA_VAL()); + + SCK_SET(); + SCK_CLR(); +} +/*********************************************************************************** +* @fn sht15_wait_measure +* +* @brief +* +* +* +* @param none +* +* @return none +*/ +void sht15_wait_measure() +{ + while(DATA_VAL()); +} +/*********************************************************************************** +* @fn sht15_init +* +* @brief +* +* +* +* @param none +* +* @return none +*/ +void sht15_init() +{ + // DATA and SCK lines are I/O + P3SEL &= ~BIT7; + P5SEL &= ~BIT4; + // Set SCK and DATA as output + DATA_OUT(); + SCK_OUT(); + DATA_SET(); + SCK_SET(); +} +/*********************************************************************************** +* @fn sht15_measure_temp +* +* @brief +* +* +* +* @param none +* +* @return none +*/ +void sht15_measure_temp() +{ + sht15_send_start(); + sht15_write8(3); +} +/*********************************************************************************** +* @fn sht15_measure_hum +* +* @brief +* +* +* +* @param none +* +* @return none +*/ +void sht15_measure_hum() +{ + sht15_send_start(); + sht15_write8(5); +} +/*********************************************************************************** +* @fn sht15_read_status +* +* @brief +* +* +* +* @param none +* +* @return none +*/ +void sht15_read_status() +{ + sht15_send_start(); + sht15_write8(7); +} +/*********************************************************************************** +* @fn sht15_write_status +* +* @brief +* +* +* +* @param none +* +* @return none +*/ +void sht15_write_status() +{ + sht15_send_start(); + sht15_write8(6); +} +/*********************************************************************************** +* @fn sht15_soft_reset +* +* @brief +* +* +* +* @param none +* +* @return none +*/ +void sht15_soft_reset() +{ + sht15_send_start(); + sht15_write8(30); +} diff --git a/platform/wismote/dev/sht15.h b/platform/wismote/dev/sht15.h new file mode 100644 index 000000000..dc438b27c --- /dev/null +++ b/platform/wismote/dev/sht15.h @@ -0,0 +1,65 @@ +/* Copyright (c) 2009 ARAGO SYSTEMS + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * 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. + * Neither the name of the copyright holders nor the names of + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT OWNER 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. +*/ +/* + $Id: v 0.1 2011/02/15 tchapelle Exp $ +*/ + + +/** + SHT15/75 Driver + +!!! be advise that the SHT15 and SHT75 are not i2C compliant sensors + they are just designed to not disturb i2C devices on a 2 wire bus + this driver allow to drive the sensor with GPIO and delay +*/ +#include "contiki.h" + +#define DATA_OUT() P3DIR |= BIT7 +#define DATA_IN() P3DIR &= ~BIT7 +#define DATA_SET() P3OUT |= BIT7; halMcuWaitUs(10) +#define DATA_CLR() P3OUT &= ~BIT7; halMcuWaitUs(10) +#define DATA_VAL() (P3IN & BIT7) + +#define SCK_OUT() P5DIR |= BIT4 +#define SCK_SET() P5OUT |= BIT4; halMcuWaitUs(10) +#define SCK_CLR() P5OUT &= ~BIT4; halMcuWaitUs(10) + + +/*********************************************************************************** +* SHT15 functions +*/ +void sht15_init(); +void sht15_measure_temp(); +void sht15_measure_hum(); +void sht15_wait_measure(); +void sht15_read_status(); +void sht15_write_status(); +void sht15_soft_reset(); +uint16_t sht15_read16(); +void sht15_write8(uint8_t val); diff --git a/platform/wismote/dev/sky-sensors.c b/platform/wismote/dev/sky-sensors.c new file mode 100644 index 000000000..6279a4afd --- /dev/null +++ b/platform/wismote/dev/sky-sensors.c @@ -0,0 +1,92 @@ +/* + * Copyright (c) 2010, 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: sky-sensors.c,v 1.2 2010/02/06 18:28:26 joxe Exp $ + * + * ----------------------------------------------------------------- + * + * Author : Joakim Eriksson + * Created : 2010-02-02 + * Updated : $Date: 2010/02/06 18:28:26 $ + * $Revision: 1.2 $ + */ + +#include "contiki.h" + +static uint8_t adc_on; +/*---------------------------------------------------------------------------*/ +void +sky_sensors_activate(uint8_t type) +{ + uint8_t pre = adc_on; + + adc_on |= type; + P6SEL |= type; + + if(pre == 0 && adc_on > 0) { + P6DIR = 0xff; + P6OUT = 0x00; + /* if nothing was started before, start up the ADC system */ + /* Set up the ADC. */ + /* ADC12CTL0 = REF2_5V + SHT0_6 + SHT1_6 + MSC; /\* Setup ADC12, ref., sampling time *\/ */ + /* ADC12CTL1 = SHP + CONSEQ_3 + CSTARTADD_0; /\* Use sampling timer, repeat-sequenc-of-channels */ + /* /\* convert up to MEM4 *\/ */ + /* ADC12MCTL9 |= EOS; */ + + /* ADC12CTL0 |= ADC12ON + REFON; */ + /* ADC12CTL0 |= ENC; /\* enable conversion *\/ */ + /* ADC12CTL0 |= ADC12SC; /\* sample & convert *\/ */ + } +} +/*---------------------------------------------------------------------------*/ +void +sky_sensors_deactivate(uint8_t type) +{ + adc_on &= ~type; + + if(adc_on == 0) { + /* stop converting immediately, turn off reference voltage, etc. */ + /* wait for conversion to stop */ + + /* ADC12CTL0 &= ~ENC; */ + /* /\* need to remove CONSEQ_3 if not EOS is configured *\/ */ + /* ADC12CTL1 &= ~CONSEQ_3; */ + + /* while(ADC12CTL1 & ADC12BUSY); */ + + /* ADC12CTL0 = 0; */ + /* ADC12CTL1 = 0; */ + + /* P6DIR = 0x00; */ + /* P6OUT = 0x00; */ + /* P6SEL = 0x00; */ + } +} +/*---------------------------------------------------------------------------*/ diff --git a/platform/wismote/dev/sky-sensors.h b/platform/wismote/dev/sky-sensors.h new file mode 100644 index 000000000..0ec18905d --- /dev/null +++ b/platform/wismote/dev/sky-sensors.h @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2010, 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: sky-sensors.h,v 1.1 2010/02/02 20:59:45 joxe Exp $ + * + * ----------------------------------------------------------------- + * + * Author : Joakim Eriksson + * Created : 2010-02-02 + * Updated : $Date: 2010/02/02 20:59:45 $ + * $Revision: 1.1 $ + */ + +#ifndef __SKY_SENSORS_H__ +#define __SKY_SENSORS_H__ + +void sky_sensors_activate(uint8_t); +void sky_sensors_deactivate(uint8_t); + +#endif /* __SKY_SENSORS_H__ */ diff --git a/platform/wismote/dev/spi.h b/platform/wismote/dev/spi.h new file mode 100644 index 000000000..e083a3bca --- /dev/null +++ b/platform/wismote/dev/spi.h @@ -0,0 +1,92 @@ +/* + * 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. + */ + +/** + * \file + * Basic SPI macros + * \author + * Niclas Finne + * Joakim Eriksson + */ + +#ifndef __SPI_H__ +#define __SPI_H__ + +/* Define macros to use for checking SPI transmission status depending + on if it is possible to wait for TX buffer ready. This is possible + on for example MSP430 but not on AVR. */ +#ifdef SPI_WAITFORTxREADY +#define SPI_WAITFORTx_BEFORE() SPI_WAITFORTxREADY() +#define SPI_WAITFORTx_AFTER() +#define SPI_WAITFORTx_ENDED() SPI_WAITFOREOTx() +#else /* SPI_WAITFORTxREADY */ +#define SPI_WAITFORTx_BEFORE() +#define SPI_WAITFORTx_AFTER() SPI_WAITFOREOTx() +#define SPI_WAITFORTx_ENDED() +#endif /* SPI_WAITFORTxREADY */ + +extern unsigned char spi_busy; + +void spi_init(void); + +/* Write one character to SPI */ +#define SPI_WRITE(data) \ + do { \ + UCB0IFG &= ~UCRXIFG; \ + SPI_TXBUF = data; \ + SPI_WAITFORTxREADY(); \ + } while(0) + +/* Write one character to SPI - will not wait for end + useful for multiple writes with wait after final */ +#define SPI_WRITE_FAST(data) \ + do { \ + UCB0IFG &= ~UCRXIFG; \ + SPI_TXBUF = data; \ + SPI_WAITFORTxREADY(); \ + } while(0) + +/* Read one character from SPI */ +#define SPI_READ(data) \ + do { \ + UCB0IFG &= ~UCRXIFG; \ + SPI_TXBUF = 0; \ + SPI_WAITFORTxREADY(); \ + SPI_BUSY_WAIT(); \ + data = SPI_RXBUF; \ + } while(0) + +/* Flush the SPI read register */ +#define SPI_FLUSH() \ + do { \ + SPI_RXBUF; \ + SPI_RXBUF; \ + } while(0); + +#endif /* __SPI_H__ */ diff --git a/platform/wismote/dev/xmem.c b/platform/wismote/dev/xmem.c new file mode 100644 index 000000000..dc3b5c25f --- /dev/null +++ b/platform/wismote/dev/xmem.c @@ -0,0 +1,268 @@ +/* + * Copyright (c) 2006, 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. + * + * @(#)$Id: xmem.c,v 1.10 2009/09/07 11:31:26 nifi Exp $ + */ + +/** + * \file + * Device driver for the ST M25P80 40MHz 1Mbyte external memory. + * \author + * Björn Grönvall + * + * Data is written bit inverted (~-operator) to flash so that + * unwritten data will read as zeros (UNIX style). + */ + +#include "contiki.h" +#include + +#include "dev/spi.h" +#include "dev/xmem.h" +#include "dev/watchdog.h" + +#if 0 +#include +#define PRINTF(...) printf(__VA_ARGS__) +#else +#define PRINTF(...) do {} while (0) +#endif + +#define SPI_FLASH_INS_WREN 0x06 +#define SPI_FLASH_INS_WRDI 0x04 +#define SPI_FLASH_INS_RDSR 0x05 +#define SPI_FLASH_INS_WRSR 0x01 +#define SPI_FLASH_INS_READ 0x03 +#define SPI_FLASH_INS_FAST_READ 0x0b +#define SPI_FLASH_INS_PP 0x02 +#define SPI_FLASH_INS_SE 0xd8 +#define SPI_FLASH_INS_BE 0xc7 +#define SPI_FLASH_INS_DP 0xb9 +#define SPI_FLASH_INS_RES 0xab +/*---------------------------------------------------------------------------*/ +static void +write_enable(void) +{ + int s; + + s = splhigh(); + SPI_FLASH_ENABLE(); + + //FASTSPI_TX(SPI_FLASH_INS_WREN); + //SPI_WAITFORTx_ENDED(); + + SPI_FLASH_DISABLE(); + splx(s); +} +/*---------------------------------------------------------------------------*/ +static unsigned +read_status_register(void) +{ + unsigned char u; + + int s; + + s = splhigh(); + SPI_FLASH_ENABLE(); + + //FASTSPI_TX(SPI_FLASH_INS_RDSR); + //SPI_WAITFORTx_ENDED(); + + //FASTSPI_CLEAR_RX(); + //FASTSPI_RX(u); + + SPI_FLASH_DISABLE(); + splx(s); + + return u; +} +/*---------------------------------------------------------------------------*/ +/* + * Wait for a write/erase operation to finish. + */ +static unsigned +wait_ready(void) +{ + unsigned u; + do { + u = read_status_register(); + } while(u & 0x01); /* WIP=1, write in progress */ + return u; +} +/*---------------------------------------------------------------------------*/ +/* + * Erase 64k bytes of data. It takes about 1s before WIP goes low! + */ +static void +erase_sector(unsigned long offset) +{ + int s; + wait_ready(); + + write_enable(); + + s = splhigh(); + SPI_FLASH_ENABLE(); + + //FASTSPI_TX(SPI_FLASH_INS_SE); + //FASTSPI_TX(offset >> 16); /* MSB */ + //FASTSPI_TX(offset >> 8); + //FASTSPI_TX(offset >> 0); /* LSB */ + //SPI_WAITFORTx_ENDED(); + + SPI_FLASH_DISABLE(); + splx(s); +} +/*---------------------------------------------------------------------------*/ +/* + * Initialize external flash *and* SPI bus! + */ +void +xmem_init(void) +{ + spi_init(); + + P4DIR |= BV(FLASH_CS) | BV(FLASH_HOLD) | BV(FLASH_PWR); + P4OUT |= BV(FLASH_PWR); /* P4.3 Output, turn on power! */ + + SPI_FLASH_DISABLE(); /* Unselect flash. */ + SPI_FLASH_UNHOLD(); +} +/*---------------------------------------------------------------------------*/ +int +xmem_pread(void *_p, int size, unsigned long offset) +{ + unsigned char *p = _p; + const unsigned char *end = p + size; + int s; + wait_ready(); + + ENERGEST_ON(ENERGEST_TYPE_FLASH_READ); + + s = splhigh(); + SPI_FLASH_ENABLE(); + + //FASTSPI_TX(SPI_FLASH_INS_READ); + //FASTSPI_TX(offset >> 16); /* MSB */ + //FASTSPI_TX(offset >> 8); + //FASTSPI_TX(offset >> 0); /* LSB */ + //SPI_WAITFORTx_ENDED(); + + //FASTSPI_CLEAR_RX(); + for(; p < end; p++) { + unsigned char u; + //FASTSPI_RX(u); + *p = ~u; + } + + SPI_FLASH_DISABLE(); + splx(s); + + ENERGEST_OFF(ENERGEST_TYPE_FLASH_READ); + + return size; +} +/*---------------------------------------------------------------------------*/ +static const char * +program_page(unsigned long offset, const unsigned char *p, int nbytes) +{ + const unsigned char *end = p + nbytes; + int s; + + wait_ready(); + + write_enable(); + + s = splhigh(); + SPI_FLASH_ENABLE(); + + // FASTSPI_TX(SPI_FLASH_INS_PP); + //FASTSPI_TX(offset >> 16); /* MSB */ + //FASTSPI_TX(offset >> 8); + //FASTSPI_TX(offset >> 0); /* LSB */ + + for(; p < end; p++) { + //FASTSPI_TX(~*p); + } + //SPI_WAITFORTx_ENDED(); + + SPI_FLASH_DISABLE(); + splx(s); + + return p; +} +/*---------------------------------------------------------------------------*/ +int +xmem_pwrite(const void *_buf, int size, unsigned long addr) +{ + const unsigned char *p = _buf; + const unsigned long end = addr + size; + unsigned long i, next_page; + + ENERGEST_ON(ENERGEST_TYPE_FLASH_WRITE); + + for(i = addr; i < end;) { + next_page = (i | 0xff) + 1; + if(next_page > end) { + next_page = end; + } + p = program_page(i, p, next_page - i); + i = next_page; + } + + ENERGEST_OFF(ENERGEST_TYPE_FLASH_WRITE); + + return size; +} +/*---------------------------------------------------------------------------*/ +int +xmem_erase(long size, unsigned long addr) +{ + unsigned long end = addr + size; + + if(size % XMEM_ERASE_UNIT_SIZE != 0) { + PRINTF("xmem_erase: bad size\n"); + return -1; + } + + if(addr % XMEM_ERASE_UNIT_SIZE != 0) { + PRINTF("xmem_erase: bad offset\n"); + return -1; + } + + watchdog_stop(); + + for (; addr < end; addr += XMEM_ERASE_UNIT_SIZE) { + erase_sector(addr); + } + + watchdog_start(); + + return size; +} +/*---------------------------------------------------------------------------*/ diff --git a/platform/wismote/flash.c b/platform/wismote/flash.c new file mode 100644 index 000000000..774c33cf7 --- /dev/null +++ b/platform/wismote/flash.c @@ -0,0 +1,102 @@ +/** + * \file + * Functions for reading and writing flash ROM. + * \author Adam Dunkels + */ + +/* Copyright (c) 2004 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. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. + * + * Author: Adam Dunkels + * + */ + +#include "contiki.h" +#include "dev/flash.h" +#include "dev/watchdog.h" + +#define FLASH_TIMEOUT 30 +#define FLASH_REQ_TIMEOUT 150 + +static uint16_t sfrie; + +/*---------------------------------------------------------------------------*/ +void +flash_setup(void) +{ + /* disable all interrupts to protect CPU + during programming from system crash */ + dint(); + + /* Clear interrupt flag1. */ + SFRIFG1 = 0; + /* The IFG1 = 0; statement locks up contikimac - not sure if this + statement needs to be here at all. I've removed it for now, since + it seems to work, but leave this little note here in case someone + stumbles over this code at some point. */ + + /* Stop watchdog. */ + watchdog_stop(); + + /* disable all NMI-Interrupt sources */ + sfrie = SFRIE1; + SFRIE1 = 0x00; +} +/*---------------------------------------------------------------------------*/ +void +flash_done(void) +{ + /* Enable interrupts. */ + SFRIE1 = sfrie; + eint(); + watchdog_start(); +} +/*---------------------------------------------------------------------------*/ +void +flash_clear(unsigned short *ptr) +{ + uint8_t r; + FCTL3 = 0xA500; /* Lock = 0 */ + while(FCTL3 & 0x0001) r++; /* Wait for BUSY = 0, not needed + unless run from RAM */ + FCTL1 = 0xA502; /* ERASE = 1 */ + *ptr = 0; /* erase Flash segment */ + FCTL1 = 0xA500; /* ERASE = 0 automatically done?! */ + FCTL3 = 0xA510; /* Lock = 1 */ +} +/*---------------------------------------------------------------------------*/ +void +flash_write(unsigned short *ptr, unsigned short word) +{ + uint8_t r; + FCTL3 = 0xA500; /* Lock = 0 */ + while(FCTL3 & 0x0001) r++; /* Wait for BUSY = 0, not needed unless + run from RAM */ + FCTL1 = 0xA540; /* WRT = 1 */ + *ptr = word; /* program Flash word */ + FCTL1 = 0xA500; /* WRT = 0 */ + FCTL3 = 0xA510; /* Lock = 1 */ +} +/*---------------------------------------------------------------------------*/ diff --git a/platform/wismote/node-id.c b/platform/wismote/node-id.c new file mode 100644 index 000000000..8cbecb1ae --- /dev/null +++ b/platform/wismote/node-id.c @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2006, 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: node-id.c,v 1.1 2007/03/23 09:59:08 nifi Exp $ + */ + +/** + * \file + * Utility to store a node id in the external flash + * \author + * Adam Dunkels + */ + +#include "node-id.h" +#include "contiki-conf.h" +#include "dev/xmem.h" + +unsigned short node_id = 0; + +/*---------------------------------------------------------------------------*/ +void +node_id_restore(void) +{ + /* unsigned char buf[4]; */ + /* xmem_pread(buf, 4, NODE_ID_XMEM_OFFSET); */ + /* if(buf[0] == 0xad && */ + /* buf[1] == 0xde) { */ + /* node_id = (buf[2] << 8) | buf[3]; */ + /* } else { */ + node_id = 0; + /* } */ +} +/*---------------------------------------------------------------------------*/ +void +node_id_burn(unsigned short id) +{ + /* unsigned char buf[4]; */ + /* buf[0] = 0xad; */ + /* buf[1] = 0xde; */ + /* buf[2] = id >> 8; */ + /* buf[3] = id & 0xff; */ + //xmem_erase(XMEM_ERASE_UNIT_SIZE, NODE_ID_XMEM_OFFSET); + //xmem_pwrite(buf, 4, NODE_ID_XMEM_OFFSET); +} +/*---------------------------------------------------------------------------*/ diff --git a/platform/wismote/node-id.h b/platform/wismote/node-id.h new file mode 100644 index 000000000..592379fc9 --- /dev/null +++ b/platform/wismote/node-id.h @@ -0,0 +1,44 @@ +/* + * Copyright (c) 2006, 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. + * + * Author: Adam Dunkels + * + * $Id: node-id.h,v 1.1 2007/03/23 09:59:08 nifi Exp $ + */ + +#ifndef __NODE_ID_H__ +#define __NODE_ID_H__ + +void node_id_restore(void); +void node_id_burn(unsigned short node_id); + +extern unsigned short node_id; + +#endif /* __NODE_ID_H__ */ diff --git a/platform/wismote/platform-conf.h b/platform/wismote/platform-conf.h new file mode 100644 index 000000000..98174bf00 --- /dev/null +++ b/platform/wismote/platform-conf.h @@ -0,0 +1,207 @@ +/* + * Copyright (c) 2010, 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. + */ + +/** + * \file + * Platform configuration for the wismote platform. + */ + +#ifndef __PLATFORM_CONF_H__ +#define __PLATFORM_CONF_H__ + +/* + * Definitions below are dictated by the hardware and not really + * changeable! + */ +/* Platform WISMOTE */ +#define WISMOTE 1 + +#define PLATFORM_HAS_LEDS 1 +#define PLATFORM_HAS_BUTTON 1 + +/* CPU target speed in Hz */ +#define F_CPU 16000000uL /*2457600uL*/ + +/* Our clock resolution, this is the same as Unix HZ. */ +#define CLOCK_CONF_SECOND 128UL + +#define BAUD2UBR(baud) ((F_CPU/baud)) + +#define CCIF +#define CLIF + +#define HAVE_STDINT_H +#include "msp430def.h" + + +/* Types for clocks and uip_stats */ +typedef unsigned short uip_stats_t; +typedef unsigned long clock_time_t; +typedef unsigned long off_t; + +/* the low-level radio driver */ +#define NETSTACK_CONF_RADIO cc2520_driver + +/* LED ports */ +#define LEDS_PxDIR P2DIR +#define LEDS_PxOUT P2OUT +#define LEDS_CONF_RED 0x10 +#define LEDS_CONF_GREEN 0 //0x20 +#define LEDS_CONF_YELLOW 0 //0x40 + +/* DCO speed resynchronization for more robust UART, etc. */ +#ifndef DCOSYNCH_CONF_ENABLED +#define DCOSYNCH_CONF_ENABLED 0 +#endif /* DCOSYNCH_CONF_ENABLED */ +#ifndef DCOSYNCH_CONF_PERIOD +#define DCOSYNCH_CONF_PERIOD 30 +#endif /* DCOSYNCH_CONF_PERIOD */ + +#define ROM_ERASE_UNIT_SIZE 512 +#define XMEM_ERASE_UNIT_SIZE (64*1024L) + + +#define CFS_CONF_OFFSET_TYPE long + + +/* Use the first 64k of external flash for node configuration */ +#define NODE_ID_XMEM_OFFSET (0 * XMEM_ERASE_UNIT_SIZE) + +/* Use the second 64k of external flash for codeprop. */ +#define EEPROMFS_ADDR_CODEPROP (1 * XMEM_ERASE_UNIT_SIZE) + +#define CFS_XMEM_CONF_OFFSET (2 * XMEM_ERASE_UNIT_SIZE) +#define CFS_XMEM_CONF_SIZE (1 * XMEM_ERASE_UNIT_SIZE) + +#define CFS_RAM_CONF_SIZE 4096 + +/* + * SPI bus configuration for the wismote + */ + +/* SPI input/output registers. */ +#define SPI_TXBUF UCB0TXBUF +#define SPI_RXBUF UCB0RXBUF + + /* USART0 Tx ready? */ +#define SPI_WAITFOREOTx() while (!(UCB0IFG & UCRXIFG)) + /* USART0 Rx ready? */ +#define SPI_WAITFOREORx() while (!(UCB0IFG & UCRXIFG)) + /* USART0 Tx buffer ready? */ +#define SPI_WAITFORTxREADY() while (!(UCB0IFG & UCRXIFG)) +#define SPI_BUSY_WAIT() while ((UCB0STAT & UCBUSY) == 1) + +#define SCK 1 /* P3.1 - Output: SPI Serial Clock (SCLK) */ +#define MOSI 2 /* P3.2 - Output: SPI Master out - slave in (MOSI) */ +#define MISO 3 /* P3.3 - Input: SPI Master in - slave out (MISO) */ + +/* + * SPI bus - M25P80 external flash configuration. + */ + +#define FLASH_PWR //3 /* P4.3 Output */ +#define FLASH_CS //4 /* P4.4 Output */ +#define FLASH_HOLD //7 /* P4.7 Output */ + +/* Enable/disable flash access to the SPI bus (active low). */ + +#define SPI_FLASH_ENABLE() //( P4OUT &= ~BV(FLASH_CS) ) +#define SPI_FLASH_DISABLE() //( P4OUT |= BV(FLASH_CS) ) + +#define SPI_FLASH_HOLD() // ( P4OUT &= ~BV(FLASH_HOLD) ) +#define SPI_FLASH_UNHOLD() //( P4OUT |= BV(FLASH_HOLD) ) + +/* + * SPI bus - CC2520 pin configuration. + */ + +#define CC2520_CONF_SYMBOL_LOOP_COUNT 800 + +/* P1.0 - Input: FIFOP from CC2520 */ +#define CC2520_FIFOP_PORT(type) P1##type +#define CC2520_FIFOP_PIN 6 +/* P1.3 - Input: FIFO from CC2520 */ +#define CC2520_FIFO_PORT(type) P1##type +#define CC2520_FIFO_PIN 5 +/* P1.4 - Input: CCA from CC2520 */ +#define CC2520_CCA_PORT(type) P1##type +#define CC2520_CCA_PIN 7 +/* P4.1 - Input: SFD from CC2520 */ +#define CC2520_SFD_PORT(type) P2##type +#define CC2520_SFD_PIN 0 +/* P4.2 - Output: SPI Chip Select (CS_N) */ +#define CC2520_CSN_PORT(type) P3##type +#define CC2520_CSN_PIN 0 +/* P4.5 - Output: VREG_EN to CC2520 */ +#define CC2520_VREG_PORT(type) P4##type +#define CC2520_VREG_PIN 3 +/* P4.6 - Output: RESET_N to CC2520 */ +#define CC2520_RESET_PORT(type) P4##type +#define CC2520_RESET_PIN 4 + +#define CC2520_IRQ_VECTOR PORT1_VECTOR + +/* Pin status.CC2520 */ +#define CC2520_FIFOP_IS_1 (!!(CC2520_FIFOP_PORT(IN) & BV(CC2520_FIFOP_PIN))) +#define CC2520_FIFO_IS_1 (!!(CC2520_FIFO_PORT(IN) & BV(CC2520_FIFO_PIN))) +#define CC2520_CCA_IS_1 (!!(CC2520_CCA_PORT(IN) & BV(CC2520_CCA_PIN))) +#define CC2520_SFD_IS_1 (!!(CC2520_SFD_PORT(IN) & BV(CC2520_SFD_PIN))) + +/* The CC2520 reset pin. */ +#define SET_RESET_INACTIVE() (CC2520_RESET_PORT(OUT) |= BV(CC2520_RESET_PIN)) +#define SET_RESET_ACTIVE() (CC2520_RESET_PORT(OUT) &= ~BV(CC2520_RESET_PIN)) + +/* CC2520 voltage regulator enable pin. */ +#define SET_VREG_ACTIVE() (CC2520_VREG_PORT(OUT) |= BV(CC2520_VREG_PIN)) +#define SET_VREG_INACTIVE() (CC2520_VREG_PORT(OUT) &= ~BV(CC2520_VREG_PIN)) + +/* CC2520 rising edge trigger for external interrupt 0 (FIFOP). */ +#define CC2520_FIFOP_INT_INIT() do { \ + CC2520_FIFOP_PORT(IES) &= ~BV(CC2520_FIFOP_PIN); \ + CC2520_CLEAR_FIFOP_INT(); \ + } while(0) + +/* FIFOP on external interrupt 0. */ +/* FIFOP on external interrupt 0. */ +#define CC2520_ENABLE_FIFOP_INT() do { P1IE |= BV(CC2520_FIFOP_PIN); } while (0) +#define CC2520_DISABLE_FIFOP_INT() do { P1IE &= ~BV(CC2520_FIFOP_PIN); } while (0) +#define CC2520_CLEAR_FIFOP_INT() do { P1IFG &= ~BV(CC2520_FIFOP_PIN); } while (0) + +/* + * Enables/disables CC2520 access to the SPI bus (not the bus). + * (Chip Select) + */ + + /* ENABLE CSn (active low) */ +#define CC2520_SPI_ENABLE() do{ UCB0CTL1 &= ~UCSWRST; clock_delay(5); P3OUT &= ~BIT0;clock_delay(5);}while(0) + /* DISABLE CSn (active low) */ +#define CC2520_SPI_DISABLE() do{clock_delay(5);UCB0CTL1 |= UCSWRST;clock_delay(1); P3OUT |= BIT0;clock_delay(5);}while(0) +#define CC2520_SPI_IS_ENABLED() ((CC2520_CSN_PORT(OUT) & BV(CC2520_CSN_PIN)) != BV(CC2520_CSN_PIN)) + +#endif /* __PLATFORM_CONF_H__ */ diff --git a/platform/wismote/spix.c b/platform/wismote/spix.c new file mode 100644 index 000000000..df0670b2b --- /dev/null +++ b/platform/wismote/spix.c @@ -0,0 +1,60 @@ +/* + * 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. + */ + +#include "contiki.h" + +/* + * This is SPI initialization code for the MSP430X architecture. + * + */ + +unsigned char spi_busy = 0; + +/* + * Initialize SPI bus. + */ +void +spi_init(void) +{ + UCB0CTL1 |= UCSWRST; // Put state machine in reset + UCB0CTL1 = UCSSEL0 | UCSSEL1; // Select ACLK + UCB0CTL0 |= UCCKPH | UCSYNC | UCMSB | UCMST; // 3-pin, 8-bit SPI master, rising edge capture + + // 16 bit baud rate register + UCB0BR0 = 0x00; // MSB => 0 + UCB0BR1 = 0x08; // LSB => SMCLK / (UCxxBR0 + UCxxBR1 × 256) + + // Set MOSI and SCLK as OUT and MISO as IN ports + P3SEL |= ( BIT1 + BIT2 + BIT3 ); // Port3 = SPI peripheral + 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 +}