📄 channelgen.c
字号:
// $Id: channelgen.c,v 1.1.2.3 2003/08/20 23:32:16 scipio Exp $/* -*- Mode: C; c-basic-indent: 2; indent-tabs-mode: nil -*- *//* * IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. By * downloading, copying, installing or using the software you agree to * this license. If you do not agree to this license, do not download, * install, copy or use the software. * * Intel Open Source License * * Copyright (c) 2002 Intel Corporation * 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 Intel Corporation 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 INTEL OR ITS * 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. * * Author: Phil Buonadonna * Revision: $Id: channelgen.c,v 1.1.2.3 2003/08/20 23:32:16 scipio Exp $ * *//* * This tool provides two things: * 1) To verify the actual channel generated by the component function * CC1000Control.TuneManual(freq) The computation engine used in * this program is EXACTLY the same as it is for the on-device * stack and should generate the same result. * * 2) To generate a C-code preset-table entry for a given frequency. * * The assumptions used are: * XOSC Freq - 14.745600 MHz * Separation Freq - 64 KHz * IF - 150 KHz * LO Injection - High Side * Baud Rate - 38.4 Kbaud (19.2 realized w/ Manchester Encoding) */#include <stdio.h>#ifndef __CYGWIN__#include <inttypes.h>#endifchar gfPrintPreset = 0;enum { IF = 150000, FREQ_MIN = 4194304, FREQ_MAX = 16751615};const uint32_t FRefTbl[9] = {2457600, 2106514, 1843200, 1638400, 1474560, 1340509, 1228800, 1134277, 1053257};const uint16_t CorTbl[9] = {1213, 1416, 1618, 1820, 2022, 2224, 2427, 2629, 2831};const uint16_t FSepTbl[9] = {0x1AA, 0x1F1, 0x238, 0x280, 0x2C7, 0x30E, 0x355, 0x39C, 0x3E3};uint32_t cc1000ComputeFreq(uint32_t desiredFreq) { uint32_t ActualChannel = 0; uint32_t RXFreq = 0, TXFreq = 0; int32_t Offset = 0x7fffffff; uint16_t FSep = 0; uint8_t RefDiv = 0; uint8_t i; for (i = 0; i < 9; i++) { uint32_t NRef = ((desiredFreq + IF)); uint32_t FRef = FRefTbl[i]; uint32_t Channel = 0; uint32_t RXCalc = 0, TXCalc = 0; int32_t diff; NRef = ((desiredFreq + IF) << 2) / FRef; if (NRef & 0x1) { NRef++; } if (NRef & 0x2) { RXCalc = 16384 >> 1; Channel = FRef >> 1; } NRef >>= 2; RXCalc += (NRef * 16384) - 8192; if ((RXCalc < FREQ_MIN) || (RXCalc > FREQ_MAX)) continue; TXCalc = RXCalc - CorTbl[i]; if ((TXCalc < FREQ_MIN) || (TXCalc > FREQ_MAX)) continue; Channel += (NRef * FRef); Channel -= IF; diff = Channel - desiredFreq; if (diff < 0) diff = 0 - diff; if (diff < Offset) { RXFreq = RXCalc; TXFreq = TXCalc; ActualChannel = Channel; FSep = FSepTbl[i]; RefDiv = i + 6; Offset = diff; } } if (RefDiv != 0) { uint8_t ucRxVcoCurrent, ucRxLoDrive, ucRxMatch; uint8_t ucTxVcoCurrent, ucTxPaDrive; uint8_t ucBufCurrent, ucLNACurrent; if (ActualChannel < 500000000) { if (ActualChannel < 400000000) { // CURRENT (RX) //gCurrentParameters[0x9] = ((8 << CC1K_VCO_CURRENT) | (1 << CC1K_LO_DRIVE)); ucRxVcoCurrent = 8; ucRxLoDrive = 1; // CURRENT (TX) //gCurrentParameters[0x1d] = ((9 << CC1K_VCO_CURRENT) | (1 << CC1K_PA_DRIVE)); ucTxVcoCurrent = 9; ucTxPaDrive = 1; } else { // CURRENT (RX) // gCurrentParameters[0x9] = ((4 << CC1K_VCO_CURRENT) | (1 << CC1K_LO_DRIVE)); ucRxVcoCurrent = 4; ucRxLoDrive = 1; // CURRENT (TX) // gCurrentParameters[0x1d] = ((8 << CC1K_VCO_CURRENT) | (1 << CC1K_PA_DRIVE)); ucTxVcoCurrent = 8; ucTxPaDrive = 1; } // FRONT_END //gCurrentParameters[0xa] = (1 << CC1K_IF_RSSI); ucBufCurrent = 0; ucLNACurrent = 0; // MATCH //gCurrentParameters[0x12] = (7 << CC1K_RX_MATCH); ucRxMatch = 7; } else { // CURRENT (RX) // gCurrentParameters[0x9] = ((8 << CC1K_VCO_CURRENT) | (3 << CC1K_LO_DRIVE)); ucRxVcoCurrent = 8; ucRxLoDrive = 3; // CURRENT (TX) // gCurrentParameters[0x1d] = ((15 << CC1K_VCO_CURRENT) | (3 << CC1K_PA_DRIVE)); ucTxVcoCurrent = 15; ucTxPaDrive = 3; // FRONT_END //gCurrentParameters[0xa] = ((1<<CC1K_BUF_CURRENT) | (2<<CC1K_LNA_CURRENT) | (1<<CC1K_IF_RSSI)); ucBufCurrent = 1; ucLNACurrent = 2; // MATCH //gCurrentParameters[0x12] = (2 << CC1K_RX_MATCH); ucRxMatch = 2; } // PLL //gCurrentParameters[0xc] = (RefDiv << CC1K_REFDIV); if (!gfPrintPreset) { printf("\n"); printf("DesiredFreq(Hz)\tActualFreq(Hz)\tOffset(Hz)\n"); printf("-----------------------------------------------------------------------\n"); printf("%d\t",desiredFreq); printf("%d\t",ActualChannel); printf("%d\n\n",Offset); } else { printf("// %f MHz Channel, 19.2 Kbps data, Manchester Encoding, High Side LO\n", ((float)ActualChannel/1.0e6)); printf("{\n "); // MAIN printf("0x31,\n "); // FREQA printf("0x%x,",(uint8_t)((RXFreq >> 16) & 0xFF)); // MSB printf("0x%x,",(uint8_t)((RXFreq >> 8) & 0xFF)); printf("0x%x,\n ",(uint8_t)((RXFreq) & 0xFF)); // LSB // FREQB printf("0x%x,",(uint8_t)((TXFreq >> 16) & 0xFF)); // MSB printf("0x%x,",(uint8_t)((TXFreq >> 8) & 0xFF)); printf("0x%x,\n ",(uint8_t)((TXFreq) & 0xFF)); // LSB // FSEP printf("0x%x,",(uint8_t)((FSep >> 8) & 0xFF)); //MSB printf("0x%x,\n ",(uint8_t)((FSep) & 0xFF)); // LSB // CURRENT (RX) printf("((%d << CC1K_VCO_CURRENT) | (%d << CC1K_LO_DRIVE)), \n ",ucRxVcoCurrent,ucRxLoDrive); // FRONT_END printf("((%d<<CC1K_BUF_CURRENT) | (%d<<CC1K_LNA_CURRENT) | (1<<CC1K_IF_RSSI)), \n ", ucBufCurrent,ucLNACurrent); // PA_POW printf("((0x8<<CC1K_PA_HIGHPOWER) | (0x0<<CC1K_PA_LOWPOWER)),\n "); // PLL printf("((%d<<CC1K_REFDIV)),\n ",RefDiv); // LOCK printf("((0x1<<CC1K_LOCK_SELECT)),\n "); // CAL printf("((1<<CC1K_CAL_WAIT) | (6<<CC1K_CAL_ITERATE)),\n "); // MODEM2 printf("((0<<CC1K_PEAKDETECT)),\n "); // MODEM1 printf("((3<<CC1K_MLIMIT) | (1<<CC1K_LOCK_AVG_MODE) | (3<<CC1K_SETTLING) | (1<<CC1K_MODEM_RESET_N)),\n "); // MODEM0 printf("((5<<CC1K_BAUDRATE) | (1<<CC1K_DATA_FORMAT) | (1<<CC1K_XOSC_FREQ)),\n "); // MATCH printf("((%d<<CC1K_RX_MATCH) | (0<<CC1K_TX_MATCH)),\n ",ucRxMatch); // FSCTRL printf("((1<<CC1K_FS_RESET_N)),\n "); // FSHAPE7 - FSHAPE1 printf("0x00,0x00,0x00,0x00,0x00,0x00,0x00,\n "); // FSDELAY printf("0x00,\n "); // PRESCALER printf("0x00,\n "); // CURRENT (TX) printf("((%d << CC1K_VCO_CURRENT) | (%d << CC1K_PA_DRIVE)), \n ",ucTxVcoCurrent,ucTxPaDrive); // Injection Mode printf("TRUE\n},"); } } //gCurrentChannel = ActualChannel; return ActualChannel;}void PrintUsage(char *ProgName) { printf ("Usage: %s [OPTIONS] FREQUENCY\n",ProgName); printf ("Determine CC1000 actual channel frequency and preset constants for\n"); printf ("desired FREQUENCY (in Hz).\n"); printf ("\n"); printf ("-p\t Generate formatted C preset table entry\n"); printf ("\n"); printf ("Report bugs to <tinyos@millennium.berkeley.edu>\n");}int main(int argc, char **argv) { uint32_t DesiredFreq; uint32_t ActualFreq; char *szProgName = argv[0]; char cOption; if (argc < 2) { PrintUsage(szProgName); return 0; } while ((--argc > 0) && ((*++argv)[0] == '-')) { while (cOption = *++argv[0]) { switch (cOption) { case 'p': gfPrintPreset = 1; break; default: PrintUsage(szProgName); return 0; } } } DesiredFreq = atoi(argv[0]); if ((DesiredFreq < 300000000) || (DesiredFreq > 1000000000)) { fprintf(stderr,"Frequency %d not in range 300000000 Hz - 1000000000 Hz\n",DesiredFreq); return 0; } ActualFreq = cc1000ComputeFreq(DesiredFreq); return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -