// $Id: channelgen.c,v 1.2 2003/10/07 21:46:12 idgay 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.2 2003/10/07 21:46:12 idgay 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 #ifndef __CYGWIN__ #include #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<> 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<\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; }