00001 // $Id: GenXSequence.cpp 2943 2011-10-25 17:17:11Z yanweignss $ 00002 00003 //============================================================================ 00004 // 00005 // This file is part of GPSTk, the GPS Toolkit. 00006 // 00007 // The GPSTk is free software; you can redistribute it and/or modify 00008 // it under the terms of the GNU Lesser General Public License as published 00009 // by the Free Software Foundation; either version 2.1 of the License, or 00010 // any later version. 00011 // 00012 // The GPSTk is distributed in the hope that it will be useful, 00013 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00015 // GNU Lesser General Public License for more details. 00016 // 00017 // You should have received a copy of the GNU Lesser General Public 00018 // License along with GPSTk; if not, write to the Free Software Foundation, 00019 // Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 00020 // 00021 // Copyright 2004, The University of Texas at Austin 00022 // 00023 //============================================================================ 00024 00025 //============================================================================ 00026 // 00027 //This software developed by Applied Research Laboratories at the University of 00028 //Texas at Austin, under contract to an agency or agencies within the U.S. 00029 //Department of Defense. The U.S. Government retains all rights to use, 00030 //duplicate, distribute, disclose, or release this software. 00031 // 00032 //Pursuant to DoD Directive 523024 00033 // 00034 // DISTRIBUTION STATEMENT A: This software has been approved for public 00035 // release, distribution is unlimited. 00036 // 00037 //============================================================================= 00038 00039 00040 00041 00042 00043 00044 /* 00045 * GenXSequence.cpp - Generate GPS X-register sequences 00046 */ 00047 00048 // Local headers 00049 #include <string> 00050 #include "GenXSequence.hpp" 00051 00052 using namespace std; 00053 namespace gpstk 00054 { 00055 // Constructor 00056 GenXSequence::GenXSequence( const unsigned int initialState, 00057 const unsigned int tapRegister, 00058 const int initialLengthOfSequence, 00059 const int maxDelay ) 00060 { 00061 00062 /* 00063 * NOTE: the x register functions assume a LSB-to-MSB shift. Therefore, 00064 * the tap register definition and the initialization definition for the 00065 * X register correspond to the diagrams in ICD-GPS-200, assuming 00066 * "stage 0" is the LSB. That means the diagrams have to be read from 00067 * LSB (LEFT) -> MSB (RIGHT). The corresponding text doesn't have this 00068 * problem. 00069 */ 00070 unsigned int mask12bits[12] = { 0x0001, 0x0002, 0x0004, 0x0008, 00071 0x0010, 0x0020, 0x0040, 0x0080, 00072 0x0100, 0x0200, 0x0400, 0x0800 }; 00073 00074 unsigned int reg = initialState; 00075 lengthOfSequence = initialLengthOfSequence; 00076 maxOfSequence = lengthOfSequence + maxDelay; 00077 00078 uint32_t output; 00079 word_num = 0; 00080 bit_num = 0; 00081 int bit16cnt; 00082 int andBits; 00083 int i; 00084 00085 // Clear the output array 00086 for ( i=0; i<MAX_WORD; ++i ) bits[i] = 0x00000000; 00087 debugPrint = false; 00088 00089 for ( i=0; i<lengthOfSequence ; ++i) 00090 { 00091 // Get current output and store it away 00092 if ( (reg & 0x0800) != 0 ) output = 0x00000001; 00093 else output = 0x00000000; 00094 addBitToSequence( output ); 00095 00096 // Calculate next input bit 00097 andBits = reg & tapRegister; 00098 reg <<= 1; 00099 reg &= 0x0FFF; 00100 int cnt = 0; 00101 for ( int bit12cnt=0; bit12cnt<12; ++bit12cnt) 00102 { 00103 if (( andBits & mask12bits[bit12cnt] ) != 0) ++cnt; 00104 } 00105 int newBit = cnt % 2; 00106 reg |= newBit; 00107 } 00108 00109 // Fill delay bits with copies of the last ouptut bit 00110 for ( i=0; i<maxDelay; ++i) addBitToSequence( output ); 00111 00112 // When finished, make sure the last word (which is probably 00113 // a partially-filled word) is left-justified. 00114 if (bit_num>0) bits[word_num] <<= (MAX_BIT-bit_num); 00115 } 00116 00117 // Private helper method to avoid duplicate code. 00118 void GenXSequence::addBitToSequence( uint32_t newBit ) 00119 { 00120 // Left shift any pre-existing data, then OR on the new 00121 // data (assumed to be right-justified). 00122 bits[word_num] <<= 1; 00123 bits[word_num] |= newBit; 00124 00125 /* 00126 Increment bit pointer and check for word overflow. 00127 NOTE: Overflow of the WORD pointer is a "programming problem" 00128 that is unrecoverable and should NEVER happen in production. 00129 */ 00130 ++bit_num; 00131 if (bit_num>=MAX_BIT) 00132 { 00133 ++word_num; 00134 bit_num=0; 00135 } 00136 } 00137 00138 /* 00139 Given a bit position within the X sequence (numbered starting at 0), 00140 return the next 32 bits. Note: if there are insufficient bits left 00141 to fill the request, wrap around to the beginning of the sequence. 00142 Note that the location of the wrap around can be modified using the 00143 function GenXSequence::setEndOfSequence( int los ); 00144 */ 00145 uint32_t GenXSequence::operator[] ( const int ia ) 00146 { 00147 uint32_t retArg = 0x00000000; 00148 int i = ia; 00149 if (i >= lengthOfSequence) i = i % lengthOfSequence; 00150 int ndx1 = i / MAX_BIT; 00151 int offset = i % MAX_BIT; 00152 if ( (i+MAX_BIT) <= lengthOfSequence ) 00153 { 00154 if (offset==0) retArg = bits[ndx1]; 00155 else retArg = merge( bits[ndx1], bits[ndx1+1], offset ); 00156 } 00157 /* 00158 Complicated case when coming up to end of sequence. May have to 00159 put together parts of up to three words to get 32 bits. Two words 00160 at the end of sequence plus "wrap around" bits from beginning of 00161 sequence. 00162 First: If end of sequence doesn't fall in current word, use up 00163 remaining bits in the current word. 00164 Second: use bits up to the end of sequence. 00165 Third: fill remaining bits from the beginning of the sequence. 00166 */ 00167 else 00168 { 00169 int numRemainingInSequence = lengthOfSequence - i; 00170 int numRemainingInWord = MAX_BIT - offset; 00171 int numFilled = 0; 00172 00173 /* 00174 Get bits (if any) from next-to-last word. 00175 */ 00176 if (numRemainingInWord<numRemainingInSequence) 00177 { 00178 retArg = bits[ndx1++] << offset; 00179 numRemainingInSequence -= numRemainingInWord; 00180 numFilled = numRemainingInWord; 00181 } 00182 00183 uint32_t temp = bits[ndx1]; 00184 /* 00185 Get bits from last word 00186 Case 1: No bits from previous word, need only "middle" section 00187 from last word. 00188 Case 2: Need all bits available from final word (may or 00189 may not have bits from preceding word) 00190 */ 00191 if (numFilled==0 && offset!=0) 00192 { 00193 temp <<= offset; // Move to left to clear excess msb 00194 temp >>= (MAX_BIT-numRemainingInSequence); // Shift right to clear excess lsb 00195 temp <<= (MAX_BIT - (numRemainingInSequence+numFilled) ); 00196 retArg |= temp; 00197 } 00198 else 00199 { 00200 temp >>= (MAX_BIT-numRemainingInSequence); 00201 temp <<= (MAX_BIT-(numRemainingInSequence+numFilled)); 00202 retArg |= temp; 00203 } 00204 00205 // Finally, add bits from the "wraparound" word at the 00206 // beginning of the array. 00207 retArg |= bits[0] >> (numRemainingInSequence+numFilled); 00208 } 00209 return(retArg); 00210 } 00211 00212 void GenXSequence::setLengthOfSequence( int los ) 00213 { 00214 lengthOfSequence = los; 00215 return; 00216 } 00217 } // end of namespace
1.3.9.1