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

📄 evboard.c

📁 zigbee 协议堆栈 stack(简化协议)
💻 C
📖 第 1 页 / 共 2 页
字号:
/*
  V0.1 Initial Release   10/July/2006  RBR
  V0.1 Port over TMote   29/December/2006  RS

  V0.1.2.1
  7/17/2006 Fixed problem with maximum length packet (0x7F) 
    reception in interrupt service function. Was checking for overflow,
  when I should not have been, since the RX fifo is flushed after
  reception anyway.  RBR.

  V0.2.2.  
  8/2/2006 Fixed problem with checking of CRC byte.  RBR

  V0.2.3
   8/15/2006 Changed halSendPacket() packet so that TX FIFO is loaded
 before STXONCCA is done.

 V.02.3.4 
 Made change in halInitRadio() with regards to the CC2420_IOCFG0 if
 dynamic PANIDs are used to accept all BCN frames

*/

#include "compiler.h"
#include "lrwpan_common_types.h"
#include "ieee_lrwpan_defs.h"
#include "hal.h"
#include "halStack.h"
#include "debug.h"
#include "evboard.h"
#include "cc2420.h"
#include "memalloc.h"
#include "console.h"
#include "phy.h"
#include "mac.h"
#include "neighbor.h"

RADIO_FLAGS local_radio_flags;
EVB_SW_STATE sw_state;

static UINT16 random_seed;
void evbInitRandomSeed(void);

static void init_ports(void) {
/* Turn everything off, device drivers are supposed to enable what is
 * really needed!
 */

/* All configured for digital I/O */
#ifdef P1SEL
  P1SEL = 0;
#endif
#ifdef P2SEL
  P2SEL = 0;
#endif
#ifdef P3SEL
  P3SEL = 0;
#endif
#ifdef P4SEL
  P4SEL = 0;
#endif
#ifdef P5SEL
  P5SEL = 0;
#endif
#ifdef P6SEL
  P6SEL = 0;
#endif

/* All available inputs */
#ifdef P1DIR
  P1DIR = 0;
  P1OUT = 0;
#endif
#ifdef P2DIR
  P2DIR = 0;
  P2OUT = 0;
#endif
#ifdef P3DIR
  P3DIR = 0;
  P3OUT = 0;
#endif
#ifdef P4DIR
  P4DIR = 0;
  P4OUT = 0;
#endif

#ifdef P5DIR
  P5DIR = 0;
  P5OUT = 0;
#endif

#ifdef P6DIR
  P6DIR = 0;
  P6OUT = 0;
#endif
  P1IE = 0;
  P2IE = 0;
}

//not yet implemented...called from ISR of slow timer
//see evboard.h for more stuff about switches
void evbIntCallback(void){
//poll the switches
}

//switched aren't yet implemented...see above
void evbPoll(void){
//only do this if the slow timer not enabled since
//the slowtimer interrupt will handle the polling
#ifndef LRWPAN_ENABLE_SLOW_TIMER
// poll the switches
#endif
}

//init Tmote Sky
void evbInit(void){
   local_radio_flags.val = 0;
   
   init_ports();
   evbInitRandomSeed();

   LED_CONFIG();
   cc2420_init();
}

void evbLedSet(BYTE lednum, BOOL state) {
    switch(lednum) {
       case 1:    if (state) led_red_on(); else led_red_off(); break;
       case 2:    if (state) led_green_on(); else led_green_off(); break;
       case 3:    if (state) led_blue_on(); else led_blue_on(); break;
    }
}

BOOL evbLedGet(BYTE lednum){
 switch(lednum) {
       case 1:    return(led_red_state());
       case 2:    return(led_green_state());
       case 3:    return(led_blue_state());
    }
  return FALSE;
}

//since PIC18 architecture has no good way of doing RANDOM nums, put this
//in the evboard file.

//random_seed variable is unitialized on purpose in RAM
//personalize random_seed by MAC address and TimerA value
void evbInitRandomSeed(void) {
  random_seed = random_seed ^ (TAR & 0xFF) ^ aExtendedAddress_B0;
  random_seed = random_seed << 8;
  random_seed = random_seed ^ (TAR & 0xFF) ^ aExtendedAddress_B1;
  if (random_seed == 0) {
  	random_seed = (TAR & 0xFF00);
    random_seed = random_seed << 8;
    random_seed = random_seed | (TAR & 0xFF);
  }
}

UINT8 halGetRandomByte(void) {

     BYTE bit;
     
     bit = 0;
     if (random_seed & 0x8000) bit = bit ^ 1;
     if (random_seed & 0x4000) bit = bit ^ 1;
     if (random_seed & 0x1000) bit = bit ^ 1;
     if (random_seed & 0x0008) bit = bit ^ 1;
     
     random_seed = random_seed << 1;
     if (bit) random_seed++;
     return(random_seed & 0xFF);  
}


/*********************** RADIO stuff ******************************/
//Set up PANID
void halSetRadioPANID(UINT16 panid){ 
	
  	UINT8 n,intStatus;
  
  	SAVE_AND_DISABLE_GLOBAL_INTERRUPT(intStatus);
   	FASTSPI_WRITE_RAM_LE(&panid, CC2420RAM_PANID, 2, n);
  	RESTORE_GLOBAL_INTERRUPT(intStatus);
  	
 	DEBUG_STRING(DBG_INFO,"RadioPanID: ");
   	DEBUG_UINT16(DBG_INFO,panid);
    DEBUG_STRING(DBG_INFO,"\n");
}

//Set up short address
void halSetRadioShortAddr(SADDR saddr){
	
   	UINT8 n,intStatus;
   	
   	SAVE_AND_DISABLE_GLOBAL_INTERRUPT(intStatus) ;
   	FASTSPI_WRITE_RAM_LE(&saddr, CC2420RAM_SHORTADDR, 2, n);
   	RESTORE_GLOBAL_INTERRUPT(intStatus); 
}

//Set up IEEE address
void halSetRadioIEEEAddress(void) {
	
 	UINT8 n,intStatus;
  	BYTE buf[8];

 	halGetProcessorIEEEAddress(buf);
 	SAVE_AND_DISABLE_GLOBAL_INTERRUPT(intStatus) ;
 	FASTSPI_WRITE_RAM_LE(&buf[0], CC2420RAM_IEEEADDR, 8, n);
 	RESTORE_GLOBAL_INTERRUPT(intStatus); 
}

//TODO
void halRfWaitForCrystalOscillator(void) {
	
    BYTE spiStatusByte,intStatus;

} // halRfWaitForCrystalOscillator

//Disable CC2420
void halDisableRadio(void) {
	
  	DISABLE_FIFOP_INT();
 	SET_VREG_INACTIVE();
  	SET_RESET_ACTIVE();
  	halWaitMs(10);
}

//Set up channel
LRWPAN_STATUS_ENUM halSetChannel(BYTE channel) {
	
    UINT16 f,intStatus;

	// Derive frequency programming from the given channel number
	f = (UINT16) (channel - 11); // Subtract the base channel 
	f = f + (f << 2);    		 // Multiply with 5, which is the channel spacing
	f = f + 357 + 0x4000;		 // 357 is 2405-2048, 0x4000 is LOCK_THR = 1
	
    // Write it to the CC2420
	SAVE_AND_DISABLE_GLOBAL_INTERRUPT(intStatus);
	FASTSPI_SETREG(CC2420_FSCTRL, f);
    RESTORE_GLOBAL_INTERRUPT(intStatus);
    
  	return(LRWPAN_STATUS_SUCCESS);
}

//this is a desperation move to restart a stuck radio
//called by the SendPacket
void halResetRadio(void){
  
  	SET_VREG_INACTIVE();
  	halWaitMs(10);
  	
  	halInitRadio(phy_pib.phyCurrentFrequency, phy_pib.phyCurrentChannel, local_radio_flags);
 	//write our PANID, our short address
 	halSetRadioPANID(mac_pib.macPANID);
 	halSetRadioShortAddr(macGetShortAddr());
}

//Main init of CC2420
#define CRYSTAL_TIMEOUT 100  //in ms
LRWPAN_STATUS_ENUM halInitRadio(PHY_FREQ_ENUM frequency, BYTE channel, RADIO_FLAGS radio_flags) {
	
	BYTE intStatus;
    UINT8 tmp;
    UINT32 start_tick;
    BYTE spiStatusByte;

  	// Make sure that the voltage regulator is on, and that the reset pin is inactive
    SET_RESET_ACTIVE();
    SET_VREG_ACTIVE();
    halWaitMs(1);   
    SET_RESET_INACTIVE();
    halWaitUs(10);

    SAVE_AND_DISABLE_GLOBAL_INTERRUPT(intStatus) ;
  
    // Register modifications  
    // Poll the SPI status byte until the crystal oscillator is stable
    start_tick = halGetMACTimer();
    do {
    	halGetRandomByte(); //shift the LFSR to try to make PANID more random
	    FASTSPI_STROBE(CC2420_SXOSCON);
	    FASTSPI_UPD_STATUS(spiStatusByte);
          if (! (!(spiStatusByte & (BM(CC2420_XOSC16M_STABLE))))) break;	   
    } while (halMACTimerNowDelta(start_tick) < MSECS_TO_MACTICKS(CRYSTAL_TIMEOUT));

    if (!(spiStatusByte & (BM(CC2420_XOSC16M_STABLE)))) {
    	DEBUG_STRING(DBG_ERR,"halInitRadio: Crystal failed to stabilize\n");
        RESTORE_GLOBAL_INTERRUPT(intStatus); 
        
        return(LRWPAN_STATUS_PHY_RADIO_INIT_FAILED);
    }

#define PAN_COORDINATOR 0x10
#define ADR_DECODE      0x08
#define AUTO_CRC        0x20
#define AUTO_ACK        0x10

   	// set some registers
  	SPI_ENABLE();
 	// with auto ack, auto_crc, pan_coor, the MDMCTRL0 reg should be a value of 0x1AF2
  	// high byte MDCTRL0
        
    FASTSPI_TX_ADDR(CC2420_MDMCTRL0);
    
    //first, MSB
    tmp = 0x02;      //CCA hystersis, mid range
    if (radio_flags.bits.pan_coordinator) {
       tmp = tmp | PAN_COORDINATOR;
    }
    
    if (!radio_flags.bits.listen_mode) {
    	// Turning on Address Decoding
        tmp = tmp | ADR_DECODE;
    }
    FASTSPI_TX(tmp);
    
    //now, LSB
    tmp = 0xC2;   
    if (!radio_flags.bits.listen_mode) {
       //turn on autoCRC and autoACK, address decode
       tmp = tmp | AUTO_CRC | AUTO_ACK ;
    } 
    FASTSPI_TX(tmp);
   
    SPI_DISABLE();
    local_radio_flags = radio_flags;   //save these if we need to do a reset

    //set the rest
    FASTSPI_SETREG(CC2420_MDMCTRL1, 0x0500); // Set the correlation threshold = 20
#ifdef LRWPAN_COORDINATOR
    FASTSPI_SETREG(CC2420_IOCFG0, 0x007F);   // Set the FIFOP threshold to maximum
#else

#ifdef LRWPAN_USE_STATIC_PANID
 	FASTSPI_SETREG(CC2420_IOCFG0, 0x007F);   // Set the FIFOP threshold to maximum
#else
 	FASTSPI_SETREG(CC2420_IOCFG0, 0x087F);   // Set the FIFOP threshold to maximum, received all BCN frames
#endif
#endif

    FASTSPI_SETREG(CC2420_SECCTRL0, 0x01C4); // Turn off "Security enable"

    //have to set our Long address
    halSetRadioIEEEAddress();

    // Set the RF channel
    halSetChannel(channel);

    DEBUG_STRING(DBG_INFO, "Radio configured\n");
    
    //enable the receive
	FASTSPI_STROBE(CC2420_SRXON);

⌨️ 快捷键说明

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