xe1205phyrssiconfp.nc
来自「tinyos-2.0源代码!转载而已!要的尽管拿!」· NC 代码 · 共 385 行
NC
385 行
/* * 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(-2000000)); // 869mhz - 2mhz = 867mhz (preset 0) call MCParam4.write(XE1205_FREQ_LO(-2000000)); 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_867mhz: return tuneManual(867000000); case xe1205_channelpreset_868mhz: return tuneManual(868000000); case xe1205_channelpreset_869mhz: return tuneManual(869000000); 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) { error_t status; if (call SpiResource.isOwner()) return EBUSY; status = call SpiResource.immediateRequest(); xe1205check(5, status); if (status != SUCCESS) return status; if (on) rxparam9 |= 0x80; else rxparam9 &= ~0x80; call RXParam9.write(rxparam9); call SpiResource.release(); return SUCCESS; } async command uint16_t XE1205RssiConf.getRssiMeasurePeriod_us() { return rssi_period_us; } async command error_t XE1205RssiConf.setRssiRange(bool high) { error_t status; if (call SpiResource.isOwner()) return EBUSY; status = call SpiResource.immediateRequest(); xe1205check(6, status); if (status != SUCCESS) return status; if (high) rxparam9 |= 0x40; else rxparam9 &= ~0x40; call RXParam9.write(rxparam9); call SpiResource.release(); return SUCCESS; } async command error_t XE1205RssiConf.getRssi(uint8_t* rssi) { error_t status; if (call SpiResource.isOwner()) return EBUSY; status = call SpiResource.immediateRequest(); xe1205check(7, status); if (status != SUCCESS) return status; call RXParam9.read(rssi); *rssi = (*rssi >> 4) & 0x03; call SpiResource.release(); return SUCCESS; }}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?