From f7a82a91454607a08e6ddba8f5a99a07296bea2c Mon Sep 17 00:00:00 2001 From: joxe Date: Wed, 23 Jun 2010 10:15:28 +0000 Subject: [PATCH] split SPI code into generic and CC2420-related and renamed constants in CC2420 --- core/dev/cc2420.c | 66 +++++----- core/dev/cc2420.h | 107 +++++++++++++++- core/dev/spi.h | 302 +++++++++++----------------------------------- 3 files changed, 203 insertions(+), 272 deletions(-) diff --git a/core/dev/cc2420.c b/core/dev/cc2420.c index 78a158be1..ddb921622 100644 --- a/core/dev/cc2420.c +++ b/core/dev/cc2420.c @@ -28,7 +28,7 @@ * * This file is part of the Contiki operating system. * - * @(#)$Id: cc2420.c,v 1.55 2010/06/21 19:48:00 joxe Exp $ + * @(#)$Id: cc2420.c,v 1.56 2010/06/23 10:15:28 joxe Exp $ */ /* * This code is almost device independent and should be easy to port. @@ -150,42 +150,38 @@ static uint8_t receive_on; static int channel; /*---------------------------------------------------------------------------*/ -static uint8_t rxptr; /* Pointer to the next byte in the rxfifo. */ static void getrxdata(void *buf, int len) { - FASTSPI_READ_FIFO_NO_WAIT(buf, len); - rxptr = (rxptr + len) & 0x7f; + SPI_READ_FIFO_BUF(buf, len); } static void getrxbyte(uint8_t *byte) { - FASTSPI_READ_FIFO_BYTE(*byte); - rxptr = (rxptr + 1) & 0x7f; + SPI_READ_FIFO_BYTE(*byte); } static void flushrx(void) { uint8_t dummy; - FASTSPI_READ_FIFO_BYTE(dummy); - FASTSPI_STROBE(CC2420_SFLUSHRX); - FASTSPI_STROBE(CC2420_SFLUSHRX); - rxptr = 0; + SPI_READ_FIFO_BYTE(dummy); + SPI_STROBE(CC2420_SFLUSHRX); + SPI_STROBE(CC2420_SFLUSHRX); } /*---------------------------------------------------------------------------*/ static void strobe(enum cc2420_register regname) { - FASTSPI_STROBE(regname); + SPI_STROBE(regname); } /*---------------------------------------------------------------------------*/ static unsigned int status(void) { uint8_t status; - FASTSPI_UPD_STATUS(status); + SPI_GET_STATUS(status); return status; } /*---------------------------------------------------------------------------*/ @@ -197,7 +193,7 @@ on(void) /* PRINTF("on\n");*/ receive_on = 1; - ENABLE_FIFOP_INT(); + CC2420_ENABLE_FIFOP_INT(); strobe(CC2420_SRXON); while(!(status() & (BV(CC2420_XOSC16M_STABLE)))); ENERGEST_ON(ENERGEST_TYPE_LISTEN); @@ -214,10 +210,10 @@ off(void) ENERGEST_OFF(ENERGEST_TYPE_LISTEN); strobe(CC2420_SRFOFF); - DISABLE_FIFOP_INT(); + CC2420_DISABLE_FIFOP_INT(); LEDS_OFF(LEDS_GREEN); - if(!FIFOP_IS_1) { + if(!CC2420_FIFOP_IS_1) { flushrx(); } } @@ -242,14 +238,14 @@ static unsigned getreg(enum cc2420_register regname) { unsigned reg; - FASTSPI_GETREG(regname, reg); + SPI_READ_REG(regname, reg); return reg; } /*---------------------------------------------------------------------------*/ static void setreg(enum cc2420_register regname, unsigned value) { - FASTSPI_SETREG(regname, value); + SPI_WRITE_REG(regname, value); } /*---------------------------------------------------------------------------*/ static void @@ -276,8 +272,8 @@ cc2420_init(void) { int s = splhigh(); cc2420_arch_init(); /* Initalize ports and SPI. */ - DISABLE_FIFOP_INT(); - FIFOP_INT_INIT(); + CC2420_DISABLE_FIFOP_INT(); + CC2420_FIFOP_INT_INIT(); splx(s); } @@ -329,7 +325,7 @@ cc2420_init(void) cc2420_set_channel(26); flushrx(); - + process_start(&cc2420_process, NULL); return 1; } @@ -377,12 +373,13 @@ cc2420_transmit(unsigned short payload_len) #endif /* WITH_SEND_CCA */ for(i = LOOP_20_SYMBOLS; i > 0; i--) { - if(SFD_IS_1) { + if(CC2420_SFD_IS_1) { if(!(status() & BV(CC2420_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(); + printf("CC2420 Collission\n"); return RADIO_TX_COLLISION; } if(receive_on) { @@ -453,10 +450,10 @@ cc2420_prepare(const void *payload, unsigned short payload_len) checksum = crc16_data(payload, payload_len, 0); #endif /* CC2420_CONF_CHECKSUM */ total_len = payload_len + AUX_LEN; - FASTSPI_WRITE_FIFO(&total_len, 1); - FASTSPI_WRITE_FIFO(payload, payload_len); + SPI_WRITE_FIFO_BUF(&total_len, 1); + SPI_WRITE_FIFO_BUF(payload, payload_len); #if CC2420_CONF_CHECKSUM - FASTSPI_WRITE_FIFO(&checksum, CHECKSUM_LEN); + SPI_WRITE_FIFO_BUF(&checksum, CHECKSUM_LEN); #endif /* CC2420_CONF_CHECKSUM */ RELEASE_LOCK(); @@ -574,18 +571,18 @@ cc2420_set_pan_addr(unsigned pan, tmp[0] = pan & 0xff; tmp[1] = pan >> 8; - FASTSPI_WRITE_RAM_LE(&tmp, CC2420RAM_PANID, 2, f); + SPI_WRITE_RAM(&tmp, CC2420RAM_PANID, 2); tmp[0] = addr & 0xff; tmp[1] = addr >> 8; - FASTSPI_WRITE_RAM_LE(&tmp, CC2420RAM_SHORTADDR, 2, f); + SPI_WRITE_RAM(&tmp, CC2420RAM_SHORTADDR, 2); if(ieee_addr != NULL) { uint8_t tmp_addr[8]; /* LSB first, MSB last for 802.15.4 addresses in CC2420 */ for (f = 0; f < 8; f++) { tmp_addr[7 - f] = ieee_addr[f]; } - FASTSPI_WRITE_RAM_LE(tmp_addr, CC2420RAM_IEEEADDR, 8, f); + SPI_WRITE_RAM(tmp_addr, CC2420RAM_IEEEADDR, 8); } RELEASE_LOCK(); } @@ -601,7 +598,7 @@ TIMETABLE_AGGREGATE(aggregate_time, 10); int cc2420_interrupt(void) { - CLEAR_FIFOP_INT(); + CC2420_CLEAR_FIFOP_INT(); process_poll(&cc2420_process); #if CC2420_TIMETABLE_PROFILING timetable_clear(&cc2420_timetable); @@ -609,7 +606,6 @@ cc2420_interrupt(void) #endif /* CC2420_TIMETABLE_PROFILING */ pending++; - cc2420_packets_seen++; return 1; } @@ -656,7 +652,7 @@ cc2420_read(void *buf, unsigned short bufsize) uint16_t checksum; #endif /* CC2420_CONF_CHECKSUM */ - if(!FIFOP_IS_1) { + if(!CC2420_FIFOP_IS_1) { return 0; } /* if(!pending) { @@ -724,8 +720,8 @@ cc2420_read(void *buf, unsigned short bufsize) len = AUX_LEN; } - if(FIFOP_IS_1) { - if(!FIFO_IS_1) { + if(CC2420_FIFOP_IS_1) { + if(!CC2420_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. */ @@ -831,7 +827,7 @@ cc2420_cca(void) /* printf("cc2420_rssi: RSSI not valid.\n"); */ } - cca = CCA_IS_1; + cca = CC2420_CCA_IS_1; if(radio_was_off) { cc2420_off(); @@ -843,13 +839,13 @@ cc2420_cca(void) int cc2420_receiving_packet(void) { - return SFD_IS_1; + return CC2420_SFD_IS_1; } /*---------------------------------------------------------------------------*/ static int pending_packet(void) { - return FIFOP_IS_1; + return CC2420_FIFOP_IS_1; } /*---------------------------------------------------------------------------*/ void diff --git a/core/dev/cc2420.h b/core/dev/cc2420.h index 92bf1d843..b26e03715 100644 --- a/core/dev/cc2420.h +++ b/core/dev/cc2420.h @@ -28,7 +28,7 @@ * * This file is part of the Contiki operating system. * - * $Id: cc2420.h,v 1.9 2010/02/23 18:24:49 adamdunkels Exp $ + * $Id: cc2420.h,v 1.10 2010/06/23 10:15:28 joxe Exp $ */ /** @@ -36,13 +36,16 @@ * CC2420 driver header file * \author * Adam Dunkels + * Joakim Eriksson */ #ifndef __CC2420_H__ #define __CC2420_H__ #include "contiki.h" +#include "spi.h" #include "dev/radio.h" +#include "cc2420_const.h" int cc2420_init(void); @@ -52,8 +55,8 @@ void cc2420_set_channel(int channel); int cc2420_get_channel(void); void cc2420_set_pan_addr(unsigned pan, - unsigned addr, - const uint8_t *ieee_addr); + unsigned addr, + const uint8_t *ieee_addr); extern signed char cc2420_last_rssi; extern uint8_t cc2420_last_correlation; @@ -86,4 +89,102 @@ int cc2420_off(void); void cc2420_set_cca_threshold(int value); +/************************************************************************/ +/* Additional SPI Macros for the CC2420 */ +/************************************************************************/ +/* Send a strobe to the CC2420 */ +#define SPI_STROBE(s) \ + do { \ + CC2420_SPI_ENABLE(); \ + SPI_WRITE(s); \ + CC2420_SPI_DISABLE(); \ + } while (0) + +/* Write to a register in the CC2420 */ +/* Note: the SPI_WRITE(0) seems to be needed for getting the */ +/* write reg working on the Z1 / MSP430X platform */ +#define SPI_WRITE_REG(adr,data) \ + do { \ + CC2420_SPI_ENABLE(); \ + SPI_WRITE_FAST(adr); \ + SPI_WRITE_FAST((uint8_t)((data) >> 8)); \ + SPI_WRITE_FAST((uint8_t)(data & 0xff)); \ + SPI_WAITFORTx_ENDED(); \ + SPI_WRITE(0); \ + CC2420_SPI_DISABLE(); \ + } while(0) + +/* Read a register in the CC2420 */ +#define SPI_READ_REG(adr,data) \ + do { \ + CC2420_SPI_ENABLE(); \ + SPI_WRITE(adr | 0x40); \ + data = (uint8_t)SPI_RXBUF; \ + SPI_TXBUF = 0; \ + SPI_WAITFOREORx(); \ + data = SPI_RXBUF << 8; \ + SPI_TXBUF = 0; \ + SPI_WAITFOREORx(); \ + data |= SPI_RXBUF; \ + CC2420_SPI_DISABLE(); \ + } while(0) + +#define SPI_READ_FIFO_BYTE(data) \ + do { \ + CC2420_SPI_ENABLE(); \ + SPI_WRITE(CC2420_RXFIFO | 0x40); \ + (void)SPI_RXBUF; \ + SPI_READ(data); \ + clock_delay(1); \ + CC2420_SPI_DISABLE(); \ + } while(0) + +#define SPI_READ_FIFO_BUF(buffer,count) \ + do { \ + uint8_t i; \ + CC2420_SPI_ENABLE(); \ + SPI_WRITE(CC2420_RXFIFO | 0x40); \ + (void)SPI_RXBUF; \ + for(i = 0; i < (count); i++) { \ + SPI_READ(((uint8_t *)(buffer))[i]); \ + } \ + clock_delay(1); \ + CC2420_SPI_DISABLE(); \ + } while(0) + +#define SPI_WRITE_FIFO_BUF(buffer,count) \ + do { \ + uint8_t i; \ + CC2420_SPI_ENABLE(); \ + SPI_WRITE_FAST(CC2420_TXFIFO); \ + for(i = 0; i < (count); i++) { \ + SPI_WRITE_FAST(((uint8_t *)(buffer))[i]); \ + } \ + SPI_WAITFORTx_ENDED(); \ + CC2420_SPI_DISABLE(); \ + } while(0) + +/* Write to RAM in the CC2420 */ +#define SPI_WRITE_RAM(buffer,adr,count) \ + do { \ + uint8_t i; \ + CC2420_SPI_ENABLE(); \ + SPI_WRITE_FAST(0x80 | (adr & 0x7f)); \ + SPI_WRITE_FAST((adr >> 1) & 0xc0); \ + for(i = 0; i < (count); i++) { \ + SPI_WRITE_FAST(((uint8_t*)(buffer))[i]); \ + } \ + SPI_WAITFORTx_ENDED(); \ + CC2420_SPI_DISABLE(); \ + } while(0) + +/* Read status of the CC2420 */ +#define SPI_GET_STATUS(s) \ + do { \ + CC2420_SPI_ENABLE(); \ + SPI_WRITE(CC2420_SNOP); \ + s = SPI_RXBUF; \ + CC2420_SPI_DISABLE(); \ + } while (0) + #endif /* __CC2420_H__ */ diff --git a/core/dev/spi.h b/core/dev/spi.h index e8d8f0f08..c8ee20b7f 100644 --- a/core/dev/spi.h +++ b/core/dev/spi.h @@ -1,8 +1,44 @@ -/* -*- C -*- */ -/* @(#)$Id: spi.h,v 1.7 2010/03/15 23:01:37 nifi Exp $ */ +/* + * 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: spi.h,v 1.8 2010/06/23 10:15:28 joxe Exp $ + */ -#ifndef SPI_H -#define SPI_H +/** + * \file + * Basic SPI macros + * \author + * Joakim Eriksson + * Niclas Finne + */ + +#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 @@ -21,238 +57,36 @@ extern unsigned char spi_busy; void spi_init(void); -/****************************************************************************************************** -* TEXAS INSTRUMENTS INC., * -* MSP430 APPLICATIONS. * -* Copyright Texas Instruments Inc, 2004 * - *****************************************************************************************************/ +/* Write one character to SPI */ +#define SPI_WRITE(data) \ + do { \ + SPI_WAITFORTx_BEFORE(); \ + SPI_TXBUF = data; \ + SPI_WAITFOREOTx(); \ + } while(0) -/*********************************************************** - FAST SPI: Low level functions -***********************************************************/ +/* Write one character to SPI - will not wait for end + useful for multiple writes with wait after final */ +#define SPI_WRITE_FAST(data) \ + do { \ + SPI_WAITFORTx_BEFORE(); \ + SPI_TXBUF = data; \ + SPI_WAITFORTx_AFTER(); \ + } while(0) -#define FASTSPI_TX(x)\ - do {\ - SPI_WAITFORTx_BEFORE();\ - SPI_TXBUF = x;\ - SPI_WAITFORTx_AFTER();\ - } while(0) +/* Read one character from SPI */ +#define SPI_READ(data) \ + do { \ + SPI_TXBUF = 0; \ + SPI_WAITFOREORx(); \ + data = SPI_RXBUF; \ + } while(0) -#define FASTSPI_RX(x)\ - do {\ - SPI_TXBUF = 0;\ - SPI_WAITFOREORx();\ - x = SPI_RXBUF;\ - } while(0) - -#define FASTSPI_CLEAR_RX(x) do{ SPI_RXBUF; }while(0) - -#define FASTSPI_RX_GARBAGE()\ - do {\ - SPI_TXBUF = 0;\ - SPI_WAITFOREORx();\ - (void)SPI_RXBUF;\ - } while(0) - -#define FASTSPI_TX_MANY(p,c)\ - do {\ - u8_t spiCnt;\ - for (spiCnt = 0; spiCnt < (c); spiCnt++) {\ - FASTSPI_TX(((u8_t*)(p))[spiCnt]);\ - }\ - SPI_WAITFORTx_ENDED();\ - } while(0) +/* Flush the SPI read register */ +#define SPI_FLUSH() \ + do { \ + SPI_RXBUF; \ + } while(0); -#define FASTSPI_RX_WORD(x)\ - do {\ - SPI_TXBUF = 0;\ - SPI_WAITFOREORx();\ - x = SPI_RXBUF << 8;\ - SPI_TXBUF = 0;\ - SPI_WAITFOREORx();\ - x |= SPI_RXBUF;\ - } while (0) - -#define FASTSPI_TX_ADDR(a)\ - do {\ - SPI_TXBUF = a;\ - SPI_WAITFOREOTx();\ - } while (0) - -#define FASTSPI_RX_ADDR(a)\ - do {\ - SPI_TXBUF = (a) | 0x40;\ - SPI_WAITFOREOTx();\ - } while (0) - - - -/*********************************************************** - FAST SPI: Register access -***********************************************************/ -// s = command strobe -// a = register address -// v = register value - -#define FASTSPI_STROBE(s) \ - do {\ - SPI_ENABLE();\ - FASTSPI_TX_ADDR(s);\ - SPI_DISABLE();\ - } while (0) - -#define FASTSPI_SETREG(a,v)\ - do {\ - SPI_ENABLE();\ - FASTSPI_TX_ADDR(a);\ - FASTSPI_TX((u8_t) ((v) >> 8));\ - FASTSPI_TX((u8_t) (v));\ - SPI_WAITFORTx_ENDED();\ - SPI_DISABLE();\ - } while (0) - - -#define FASTSPI_GETREG(a,v)\ - do {\ - SPI_ENABLE();\ - FASTSPI_RX_ADDR(a);\ - v= (u8_t)SPI_RXBUF;\ - FASTSPI_RX_WORD(v);\ - clock_delay(1);\ - SPI_DISABLE();\ - } while (0) - -// Updates the SPI status byte - -#define FASTSPI_UPD_STATUS(s)\ - do {\ - SPI_ENABLE();\ - SPI_TXBUF = CC2420_SNOP;\ - SPI_WAITFOREOTx();\ - s = SPI_RXBUF;\ - SPI_DISABLE();\ - } while (0) - -/*********************************************************** - FAST SPI: FIFO Access -***********************************************************/ -// p = pointer to the byte array to be read/written -// c = the number of bytes to read/write -// b = single data byte - -#define FASTSPI_WRITE_FIFO(p,c)\ - do {\ - SPI_ENABLE();\ - u8_t i;\ - FASTSPI_TX_ADDR(CC2420_TXFIFO);\ - for (i = 0; i < (c); i++) {\ - FASTSPI_TX(((u8_t*)(p))[i]);\ - }\ - SPI_WAITFORTx_ENDED();\ - SPI_DISABLE();\ - } while (0) - -#define FASTSPI_WRITE_FIFO_NOCE(p,c)\ - do {\ - FASTSPI_TX_ADDR(CC2420_TXFIFO);\ - for (u8_t spiCnt = 0; spiCnt < (c); spiCnt++) {\ - FASTSPI_TX(((u8_t*)(p))[spiCnt]);\ - }\ - SPI_WAITFORTx_ENDED();\ - } while (0) - -#define FASTSPI_READ_FIFO_BYTE(b)\ - do {\ - SPI_ENABLE();\ - FASTSPI_RX_ADDR(CC2420_RXFIFO);\ - (void)SPI_RXBUF;\ - FASTSPI_RX(b);\ - clock_delay(1);\ - SPI_DISABLE();\ - } while (0) - - -#define FASTSPI_READ_FIFO_NO_WAIT(p,c)\ - do {\ - u8_t spiCnt;\ - SPI_ENABLE();\ - FASTSPI_RX_ADDR(CC2420_RXFIFO);\ - (void)SPI_RXBUF;\ - for (spiCnt = 0; spiCnt < (c); spiCnt++) {\ - FASTSPI_RX(((u8_t*)(p))[spiCnt]);\ - }\ - clock_delay(1);\ - SPI_DISABLE();\ - } while (0) - - - -#define FASTSPI_READ_FIFO_GARBAGE(c)\ - do {\ - u8_t spiCnt;\ - SPI_ENABLE();\ - FASTSPI_RX_ADDR(CC2420_RXFIFO);\ - (void)SPI_RXBUF;\ - for (spiCnt = 0; spiCnt < (c); spiCnt++) {\ - FASTSPI_RX_GARBAGE();\ - }\ - clock_delay(1);\ - SPI_DISABLE();\ - } while (0) - - - -/*********************************************************** - FAST SPI: CC2420 RAM access (big or little-endian order) -***********************************************************/ -// FAST SPI: CC2420 RAM access (big or little-endian order) -// p = pointer to the variable to be written -// a = the CC2420 RAM address -// c = the number of bytes to write -// n = counter variable which is used in for/while loops (u8_t) -// -// Example of usage: -// u8_t n; -// u16_t shortAddress = 0xBEEF; -// FASTSPI_WRITE_RAM_LE(&shortAddress, CC2420RAM_SHORTADDR, 2); - - -#define FASTSPI_WRITE_RAM_LE(p,a,c,n)\ - do {\ - SPI_ENABLE();\ - FASTSPI_TX(0x80 | (a & 0x7F));\ - FASTSPI_TX((a >> 1) & 0xC0);\ - for (n = 0; n < (c); n++) {\ - FASTSPI_TX(((u8_t*)(p))[n]);\ - }\ - SPI_WAITFORTx_ENDED();\ - SPI_DISABLE();\ - } while (0) - -#define FASTSPI_WRITE_RAM_BE(p,a,c,n) \ - do { \ - SPI_ENABLE(); \ - FASTSPI_TX(0x80 | (a & 0x7F)); \ - FASTSPI_TX((a >> 1) & 0xC0); \ - for (n = (c); n > 0; n--) { \ - FASTSPI_TX(((uint8_t *)(p))[n - 1]); \ - } \ - SPI_WAITFORTx_ENDED(); \ - SPI_DISABLE(); \ - } while (0) - -#define FASTSPI_READ_RAM_LE(p,a,c,n)\ - do {\ - SPI_ENABLE();\ - FASTSPI_TX(0x80 | (a & 0x7F));\ - FASTSPI_TX(((a >> 1) & 0xC0) | 0x20);\ - SPI_WAITFORTx_ENDED();\ - SPI_RXBUF;\ - for (n = 0; n < (c); n++) {\ - FASTSPI_RX(((u8_t*)(p))[n]);\ - }\ - SPI_DISABLE();\ - } while (0) - -#endif /* SPI_H */ +#endif /* __SPI_H__ */