📄 message.c
字号:
if( HOW & 3) // Confirm zeros return; // Preliminary checks passed, now final check of parity if( !ParityCheck( TLM)) return; if( !ParityCheck( HOW)) return; // Hooray! We found a valid preamble and a sane HOW word, so for now // we'll assume we're synced. We won't really know until we get the next // subframe and check that the TOW has incremented by exactly 1. messages[ch].frame_sync = 1; // Hand off the current satellite to the message structure messages[ch].prn = CH[ch].prn; // Record the current subframe number (from zero) messages[ch].subframe = --current_sf; // Flag whether the bits are inverted, and if so invert wordbuf0 so we // don't lose the next incoming word. if( data_inverted) { messages[ch].data_inverted = 1; messages[ch].wordbuf0 = ~messages[ch].wordbuf0; } else messages[ch].data_inverted = 0; messages[ch].sf[current_sf].word[0] = TLM; messages[ch].sf[current_sf].word[1] = HOW; // We've just stored two words into the current subframe messages[ch].wordcount = 2; // Flag Words 0 and 1 as valid words messages[ch].sf[current_sf].valid = 3; // Extract and store the TOW from the HOW so we can easily compare it to // future TOWs to verify our frame sync. (TOW == bits 1-17 of 30 bit word) // Maybe this should be a macro. Could be done faster if we assumed 32bits. messages[ch].sf[current_sf].TOW = (HOW >> (30 - 17)) & ((1 << 17) - 1); if( current_sf > 0) previous_sf = current_sf - 1; else previous_sf = 4; // Even if the previous subframe had valid TLM and HOW words, kill both the // current and previous subframes if their TOW's are not incrementally // different. if( messages[ch].sf[previous_sf].valid & 3) { if( messages[ch].sf[current_sf].TOW != (messages[ch].sf[previous_sf].TOW + 1)) { // We're not actually synced. Kill everything and start // the sync search over again. clear_messages( ch); return; } // We confirmed that we have sync since the TOW's are incremental. And // now that we have a valid TLM/HOW, we know the actual time of week. // We don't want to keep syncing the time in bits or keep setting the // epoch counters, so do this only once, after we confirm sync for // this channel. We'll do this again only if we clear the message. if( !messages[ch].set_ch_time) { // Don't run this code again until we've lost frame sync. messages[ch].set_ch_time = 1; // Update the gps "time_in_bits". Given that we know the current bit // is the last bit of the HOW word (the 60th bit of the subframe), // we can calculate the gps time in bit-counts (1/50 seconds). The // TOW in the HOW is actually the time at the start of the NEXT // subframe (see the ICD for the clearest documentation on this). // Note, time_in_bits is incremented in the tracking.c lock() // function, so TODO guarantee that this is set before tracking() // increments it, or compensate if it does. if( messages[ch].sf[current_sf].TOW) CH[ch].time_in_bits = messages[ch].sf[current_sf].TOW * 300 - 240; // The TOW can be zero so handle this case. else CH[ch].time_in_bits = BITS_IN_WEEK - 240; // Update the gps time in seconds (the receiver's main clock) if we // haven't already. set_time_with_tow( messages[ch].sf[current_sf].TOW); // Finally, flag the tracking loop that the next bit (20ms epoch) // is the beginning of a new word. TODO Like above, guarantee // that this happens before the next bit arrives from the // tracking loops. CH[ch].sync_20ms_epoch_count = 1; } // Do a sanity check on the time_in_bits; it should always agree with // the TOW bits. Handles the case where TOW is zero at the start of // a GPS week. TODO Like above, guarantee this happens before the next // bit arrives from the tracking loops. else { if( messages[ch].sf[current_sf].TOW) { if( CH[ch].time_in_bits != (messages[ch].sf[current_sf].TOW * 300 - 240)) diag_printf( "MESSAGE.C: TOW HAS BECOME UNSYNCHRONIZED."); } else if( CH[ch].time_in_bits != (BITS_IN_WEEK - 240)) diag_printf( "MESSAGE.C: TOW HAS BECOME UNSYNCHRONIZED."); } }}/****************************************************************************** * Stuff incoming bits from the tracking interrupt into words and subframes in * the messages structure. ******************************************************************************/voidmessage_thread( CYG_ADDRWORD data) // input 'data' not used{ cyg_flag_value_t channels_with_bits; cyg_flag_value_t channels_with_subframes; unsigned short ch; // There's no way that we're going to get a bit before this thread // is first executed, so it's ok to run the flag init here. cyg_flag_init( &message_flag); while(1) { // Sleep here until tracking() signals there are channels with new // navigation bits ready. Clear the message_flag and save the active // channels in channels_with_bits. channels_with_bits = cyg_flag_wait( &message_flag, (1 << N_CHANNELS) - 1, // 0xfff (any channel) CYG_FLAG_WAITMODE_OR | // any flag CYG_FLAG_WAITMODE_CLR); // clear flags // OK we're awake, process the messages setbits32( GPS4020_GPIO_WRITE, LED3); // DEBUG: // Clear the flag IPC shadow (see below) channels_with_subframes = 0; for( ch = 0; ch < N_CHANNELS; ch++) { if( channels_with_bits & (1 << ch)) { // This channel has a bit to process: // store the bit in the word buffers store_bit( ch, CH[ch].bit); // If the channel isn't sync'd to the message frame, // look for the preamble if( !messages[ch].frame_sync) { look_for_preamble( ch); // If we just found sync, then reset the counters if( messages[ch].frame_sync) { messages[ch].bitcount = 0; } } // Frame is sync'd, so get bits and words. else /* Frame is sync'd */ { // If we have 30 bits, that's a word so store it messages[ch].bitcount++; if( messages[ch].bitcount >= 30) { messages[ch].bitcount = 0; // Store the word in the subframes array store_word( ch); messages[ch].wordcount++; if( messages[ch].wordcount >= 10) { // We've got 10 words so we have a subframe. Use // frame_sync to restart the subframe parsing. // Note that preamble will reset wordcount. messages[ch].frame_sync = 0; // we assume in the preamble that the bit stream // hasn't been inverted when we check the TLM/HOW. // so if the channel IS inverted, make it non- // inverted as we check the TLM/HOW. if( messages[ch].data_inverted) messages[ch].wordbuf0 = ~messages[ch].wordbuf0; // Only send along complete, error free subframes if( messages[ch].sf[messages[ch].subframe].valid == 0x3ff) // 0x3ff === 10 good words { // Set the flags to wake up the ephemeris thread cyg_flag_value_t which_subframe = (1 << messages[ch].subframe); channels_with_subframes |= (1 << ch); // Set the subframe flag so we know which // subframe to process. We don't need a // shadow register here because we're only // going to set one subframe per channel // at a time. cyg_flag_setbits( &ephemeris_subframe_flags[ch], which_subframe); } } } } } } // Wake up the ephemeris thread if there are subframes ready if( channels_with_subframes) cyg_flag_setbits( &ephemeris_channel_flag, channels_with_subframes); clearbits32( GPS4020_GPIO_WRITE, LED3); // DEBUG: }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -