📄 tos-channelgen.c
字号:
// $Id: tos-channelgen.c,v 1.4 2006/12/12 18:23:00 vlahan 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: tos-channelgen.c,v 1.4 2006/12/12 18:23:00 vlahan 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>
#endif
char 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 + -