This is a work-in-progress implementation of a m-sequence based channel sounder for GNU Radio and the USRP. In typical use, the user would run the sounder as a transmitter on one USRP, and a receiver on another at a different location. The receiver will determine the impulse response of the RF channel in between. The sounder uses a custom FPGA bitstream that is able to generate and receive a sounder waveform across a full 32 MHz wide swath of RF spectrum; the waveform generation and impulse response processing occur in logic in the USRP FPGA and not in the host PC. This avoids the USB throughput bottleneck entirely. Unfortunately, there is still roll-off in the AD9862 digital up-converter interpolation filter that impacts the outer 20% of bandwidth, but this can be compensated for by measuring and subtracting out this response during calibration. The sounder is based on sending a maximal-length PN code modulated as BPSK with the supplied center frequency, with a chip-rate of 32 MHz. The receiver correlates the received signal across all phases of the PN code and outputs an impulse response vector. As auto-correlation of an m-sequence is near zero for any relative phase shift, the actual measured energy at a particular phase shift is related to the impulse response for that time delay. This is the same principle used in spread-spectrum RAKE receivers such as are used with GPS and CDMA. The transmitter is designed to work only with the board in side A. The receiver may be in side A or side B. The boards may be standalone LFTX/LFRXs or RFX daughterboards. To use, the following script is installed into $prefix/bin: Usage: usrp_sounder.py [options] Options: -h, --help show this help message and exit -R RX_SUBDEV_SPEC, --rx-subdev-spec=RX_SUBDEV_SPEC select USRP Rx side A or B -f FREQ, --frequency=FREQ set frequency to FREQ in Hz, default is 0.0 -d DEGREE, --degree=DEGREE set sounding sequence degree (2-12), default is 12, -t, --transmit enable sounding transmitter -r, --receive enable sounding receiver -l, --loopback enable digital loopback, default is disabled -v, --verbose enable verbose output, default is disabled -D, --debug enable debugging output, default is disabled -F FILENAME, --filename=FILENAME log received impulse responses to file To use with an LFTX board, set the center frequency to 16M: $ usrp_sounder.py -f 16M -t The sounder receiver command line is: $ usrp_sounder.py -f 16M -r -F output.dat You can vary the m-sequence degree between 2 and 12, which will create sequence lengths between 3 and 4095 (128 us). This will affect how frequently the receiver can calculate impulse response vectors. The correlator uses an O(N^2) algorithm, by using an entire PN period of the received signal to correlate at each lag value. Thus, using a degree 12 PN code of length 4095, it takes 4095*4095/32e6 seconds to calculate a single impulse response vector, about a half a second. One can reduce this time by a factor of 4 for each decrement in PN code degree, but this also reduces the inherent processing gain by 6 dB as well. The impulse response vectors are written to a file in complex float format, and consist of the actual impulse response with a noise floor dependent on the PN code degree in use. There is a loopback test mode that causes the sounding waveform to be routed back to the receiver inside the USRP: $ usrp_sounder.py -r -t -l -F output.dat The resulting impulse response will be a spike followed by a near zero value for the rest of the period. Synchronization at the receiver is not yet implemented, so the actual impulse response may be time shifted an arbitrary value within the the impulse response vector. If one assumes the first to arrive signal is the strongest, then one can circularly rotate the vector until the peak is at time zero. Johnathan Corgan Corgan Enterprises LLC jcorgan@corganenterprises.com 5/28/07