⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 measure.c

📁 此程序为GPS接收机的源码
💻 C
字号:
// measure.c Take measurements each TIC interrupt (~100ms)// Copyright (C) 2005  Andrew Greenberg// Distributed under the GNU GENERAL PUBLIC LICENSE (GPL) Version 2 (June 1991).// See the "COPYING" file distributed with this software for more information.#include <cyg/kernel/kapi.h>#include <cyg/infra/diag.h>#include "measure.h"#include "constants.h"#include "gp4020.h"#include "gp4020_io.h"#include "message.h"#include "pseudorange.h"#include "time.h"#include "tracking.h"/****************************************************************************** * Globals ******************************************************************************/measurement_t   meas[N_CHANNELS];gpstime_t       meas_time;cyg_sem_t       measure_semaphore;/****************************************************************************** * Grab the time in bits from the tracking loops. * * Note, when the TIC comes right at the end of a message bit transition, then * an accum_int may increment a time_in_bits for one of the channels *while* * we're running in the measure_thread(). we handle that case by calling this * small routine directly from the accumulate DSR in interrupts.c . ******************************************************************************/voidgrab_bit_times( void){    unsigned short ch;    for( ch = 0; ch < N_CHANNELS; ch++)        meas[ch].meas_bit_time = CH[ch].time_in_bits; // meas_bit_time}/****************************************************************************** * Grab the latched measurement data from the accumulators after a TIC. ******************************************************************************/voidmeasure_thread( CYG_ADDRWORD data) // input 'data' not used{    static unsigned short prev_channels;    cyg_flag_value_t channels_ready;    unsigned short   ch;    unsigned short   carrier_low;    unsigned short   carrier_high;    unsigned short   meas_status_a;    unsigned short   posts_left;    unsigned short   raw_epoch;    volatile union _gp4020_channel_control *channel_control =            (volatile union _gp4020_channel_control *)            GP4020_CORR_CHANNEL_CONTROL;    cyg_semaphore_init( &measure_semaphore, 0);    while(1)    {        cyg_semaphore_wait( &measure_semaphore); // Wait for acum_dsr()        setbits32( GPS4020_GPIO_WRITE, LED2); // DEBUG        meas_status_a = in16( GP4020_CORR_MEAS_STATUS_A);        // We just had a Tic (~100ms) so update the receiver clock        increment_time_with_tic();        // Get the current GPS time to mark the time of measurement        meas_time = get_time(); // Is the syncronization here correct?        // If the channel is 1) locked and 2) the signal is good and 3) the        // clock is set vaguely correctly and 4) we've set the channel's        // time bits, THEN grab the measurement data.        channels_ready = 0;        for( ch = 0; ch < N_CHANNELS; ch++)        {            if( (CH[ch].state == CHANNEL_LOCK)                 && CH[ch].avg > SIGNAL_LOSS_AVG                 && (get_clock_state() >= SF1_CLOCK)                 && messages[ch].set_ch_time)            {                // Grab the latched data from the correlators (in their                // numerical order -- go optimized compiler, go!)                meas[ch].code_phase = channel_control[ch].read.code_phase;                carrier_low = channel_control[ch].read.carrier_cycle_low;                meas[ch].carrier_dco_phase =                        channel_control[ch].read.carrier_dco_phase;                raw_epoch = channel_control[ch].read.epoch;                meas[ch].code_dco_phase =                        channel_control[ch].read.code_dco_phase;                carrier_high = channel_control[ch].read.carrier_cycle_high;                // NOTE: Carrier phase measurements are not supported (yet)                meas[ch].carrier_cycles = (carrier_high << 16) | carrier_low;                // If a TIC hits right before a dump, it's possible for the                // code phase to latch 2046. In this case the epoch counter                // won't be incremented yet. If so, increment the epoch manually                // (see the GP4020 design manual section 7.6.17). Of course, we                // have to handle rollover of the epoch counter too.                if( meas[ch].code_phase < MAX_CODE_PHASE)                {                    // normal case                    meas[ch].epoch_20ms = raw_epoch >> 8;                    meas[ch].epoch_1ms = raw_epoch & 0x1f;                }                else // overflow                {                    meas[ch].code_phase -= MAX_CODE_PHASE;                    if( (raw_epoch | 0x1f) == 19)                    {                        meas[ch].epoch_1ms = 0;                        meas[ch].epoch_20ms = (raw_epoch >> 8) + 1;                        if( meas[ch].epoch_20ms > 49) // Not sure we                            meas[ch].epoch_20ms = 0; // need to do this?                    }                    else                    {                        meas[ch].epoch_20ms  = raw_epoch >> 8;                        meas[ch].epoch_1ms = (raw_epoch & 0x1f) + 1;                    }                }                // Note: meas_bit_time set in grab_bit_times() above.                meas[ch].doppler = CH[ch].carrier_freq;                meas[ch].prn = CH[ch].prn;                meas[ch].valid = 1;                // Tell the pseudorange thread which measurements it can use.                // Note that we don't want to just call the pr thread from here                // because we're in a DSR and should get out ASAP                channels_ready |= (1 << ch);            }            else            {                // Read the code_phase counter to indicate that                // we didn't miss any interrupts (but toss the value)                carrier_low = channel_control[ch].read.code_phase;                meas[ch].valid = 0; /* Can't use this measurement */            }            // Check to see if we missed this channel on an earlier TIC            if( meas_status_a & (1 << ch))                meas[ch].missed++;        }        // Finally, flag all valid measurements for the pseudorange thread.        // If there are none, but there were last TIC, then explicitly clear        // the pseudoranges. -- Is this necessary?        // Is it really true that .._sebits(0) doesn't work?        if( channels_ready)            cyg_flag_setbits( &pseudorange_flag, channels_ready);        else if( prev_channels)            clear_pseudoranges();        prev_channels = channels_ready;        // Finally, make sure we didn't miss any other posts to the measure        // semaphore- if we did, complain about it.        posts_left = cyg_semaphore_trywait( &measure_semaphore);        if( posts_left)        {            diag_printf( "MEASURE THREAD: MISSED SEMAPHORE");            do{                posts_left = cyg_semaphore_trywait( &measure_semaphore);            } while( posts_left);        }        clearbits32( GPS4020_GPIO_WRITE, LED2); // DEBUG    }}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -