?? zphycc2420.c
字號:
/*********************************************************************
*
* Zigbee PHY layer using CC2420
* (Not completely impelemented in Rel 1.0)
*
*********************************************************************
* FileName: zPHYCC2420.c
* Dependencies:
* Processor: PIC18F
* Complier: MCC18 v2.30 or higher
* HITECH PICC-18 V8.10PL1 or higher
* Company: Microchip Technology, Inc.
*
* Software License Agreement
*
* The software supplied herewith by Microchip Technology Incorporated
* (the 揅ompany? for its PICmicro?Microcontroller is intended and
* supplied to you, the Company抯 customer, for use solely and
* exclusively on Microchip PICmicro Microcontroller products. The
* software is owned by the Company and/or its supplier, and is
* protected under applicable copyright laws. All rights are reserved.
* Any use in violation of the foregoing restrictions may subject the
* user to criminal sanctions under applicable laws, as well as to
* civil liability for the breach of the terms and conditions of this
* license.
*
* THIS SOFTWARE IS PROVIDED IN AN 揂S IS?CONDITION. NO WARRANTIES,
* WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT NOT LIMITED
* TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. THE COMPANY SHALL NOT,
* IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL OR
* CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
*
*
* Author Date Comment
*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
* Nilesh Rajbharti 7/12/04 Rel 0.9
* Nilesh Rajbharti 11/1/04 Pre-release version
********************************************************************/
// Uncommnt ENABLE_DEBUG line to enable debug mode for this file.
// Or you may also globally enable debug by defining this macro
// in zigbee.def file or from compiler command-line.
#ifndef ENABLE_DEBUG
//#define ENABLE_DEBUG
#endif
#include "zigbee.h"
#include "zPHY.h"
#include "zPHYCC2420.h"
#if defined(WIN32)
#include "physim.h"
#endif
/*
* PA_LEVEL determiens output power of transciever
* According to Table 9 of CC2420 datasheet
*
* PA_LEVEL (TXCTRL.LSB) Output Power (dBm) Current Consumtiion
* ====================================================================
* 0xFF 0 17.4 mA
* 0xFB -1 16.5 mA
* 0xF7 -3 15.2 mA
* 0xF3 -5 13.9 mA
* 0xEF -7 12.5 mA
* 0xEB -10 11.2 mA
* 0xE7 -15 9.9 mA
* 0xE3 -25 8.5 mA
*/
#define PA_LEVEL (0xFF) // Select one of the above as per your requirement.
BYTE currentChannel;
/*********************************************************************
* Function: BOOL PHYInit(void)
*
* PreCondition: None
*
* Input: None
*
* Output: TRUE if the PHY was successfully initialized
* FALSE if the PHY malfunctioned. Power cycling
* the PHY and calling PHYInit again might be
* worthwhile.
*
* Side Effects: None
*
* Overview: PHY is initialized
*
* Note: None
********************************************************************/
void Delay(WORD i)
{
while( i-- );
}
BOOL PHYInit(void)
{
typedef union _PHY_STATUS
{
struct
{
unsigned int :1;
unsigned int RSSI_VALID : 1;
unsigned int LOCK : 1;
unsigned int TX_ACTIVE : 1;
unsigned int ENC_BUSY : 1;
unsigned int TX_UNDERFLOW : 1;
unsigned int XOSC16M_STABLE : 1;
} bits;
BYTE Val;
} PHY_STATUS;
PHY_STATUS phyStatus;
BYTE AttemptCount;
/*
* Do soft reset of the the chip
*/
// TODO: Use optimum delay.
PHY_RESET(0);
Delay(1000);
PHY_RESET(1);
Delay(500);
// Switch oscillator ON here and do other things in parallel
// while oscillator stabilizes.
PHYBegin();
PHYPut(STROBE_SXOSCON);
PHYEnd();
PHYBegin();
/*
* For MDMCTRL0, we will accept the default settings of most bits except
* that we need to do AutoACK
*/
PHYPut(REG_MDMCTRL0);
// Set AUTOACK bit in MDMCTRL0 register.
// 15:14 = '00' = Reserved
// 13 = '0' = Reserved frames are rejected
// 12 = '?' = '1' if this is coordinator, '0' if otherwise
// 11 = '1' = Address decoding is enabled
// 10:8 = '010' = CCA Hysteresis in DB - default value
// 7:6 = '11' = CCA = 1, when RSSI_VAL < CCA_THR - CCA_HYST and not receiving valid IEEE 802.15.4 data
// 5 = '1' = Auto CRC
// 4 = '1' = Auto ACK
// 3:0 = '0010' = 3 leading zero bytes - IEEE compliant.
#if defined(I_AM_COORDINATOR)
// MSB = 0b0001 1010
PHYPut(0x1A);
#else
// MSB = 0b0000 1010
PHYPut(0x0A);
#endif
// LSB = 0b1111 0010
PHYPut(0xf2);
PHYEnd();
/*
*
*/
/*
* For MDMCTRL1, set CORR_THR to 20.
*/
PHYBegin();
PHYPut(REG_MDMCTRL1);
PHYPut(0x05); // MSB
PHYPut(0x00); // LSB
PHYEnd();
/*
*
*/
PHYBegin(); // Disable MAC security
PHYPut(REG_SECCTRL0);
PHYPut(0x01); // MSB
PHYPut(0xC4); // LSB
PHYEnd();
// Select desired TX output power level
PHYBegin();
PHYPut(REG_TXCTRL);
// As defined by Table 9 of CC2420 datasheet.
PHYPut(0xA); // MSB
PHYPut(PA_LEVEL); // LSB
PHYEnd();
// Set FIFOP threshold to full RXFIFO buffer
PHYBegin();
PHYPut(REG_IOCFG0);
PHYPut(0x00);
PHYPut(0x7F);
PHYEnd();
// Turn on oscillator
PHYBegin();
AttemptCount = 100;
do // Wait for stable oscillator.
{
// Execute NOP to read the status.
PHYPut(STROBE_SNOP);
phyStatus.Val = PHYGet();
#if defined(WIN32)
phyStatus.bits.XOSC16M_STABLE = 1;
#endif
} while( phyStatus.bits.XOSC16M_STABLE == 0 && --AttemptCount);
PHYPut(STROBE_SFLUSHTX);
PHYPut(STROBE_SFLUSHRX);
PHYEnd();
return AttemptCount != 0;
}
/*********************************************************************
* Function: void PHYSetTxPower(BYTE val)
*
* PreCondition: None
*
* Input: val - Power level as described above
*
* Output: None
*
* Side Effects: None
*
* Overview: Changes transmit output power as per given value
*
* Note: None
********************************************************************/
void PHYSetTxPower(BYTE val)
{
// Select desired TX output power level
PHYBegin();
PHYPut(REG_TXCTRL);
// As defined by Table 9 of CC2420 datasheet.
PHYPut(0xA); // MSB
PHYPut(val); // LSB
PHYEnd();
}
/*********************************************************************
* Function: BOOL PHYProcessRxOverflow(void)
*
* PreCondition: PHYInit() is called
*
* Input: None
*
* Output: None
*
* Side Effects: None
*
* Overview: Chedks for receive overflow and clears as per
* RF chip specific procedure
*
* Note: None
********************************************************************/
BOOL PHYProcessRxOverflow(void)
{
BYTE v;
// Check to see if there was an overflow.
if ( PHY_FIFO == 0 && PHY_FIFOP == 1 )
{
// As per CC2420, overflow would be handled by
// reading at least one RX byte and then issuing
// RX FLUSH command.
PHYBegin();
// Select RX FIFO.
PHYSelectRxFIFO();
// Read one byte.
v = PHYGet();
// End of dummy read sequence.
PHYEnd();
// Start RX flush sequence
PHYBegin();
// Now issue SFLUSHRX command
PHYFlushRx();
PHYEnd();
return TRUE;
}
return FALSE;
}
/*********************************************************************
* Function: BYTE CC2420GetStatus(void)
*
* PreCondition: None
*
* Input: None
*
* Output: Status byte of CC2420
*
* Side Effects: None
*
* Overview: None
*
* Note: None
********************************************************************/
BYTE CC2420GetStatus(void)
{
BYTE v;
PHYBegin();
v = PHYGet();
PHYEnd();
return v;
}
/*********************************************************************
* Function: BOOL PHYSetNextChannel(void)
*
* PreCondition: None
*
* Input: None
*
* Output: TRUE if next channel was selected
* FALSE, if top channel is reached.
*
* Side Effects: None
*
* Overview: None
*
* Note: None
********************************************************************/
BOOL PHYSetNextChannel(void)
{
// If we reach upper end of available channels, tell app about it.
if ( currentChannel == 26 )
return FALSE;
// We can still go up next channel.
currentChannel++;
PHYSetChannel(currentChannel);
return TRUE;
}
/*********************************************************************
* Function: void PHYSetChannel(BYTE channel)
*
* PreCondition: None
*
* Input: channel - Channel number to set (Must be 11 - 26)
*
* Output: None
*
* Side Effects: None
*
* Overview: None
*
* Note: None
********************************************************************/
void PHYSetChannel(BYTE channel)
{
currentChannel = channel;
PHYBegin();
PHYPut(REG_FSCTRL);
PHYPut(0x41); // LOCK_THR = 1 as recommended, with bit 8 = 1 for MSb of FREQ value
PHYPut((channel-11)*5+101); // Create raw LSB for given channel
PHYEnd();
}
/*********************************************************************
* Function: BYTE PHYGetED(void)
*
* PreCondition: TXON = TRUE
*
* Input: None
*
* Output: 0x00 - 0xff energy level on current channel
*
* Side Effects: None
*
* Overview: None
*
* Note: None
********************************************************************/
BYTE PHYGetED(void)
{
BYTE val;
PHYBegin();
PHYPut(REG_RSSI | CMD_READ);
// Read the value
val = PHYGet();
PHYEnd();
return val;
}
/*********************************************************************
* Function: void PHYSetTRXState(PHY_TRX_STATE state)
*
* PreCondition: PHYInit() is called.
*
* Input: state - State to set
*
* Output: None
*
* Side Effects: None
*
* Overview: None
*
* Note: None
********************************************************************/
void PHYSetTRXState(PHY_TRX_STATE state)
{
PHYBegin();
if ( state == PHY_TRX_RX_ON )
{
PHYPut(STROBE_SRXON);
}
else if ( state == PHY_TRX_OFF || state == PHY_TRX_FORCE_OFF )
{
PHYPut(STROBE_SRFOFF);
}
else if ( state == PHY_TRX_TX_ON )
{
PHYPut(STROBE_STXON);
}
PHYEnd();
}
// A temp function to work around CC2420 bug.
// Called by MAC when required.
void PHYEnableRxFilter(BOOL bEnable)
{
PHYBegin();
/*
* For MDMCTRL0, we will accept the default settings of most bits except
* that we need to do AutoACK
*/
PHYPut(REG_MDMCTRL0);
// Set AUTOACK bit in MDMCTRL0 register.
// 15:14 = '00' = Reserved
// 13 = '0' = Reserved frames are rejected
// 12 = '?' = '1' if this is coordinator, '0' if otherwise
// 11 = '1' = Address decoding is enabled
// 10:8 = '010' = CCA Hysteresis in DB - default value
// 7:6 = '11' = CCA = 1, when RSSI_VAL < CCA_THR - CCA_HYST and not receiving valid IEEE 802.15.4 data
// 5 = '1' = Auto CRC
// 4 = '1' = Auto ACK
// 3:0 = '0010' = 3 leading zero bytes - IEEE compliant.
#if defined(I_AM_COORDINATOR)
// MSB = 0b0001 1010
if ( bEnable )
{
PHYPut(0x1A);
}
else
{
PHYPut(0x12);
}
#else
if ( bEnable )
{
// MSB = 0b0000 1010
PHYPut(0x0A);
}
else
{
PHYPut(0x02);
}
#endif
// LSB = 0b1111 0010
PHYPut(0xf2);
PHYEnd();
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -