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

📄 xe1205phyrssiconfp.nc

📁 tinyos-2.x.rar
💻 NC
字号:
/* 
 * Copyright (c) 2006, Ecole Polytechnique Federale de Lausanne (EPFL),
 * Switzerland.
 * All rights reserved.
 *
 * 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 the Ecole Polytechnique Federale de Lausanne (EPFL) 
 *   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 COPYRIGHT HOLDERS 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 COPYRIGHT
 * OWNER 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.
 *
 * ========================================================================
 */

/*
 * Implementation of XE1205PhyConf and XE1205RssiConf interfaces.
 * These are implemented jointly because the rssi measure period depends 
 * on the frequency deviation (which itself depends on bitrate).
 *
 * @author Henri Dubois-Ferriere
 */


module XE1205PhyRssiConfP {

    provides interface XE1205PhyConf;
    provides interface XE1205RssiConf;
    provides interface Init @atleastonce();

    uses interface Resource as SpiResource;
    uses interface XE1205Register as MCParam0;
    uses interface XE1205Register as MCParam1;
    uses interface XE1205Register as MCParam2;
    uses interface XE1205Register as MCParam3;
    uses interface XE1205Register as MCParam4;
    uses interface XE1205Register as TXParam7;
    uses interface XE1205Register as RXParam8;
    uses interface XE1205Register as RXParam9;
}
implementation {
#include "xe1205debug.h"

    /* 
     * Default settings for initial parameters. 
     */ 
#ifndef XE1205_BITRATE_DEFAULT
#define XE1205_BITRATE_DEFAULT  76170
#endif
    //xxx/make this computed as a fun of XE1205_BITRATE_DEFAULT
#ifndef XE1205_FREQDEV_DEFAULT
#define XE1205_FREQDEV_DEFAULT  100000
#endif


    /*
     * Register calculation helper macros.
     */
#define XE1205_FREQ(value_)                     (((value_) * 100) / 50113L)
#define XE1205_EFFECTIVE_FREQ(value_)           (((int32_t)((int16_t)(value_)) * 50113L) / 100)
#define XE1205_FREQ_DEV_HI(value_)              ((XE1205_FREQ(value_) >> 8) & 0x01)
#define XE1205_FREQ_DEV_LO(value_)              (XE1205_FREQ(value_) & 0xff)
#define XE1205_FREQ_HI(value_)                  ((XE1205_FREQ(value_) >> 8) & 0xff)
#define XE1205_FREQ_LO(value_)                  (XE1205_FREQ(value_) & 0xff)
#define XE1205_BIT_RATE(value_)                 ((152340L / (value_) - 1) & 0x7f)
#define XE1205_EFFECTIVE_BIT_RATE(value_)       (152340L / ((value_) + 1))


    /**
     * Frequency bands.
     */
    enum xe1205_freq_bands {
	XE1205_Band_434 = 434000000,
	XE1205_Band_869 = 869000000,
	XE1205_Band_915 = 915000000
    };
  

    // this value is the time between rssi measurement updates, plus a buffer time.
    // we keep it cached for fast access during packet reception
    uint16_t rssi_period_us; 

    // time to xmit/receive a byte at current bitrate 
    uint16_t byte_time_us;

    // norace is ok because protected by the isOwner() calls
    norace uint8_t rxparam9 = 0xff; 
    norace uint8_t txparam7 = 0xff;

    // returns appropriate baseband filter in khz bw for given bitrate in bits/sec.
    uint16_t baseband_bw_from_bitrate(uint32_t bitrate) {
	return (bitrate * 400) /152340;
    }


    // returns appropriate freq. deviation for given bitrate in bits/sec.
    uint32_t freq_dev_from_bitrate(uint32_t bitrate) {
	return (bitrate * 6) / 5;
    }

    // returns xe1205 encoding of baseband bandwidth in appropriate bit positions
    // for writing into rxparam7 register
    uint8_t baseband_bw_rxparam7_bits(uint16_t bbw_khz) 
    {
	if(bbw_khz <= 10) {
	    return 0x00;
	} else if(bbw_khz <= 20) {
	    return 0x20;
	} else if(bbw_khz <= 40) {
	    return 0x40;
	} else if(bbw_khz <= 200) {
	    return 0x60;
	} else if(bbw_khz <= 400) {
	    return 0x10;
	} else return 0x10; 
    }

    // returns the period (in us) between two successive rssi measurements
    // (see xemics data sheet 4.2.3.4), as a function of frequency deviation
    uint16_t rssi_meas_time(uint32_t freqdev_hz) 
    {
	if (freqdev_hz > 20000)      // at 152kbps, equiv to 2 byte times, at 76kbps, equiv to 1 byte time, at 38kbps equiv to 4 bits, etc
	    return 100;
	else if (freqdev_hz > 10000) // at 9.6kbps, equiv to 4 byte times.
	    return 200;           
	else if (freqdev_hz > 7000)
	    return 300;
	else if (freqdev_hz > 5000)  // at 4.8kbps, equiv to 4 byte times.
	    return 400;
	else 
	    return 500;                // at 1200, equiv to 13 byte times.
    }

    task void initTask() 
    {
	atomic {
	    byte_time_us = 8000000 / XE1205_BITRATE_DEFAULT;
	    rssi_period_us = rssi_meas_time(XE1205_FREQDEV_DEFAULT) + 10;

	    xe1205check(1, call SpiResource.immediateRequest()); // should always succeed: task happens after softwareInit, before interrupts are enabled

	    call TXParam7.write(0x00); // tx power 0dbm, normal modulation & bitsync, no flitering
	    txparam7=0;

	    call MCParam0.write(0x3c | XE1205_FREQ_DEV_HI(XE1205_FREQDEV_DEFAULT)); // buffered mode, transceiver select using SW(0:1), Data output, 868mhz band, 
	    call MCParam1.write(XE1205_FREQ_DEV_LO(XE1205_FREQDEV_DEFAULT));
	    call MCParam2.write(XE1205_BIT_RATE(XE1205_BITRATE_DEFAULT));

	    call MCParam3.write(XE1205_FREQ_HI(-1000000)); // 869mhz - 1mhz = 868mhz (preset 0)
	    call MCParam4.write(XE1205_FREQ_LO(-1000000));


	    call RXParam8.write(baseband_bw_rxparam7_bits(baseband_bw_from_bitrate(XE1205_BITRATE_DEFAULT))
				| 0x0a); // calibrate & init baseband filter each time bbw changes

	    call RXParam9.write(0x00); // rssi off by default, fei off
	    rxparam9=0;
	    call SpiResource.release();
	}
    }

    command error_t Init.init() 
    {
	post initTask();
	return SUCCESS;
    }
  
    event void SpiResource.granted() {
    }

    error_t tuneManual(uint32_t freq) 
    {
	uint32_t bandCenter;
	uint8_t mcp0reg;
	uint16_t mcp34reg;
	error_t status;

	if (call SpiResource.isOwner()) return EBUSY;
	status = call SpiResource.immediateRequest();
	xe1205check(2, status);
	if (status != SUCCESS) return status;


	call MCParam0.read(&mcp0reg);

	mcp0reg &= ~0x6;

	if ((freq >= (XE1205_Band_434 + XE1205_EFFECTIVE_FREQ(0x8000)))
	    && (freq <= (XE1205_Band_434 + XE1205_EFFECTIVE_FREQ(0x7fff)))) {

	    mcp0reg |= (1 << 1);
	    bandCenter = XE1205_Band_434;

	} else if ((freq >= (XE1205_Band_869 + XE1205_EFFECTIVE_FREQ(0x8000)))
		   && (freq <= (XE1205_Band_869 + XE1205_EFFECTIVE_FREQ(0x7fff)))) {

	    mcp0reg |= (2 << 1);
	    bandCenter = XE1205_Band_869;

	} else if ((freq >= (XE1205_Band_915+ XE1205_EFFECTIVE_FREQ(0x8000)))
		   && (freq <= (XE1205_Band_915 + XE1205_EFFECTIVE_FREQ(0x7fff)))) {

	    mcp0reg |= (3 << 1);
	    bandCenter = XE1205_Band_915;

	} else {
	    call SpiResource.release();
	    return EINVAL;
	}                       


	mcp34reg = XE1205_FREQ(freq - bandCenter);

	call MCParam0.write(mcp0reg);
	call MCParam3.write(mcp34reg >> 8);
	call MCParam4.write(mcp34reg & 0xff);

	call SpiResource.release();

	return SUCCESS;
    }


    command error_t XE1205PhyConf.tunePreset(xe1205_channelpreset_t preset) 
    {
	switch(preset) {

	case xe1205_channelpreset_868mhz:
	    return tuneManual(868000000);

	case xe1205_channelpreset_869mhz:
	    return tuneManual(869000000);

	case xe1205_channelpreset_870mhz:
	    return tuneManual(870000000);

	case xe1205_channelpreset_433mhz:
	    return tuneManual(433000000);

	case xe1205_channelpreset_434mhz:
	    return tuneManual(434000000);

	case xe1205_channelpreset_435mhz:
	    return tuneManual(435000000);

	default:
	    return FAIL;
	}
    }

    async command error_t XE1205PhyConf.setRFPower(xe1205_txpower_t txpow)
    {
	error_t status;

	if (txpow > xe1205_txpower_15dbm)
	    return EINVAL;

	if (call SpiResource.isOwner()) return EBUSY;
	status = call SpiResource.immediateRequest();
	xe1205check(3, status);
	if (status != SUCCESS) return status;

	txparam7 &= ~(3 << 6);
	txparam7 |= (txpow << 6);
	call TXParam7.write(txparam7);
	call SpiResource.release();
	return SUCCESS;
    }


  

    command error_t XE1205PhyConf.setBitrate(xe1205_bitrate_t bitrate) 
    {
	uint16_t bbw;
	uint32_t freqdev;
	uint8_t rxp8reg, mcp0reg, mcp1reg, mcp2reg;
	error_t status;

	if (bitrate < xe1205_bitrate_38085 || bitrate > xe1205_bitrate_152340) return EINVAL;

	if (call SpiResource.isOwner()) return EBUSY;
	status = call SpiResource.immediateRequest();
	xe1205check(4, status);
	if (status != SUCCESS) return status;

	// receiver bandwidth
	call RXParam8.read(&rxp8reg);
	bbw = baseband_bw_from_bitrate(bitrate);
	rxp8reg &= ~0x70;
	rxp8reg |= baseband_bw_rxparam7_bits(bbw);


	// frequency deviation
	freqdev = freq_dev_from_bitrate(bitrate);
	rssi_period_us = rssi_meas_time(freqdev) + 10;

	call MCParam0.read(&mcp0reg);
	mcp0reg &= ~0x01;
	mcp0reg |= XE1205_FREQ_DEV_HI(freqdev);

	mcp1reg = XE1205_FREQ_DEV_LO(freqdev);

	mcp2reg = XE1205_BIT_RATE(bitrate);

	call RXParam8.write(rxp8reg);
	call MCParam0.write(mcp0reg);
	call MCParam1.write(mcp1reg);
	call MCParam2.write(mcp2reg);;

	atomic byte_time_us =   8000000 / bitrate;
	call SpiResource.release(); 
	return SUCCESS;
    }

    async command uint16_t XE1205PhyConf.getByteTime_us() { 
	return byte_time_us;
    }

    async command error_t XE1205RssiConf.setRssiMode(bool on) 
    {
	// must have bus
	if (on) 
	    rxparam9 |= 0x80;
	else 
	    rxparam9 &= ~0x80;
	call RXParam9.write(rxparam9);

	return SUCCESS;
    }

    async command uint16_t XE1205RssiConf.getRssiMeasurePeriod_us() {
	return rssi_period_us;
    }

    async command error_t XE1205RssiConf.setRssiRange(bool high) 
    {
	// must have bus
	if (high) {
	    rxparam9 |= 0x40;
	} else {
	    rxparam9 &= ~0x40;
	}
	call RXParam9.write(rxparam9);
	return SUCCESS;
    }

    async command error_t XE1205RssiConf.getRssi(uint8_t* rssi) 
    {
	// must have bus
	call RXParam9.read(rssi);
    
	*rssi = (*rssi >> 4) & 0x03;

	return SUCCESS;
    }

}

⌨️ 快捷键说明

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