GenXSequence.cpp

Go to the documentation of this file.
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

Generated on Thu Feb 9 03:30:57 2012 for GPS ToolKit Software Library by  doxygen 1.3.9.1