diff --git a/platform/msb430/dev/adc.c b/platform/msb430/dev/adc.c new file mode 100644 index 000000000..6e87d09eb --- /dev/null +++ b/platform/msb430/dev/adc.c @@ -0,0 +1,83 @@ +/* + * 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 + * ADC functions. + * \author + * Nicolas Tsiftes + */ + +#include +#include + +#include "contiki-msb430.h" + +void +adc_init(void) { + //Setup ADC12, ref., sampling time, REFON for DAC!! + ADC12CTL0 = SHT0_15 + SHT1_15 + MSC; + + // Use sampling timer, repeat-sequence-of-channels + ADC12CTL1 = SHP + CONSEQ_3 + CSTARTADD_0; + ADC12MCTL0 = INCH_0 + SREF_0; // P60: AIN0 + ADC12MCTL1 = INCH_0 + SREF_0; // P60: AIN0 + ADC12MCTL2 = INCH_0 + SREF_0; // P60: AIN0 + ADC12MCTL3 = INCH_1 + SREF_0; // P61: AIN1 + ADC12MCTL4 = INCH_1 + SREF_0; // P61: AIN1 + ADC12MCTL5 = INCH_1 + SREF_0; // P61: AIN1 + ADC12MCTL6 = INCH_2 + SREF_0; // P62: AIN2 + ADC12MCTL7 = INCH_2 + SREF_0; // P62: AIN2 + ADC12MCTL8 = INCH_2 + SREF_0; // P62: AIN2 + ADC12MCTL9 = INCH_2 + SREF_0; // P62: AIN2 + ADC12MCTL10 = INCH_3 + SREF_0; // P63: AIN2 + ADC12MCTL11 = INCH_4 + SREF_0; // P64: AIN3 + ADC12MCTL12 = INCH_5 + SREF_0; // P65: AIN4 + ADC12MCTL13 = INCH_10 + SREF_0 + EOS; // Temp diode +} + +void +adc_on(void) +{ + ADC12CTL0 |= ADC12ON; + clock_delay(600); + ADC12CTL0 |= ENC; + ADC12CTL0 |= ADC12SC; +} + +void +adc_off(void) +{ + ADC12CTL0 &= ~ENC; + clock_delay(600); + ADC12CTL0 &= ~ADC12ON; +} diff --git a/platform/msb430/dev/adc.h b/platform/msb430/dev/adc.h new file mode 100644 index 000000000..e8d5a2dd9 --- /dev/null +++ b/platform/msb430/dev/adc.h @@ -0,0 +1,40 @@ +/* + * 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. + * + */ + +#ifndef ADC_H +#define ADC_H + +void adc_init(void); +void adc_on(void); +void adc_off(void); + +#endif /* !ADC_H */ diff --git a/platform/msb430/dev/cc1020-internal.h b/platform/msb430/dev/cc1020-internal.h new file mode 100644 index 000000000..06a8f5bec --- /dev/null +++ b/platform/msb430/dev/cc1020-internal.h @@ -0,0 +1,225 @@ +#include + +#define CC1020_MAIN 0x00 +#define CC1020_INTERFACE 0x01 +#define CC1020_RESET 0x02 +#define CC1020_SEQUENCING 0x03 +#define CC1020_FREQ_2A 0x04 +#define CC1020_FREQ_1A 0x05 +#define CC1020_FREQ_0A 0x06 +#define CC1020_CLOCK_A 0x07 +#define CC1020_FREQ_2B 0x08 +#define CC1020_FREQ_1B 0x09 +#define CC1020_FREQ_0B 0x0A +#define CC1020_CLOCK_B 0x0B +#define CC1020_VCO 0x0C +#define CC1020_MODEM 0x0D +#define CC1020_DEVIATION 0x0E +#define CC1020_AFC_CONTROL 0x0F +#define CC1020_FILTER 0x10 +#define CC1020_VGA1 0x11 +#define CC1020_VGA2 0x12 +#define CC1020_VGA3 0x13 +#define CC1020_VGA4 0x14 +#define CC1020_LOCK 0x15 +#define CC1020_FRONTEND 0x16 +#define CC1020_ANALOG 0x17 +#define CC1020_BUFF_SWING 0x18 +#define CC1020_BUFF_CURRENT 0x19 +#define CC1020_PLL_BW 0x1A +#define CC1020_CALIBRATE 0x1B +#define CC1020_PA_POWER 0x1C +#define CC1020_MATCH 0x1D +#define CC1020_PHASE_COMP 0x1E +#define CC1020_GAIN_COMP 0x1F +#define CC1020_POWERDOWN 0x20 +#define CC1020_TEST1 0x21 +#define CC1020_TEST2 0x22 +#define CC1020_TEST3 0x23 +#define CC1020_TEST4 0x24 +#define CC1020_TEST5 0x25 +#define CC1020_TEST6 0x26 +#define CC1020_TEST7 0x27 +#define CC1020_STATUS 0x40 +#define CC1020_RESET_DONE 0x41 +#define CC1020_RSS 0x42 +#define CC1020_AFC 0x43 +#define CC1020_GAUSS_FILTER 0x44 +#define CC1020_STATUS1 0x45 +#define CC1020_STATUS2 0x46 +#define CC1020_STATUS3 0x47 +#define CC1020_STATUS4 0x48 +#define CC1020_STATUS5 0x49 +#define CC1020_STATUS6 0x4A +#define CC1020_STATUS7 0x4B + +// For CC1020_STATUS +#define LOCK_CONTINUOUS 0x10 +#define CAL_COMPLETE 0x80 +#define PA_POWER 0x0F // initial default for output power +#define LOCK_NOK 0x00 +#define LOCK_OK 0x01 +#define LOCK_RECAL_OK 0x02 +#define CAL_TIMEOUT 0x7FFE +#define LOCK_TIMEOUT 0x7FFE +#define RESET_TIMEOUT 0x7FFE +#define TX_CURRENT 0x87 +#define RX_CURRENT 0x86 + +// CC1020 driver configuration +#define CC1020_BUFFERSIZE 250 + +// PDI (Data in) is on P21 +#define PDO (P2IN & 0x01) + +// PSEL is on P30 and low active +#define PSEL_ON do { P3OUT &= ~0x01; } while(0) +#define PSEL_OFF do { P3OUT |= 0x01; } while(0) +#define PCLK_HIGH do { P2OUT |= 0x08; } while(0) +#define PCLK_LOW do { P2OUT &= ~0x08; } while(0) + +// PDO (Data out) is on P22 +#define PDI_HIGH do { P2OUT |= 0x02; } while(0) + +#define PDI_LOW do { P2OUT &= ~0x02; } while(0) + +// Enable power for LNA (P24, low-active) +#define LNA_POWER_ON() do { P2OUT &= ~0x10; } while(0) + +#define LNA_POWER_OFF() do { P2OUT |= 0x10; } while(0) + +#define CC_LOCK (P2IN & 0x04) + +#define DISABLE_RX_IRQ() \ + do { IE1 &= ~(URXIE0); } while(0) + +#define ENABLE_RX_IRQ() \ + do { IFG1 &= ~URXIFG0; IE1 |= URXIE0; } while(0) + +#define ACK_TIMEOUT_115 4 // In RADIO_STROKE ticks +#define ACK_TIMEOUT_19 16 + +#define MHZ_869525 1 + +const u8_t cc1020_config_19200[41] = { + 0x01, // 0x00, MAIN + 0x0F, // 0x01, INTERFACE + 0xFF, // 0x02, RESET + 0x8F, // 0x03, SEQUENCING + //869.525 bei 50kHz + 0x3A, // 0x04, FREQ_2A + 0x32, // 0x05, FREQ_1A + 0x97, // 0x06, FREQ_0A // 19200 + 0x38, // 0x07, CLOCK_A // 19200 + 0x3A, // 0x08, FREQ_2B + 0x37, // 0x09, FREQ_1B + 0xEB, // 0x0A, FREQ_0B // 19200 + 0x38, // 0x0B, CLOCK_B // 19200 + 0x44, // 0x0C, VCO 44 + 0x51, // 0x0D, MODEM Manchester + 0x2B, // 0x0E, DEVIATION // FSK + 0x4C, // 0x0F, AFC_CONTROL Ruetten 0xCC + 0x25, // 0x10, FILTER Bandwith 100 kHz + 0x61, // 0x11, VGA1 + 0x55, // 0x12, VGA2 + 0x2D, // 0x13, VGA3 + 0x37, // 0x14, VGA4 // 0x29, VGA4 ADJUSTED CS to 23! + 0x40, // 0x15, LOCK is Carrier SENSE + 0x76, // 0x16, FRONTEND + 0x87, // 0x17, ANALOG, RX=86/TX=87 + 0x10, // 0x18, BUFF_SWING + 0x25, // 0x19, BUFF_CURRENT + 0xAE, // 0x1A, PLL_BW + 0x34, // 0x1B, CALIBRATE + PA_POWER, // 0x1C, PA_POWER AN025 = 0xA0 + 0xF0, // 0x1D, MATCH + 0x00, // 0x1E, PHASE_COMP + 0x00, // 0x1F, GAIN_COMP + 0x00, // 0x20, POWERDOWN + 0x4d, // 0x4d, // 0x21, + 0x10, // 0x10, // 0x22, + 0x06, // 0x06, // 0x23, + 0x00, // 0x00, // 0x24, + 0x40, // 0x40, // 0x25, + 0x00, // 0x00, // 0x26, + 0x00, // 0x00, // 0x27, + // Not in real config of chipCon from here!!! + ACK_TIMEOUT_19 +}; + +const u8_t cc1020_config_115200[41] = { + 0x01, // 0x00, MAIN + 0x0F, // 0x01, INTERFACE + 0xFF, // 0x02, RESET + 0x8F, // 0x03, SEQUENCING + // 869.525 bei 200kHz + 0x3A, // 0x04, FREQ_2A + 0x32, // 0x05, FREQ_1A + 0x97, // 0x06, FREQ_0A // 19200 + 0x29, // 0x07, CLOCK_A // 19200 + 0x3A, // 0x08, FREQ_2B + 0x37, // 0x09, FREQ_1B + 0xEB, // 0x0A, FREQ_0B // 19200 + 0x29, // 0x0B, CLOCK_B // 19200 + 0x44, // 0x0C, VCO 44 + 0x51, // 0x0D, MODEM Manchester + 0x58, // 0x0E, DEVIATION // FSK + 0x4C, // 0x0F, AFC_CONTROL Ruetten 0xCC + 0x80, // 0x10, FILTER Bandwith 500 kHz + 0x61, // 0x11, VGA1 + 0x55, // 0x12, VGA2 + 0x30, // 0x13, VGA3 + 0x35, // 0x14, VGA4 + 0x20, // 0x15, LOCK is Carrier SENSE + 0x76, // 0x16, FRONTEND + 0x87, // 0x17, ANALOG, RX=86/TX=87 + 0x10, // 0x18, BUFF_SWING + 0x25, // 0x19, BUFF_CURRENT + 0xAE, // 0x1A, PLL_BW + 0x34, // 0x1B, CALIBRATE + PA_POWER, // 0x1C, PA_POWER AN025 = 0xA0 + 0xF0, // 0x1D, MATCH + 0x00, // 0x1E, PHASE_COMP + 0x00, // 0x1F, GAIN_COMP + 0x00, // 0x20, POWERDOWN + 0x4d, // 0x21, + 0x10, // 0x22, + 0x06, // 0x23, + 0x00, // 0x24, + 0x40, // 0x25, + 0x00, // 0x26, + 0x00, // 0x27, + // Not in real config of chipCon from here!!! + ACK_TIMEOUT_115 +}; + +/// cc1020 state +enum cc1020_state { + CC1020_OFF, + CC1020_RX, + CC1020_TX +}; + +/****************************************************************************** + * @name Packet specification + * @{ + */ +#define PREAMBLESIZE 6 // number of bytes in preamble +#define PREAMBLE 0xAA +#define SYNCWDSIZE 2 // number of bytes in syncword +const u8_t syncword[2] = {0xD3,0x91}; +#define HDRSIZE 1 // number of bytes in header +#define TAILSIZE 2 // number of bytes in tail +#define TAIL 0xFA +__attribute__((packed)) +struct cc1020_header { + u8_t length; // header: number of bytes in packet (incl. header) +}; +///@} + +/// cc1020 receiver state +enum cc1020_rxstate { + CC1020_RX_SEARCHING, // searching for preamble + sync word + CC1020_RX_RECEIVE, // receiving bytes + CC1020_RX_PROCESSING // processing data in buffer +}; diff --git a/platform/msb430/dev/cc1020.c b/platform/msb430/dev/cc1020.c new file mode 100644 index 000000000..4953dc7ab --- /dev/null +++ b/platform/msb430/dev/cc1020.c @@ -0,0 +1,722 @@ +/* +Copyright 2006, Freie Universitaet Berlin. All rights reserved. + +These sources were developed at the Freie Universität Berlin, Computer +Systems and Telematics group. + +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 Freie Universitaet Berlin (FUB) 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 FUB and the contributors on an "as is" +basis, without any representations or warranties of any kind, express +or implied including, but not limited to, representations or +warranties of non-infringement, merchantability or fitness for a +particular purpose. In no event shall FUB 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 implementation was developed by the CST group at the FUB. + +For documentation and questions please use the web site +http://scatterweb.mi.fu-berlin.de and the mailinglist +scatterweb@lists.spline.inf.fu-berlin.de (subscription via the Website). +Berlin, 2006 +*/ + + +/** + * @file cc1020.c + * @author FUB ScatterWeb Developers, Michael Baar, Nicolas Tsiftes + * + * Taken from ScatterWeb² 1.1 and modified/reformatted for Contiki 2.0 + **/ + +#include +#include +#include + +#include "contiki-msb430.h" +#include "cc1020-internal.h" +#include "cc1020.h" +#include "lib/random.h" +#include "dev/irq.h" + +static int cc1020_calibrate(void); +static int cc1020_setupTX(int); +static int cc1020_setupRX(int); +static void cc1020_setupPD(void); +static void cc1020_wakeupTX(int); +static void cc1020_wakeupRX(int); +static u8_t cc1020_read_reg(u8_t addr); +static void cc1020_write_reg(u8_t addr, u8_t adata); +static void cc1020_load_config(const u8_t *); +static void cc1020_reset(void); + +/// selected rx/tx/pd switching algorithm +static enum cc1020_power_mode cc1020_power_mode = CC1020_ALWAYS_ON; + +// current mode of cc1020 chip +static enum cc1020_state cc1020_state = CC1020_OFF; +volatile u8_t cc1020_rxbuf[HDRSIZE + CC1020_BUFFERSIZE]; +volatile u8_t cc1020_txbuf[PREAMBLESIZE + HDRSIZE + CC1020_BUFFERSIZE + + TAILSIZE]; +static enum cc1020_rxstate cc1020_rxstate = CC1020_RX_SEARCHING; + +/// number of bytes in receive buffer +static unsigned short cc1020_rxlen = 0; + +/// received signal strength indicator reading for last received packet +static unsigned char rssi; + +/// callback when a packet has been received +static void (*receiver_callback) (void); +static unsigned char cc1020_pa_power = PA_POWER; +static unsigned short cc1020_txlen = 0; + +const struct radio_driver cc1020_driver = + { + cc1020_send, + cc1020_read, + cc1020_set_receiver, + cc1020_on, + cc1020_off + }; + +process_event_t cc1020_event; + +PROCESS(cc1020_sender_process, "CC1020 sender"); + +void +cc1020_init(const u8_t * config) +{ + cc1020_event = process_alloc_event(); + + cc1020_setupPD(); + cc1020_reset(); + cc1020_load_config(config); + + // init tx buffer with preamble + syncword + memset(cc1020_txbuf, PREAMBLE, PREAMBLESIZE); + memcpy((char *) cc1020_txbuf + PREAMBLESIZE, &syncword, SYNCWDSIZE); + + // calibrate receiver + cc1020_wakeupRX(RX_CURRENT); + if (!cc1020_calibrate()) + printf("rx calibration failed\n"); + + // calibrate transmitter + cc1020_wakeupTX(TX_CURRENT); + if (!cc1020_calibrate()) + printf("tx calibration failed\n"); + + // power down + cc1020_setupPD(); + process_start(&cc1020_sender_process, NULL); +} + +int +cc1020_on(void) +{ + if (cc1020_power_mode == CC1020_ALWAYS_ON) { + + // Switch to receive mode + cc1020_set_rx(); + } else { + cc1020_off(); + } + return true; +} + +void +cc1020_off(void) +{ + if (cc1020_rxstate == CC1020_OFF) + return; + LNA_POWER_OFF(); // power down lna + _DINT(); + cc1020_rxstate = CC1020_OFF; + DISABLE_RX_IRQ(); + cc1020_state = CC1020_OFF; + _EINT(); + cc1020_setupPD(); // power down radio +} + +void +cc1020_set_rx(void) +{ + // configure controller + _DINT(); + + // Reset SEL for P3[1-3] (CC DIO, DIO, DCLK) and P3[4-5] (Camera Rx+Tx) + P3SEL &= ~0x3E; + IFG1 &= ~(UTXIE0 | URXIE0); // Clear interrupt flags + ME1 &= ~(UTXE0 | URXE0); // Disable Uart0 Tx + Rx + UCTL0 = SWRST; // U0 into reset state. + UCTL0 |= CHAR | SYNC; // 8-bit character, SPI, Slave mode + + // CKPH works also, but not CKPH+CKPL or none of them!! + UTCTL0 = CKPL + STC; + URCTL0 = 0x00; + UBR00 = 0x00; // No baudrate divider + UBR10 = 0x00; // settings for a spi + UMCTL0 = 0x00; // slave. + ME1 |= USPIE0; // Enable USART0 TXD/RXD, disabling does not yield any powersavings + P3SEL |= 0x0A; // Select rx line and clk + UCTL0 &= ~SWRST; // Clear reset bit + _EINT(); + + // configure driver + cc1020_rxlen = 0; // receive buffer position to start + cc1020_rxstate = CC1020_RX_SEARCHING; // rx state machine to searching mode + cc1020_state = CC1020_RX; // driver state to receive mode + + // configure radio + cc1020_wakeupRX(RX_CURRENT); + cc1020_setupRX(RX_CURRENT); + LNA_POWER_ON(); // enable amplifier + + // activate + IE1 |= URXIE0; // enable interrupt +} + +void +cc1020_set_tx(void) +{ + + // configure radio rx + LNA_POWER_OFF(); // power down LNA + _DINT(); + DISABLE_RX_IRQ(); + P3SEL &= ~0x02; // Ensure Rx line is off + _EINT(); + + // configure radio tx + cc1020_wakeupTX(TX_CURRENT); + cc1020_setupTX(TX_CURRENT); + P3SEL |= 0x0C; // select Tx line and clk + U0CTL |= SWRST; // UART to reset mode + IFG1 &= ~UTXIFG0; // Reset IFG. + + // configure driver + cc1020_state = CC1020_TX; +} + +void +cc1020_set_receiver(void (*recv) (void)) +{ + receiver_callback = recv; +} + +__inline void +cc1020_set_power_mode(enum cc1020_power_mode mode) +{ + cc1020_power_mode = mode; +} + +__inline void +cc1020_set_power(u8_t pa_power) +{ + cc1020_pa_power = pa_power; +} + +unsigned int +cc1020_read(u8_t * buf, unsigned int bufsize) +{ + unsigned short len; + + if (cc1020_rxlen > HDRSIZE) { + len = cc1020_rxlen - HDRSIZE; + if (len > bufsize) { + + // XXX Must handle this condition. + printf + ("read buffer smaller than packet payload. payload length=%u, buffer size=%u\n", + len, bufsize); + } else { + memcpy(buf, (char *) cc1020_rxbuf + HDRSIZE, len); + return len; + } + } + return 0; +} + +__inline u8_t +cc1020_get_rssi() +{ + return rssi; +} + +unsigned +cc1020_send(u8_t * buf, unsigned int len) +{ + if (len > CC1020_BUFFERSIZE) // too large + return 0; + if (cc1020_txlen > 0) // buffer in use + return 0; + + // prefix + // (preamble+syncword are already in buffer) + cc1020_txlen = PREAMBLESIZE + SYNCWDSIZE; + + // header + cc1020_txbuf[cc1020_txlen++] = HDRSIZE + len; + + // data to send + memcpy((char *) cc1020_txbuf + cc1020_txlen, buf, len); + cc1020_txlen += len; + + // suffix + cc1020_txbuf[cc1020_txlen++] = 0xFA; + cc1020_txbuf[cc1020_txlen++] = 0xFA; + + // poll sender + process_poll(&cc1020_sender_process); + return len; +} + +interrupt(UART0RX_VECTOR) cc1020_rxhandler(void) +{ + static signed char syncbs; + static union { + struct { + u8_t b2; + u8_t b1; + u8_t b4; + u8_t b3; + }; + struct { + UINT16 i1; + UINT16 i2; + }; + } shiftbuf; + + switch (cc1020_rxstate) { + case CC1020_RX_SEARCHING: + shiftbuf.b1 = shiftbuf.b2; + shiftbuf.b2 = shiftbuf.b3; + shiftbuf.b3 = shiftbuf.b4; + shiftbuf.b4 = RXBUF0; + if (shiftbuf.i1 == 0xAAD3 && shiftbuf.i2 == 0x9100) { + + // 0 AA D3 91 00 | FF 00 | + syncbs = 0; + cc1020_rxbuf[cc1020_rxlen++] = shiftbuf.b4; + } else if (shiftbuf.i1 == 0x5569 && shiftbuf.i2 == 0xC880) { + + // 1 55 69 C8 80 | 7F 80 | + syncbs = -1; + } else if (shiftbuf.i1 == 0xAAB4 && shiftbuf.i2 == 0xE440) { + + // 2 AA B4 E4 40 | 3F C0 | + syncbs = -2; + } else if (shiftbuf.i1 == 0x555A && shiftbuf.i2 == 0x7220) { + + // 3 55 5A 72 20 | 1F E0 | + syncbs = -3; + } else if (shiftbuf.i1 == 0xAAAD && shiftbuf.i2 == 0x3910) { + + // 4 AA AD 39 10 | 0F F0 | + syncbs = -4; + } else if (shiftbuf.i1 == 0x5556 && shiftbuf.i2 == 0x9C88) { + + // 5 55 56 9C 88 | 07 F8 | + syncbs = +3; + } else if (shiftbuf.i1 == 0xAAAB && shiftbuf.i2 == 0x4E44) { + + // 6 AA AB 4E 44 | 03 FC | + syncbs = +2; + } else if (shiftbuf.i1 == 0x5555 && shiftbuf.i2 == 0xA722) { + + // 7 55 55 A7 22 | 01 FE | + syncbs = +1; + } else { + return; + } + cc1020_rxstate = CC1020_RX_RECEIVE; + + // Signal "Channel busy" + rssi = cc1020_read_reg(CC1020_RSS); + break; + case CC1020_RX_RECEIVE: + if (syncbs == 0) { + cc1020_rxbuf[cc1020_rxlen] = RXBUF0; + } else { + shiftbuf.b3 = shiftbuf.b4; + shiftbuf.b4 = RXBUF0; + if (syncbs < 0) { + shiftbuf.i1 = shiftbuf.i2 << -syncbs; + cc1020_rxbuf[cc1020_rxlen] = shiftbuf.b1; + } else { + shiftbuf.i1 = shiftbuf.i2 >> syncbs; + cc1020_rxbuf[cc1020_rxlen] = shiftbuf.b2; + } + } + cc1020_rxlen++; + if (cc1020_rxlen > HDRSIZE) { + if (cc1020_rxlen == ((struct cc1020_header *) cc1020_rxbuf)->length) { + + // disable receiver + DISABLE_RX_IRQ(); + cc1020_rxstate = CC1020_RX_PROCESSING; + + // call receiver to copy from buffer + if (receiver_callback != NULL) + receiver_callback(); + + // reset receiver + cc1020_rxlen = 0; + cc1020_rxstate = CC1020_RX_SEARCHING; + ENABLE_RX_IRQ(); + } + } + break; + default: + break; + } +} + +PROCESS_THREAD(cc1020_sender_process, ev, data) +{ + PROCESS_BEGIN(); + while (1) { + // Wait for data in buffer. + PROCESS_WAIT_UNTIL(cc1020_txlen > 0); + + // Radio could be in OFF or RX mode. + if (cc1020_state == CC1020_OFF) + cc1020_set_rx(); + + // Radio is in RX mode. + + // Wait until the receiver is idle. + PROCESS_WAIT_UNTIL(cc1020_rxstate == CC1020_RX_SEARCHING); + + // Wait for a short pseudo-random time before sending. + clock_delay(1 + (random_rand() & 0xf)); + + // Switch to transceive mode. + cc1020_set_tx(); + + // Initiate radio transfer. + + // Configure DMA Channel 0 for UART0 TXIFG. + DMACTL0 = DMA0TSEL_4; + + // No DMAONFETCH, ROUNDROBIN, ENNMI. + DMACTL1 = 0x0000; + + /* + * Single transfer mode, dstadr unchanged, srcadr + * incremented, byte access + * Important to use DMALEVEL when using USART TX + * interrupts so first edge + * doesn't get lost (hangs every 50. - 100. time)! + */ + DMA0CTL = + DMADT_0 | DMADSTINCR_0 | DMASRCINCR_3 | DMASBDB | DMALEVEL | DMAIE; + DMA0SA = (unsigned) cc1020_txbuf; + DMA0DA = (unsigned) &TXBUF0; + DMA0SZ = cc1020_txlen; + DMA0CTL |= DMAEN; // enable DMA + U0CTL &= ~SWRST; // enable UART, starts transfer + + // wait for DMA0 to finish + PROCESS_WAIT_UNTIL(ev == cc1020_event && *((unsigned char *) data) == 0); + + // clean up + cc1020_txlen = 0; + cc1020_on(); + } PROCESS_END(); +} + +static void +cc1020_write_reg(u8_t addr, u8_t adata) +{ + unsigned i; + unsigned char data; + + PSEL_OFF; + data = addr << 1; + PSEL_ON; + + // Send address bits + for (i = 0; i < 7; i++) { + nop(); // Delay50ns(); + PCLK_LOW; + nop(); // Delay50ns(); + if (data & 0x80) + PDI_HIGH; + + else + PDI_LOW; + data = data << 1; + PCLK_HIGH; + } + + // Send read/write bit + // Ignore bit in data, always use 1 + nop(); // Delay50ns(); + PCLK_LOW; + PDI_HIGH; + nop(); // Delay50ns(); + PCLK_HIGH; + nop(); // Delay50ns(); + PCLK_LOW; + data = adata; + + // Send data bits + for (i = 0; i < 8; i++) { + nop(); // Delay50ns(); + PCLK_LOW; + nop(); // Delay50ns(); + if (data & 0x80) + PDI_HIGH; + + else + PDI_LOW; + data = data << 1; + PCLK_HIGH; + } + nop(); // Delay50ns(); + PCLK_LOW; + nop(); // Delay50ns(); + PSEL_OFF; +} + +static u8_t +cc1020_read_reg(u8_t addr) +{ + unsigned i; + unsigned char data = 0; + + PSEL_OFF; + data = addr << 1; + PSEL_ON; + nop(); // Delay50ns(); + // Send address bits + for (i = 0; i < 7; i++) { + nop(); // Delay50ns(); + PCLK_LOW; + nop(); // Delay50ns(); + if (data & 0x80) + PDI_HIGH; + + else + PDI_LOW; + data = data << 1; + PCLK_HIGH; + } + + // Send read/write bit + // Ignore bit in data, always use 0 + nop(); // Delay50ns(); + PCLK_LOW; + PDI_LOW; + nop(); // Delay50ns(); + PCLK_HIGH; + nop(); // Delay50ns(); + PCLK_LOW; + + // Receive data bits + for (i = 0; i < 8; i++) { + nop(); // Delay50ns(); + PCLK_HIGH; + nop(); // Delay50ns(); + data = data << 1; + if (PDO) + data++; + nop(); // Delay50ns(); + PCLK_LOW; + } + nop(); // Delay50ns(); + PSEL_OFF; + return data; +} + +static void +cc1020_load_config(const u8_t * config) +{ + int i; + + for (i = 0; i < 0x28; i++) + cc1020_write_reg(i, config[i]); +} + +static void +cc1020_reset(void) +{ + + // Reset CC1020 + cc1020_write_reg(CC1020_MAIN, 0x0FU & ~0x01U); + + // Bring CC1020 out of reset + cc1020_write_reg(CC1020_MAIN, 0x1F); +} + +static int +cc1020_calibrate(void) +{ + unsigned char tmp; + unsigned int timeout_cnt; + + + // Turn off PA to avoid spurs during calibration in TX mode + cc1020_write_reg(CC1020_PA_POWER, 0x00); + + // Start calibration + cc1020_write_reg(CC1020_CALIBRATE, 0xB5); + clock_delay(1200); + while ((tmp = cc1020_read_reg(CC1020_STATUS) & CAL_COMPLETE) == 0); + clock_delay(800); + + // Monitor lock + timeout_cnt = LOCK_TIMEOUT; + + do { + tmp = cc1020_read_reg(CC1020_STATUS); + } while (tmp & LOCK_CONTINUOUS && --timeout_cnt > 0); + + // Restore PA_POWER + cc1020_write_reg(CC1020_PA_POWER, cc1020_pa_power); + + // Return state of LOCK_CONTINUOUS bit + return (cc1020_read_reg(CC1020_STATUS) & LOCK_CONTINUOUS) == + LOCK_CONTINUOUS; +} + +static int +cc1020_lock(void) +{ + char lock_status; + int i; + + // Monitor LOCK, lasts 420 - 510 cycles @ 4505600 = 93 us - 113 us + for (i = LOCK_TIMEOUT; i > 0; i--) { + lock_status = cc1020_read_reg(CC1020_STATUS) & LOCK_CONTINUOUS; + if (lock_status) + break; + } + if (lock_status == LOCK_CONTINUOUS) { + return LOCK_OK; + } else { + + // If recalibration ok + if (cc1020_calibrate()) + return LOCK_RECAL_OK; // Indicate PLL in LOCK + else + return LOCK_NOK; // Indicate PLL out of LOCK + } +} +static int +cc1020_setupRX(int analog) +{ + char lock_status; + + // Switch into RX, switch to freq. reg A + cc1020_write_reg(CC1020_MAIN, 0x11); + + // Setup bias current adjustment + cc1020_write_reg(CC1020_ANALOG, analog); + clock_delay(400); // Wait for 1 msec + lock_status = cc1020_lock(); + + // Switch RX part of CC1020 on + cc1020_write_reg(CC1020_MAIN, 0x01); + cc1020_write_reg(CC1020_INTERFACE, 0x02); + + // Return LOCK status to application + return lock_status; +} + +static int +cc1020_setupTX(int analog) +{ + char lock_status; + + // Setup bias current adjustment + cc1020_write_reg(CC1020_ANALOG, analog); + + // Switch into TX, switch to freq. reg B + cc1020_write_reg(CC1020_MAIN, 0xC1); + clock_delay(400); // Wait for 1 msec + lock_status = cc1020_lock(); + + // Restore PA_POWER + cc1020_write_reg(CC1020_PA_POWER, cc1020_pa_power); + + // Turn OFF DCLK squelch in TX + cc1020_write_reg(CC1020_INTERFACE, 0x01); + + // Return LOCK status to application + return lock_status; +} + +static void +cc1020_setupPD(void) +{ + // Put CC1020 into power-down + cc1020_write_reg(CC1020_MAIN, 0x1F); + + // Turn off PA to minimise current draw + cc1020_write_reg(CC1020_PA_POWER, 0x00); +} + +static void +cc1020_wakeupRX(int analog) +{ + // Turn on crystal oscillator core. + cc1020_write_reg(CC1020_MAIN, 0x1B); + + // Setup bias current adjustment. + cc1020_write_reg(CC1020_ANALOG, analog); + + // Insert wait routine here, must wait for xtal oscillator to stabilise, + // typically takes 2-5ms. + clock_delay(1200); // DelayMs(5); + + // Turn on bias generator. + cc1020_write_reg(CC1020_MAIN, 0x19); + clock_delay(400); // NOT NEEDED? + + // Turn on frequency synthesizer. + cc1020_write_reg(CC1020_MAIN, 0x11); +} + +static void +cc1020_wakeupTX(int analog) +{ + // Turn on crystal oscillator core. + cc1020_write_reg(CC1020_MAIN, 0xDB); + + // Setup bias current adjustment. + cc1020_write_reg(CC1020_ANALOG, analog); + + // Insert wait routine here, must wait for xtal oscillator to stabilise, + // typically takes 2-5ms. + clock_delay(1200); // DelayMs(5); + + // Turn on bias generator. + cc1020_write_reg(CC1020_MAIN, 0xD9); + clock_delay(400); // NOT NEEDED? + + // Turn on frequency synthesizer. + clock_delay(400); + cc1020_write_reg(CC1020_MAIN, 0xD1); +} diff --git a/platform/msb430/dev/cc1020.h b/platform/msb430/dev/cc1020.h new file mode 100644 index 000000000..16865c362 --- /dev/null +++ b/platform/msb430/dev/cc1020.h @@ -0,0 +1,99 @@ +/* +Copyright 2006, Freie Universitaet Berlin. All rights reserved. + +These sources were developed at the Freie Universität Berlin, Computer +Systems and Telematics group. + +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 Freie Universitaet Berlin (FUB) 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 FUB and the contributors on an "as is" +basis, without any representations or warranties of any kind, express +or implied including, but not limited to, representations or +warranties of non-infringement, merchantability or fitness for a +particular purpose. In no event shall FUB 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 implementation was developed by the CST group at the FUB. + +For documentation and questions please use the web site +http://scatterweb.mi.fu-berlin.de and the mailinglist +scatterweb@lists.spline.inf.fu-berlin.de (subscription via the Website). +Berlin, 2006 +*/ + +/** + * @file cc1020.h + * @author FUB ScatterWeb Developers, Michael Baar, Nicolas Tsiftes + * + **/ + +#ifndef CC1020_H +#define CC1020_H + +#include "dev/radio.h" + +enum cc1020_power_mode { + CC1020_ALWAYS_ON +}; + +extern const u8_t cc1020_config_19200[]; +extern const u8_t cc1020_config_115200[]; + +void cc1020_init(const u8_t* config); + +int cc1020_on(); + +void cc1020_set_rx(); + +void cc1020_set_tx(); + +void cc1020_off(); + +void cc1020_set_receiver(void (* recv)(void)); + +void cc1020_set_power_mode(enum cc1020_power_mode mode); + +/** + * @brief Set output power amplifier power- + * + * For good values see CC1020 documentation. + */ +void cc1020_set_power(u8_t pa_power); + +unsigned int cc1020_read(u8_t *buf, unsigned int bufsize); + +/** + * @brief Get RSSI of last received packet + * + * Best to call in packet handler + */ +u8_t cc1020_get_rssi(); + +unsigned int cc1020_send(u8_t* buf, unsigned int bufsize); + +extern const struct radio_driver cc1020_driver; + +PROCESS_NAME(cc1020_sender_process); + +extern process_event_t cc1020_event; + +#endif diff --git a/platform/msb430/dev/dma.c b/platform/msb430/dev/dma.c new file mode 100644 index 000000000..4c16ffffd --- /dev/null +++ b/platform/msb430/dev/dma.c @@ -0,0 +1,69 @@ +/* + * 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 + * DMA interrupt handling. + * \author + * Nicolas Tsiftes + */ + +#include +#include + +#include "contiki-msb430.h" +#include "dev/cc1020.h" + +interrupt(DACDMA_VECTOR) irq_dacdma(void) +{ + static unsigned char line; + + if (DMA0CTL & DMAIFG) { + DMA0CTL &= ~(DMAIFG | DMAIE); + line = 0; + process_post(&cc1020_sender_process, cc1020_event, &line); + } + + if (DMA1CTL & DMAIFG) { + DMA1CTL &= ~(DMAIFG | DMAIE); + line = 1; + process_post(&cc1020_sender_process, cc1020_event, &line); + } + + if (DAC12_0CTL & DAC12IFG) { + DAC12_0CTL &= ~(DAC12IFG | DAC12IE); + } + + if (DAC12_1CTL & DAC12IFG) { + DAC12_1CTL &= ~(DAC12IFG | DAC12IE); + } +} diff --git a/platform/msb430/dev/dma.h b/platform/msb430/dev/dma.h new file mode 100644 index 000000000..6e87d09eb --- /dev/null +++ b/platform/msb430/dev/dma.h @@ -0,0 +1,83 @@ +/* + * 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 + * ADC functions. + * \author + * Nicolas Tsiftes + */ + +#include +#include + +#include "contiki-msb430.h" + +void +adc_init(void) { + //Setup ADC12, ref., sampling time, REFON for DAC!! + ADC12CTL0 = SHT0_15 + SHT1_15 + MSC; + + // Use sampling timer, repeat-sequence-of-channels + ADC12CTL1 = SHP + CONSEQ_3 + CSTARTADD_0; + ADC12MCTL0 = INCH_0 + SREF_0; // P60: AIN0 + ADC12MCTL1 = INCH_0 + SREF_0; // P60: AIN0 + ADC12MCTL2 = INCH_0 + SREF_0; // P60: AIN0 + ADC12MCTL3 = INCH_1 + SREF_0; // P61: AIN1 + ADC12MCTL4 = INCH_1 + SREF_0; // P61: AIN1 + ADC12MCTL5 = INCH_1 + SREF_0; // P61: AIN1 + ADC12MCTL6 = INCH_2 + SREF_0; // P62: AIN2 + ADC12MCTL7 = INCH_2 + SREF_0; // P62: AIN2 + ADC12MCTL8 = INCH_2 + SREF_0; // P62: AIN2 + ADC12MCTL9 = INCH_2 + SREF_0; // P62: AIN2 + ADC12MCTL10 = INCH_3 + SREF_0; // P63: AIN2 + ADC12MCTL11 = INCH_4 + SREF_0; // P64: AIN3 + ADC12MCTL12 = INCH_5 + SREF_0; // P65: AIN4 + ADC12MCTL13 = INCH_10 + SREF_0 + EOS; // Temp diode +} + +void +adc_on(void) +{ + ADC12CTL0 |= ADC12ON; + clock_delay(600); + ADC12CTL0 |= ENC; + ADC12CTL0 |= ADC12SC; +} + +void +adc_off(void) +{ + ADC12CTL0 &= ~ENC; + clock_delay(600); + ADC12CTL0 &= ~ADC12ON; +} diff --git a/platform/msb430/dev/infomem.c b/platform/msb430/dev/infomem.c new file mode 100644 index 000000000..3c030dbf6 --- /dev/null +++ b/platform/msb430/dev/infomem.c @@ -0,0 +1,118 @@ +/* +Copyright 2007, Freie Universitaet Berlin. All rights reserved. + +These sources were developed at the Freie Universität Berlin, Computer +Systems and Telematics group. + +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 Freie Universitaet Berlin (FUB) 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 FUB and the contributors on an "as is" +basis, without any representations or warranties of any kind, express +or implied including, but not limited to, representations or +warranties of non-infringement, merchantability or fitness for a +particular purpose. In no event shall FUB 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 implementation was developed by the CST group at the FUB. + +For documentation and questions please use the web site +http://scatterweb.mi.fu-berlin.de and the mailinglist +scatterweb@lists.spline.inf.fu-berlin.de (subscription via the Website). +Berlin, 2007 +*/ + +/** + * @file infomem.c + * @addtogroup storage + * @brief MSP430 Infomemory Storage + * @author Michael Baar + * + * Functions to store and read data from the two infomemories (2 x 128 Bytes). + * Offset addresses start at zero, size has a maximum of 128, write operations + * across both blocks are not allowed. + */ +#include +#include +#include +#include "contiki-conf.h" +#include +#include "infomem.h" + +void infomem_read(void* buffer, unsigned int offset, unsigned char size) { + UINT8* address = (UINT8*)INFOMEM_START + offset; + memcpy(buffer, address, size); +} + +bool infomem_write(unsigned int offset, unsigned char count, ...) { + char backup[INFOMEM_BLOCK_SIZE]; + + register UINT8* buffer; + register UINT16 i; + UINT8* flash; + + if( offset > ( 2 * INFOMEM_BLOCK_SIZE) ) + return false; + + flash = (UINT8*)INFOMEM_START + offset; + + _DINT(); + + // backup into RAM + memcpy(backup, flash, INFOMEM_BLOCK_SIZE); + + // merge backup with new data + va_list argp; + va_start(argp, count); + + buffer = (UINT8*)backup; + for( i = 0; i < count; i++ ) { + register UINT16 size; + register UINT8* data; + + data = va_arg(argp, UINT8*); + size = va_arg(argp, UINT16); + memcpy(buffer, data, size); + buffer += size; + } + va_end(argp); + + // init flash access + FCTL2 = FWKEY + FSSEL1 + FN2; + FCTL3 = FWKEY; + + // erase flash + FCTL1 = FWKEY + ERASE; + *flash = 0; + + // write flash + FCTL1 = FWKEY + WRT; + buffer = (UINT8*)backup; + for( i = 0; i < INFOMEM_BLOCK_SIZE; i++ ) { + *flash = *buffer; + buffer++; flash++; + } + FCTL1 = FWKEY; + FCTL3 = FWKEY + LOCK; + + _EINT(); + return true; +} diff --git a/platform/msb430/dev/infomem.h b/platform/msb430/dev/infomem.h new file mode 100644 index 000000000..4fd3db9e3 --- /dev/null +++ b/platform/msb430/dev/infomem.h @@ -0,0 +1,85 @@ +/* +Copyright 2006, Freie Universitaet Berlin. All rights reserved. + +These sources were developed at the Freie Universität Berlin, Computer +Systems and Telematics group. + +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 Freie Universitaet Berlin (FUB) 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 FUB and the contributors on an "as is" +basis, without any representations or warranties of any kind, express +or implied including, but not limited to, representations or +warranties of non-infringement, merchantability or fitness for a +particular purpose. In no event shall FUB 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 implementation was developed by the CST group at the FUB. + +For documentation and questions please use the web site +http://scatterweb.mi.fu-berlin.de and the mailinglist +scatterweb@lists.spline.inf.fu-berlin.de (subscription via the Website). +Berlin, 2006 +*/ + +/** + * @file infomem.h + * @addtogroup storage + * @brief MSP430 Infomemory Storage + * + * @author Michael Baar + */ + +#ifndef INFOMEM_H_ +#define INFOMEM_H_ + +/* These defines might depend on the specific CPU used and have to be defined in platform: +#define INFOMEM_START 0x1000 +#define INFOMEM_BLOCK_SIZE 128 +*/ +#if !defined(INFOMEM_START) || !defined(INFOMEM_BLOCK_SIZE) + #error "Infomemory position (INFOMEM_START) and blocksize (INFOMEM_BLOCK_SIZE) need to be defined for current platform" +#endif + +/** + * @brief Read bytes from infomemory + * @param[out] buffer Pointer to buffer for read data + * @param[in] offset Offset in infomemory (0-254) + * @param[in] size Number of bytes to read + */ +void infomem_read(void* buffer, unsigned int offset, unsigned char size); + +/** + * @brief Write bytes to infomemory + * @param[in] offset Offset in infomemory (0-254) + * @param[in] count Number of items following + * each item is a pair pointer, length + * + * Example: Infomem_write( 0, 2, &a,3, &b,1 ); + * + * \note: The MSP430 has two consecutive blocks of infomemory. Each is 128 Bytes large. + * The offset is the relative address starting at the beginning of the first block. + * You can write an arbitrary number of bytes at any offse, but this + * function cannot write across the two blocks of infomemory. + */ +bool infomem_write(unsigned int offset, unsigned char count, ...); + +#endif // INFOMEM_H diff --git a/platform/msb430/dev/msb430-uart1.c b/platform/msb430/dev/msb430-uart1.c new file mode 100644 index 000000000..7c50f7f55 --- /dev/null +++ b/platform/msb430/dev/msb430-uart1.c @@ -0,0 +1,211 @@ +/* +Copyright 2007, Freie Universitaet Berlin. All rights reserved. + +These sources were developed at the Freie Universität Berlin, Computer +Systems and Telematics group. + +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 Freie Universitaet Berlin (FUB) 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 FUB and the contributors on an "as is" +basis, without any representations or warranties of any kind, express +or implied including, but not limited to, representations or +warranties of non-infringement, merchantability or fitness for a +particular purpose. In no event shall FUB 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 implementation was developed by the CST group at the FUB. + +For documentation and questions please use the web site +http://scatterweb.mi.fu-berlin.de and the mailinglist +scatterweb@lists.spline.inf.fu-berlin.de (subscription via the Website). +Berlin, 2007 +*/ + +/** + * @file ScatterWeb.Uart.c + * @addtogroup interfaces + * @brief UART interface + * @author Michael Baar + * + * UART switch for RS232 and SPI protocols on UART1 written for + * ScatterWeb MSB boards. Compatible to ScatterWeb EOS, + * ScatterWeb Bootload and Contiki. + */ + +#include +#include +#include +#include "dev/msb430-uart1.h" +#include "msp430.h" +#include "dev/lpm.h" + +#ifndef U1ME +#define U1ME ME2 +#endif + +void _uart_configure(unsigned char mode); +void _uart_set_mode(unsigned char mode); + +volatile unsigned char uart_mode = UART_MODE_RESET; +volatile unsigned char uart_lockcnt = 0; + +static unsigned char _uart_speed_br0[UART_NUM_MODES]; +static unsigned char _uart_speed_br1[UART_NUM_MODES]; +static unsigned char _uart_speed_bmn[UART_NUM_MODES]; +static fp_uart_handler _uart_handler[UART_NUM_MODES] = {NULL, NULL}; + +/*---------------------------------------------------------------------------*/ +void +uart_set_speed(unsigned char mode, unsigned char ubr0, + unsigned char ubr1, unsigned char umctl) +{ + // store setting + _uart_speed_br0[mode] = ubr0; // baudrate + _uart_speed_br1[mode] = ubr1; // baudrate + _uart_speed_bmn[mode] = umctl; // modulation + + // reconfigure, if mode active + if (uart_mode == mode) + _uart_configure(mode); +} +/*---------------------------------------------------------------------------*/ +void +uart_set_handler(unsigned char mode, fp_uart_handler fpHandler) +{ + // store setting + _uart_handler[mode] = fpHandler; + if (mode == uart_mode) { + if (fpHandler == NULL) + IE2 &= ~URXIE1; // Disable USART1 RX interrupt + else + IE2 |= URXIE1; // Enable USART1 RX interrupt + } +} +/*---------------------------------------------------------------------------*/ +char +uart_lock(unsigned char mode) +{ + // already locked? + if ((mode != uart_mode) && (uart_lockcnt)) { + return 0; + } else { + // increase lock count + uart_lockcnt++; + // switch mode (if neccessary) + _uart_set_mode(mode); + return 1; + } +} +/*---------------------------------------------------------------------------*/ +char +uart_unlock(unsigned char mode) +{ + /* + Do we wan't strict checking? + if( (uart_lockcnt == 0) || (mode != uart_mode) ) + return false; + */ + + // decrement lock + if (uart_lockcnt > 0) { + uart_lockcnt--; + + // if no more locks, switch back to default mode + if (uart_lockcnt == 0) { + _uart_set_mode(UART_MODE_DEFAULT); + } + return 1; + } + return 0; +} +/*---------------------------------------------------------------------------*/ +void +_uart_configure(unsigned char mode) +{ + _DINT(); // disable interrupts + + UART_WAIT_TXDONE(); +// wait till all buffered data has been transmitted + + // configure + if (mode == UART_MODE_RS232) { + P5OUT |= 0x01; + // unselect SPI + P3SEL |= 0xC0; + // select rs232 + // to RS232 mode + UCTL1 = SWRST | CHAR; // 8-bit character + UTCTL1 |= SSEL1; // UCLK = MCLK + // activate + U1ME |= UTXE1 | URXE1; // Enable USART1 TXD/RXD + } else if( mode == UART_MODE_SPI ) { + P3SEL &= ~0xC0; // unselect RS232 + // to SPI mode + UCTL1 = SWRST | CHAR | SYNC | MM; // 8-bit SPI Master + /* + * SMCLK, 3-pin mode, clock idle low, data valid on + * rising edge, UCLK delayed + */ + UTCTL1 |= CKPH | SSEL1 | SSEL0 | STC; // activate + U1ME |= USPIE1; // Enable USART1 SPI + } + + // restore speed settings + UBR01 = _uart_speed_br0[mode]; // set baudrate + UBR11 = _uart_speed_br1[mode]; + UMCTL1 = _uart_speed_bmn[mode]; // set modulation + + UCTL1 &= ~SWRST; // clear reset flag + _EINT(); // enable interrupts +} +/*---------------------------------------------------------------------------*/ +void +_uart_set_mode(unsigned char mode) +{ + // do nothing if mode already set + if( mode == uart_mode ) + return; + + IE2 &= ~(URXIE1 | UTXIE1); // disable irq + _uart_configure(mode); // configure uart parameters + uart_mode = mode; + + if (_uart_handler[mode] != NULL) + IE2 |= URXIE1; // Enable USART1 RX interrupt +} + +/*---------------------------------------------------------------------------*/ +interrupt(UART1RX_VECTOR)_uart_rx(void) +{ + fp_uart_handler handler = _uart_handler[uart_mode]; + + /* Check status register for receive errors. - before reading RXBUF since + it clears the error and interrupt flags */ + if (!(URCTL1 & RXERR) && handler != NULL) { + if(handler(UART_RX)) { + LPM_AWAKE(); + } + } else { + // read out the char to clear the I-flags, etc. + UART_RX; + } +} diff --git a/platform/msb430/dev/msb430-uart1.h b/platform/msb430/dev/msb430-uart1.h new file mode 100644 index 000000000..f470ade28 --- /dev/null +++ b/platform/msb430/dev/msb430-uart1.h @@ -0,0 +1,120 @@ +/* +Copyright 2007, Freie Universitaet Berlin. All rights reserved. + +These sources were developed at the Freie Universität Berlin, Computer +Systems and Telematics group. + +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 Freie Universitaet Berlin (FUB) 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 FUB and the contributors on an "as is" +basis, without any representations or warranties of any kind, express +or implied including, but not limited to, representations or +warranties of non-infringement, merchantability or fitness for a +particular purpose. In no event shall FUB 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 implementation was developed by the CST group at the FUB. + +For documentation and questions please use the web site +http://scatterweb.mi.fu-berlin.de and the mailinglist +scatterweb@lists.spline.inf.fu-berlin.de (subscription via the Website). +Berlin, 2007 +*/ + +/** + * @addtogroup interfaces + * @{ */ + +/** + * @defgroup uart1 UART1 + * The UART module multiplexes differenct protocol on the MSB's UART1 + * interface. Currently RS232 and SPI are supported. + * @{ + */ + +/** + * @file ScatterWeb.Uart.h + * @author Michael Baar + * + * Header file for MSP430 UART driver. + */ + +#ifndef __UART_H__ +#define __UART_H__ + +#define UART_RX RXBUF1 +#define UART_TX TXBUF1 +#define UART_RESET_RX() do { U1IFG &= ~URXIFG1; } while(0) +#define UART_RESET_RXTX() do { U1IFG &= ~(URXIFG1 | UTXIFG1); } while(0) +#define UART_WAIT_RX() while( (U1IFG & URXIFG1) == 0 ) { _NOP(); } +#define UART_WAIT_TX() while( (U1IFG & UTXIFG1) == 0 ) { _NOP(); } +#define UART_WAIT_TXDONE() while( (UTCTL1 & TXEPT) == 0 ) { _NOP(); } + +/** + * @brief Operating state + */ +extern volatile unsigned char uart_mode; +extern volatile unsigned char uart_lockcnt; + +/** + * @name UART mode flags + * @{ + */ +#define UART_MODE_RS232 (0x00u) ///< RS232 mode +#define UART_MODE_SPI (0x01u) ///< SPI mode +#define UART_MODE_DEFAULT UART_MODE_RS232 +#define UART_NUM_MODES (UART_MODE_SPI + 1) ///< Highest mode number +#define UART_MODE_RESET (0xFFu) ///< reset with current settings +/** @} */ + +#define UART_WAIT_LOCK(x) ( (uart_mode != x ) && (uart_lockcnt) ) +#define UART_MODE_IS(x) ( uart_mode == x ) + +#if 0 +#ifdef __SCATTERWEB__ + typedef void(*fp_uart_handler)(void); +#else + typedef unsigned int(*fp_uart_handler)(unsigned char); +#endif +#endif + typedef unsigned int(*fp_uart_handler)(unsigned char); + +/** + * \brief Initialize the UART module + * + * This function is called from the boot up code to + * initalize the UART module. + */ +void uart_init(void); + +void uart_set_speed(unsigned char mode, unsigned char ubr0, unsigned char ubr1, unsigned char umctl); + +void uart_set_handler(unsigned char mode, fp_uart_handler fpHandler); + +char uart_lock(unsigned char mode); + +char uart_unlock(unsigned char mode); + +#endif /* __UART_H__ */ + +/** @} */ +/** @} */ diff --git a/platform/msb430/dev/rs232.c b/platform/msb430/dev/rs232.c new file mode 100644 index 000000000..6f6560ef7 --- /dev/null +++ b/platform/msb430/dev/rs232.c @@ -0,0 +1,117 @@ +/* + * 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: rs232.c,v 1.1 2007/06/28 12:52:42 nvt-se Exp $ + */ + +/** \addtogroup esbrs232 + * @{ */ + +/** + * \file + * RS232 communication device driver for the MSP430. + * \author Adam Dunkels + * + * This file contains an RS232 device driver for the MSP430 microcontroller. + * + */ + +#include +#include +#include +#include "dev/msb430-uart1.h" +#include "rs232.h" + +#ifndef U1IFG +#define U1IFG IFG2 +#endif + +/*---------------------------------------------------------------------------*/ +/** + * Initalize the RS232 port. + * + */ +void +rs232_init(void) +{ +// rs232_set_speed(RS232_57600); + rs232_set_speed(RS232_115200); +} +/*---------------------------------------------------------------------------*/ +void +rs232_send(char c) +{ + /* Check if the UART is in RS232 mode before sending. + This check can be ommitted if every access to rs232 locks the uart + before using it. + */ + + if (uart_mode == UART_MODE_RS232) { + /* Loop until the transmission buffer is available. */ + UART_WAIT_TX(); + /* Transmit the data. */ + UART_TX = c; + } +} +/*---------------------------------------------------------------------------*/ +void +rs232_set_speed(enum rs232_speed speed) +{ + // baud + const unsigned char br_table[4][3] = { + {0x80, 0x00, 0x00}, // 19200 + {0x40, 0x00, 0x00}, // 38400 + {0x2a, 0x00, 0x5b}, // 57600 + {0x15, 0x00, 0x4a} // 115200 + }; + + uart_set_speed(UART_MODE_RS232, br_table[speed][0], + br_table[speed][1], br_table[speed][2]); +} +/*---------------------------------------------------------------------------*/ +void +rs232_print(char *cptr) +{ + // lock UART for print operation + if (uart_lock(UART_MODE_RS232)) { + while(*cptr != 0) { + rs232_send(*cptr); + ++cptr; + } + uart_unlock(UART_MODE_RS232); + } +} +/*---------------------------------------------------------------------------*/ +void +rs232_set_input(fp_uart_handler f) +{ + uart_set_handler(UART_MODE_RS232, f); +} +/** @} */ diff --git a/platform/msb430/dev/rs232.h b/platform/msb430/dev/rs232.h new file mode 100644 index 000000000..a7cfca141 --- /dev/null +++ b/platform/msb430/dev/rs232.h @@ -0,0 +1,120 @@ +/* + * 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: rs232.h,v 1.1 2007/06/28 12:52:42 nvt-se Exp $ + */ + +/** \addtogroup esb + * @{ */ + +/** + * \defgroup esbrs232 ESB RS232 + * + * @{ + */ + +/** + * \file + * Header file for MSP430 RS232 driver. + * \author Adam Dunkels + * + */ +#ifndef __RS232_H__ +#define __RS232_H__ + +enum rs232_speed { + RS232_19200 = 0, + RS232_38400 = 1, + RS232_57600 = 2, + RS232_115200 = 3 +}; + +/** + * \brief Initialize the RS232 module + * + * This function is called from the boot up code to + * initalize the RS232 module. + */ +void rs232_init(void); + +/** + * \brief Set an input handler for incoming RS232 data + * \param f A pointer to a byte input handler + * + * This function sets the input handler for incoming RS232 + * data. The input handler function is called for every + * incoming data byte. The function is called from the + * RS232 interrupt handler, so care must be taken when + * implementing the input handler to avoid race + * conditions. + * + * The return value of the input handler affects the sleep + * mode of the CPU: if the input handler returns non-zero + * (true), the CPU is awakened to let other processing + * take place. If the input handler returns zero, the CPU + * is kept sleeping. + */ +void rs232_set_input(fp_uart_handler f); + +/** + * \brief Configure the speed of the RS232 hardware + * \param speed The speed + * + * This function configures the speed of the RS232 + * hardware. The allowed parameters are RS232_19200, + * RS232_38400, RS232_57600, and RS232_115200. + */ +void rs232_set_speed(enum rs232_speed speed); + +/** + * \brief Print a text string on RS232 + * \param str A pointer to the string that is to be printed + * + * This function prints a string to RS232. The string must + * be terminated by a null byte. The RS232 module must be + * correctly initalized and configured for this function + * to work. + */ +void rs232_print(char *text); + +/** + * \brief Print a character on RS232 + * \param c The character to be printed + * + * This function prints a character to RS232. The RS232 + * module must be correctly initalized and configured for + * this function to work. + */ +void rs232_send(char c); + +#endif /* __RS232_H__ */ + +/** @} */ +/** @} */ diff --git a/platform/msb430/dev/sdspi.c b/platform/msb430/dev/sdspi.c new file mode 100644 index 000000000..bd8e4b19c --- /dev/null +++ b/platform/msb430/dev/sdspi.c @@ -0,0 +1,147 @@ + +/* +Copyright 2007, Freie Universitaet Berlin. All rights reserved. + +These sources were developed at the Freie Universität Berlin, Computer +Systems and Telematics group. + +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 Freie Universitaet Berlin (FUB) 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 FUB and the contributors on an "as is" +basis, without any representations or warranties of any kind, express +or implied including, but not limited to, representations or +warranties of non-infringement, merchantability or fitness for a +particular purpose. In no event shall FUB 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 implementation was developed by the CST group at the FUB. + +For documentation and questions please use the web site +http://scatterweb.mi.fu-berlin.de and the mailinglist +scatterweb@lists.spline.inf.fu-berlin.de (subscription via the Website). +Berlin, 2007 +*/ + + +/** + * @file ScatterWeb.Spi.c + * @ingroup libsdspi + * @brief Serial Peripheral Interface for SD library + * + * @author Michael Baar + * @date 2007 + * @version 1.0 + */ + +#include +#include +#include + +#include "contiki-msb430.h" + +#define SPI_IDLE_SYMBOL 0xFF + +void +spi_init(void) +{ + + /* The 16-bit value of UxBR0+UxBR1 is the division factor of the USART clock + * source, BRCLK. The maximum baud rate that can be generated in master + * mode is BRCLK/2. The maximum baud rate that can be generated in slave + * mode is BRCLK. The modulator in the USART baud rate generator is not used + * for SPI mode and is recommended to be set to 000h. The UCLK frequency is + * given by: + * Baud rate = BRCLK / UxBR with UxBR= [UxBR1, UxBR0] + */ + uart_set_speed(UART_MODE_SPI, 0x02, 0x00, 0x00); +} + +UINT8 +spi_rx(void) +{ + UART_RESET_RX(); + UART_TX = SPI_IDLE_SYMBOL; + UART_WAIT_RX(); + return (UART_RX); +} + +void +spi_tx(register const UINT8 c) +{ + UART_RESET_RX(); + UART_TX = c; + UART_WAIT_RX(); +} + +void +spi_read(void *pDestination, const UINT16 size, const bool incDest) +{ + register UINT8 *p = (UINT8 *) pDestination; + register UINT16 i; + + for (i = size; i > 0; i--) { + *p = spi_rx(); + if (incDest) + p++; + } +} + +void +spi_write(const void *pSource, const UINT16 size, const UINT8 startToken, + const bool incSource) +{ + register unsigned char *p = (unsigned char *) pSource; + register UINT16 i; + + spi_tx(startToken); + for (i = size; i > 0; i--) { + spi_tx(*p); + if (incSource) + p++; + } +} + +void +spi_idle(register const UINT16 clocks) +{ + register UINT16 i; + + for (i = 0; i < clocks; i++) { + UART_RESET_RX(); + UART_TX = SPI_IDLE_SYMBOL; + UART_WAIT_RX(); + } +} + +UINT8 +spi_wait_token(const UINT8 token, const UINT16 timeout) +{ + UINT16 i; + UINT8 rx; + + for (i = 0; i < timeout; i++) { + rx = spi_rx(); + if (rx == token) + return true; + } + return false; +} diff --git a/platform/msb430/dev/sdspi.h b/platform/msb430/dev/sdspi.h new file mode 100644 index 000000000..83e373e55 --- /dev/null +++ b/platform/msb430/dev/sdspi.h @@ -0,0 +1,106 @@ + +/* +Copyright 2006, Freie Universitaet Berlin. All rights reserved. + +These sources were developed at the Freie Universität Berlin, Computer +Systems and Telematics group. + +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 Freie Universitaet Berlin (FUB) 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 FUB and the contributors on an "as is" +basis, without any representations or warranties of any kind, express +or implied including, but not limited to, representations or +warranties of non-infringement, merchantability or fitness for a +particular purpose. In no event shall FUB 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 implementation was developed by the CST group at the FUB. + +For documentation and questions please use the web site +http://scatterweb.mi.fu-berlin.de and the mailinglist +scatterweb@lists.spline.inf.fu-berlin.de (subscription via the Website). +Berlin, 2006 +*/ + +/** + * @defgroup libsdspi Serial Peripheral Interface + * @ingroup libsd + */ + +/** + * @file ScatterWeb.Spi.h + * @ingroup libsdspi + * @brief Serial Peripheral Interface + * + * @author Michael Baar + * @date 2006 + * @version 1.0 + */ + +#ifndef SPI_H_ +#define SPI_H_ + +#ifndef SPI_DMA_READ +#define SPI_DMA_READ 0 +#endif +#ifndef SPI_DMA_WRITE +#define SPI_DMA_WRITE 0 +#endif +#ifndef SPI_WRITE +#define SPI_WRITE 1 +#endif + +void spi_init(void); + +/// Configure UART1 for SPI mode +void spi_enable(void); + +/// Receive one byte from SPI +UINT8 spi_rx(void); + +/// Send one byte to SPI +void spi_tx(const UINT8 c); + +/// Read a number of bytes from SPI +void spi_read(void *pDestination, const UINT16 size, const bool incDest); + +#if SPI_DMA_WRITE +extern UINT8 spi_dma_lock; +#endif +#if SPI_DMA_READ || SPI_DMA_WRITE +void spi_dma_wait(); +#endif + +#if SPI_WRITE +/// Write a number of bytes to SPI +void spi_write(const void *pSource, + const UINT16 size, + const UINT8 startToken, const bool incSource); +#endif + +/// Wait a number of clock cycles +void spi_idle(const UINT16 clocks); + +/// Read chars until token is received +UINT8 spi_wait_token(const UINT8 token, const UINT16 timeout); + +#endif /*SPI_H_ */ diff --git a/platform/msb430/dev/watchdog.c b/platform/msb430/dev/watchdog.c new file mode 100644 index 000000000..a7a88d3ea --- /dev/null +++ b/platform/msb430/dev/watchdog.c @@ -0,0 +1,54 @@ +/* + * 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: watchdog.c,v 1.1 2007/06/28 12:52:47 nvt-se Exp $ + */ +#include +#include "dev/watchdog.h" + +/*------------------------------------------------------------------------------*/ +void +watchdog_init(void) +{ + WDTCTL = WDT_ARST_1000 + WDTNMI + WDTNMIES; +} +/*------------------------------------------------------------------------------*/ +void +watchdog_restart(void) +{ + WDTCTL = WDT_ARST_1000 + WDTNMI + WDTNMIES; +} +/*------------------------------------------------------------------------------*/ +void +watchdog_stop(void) +{ + WDTCTL = WDTPW + WDTHOLD + WDTNMI + WDTNMIES; +} +/*------------------------------------------------------------------------------*/