10、相关数据累积任务实现

\qquad 下面是HD-GR GNSS导航软件的相关数据累积任务实现代码:

// main_accum_task.c -- Correlation Data accumulation task accum_task(…) and 
//                      supporting functions.

/* 
 * 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.
 */

/* Namuru GPS OpenSource receiver project
 * Original : tracking.c
 * Modes    : Some code has been modified for adaption to the Namuru HW by Peter Mumford
 * 
 *    In general, the original code has been commented out and
 *    replaced (with peters initials (pjm) on the new code lines).
 *    The Namuru HW is different from the GP4020 / 2021 in the following points:
 *    1) early, prompt and late correlators, each separated by 0.5 chips
 * 
 * version  : V1.0
 * date     : 21st/Dec/2006
 */

/* 
 * HD-GR GNSS receiver project
 * Modes    : Inherited the code of tracking.c in the Namuru GPS receiver project 
 *            V1.0 and made necessary adjustments to adapt to the new HW, RTOS and 
 *            functions.
 * version  : V1.0
 * date     : xx/xx/2015
 */

#include <io.h>
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <stdlib.h>
#include "includes.h"
#include "system.h"
#include "altera_avalon_pio_regs.h"
#include "alt_types.h"
#include "sys/alt_irq.h"
#include "gnsstime.h"
#include "gps_accum_task.h"
#include "b1i_accum_task.h"
#include "main_allocate.h"
#include "main_message.h"
#include "main_measure.h"
#include "main_position.h"

/*******************************************************************************
 * Global variables
 ******************************************************************************/

unsigned short m_status __attribute__ ((section(".isrdata.rwdata")));
OS_FLAGS g_channels_to_allocate __attribute__ ((section(".isrdata.rwdata")));
OS_FLAGS g_channels_with_bits __attribute__ ((section(".isrdata.rwdata")));
OS_FLAGS g_channel_bits __attribute__ ((section(".isrdata.rwdata")));

/******************************************************************************
 * classic signum function written for the long datatype
 ******************************************************************************/
inline long sgn( long data)
{
    
    
	return (data < 0 ? -1: (data != 0) ? 1:0);
}

/******************************************************************************
 * Compute the approximate magnitude (square norm) of 2 numbers
 *
 * The "correct" function is naturally sqrt(a^2+b^2).
 * This computation is too slow for our application however.
 * We use the leading order approximation (mag = a+b/2) for b<a with sgn fixes.
 * This is probably as good as possible without a multiply.
 *
 * Haven't tried a fit, but based on endpoints a+(sqrt(2)-1)*b is a better
 * approximation. Everything else seems to have either a couple multiplies and
 * a divide, or an actual square root. It's a fact that if there's no hardware
 * multiply the binary square root is actually faster than a multiply on a GP
 * machine, but since the ARM7TDMI has a multiply the root is slower for us.
 ******************************************************************************/
inline long lmag( long a, long b)
{
    
    
	a = labs(a);
	b = labs(b);
	if (a > b) return (a + (b >> 1));
	else return (b + (a >> 1));
}

/*******************************************************************************
FUNCTION fix_atan2( long y,long x)
RETURNS  long integer

PARAMETERS
        y  long   quadrature fixed point value
        x  long   in-phase fixed point value

PURPOSE
// This is the phase discriminator function.
      This function computes the fixed point arctangent represented by
      y and x in the parameter list
      1 radian = 2^14 = 16384
      based on the power series  2^14*( (y/x)-2/9*(y/x)^3 )

// This is not a particularly good approximation.
// In particular, 0.2332025325081921, rather than 2/9 is the best
// fit parameter. The next simplest thing to do is fit {x,x^3}
// I'm assuming the interval of validity is [0,1).
// Fitting {1,x,x^3} is bad because a discriminator must come smoothly to
// zero.
// I wonder, in the average math library, if it might be faster to do the
// division un-signed?
// It's not much more expensive to fit x+a*x^2+b*x^3 (one more add).
// The compiler may not properly optimize ()/9.

WRITTEN BY
    Clifford Kelley
    Fixed for y==x  added special code for x==0 suggested by Joel Barnes, UNSW
*******************************************************************************/
inline long fix_atan2( long y, long x)
{
    
    
	long result=0,n,n3;

	// 4 quadrants, one invalid case

	// Invalid case
	if ((x == 0) && (y == 0))
		return(result);

	if (x > 0 && x >= labs(y)) {
    
    
		n=(y<<14)/x;
		n3=((((n*n)>>14)*n)>>13)/9;
		result=n-n3;
	}
	else if (x <= 0 && -x >= labs(y)) {
    
    
		n  = (y<<14)/x;
		n3 = ((((n*n)>>14)*n)>>13)/9;
		if (y > 0)
			result=n-n3+PI_SHIFT14;
		else if (y <= 0)
			result=n-n3-PI_SHIFT14;
	}
	else if (y > 0 &&  y > labs(x)) {
    
    
		n  = (x<<14)/y;
		n3 = ((((n*n)>>14)*n)>>13)/9;
		result = PI_OVER2_SHIFT14 - n + n3;
	}
	else if (y < 0 && -y > labs(x)) {
    
    
		n  = (x<<14)/y;
		n3 = ((((n*n)>>14)*n)>>13)/9;
		result = -n + n3 - PI_OVER2_SHIFT14;
	}
	return(result);
}

inline long fix_atan(long y, long x)
{
    
    
	if (x < 0) {
    
    
		x = -x;
		y = -y;
	}
	return fix_atan2(y, x);
}

inline void set_tic_delay( int delay, unsigned short delay_life, unsigned short delay_range)
{
    
    
	unsigned long tic_delay = labs(delay);
	if (delay < 0) tic_delay |= (1 << 25);
	if (delay_life) tic_delay |= (1 << 26);
	if (delay_range) tic_delay |= (1 << 27);
	write_to_correlator( PROG_TIC_DELAY, tic_delay );
}

inline void set_tic_slew( int delay, int slew, int mod)
{
    
    
	unsigned long tic_slew = (1 << 31) | labs(delay) |
			(labs(slew) << 19) | (labs(mod) << 26);
	if (delay < 0) tic_slew |= (1 << 18);
	if (slew < 0) tic_slew |= (1 << 30);
	write_to_correlator( PROG_TIC_DELAY, tic_slew );
}

inline void load_tic_count( unsigned long count)
{
    
    
	write_to_correlator( PROG_TIC_LOAD, count );
}

void initialize_tracking( void)
{
    
    
	gps_initialize_tracking();
	b1i_initialize_tracking();
}


/*******************************************************************************
 FUNCTION accum_task(void* pdata)
 RETURNS  None.

 PARAMETERS  pdata: not used

 PURPOSE Main routine which runs on an accum_int.
*******************************************************************************/

void accum_task(void* pdata)
{
    
    
	INT8U err;
	unsigned long new_data;

	while (1) {
    
    
		OSSemPend(m_SemISR, 0, &err);

		// NEW_DATA register shows which channels have new accumulation data available
		new_data = read_from_correlator(NEW_DATA);

		if (m_status & 0x1) {
    
    
			// We just had a Tic (~100ms) so update the receiver clock
			increment_time_with_tic();
	        // Grab the time in bits
	        grab_bit_times();
		}

		// 1+. The beginning of basic interaction with the baseband

		if (m_sys_posconst & POS_CONSTELL_GPS) {
    
    
			gps_accum_newdata(new_data);
		}
		if (m_sys_posconst & POS_CONSTELL_BDS) {
    
    
			b1i_accum_newdata(new_data >> BDMOD_GPS_CHANNELS);
		}

		// 1-. The end of basic interaction with the baseband

		// 2+. The beginning of baseband signal acquisition / tracking (loop control)

		// Clear the IPC shadows (see below).
		g_channels_to_allocate = 0;
		g_channels_with_bits = 0;
		g_channel_bits = 0;

		if (m_sys_posconst & POS_CONSTELL_BDS) {
    
    
			b1i_track_channels(new_data >> BDMOD_GPS_CHANNELS);
			g_channels_to_allocate <<= GPS_MAX_CHANNELS;
			g_channels_with_bits <<= GPS_MAX_CHANNELS;
			g_channel_bits <<= GPS_MAX_CHANNELS;
		}
		if (m_sys_posconst & POS_CONSTELL_GPS) {
    
    
			gps_track_channels(new_data);
		}

		// 2-. The end of baseband signal acquisition / tracking (loop control)

		// If any channels are off, signal the allocation thread that it should
		// allocate some off channels.
		if (g_channels_to_allocate) {
    
    
			OSFlagPost(m_AllocateFlag, g_channels_to_allocate, OS_FLAG_SET, &err);
		}

		// Set the flag IPC which starts up the message thread. No reason to call
		// it more than once, it's probably an expensive call, so we use the
		// g_channels_with_bits shadow.
		if (g_channels_with_bits) {
    
    
			OSFlagPost(m_MessageFlag, g_channels_with_bits, OS_FLAG_SET, &err);
		}

		// 3+. The beginning of navigation solution

		// Check status register for a TIC
		if (m_status & 0x1) {
    
    
			fill_ch_pars();
			OSSemPost(m_SemMeas);
		}

		// 3-. The end of navigation solution
	}
}

猜你喜欢

转载自blog.csdn.net/turing321_huaide/article/details/119039850