⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cc2420.c

📁 MANTIS是由科罗拉多大学开发的传感器网络嵌入式操作系统。 这是mantis的0.9.5版本的源码。
💻 C
字号:
//  This file is part of MANTIS OS, Operating System//  See http://mantis.cs.colorado.edu/////  Copyright (C) 2003,2004,2005 University of Colorado, Boulder////  This program is free software; you can redistribute it and/or//  modify it under the terms of the mos license (see file LICENSE)#include "com.h"#include "mos.h"#include "spi.h"#if defined(PLATFORM_MICAZ) || defined(PLATFORM_TELOSB)#include <stdarg.h>#include "sem.h"#include "msched.h"#include "node_id.h"#include "mutex.h"#include "clock.h"#include "cc2420.h"#include "led.h"#include "bitops.h"#include "plat_dep.h"#include "printf.h"#if defined(CC2420) || !defined(SCONS)#define DEFAULT_CHANNEL 26static uint16_t pan_id = 0x2420;static uint16_t id;static uint8_t cc2420_com_mode;static comBuf *cc2420_recv_buf;  //receive buffer// NOT COMPLETE//#define CC2420_INTERRUPT_DRIVEN#ifdef CC2420_INTERRUPT_DRIVENstatic sem spi_sem;typedef void (*spi_state_f) (void);static Thread *spi_thread;static uint8_t current_state;static spi_state_f spi_state;void spi_state_init(void);void spi_state_idle(void);#define SPI_STATE_INIT 0#endifstatic inline void spi_rx_address(uint8_t addr){   SPI_TX_BUF = (addr) | 0x40;   SPI_WAIT_EOTX();}static void spi_strobe(uint8_t byte){   UNSET_PORT_1(CC2420_CHIP_SELECT);   spi_tx_byte(byte);   SET_PORT_1(CC2420_CHIP_SELECT);}void spi_set_register(uint8_t reg, uint16_t val){   UNSET_PORT_1(CC2420_CHIP_SELECT);   spi_tx_byte(reg);   spi_tx_byte((uint8_t)(val >> 8));   spi_tx_byte((uint8_t)(val));   SET_PORT_1(CC2420_CHIP_SELECT);}uint16_t spi_get_register(uint8_t reg){   uint16_t ret;   UNSET_PORT_1 (CC2420_CHIP_SELECT);   spi_rx_address(reg);   ret = spi_rx_word();   SET_PORT_1(CC2420_CHIP_SELECT);   return ret;}static uint8_t spi_update_status(void){   uint8_t ret;   UNSET_PORT_1(CC2420_CHIP_SELECT);   spi_tx_byte (CC2420_SNOP);   ret = SPI_RX_BUF;   SET_PORT_1(CC2420_CHIP_SELECT);   return ret;}static void spi_write_ram(void *addr, uint16_t radio_addr,			  uint8_t count){   uint8_t i;   UNSET_PORT_1(CC2420_CHIP_SELECT);   spi_tx_byte (0x80 | (radio_addr & 0x7F));   spi_tx_byte((radio_addr >> 1) & 0xC0);   for(i = 0; i < count; i++) {      spi_tx_byte(((uint8_t *)addr)[i]);   }   SET_PORT_1(CC2420_CHIP_SELECT);}static void spi_read_ram(void *addr, uint16_t radio_addr, uint8_t count){   uint8_t i;   UNSET_PORT_1(CC2420_CHIP_SELECT);   spi_tx_byte(0x80 | (radio_addr & 0x7F));   spi_tx_byte(((radio_addr >> 1) & 0xC0) | 0x20);   for(i = 0; i < count; i++) {      ((uint8_t *)addr)[i] = spi_rx();   }   SET_PORT_1(CC2420_CHIP_SELECT);}static void spi_write_fifo(void *addr, uint8_t count){   uint8_t i;   UNSET_PORT_1(CC2420_CHIP_SELECT);   spi_tx_byte(CC2420_TXFIFO);   for(i = 0; i < count; i++) {      spi_tx_byte(((uint8_t *)addr)[i]);   }   SET_PORT_1(CC2420_CHIP_SELECT);}static void spi_read_fifo(void *addr, uint8_t count){   uint8_t i;   UNSET_PORT_1(CC2420_CHIP_SELECT);   spi_rx_address(CC2420_RXFIFO);   for(i = 0; i < count; i++) {      while(!(PORT_IN(CC2420_FIFO_PORT) & CC2420_FIFO_PIN))	 ;      ((uint8_t *)addr)[i] = spi_rx();   }   SET_PORT_1(CC2420_CHIP_SELECT);}static void spi_read_fifo_garbage(uint8_t count){   uint8_t i;   UNSET_PORT_1(CC2420_CHIP_SELECT);   spi_rx_address(CC2420_RXFIFO);   for(i = 0; i < count; i++) {      spi_rx_garbage();   }   SET_PORT_1(CC2420_CHIP_SELECT);}static void spi_read_fifo_no_wait(void *addr, uint8_t count){   uint8_t i;   UNSET_PORT_1(CC2420_CHIP_SELECT);   spi_rx_address(CC2420_RXFIFO);   for(i = 0; i < count; i++) {      ((uint8_t *)addr)[i] = spi_rx();   }   SET_PORT_1(CC2420_CHIP_SELECT);}void cc2420_init(void){   handle_t int_handle;   id = mos_node_id_get();   int_handle = mos_disable_ints();#ifdef CC2420_INTERRUPT_DRIVEN   current_state = SPI_STATE_INIT;   spi_state = spi_state_init;   mos_sem_init(&spi_sem, 0);#endif      SET_DIR_2(CC2420_RESET, CC2420_VREG);   SET_PORT_1(CC2420_RESET);      SET_DIR_2(CC2420_MOSI, CC2420_SPI_CLOCK);   SET_DIR_1(CC2420_CHIP_SELECT);   SET_PORT_2(CC2420_MOSI, CC2420_SPI_CLOCK);   SET_PORT_1(CC2420_CHIP_SELECT);      UNSET_DIR_1(CC2420_CCA);   UNSET_DIR_1(CC2420_SFD);   UNSET_PORT_1(CC2420_SFD);      UNSET_DIR_1(CC2420_FIFO);   UNSET_DIR_1(CC2420_MISO);      PLAT_SPI_INIT();      // set the voltage regulator on, reset pin inactive   SET_PORT_1(CC2420_VREG);   mos_udelay(4000);   UNSET_PORT_1(CC2420_RESET);   mos_udelay(4);   SET_PORT_1(CC2420_RESET);   mos_udelay(20);      PLAT_ENABLE_FIFOP_INT();      UNSET_DIR_1(CC2420_FIFOP);   UNSET_PORT_1(CC2420_FIFOP);#ifndef CC2420_INTERRUPT_DRIVEN   spi_strobe(CC2420_SXOSCON);   // turn on automatic packet ack   //spi_set_register (CC2420_MDMCTRL0, 0x0AF2);   // no auto ack   //printf("before set reg\n");   spi_set_register(CC2420_MDMCTRL0, 0x02E2);//   printf("CC2420_INIT: MDMCTRL0 = %x\n", spi_get_register(CC2420_MDMCTRL0));      /*   mos_enable_ints(int_handle);   uint16_t val = spi_get_register(CC2420_MDMCTRL0);   printf("CC2420_MDMCTRL0 = %x\n", val);   int_handle = mos_disable_ints();   */      //spi_set_register (CC2420_MDMCTRL0, 0x12F2);   // set correlation threshold = 20   spi_set_register(CC2420_MDMCTRL1, 0x0500);   // set fifop threshold to max   spi_set_register(CC2420_IOCFG0, 0x007F);   // turn off security   spi_set_register(CC2420_SECCTRL0, 0x01C4);      // set the channel   cc2420_set_channel(DEFAULT_CHANNEL);         // wait for the oscillator   //printf("before osc\n");   cc2420_wait_for_osc();   //printf("after osc\n");      spi_write_ram(&id, CC2420RAM_SHORTADDR, sizeof(id));   spi_write_ram(&pan_id, CC2420RAM_PANID, sizeof(pan_id));   #else   spi_thread = mos_thread_current();#endif      // start out with a free com buf   com_swap_bufs(IFACE_RADIO, NULL, &cc2420_recv_buf);   // set initial com mode   cc2420_com_mode = IF_OFF;   spi_strobe(CC2420_SFLUSHRX);   spi_strobe(CC2420_SFLUSHTX);   mos_enable_ints(int_handle);     // if we are interrupt driven, wait for the #ifdef CC2420_INTERRUPT_DRIVEN   mos_thread_suspend();#endif}//#endifvoid cc2420_wait_for_osc(void){   uint8_t status_byte;   do {      status_byte = spi_update_status();   } while(!(status_byte & (1 << CC2420_XOSC16M_STABLE)));}void cc2420_set_channel(uint8_t chan){   uint16_t c;   c = (uint16_t)(chan - 11);   c = c + (c << 2);   c = c + 357;   c = c + 0x4000;      handle_t int_handle = mos_disable_ints();   spi_set_register(CC2420_FSCTRL, c);   mos_enable_ints(int_handle);}void com_ioctl_IFACE_RADIO(uint8_t request, ...){   int arg;   va_list ap;   va_start(ap, request);   arg = va_arg(ap, int);      switch(request) {      //case CC2420_USE_ACK:      //break;   default:      break;   }   va_end(ap);      return;}void com_mode_IFACE_RADIO(uint8_t md){   handle_t int_handle;      switch(md) {   case IF_OFF:      int_handle = mos_disable_ints();      //disable FIFOP (receive) interrupt      UNMASK_1(EIMSK, CC2420_FIFOP_PIN);      //turn off radio      spi_strobe(CC2420_SRFOFF);      mos_enable_ints(int_handle);      cc2420_com_mode = md;      break;   case IF_STANDBY:      break;   case IF_IDLE:      break;   case IF_LISTEN:      int_handle = mos_disable_ints();      //enable FIFOP (receive) interrupt      MASK_1(EIMSK, CC2420_FIFOP_PIN);      //power up radio      spi_strobe(CC2420_SRXON);      spi_strobe(CC2420_SFLUSHRX);      mos_enable_ints(int_handle);      //cc2420_com_mode = md;      cc2420_com_mode = CC2420_MODE_RX;      break;   }   return;}uint8_t com_send_IFACE_RADIO (comBuf *buf){   handle_t int_handle;   uint8_t status;   // 11 bytes overhead for header   int8_t len = buf->size + 11;   // noack frame control field   uint16_t fcf = 0x8841;   // ack frame control field   //uint16_t fcf = 0x8861;   static uint8_t seq = 0;   uint16_t dest_addr = 0x1234;   while(PORT_IN(CC2420_SFD_PORT) & (1 << CC2420_SFD_PIN) ||	 PORT_IN(CC2420_FIFOP_PORT) & (1 << CC2420_FIFOP_PIN))      ;      int_handle = mos_disable_ints();   spi_strobe(CC2420_SFLUSHTX);      // turn on receiver if necessary   //if (cc2420_com_mode != CC2420_MODE_RX) {   spi_strobe(CC2420_SRXON);   //}      // wait for RSSI   do {      status = spi_update_status();      //mos_udelay(0x1fff);   } while(!(status & (1 << CC2420_RSSI_VALID)));   // fill up the fifo with the frame format   spi_write_fifo(&len, sizeof(len));   spi_write_fifo(&fcf, sizeof(fcf));   spi_write_fifo(&seq, sizeof(seq));   spi_write_fifo(&pan_id, sizeof(pan_id));   spi_write_fifo(&dest_addr, sizeof(dest_addr));   spi_write_fifo(&id, sizeof(id));   spi_write_fifo(buf->data, buf->size);   // wait for transmission   do {      spi_strobe(CC2420_STXONCCA);      status = spi_update_status();      mos_udelay(100);   } while(!(status & (1 << CC2420_TX_ACTIVE)));   /*   uint8_t mem;   uint16_t fcf2;   spi_read_ram(&mem, 0x0, 1);   spi_read_ram(&fcf2, 0x01, 2);   */      while(!(PORT_IN(CC2420_SFD_PORT) & (1 << CC2420_SFD_PIN)))      ;   //printf("sfd set\n");      if(cc2420_com_mode != CC2420_MODE_RX) {      int_handle = mos_disable_ints();      spi_strobe(CC2420_SRFOFF);      printf("srfoff is set\n");      mos_enable_ints(int_handle);   }   seq++;      //printf("returning from send\n");   return 0;}#ifdef CC2420_INTERRUPT_DRIVENstatic uint8_t spi_init[] ARCH_PROGMEM = {   CC2420_SXOSCON,   CC2420_MDMCTRL0, 0x02E2 >> 8, 0x02E2 & 0xff,   CC2420_MDMCTRL1, 0x0500 >> 8, 0x0500 & 0xff,   CC2420_IOCFG0,   0x007F >> 8, 0x007F & 0xff,   CC2420_SECCTRL0, 0x01C4 >> 8, 0x01C4 & 0xff,   0};static uint8_t spi_i;static uint8_t spi_data;void spi_state_init(void){   switch(current_state) {   case SPI_STATE_INIT:      if((spi_data = pgm_read_byte(&spi_init[spi_i++])) != 0) {	 /*SPDR*/ SPI_TX_BUF = spi_data;      } else {	 spi_state = spi_state_idle;	 mos_thread_resume(spi_thread);      }      break;   }}void spi_state_idle(void){   }SIGNAL (SIG_SPI){   spi_state();}#endifCC2420_FIFOP_INTERRUPT(){#ifdef PLATFORM_TELOSB   // clear interrupt flag   P1IFG &= ~(1 << 0);#endif   uint8_t len;   uint16_t fcf;   uint8_t seq;   uint16_t addr;      // exit on overflow, indicated by FIFOP == 1 and FIFO == 0   if((PORT_IN(CC2420_FIFOP_PORT) & (1 << CC2420_FIFOP_PIN)) &&      !(PORT_IN(CC2420_FIFO_PORT) & (1 << CC2420_FIFO_PIN))) {      // not sure why there are two of these... (from example code)      spi_strobe(CC2420_SFLUSHRX);      spi_strobe(CC2420_SFLUSHRX);      return;   }   spi_read_fifo(&len, sizeof(len));   // mask out msb   len &= 0x7f;   if(len < 5) {      spi_read_fifo_garbage(len);      return;   }   spi_read_fifo_no_wait(&fcf, sizeof(fcf));   spi_read_fifo(&seq, sizeof(seq));   if(len == 5) {      // could be an ack packet      spi_read_fifo_garbage(len);      return;   } else if(len < 11) {      // packet is too short, discard      spi_read_fifo_garbage(len);      return;   } else {      // make sure we have a com buf      if(!cc2420_recv_buf) {	 com_swap_bufs(IFACE_RADIO, NULL, &cc2420_recv_buf);	 if(!cc2420_recv_buf) {	    return;	 }      }      cc2420_recv_buf->size = len - 11;      // skip the dest PAN addr (taken care of by hw addr recognition)      spi_read_fifo_garbage(4);      spi_read_fifo_no_wait(&addr, sizeof(addr));      spi_read_fifo_no_wait(cc2420_recv_buf->data, cc2420_recv_buf->size);          // skip over RSSI for now      spi_read_fifo_garbage(2);      com_swap_bufs(IFACE_RADIO, cc2420_recv_buf, &cc2420_recv_buf);               }}#endif#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -