CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to support@ccsinfo.com

Using pointers and structures together - failure.

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
theMagni



Joined: 21 May 2004
Posts: 48
Location: Victoria, BC

View user's profile Send private message Visit poster's website

Using pointers and structures together - failure.
PostPosted: Thu May 27, 2004 11:37 am     Reply with quote

Hello, group:

I'm using a 16F628 and v3.178. I'm trying to pass a largish structure to a few functions. Then, I'm passing the pointer to other functions called inside the first function. The code doesn't function. Specifically, I'm getting either null values (which are wonderful when you try to compare them) or erratic values. (For example, GPS.quality, a 1-bit value, is "3"). I tried using the compiler's crazy way of handling pointers (reference parameters), but you can't do that with structures. Am I missing something fundamental here? I'm pretty sure that I'm doing this correctly, but the code's clearly wrong, and thus, so am I.

While you're looking at this, note that the timeout character for the timed_getc() is the % sign. (The GPS unit will never return a %.) I also tried taking out the bit assignments on the structures to see if there's a difference between documentation and performance.

Code:

struct GPS_data
{
  //This struct takes 93 bits. Some fields are one larger than what
  //is expected (i.e. 32 days per month) because they have to be
  //incremented based on the seconds. If date was 31 max, then it
  //could over-run if it gets incremented. This way is much smaller
  //in memory than a lot of checking. Now, this compiler is "hostile"
  //and will only assign the bits in blocks of eight. The white
  //space is to spilt up the struct into blocks of eight.
  int year;            //This allows up to 2016.
  int month;           //13 requires 4 bits.

  int date;            //32 requires 6 bits.
  int1 almanac;        //Single bit.
  int1 quality;        //Single bit.

  int hour;            //25 requires 5 bits.
  int1 gotdate;        //Single bit.
  int second;          //61 requires 6 bits.
  int timezone;        //+/- 13 requires 4 bits.

  int minute;          //61 requires 6 bits.
  int1 isN;            //It's either N or S.  Doing it this way sa
  int1 isW;            //It's either E or W.  ves 14 bits vs char

  //These are all eight-bit. No more whitespace.
  int longitude_deg;      //180 requires 8 bits.
  int longitude_min;      //99 requires 8 bits.
  int longitude_dec;      //Gives us up to 255 for the precision.
  int latitude_deg;       //90 requires 8 bits.
  int latitude_min;       //99 requires 8 bits.
  int latitude_dec;       //Gives us up to 255 for the precision.
  //char altitude;        //Removed(for now). Is in meters. 255 max?
};


struct date_time
{
  int year: 4;            //This allows up to 2016.
  int month: 4;           //13 requires 4 bits.

  int date: 7;            //32 requires 6 bits.
  int1 half_sec: 1;       //Single bit.

  int hour: 8;            //25 requires 5 bits.
  int minute: 8;          //61 requires 6 bits.
  int second: 8;          //61 requires 6 bits.
  int fix_age;

};

//Global since it's updated with an ISR.
struct date_time VHF_time;

main()
{
  struct GPS_data GPS;
  do{; /*nothing*/}while( initializing( &GPS, &VHF_time ) );
  puts( GPS.quality ); //for testing.
  do //superloop
  {
    if( get_GPS_fix( &GPS ) )
    {
      //do nothing for now.
    }
  }while(true);
}

#SEPARATE
int1 initializing(struct GPS_data *this_GPS,
                  struct date_time *this_VHF_time)
{
  int1 still_initializing = true;
  //Set the default Date and Time to Jan 09, 2004 at 0930. No reason.
  puts("VHF");
  *this_VHF_time->year = 4;
  *this_VHF_time->month = 1;
  *this_VHF_time->date = 9;
  *this_VHF_time->hour = 9;
  *this_VHF_time->minute = 30;
  *this_VHF_time->second = 0;
  *this_VHF_time->half_sec = 0;
  puts("GPS");
  //Ensures that it will get a fix first time.
  *this_GPS->quality = 0;
  *this_GPS->gotdate = 0;
  *this_GPS->almanac = 0;

  *this_GPS->year = 4;
  *this_GPS->month = 1;
  *this_GPS->date = 9;

  *this_GPS->hour = 9;
  *this_GPS->minute = 30;
  *this_GPS->second = 0;

  *this_GPS->timezone = 0;

  *this_GPS->isN = 1;
  *this_GPS->isW = 1;

  *this_GPS->longitude_deg = 0;
  *this_GPS->longitude_min = 0;
  *this_GPS->longitude_dec = 0;
  *this_GPS->latitude_deg = 0;
  *this_GPS->latitude_min = 0;
  *this_GPS->latitude_dec = 0;

  still_initializing = false;
  return( still_initializing );
}


int1 get_GPS_fix( struct GPS_data * G_P_S )
{
  int1 got_fix = false;
  int1 timed_out = false;
  *G_P_S->quality = 0;
  #use rs232(baud=9600, xmit=PIN_B2, rcv=PIN_B1, RESTART_WDT, ERRORS)
  // Power up the GPS engine.
  GPS_ON = HIGH;
  // Wait for GPS engine to power up (250ms is marginal).
  delay_ms( 1000 );
  //Wait for the GGA request to clear, then wait for the GGA data
  //to come back. Do nothing until then.
  if( send_GGA_request() )
  {
    if( wait_for_response( 'G', 'G', 'A' ) )
    {
      //If we didn't get the header, there's not much more to do.
      //Wait until the GPS unit has finished extracting the data.
      do
      {
        putc( *G_P_S->quality );
        puts(" = Q. GetGGA");
        timed_out = get_GGA_data( &G_P_S );
        puts("FAR");
        // Loop until the fix is found or the function times out.
      }while( !*G_P_S->quality );
      if( *G_P_S->quality )
      {
        vhf_chirp( 3 );
      }
    }
  }
  //Some more code goes here.
}

int1 get_GGA_data( struct GPS_data *passed_GPS )
{
  int1 gotdata = 1;
  int counter;
  char buffer[3];
  // Skip comma to reach UTC time field.
  gotdata = wait_for_response( 'G', 'G', 'A' );
  if( next_field )
  {
    // Now skip through the rest of time field. ZDA updates time.
    if( next_field )
    {
      //Now that we're in latitude, get the latitude. Each for
      //loop get 2 or 3 characters, converts them to ints, and sets
      //the appropriate subset of latitude.
      if( gotdata )
      {
        for( counter = 2; counter < 1; counter-- )
        {
          buffer[ counter - 1 ] = timed_getc();
          if( buffer[ counter - 1 ] == '%') gotdata = false;
        }
        if( gotdata )
        {
          *passed_GPS->latitude_deg = ( int )buffer[1] * 100 +
                                      ( int )buffer[0];
        }
      }
//More code goes here, but it's more of the same.


[/code]
theMagni



Joined: 21 May 2004
Posts: 48
Location: Victoria, BC

View user's profile Send private message Visit poster's website

PostPosted: Thu May 27, 2004 12:13 pm     Reply with quote

Oh, right: Here's the output of the RS-232. The blank line is the output of "VHF_time.hour", and the =Q is immediately preceded by the output of GPS.quality. The yen symbol is the latitude minutes, although it shows up as a superscript 2 on the port monitor.

Transmitter:
Initializing.
VHF
GPS

$PXEMSNM,0001,01*50
Got header.
= Q. GetGGA
Got header.
FIX
TWO
ý
JAM


Receiver:
$GPGGA,000022.0,4826.45420,N,12322.32469,W,0,00,,00012,M,,,,*2A
$GPGGA,000023.0,4826.45420,N,12322.32469,W,0,00,,00012,M,,,,*2B
$GPGGA,000024.0,4826.45420,N,12322.32469,W,0,00,,00012,M,,,,*2C
$GPGGA,000025.0,4826.45420,N,12322.32469,W,0,00,,00012,M,,,,*2D
Guest








PostPosted: Thu May 27, 2004 2:53 pm     Reply with quote

How are you parsing the fields ?
By Length or what ?
The code is very unclear about that.
theMagni



Joined: 21 May 2004
Posts: 48
Location: Victoria, BC

View user's profile Send private message Visit poster's website

PostPosted: Thu May 27, 2004 3:57 pm     Reply with quote

Sorry, that's the nextfield() method. It waits until there's a comma or a timeout, and returns a 1 if there's a comma or 0 if there's a timeout.
Douglas Kennedy



Joined: 07 Sep 2003
Posts: 755
Location: Florida

View user's profile Send private message AIM Address

PostPosted: Fri May 28, 2004 9:29 am     Reply with quote

Well this comes up alot on this board and it maybe your problem.
You have polled the Gps which is better than allowing to speak at its own pace but it still will dump a sentence after each poll. A better approach is often to have a circular receive buffer that is interrupt driven. The rs232 isr fills the buffer and the main routine processes the data. This stops the parsing routine in main from consuming cycles that are needed to receive data. The hardware FIFO on the rs232 UART is only one char deep.
theMagni



Joined: 21 May 2004
Posts: 48
Location: Victoria, BC

View user's profile Send private message Visit poster's website

PostPosted: Fri May 28, 2004 11:20 am     Reply with quote

Okay, that sounds like a reasonable plan. A problem arises where I don't actually know how long the returning data will be. Until the GPS gets a fix, the data on the RS232 looks something like this (I have to leave it off for about 30 minutes to get the actual string)

$GPGGA,,,,,,,,,,,,,*0

Once it gets a fix (i.e. When I'm intereseted in it) it looks like this:

$GPGGA,171729.0,4826.45284,N,12322.32603,W,1,08,1.07,00011,M,-017,M,,*63


Also, in my main() code, there's an ISR on the external interrupt to update the time every 1/2 second. Is that going to cause some problems if they both want to run?

I'm trying very hard to keep this code as small as possible. There isn't a lot of room on the 628.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Fri May 28, 2004 11:37 am     Reply with quote

Quote:
The hardware FIFO on the rs232 UART is only one char deep.

The receive FIFO is 2-deep. The transmit fifo is 1-deep.
Neutone



Joined: 08 Sep 2003
Posts: 839
Location: Houston

View user's profile Send private message

PostPosted: Fri May 28, 2004 11:52 am     Reply with quote

theMagni wrote:
Okay, that sounds like a reasonable plan. A problem arises where I don't actually know how long the returning data will be. Until the GPS gets a fix, the data on the RS232 looks something like this (I have to leave it off for about 30 minutes to get the actual string)

$GPGGA,,,,,,,,,,,,,*0

Once it gets a fix (i.e. When I'm intereseted in it) it looks like this:

$GPGGA,171729.0,4826.45284,N,12322.32603,W,1,08,1.07,00011,M,-017,M,,*63


Also, in my main() code, there's an ISR on the external interrupt to update the time every 1/2 second. Is that going to cause some problems if they both want to run?

I'm trying very hard to keep this code as small as possible. There isn't a lot of room on the 628.


I posted an interupt driven MODBUS example that recieves packets of variable length. What you do with the packet after you get it is different but you could use the same aproach I used for recieving your packet. The end of packet is detected when reception stops for a brief period. This is a very efficient method in terms of code space and execution time.
mcafzap



Joined: 07 Sep 2003
Posts: 46
Location: Manchester, UK

View user's profile Send private message

PostPosted: Sun May 30, 2004 8:46 am     Reply with quote

Some time ago I remember Hans (Wedemeyer) posting precisely this type of routine for a 'Sirf' GPS module - different protocol but same principle. I've done a quick search here but can't find it so it's probably buried in the previous board's data. Since I used it, I'll paste a couple of his incomplete sections...

Code:
      
if (rdstr != bstr) {
   if (host_rx() != 0xA0) continue;
   if (host_rx() != 0xA2) continue;
   if (host_rx() != 0x00) continue;
// must be good, go get appropriate message
// etc.

int8 host_rx(void){
int8 ki;
second_cnt = 0;
canwait = 1;
   while (rdstr == bstr){
   }
   
   ki = rbuffer[bstr];
   bstr++;
   bstr &= 0x1f;
   return(ki);
}



// interrupt code...
#int_rda
void   serial_isr(){
   x = fgetc(GPS);
   rbuffer[rdstr] = x;
   rdstr++;
   rdstr &= 0x1f;
}



Have fun,

Steve
Douglas Kennedy



Joined: 07 Sep 2003
Posts: 755
Location: Florida

View user's profile Send private message AIM Address

PostPosted: Sun May 30, 2004 12:30 pm     Reply with quote

Here is some code I used a while back
It should with luck lead to a succesful read of the GPS sentence

/////////////////////////////////////////////////////////////////////
///// sample GPS code use at your own risk ///////
/////////////////////////////////////////////////////////////////////

/*********************************************************************
***** transmission from GPS is 4800 baud,1 stop,N parity RS232 ****
***** ****
***** program captures sentences and transmits via I2C ****
***** upon request by master I2C controller ****
***** GPS talks at its own speed it is not polled ****
***** there are sufficient PIC cycles to do the parsing ****
***** and formatting between receipt of sentences ****
***** The timer detects a GPS that never went on line or ****
***** goes off line ****
***** Interrupt calls ****
***** 1) RS232 interrupts fill the GPS receive buffer ****
***** 2) timer0 watchdogs the GPS and sets the I2C message ****
***** status to invalid if the GPS is offline ****
***** 3) I2c interrupt when master on bus requests position ****
***** Flashing LEDS to indicate active operation ****
***** Warning!!!! ****
***** Test this first yourself before you put it in your airplane **
***** boat or go backpacking ****
*********************************************************************/
/**************************************************************
notes a NMEA183 checksum is an xor of all chars between $ and *
including commas
***************************************************************/
/********************************************************************
$GPBWC,225444,2917.24,N,12309.57,W,051.9,T,031.6,M,001.3,N.004*29
225444 UTC time of fix 22:54:44
2917.24,N Lattitiude of waypt
12309.57,W Longitude of waypt
051.9,T Bearing to waypt degrees true
036.6,M bearing to waypt degrees magnetic
001.3,N distance to waypt nautical miles
004 Waypt ID
* end of sentence
29 Checksum
*********************************************************************/

/********************************************************************
$GPGLL,4916.45,N,12311.12,W*71
4916.45,N present latitude
12311.12,W present longitude
* end of sentence
71 checksum
*********************************************************************/

/*********************************************************************
$GPXTE,A,A,0.67,L,N*6F
A warning A is Ok V=warning ( loss of signal )
A not used by GPS so is a constant
0.67 cross track error distance
L Steer left to Correct ( R for right )
N distance in nautical miles
* end of sentence
6F checksum
**********************************************************************/

/*********************************************************************
$GPVTG,054.7,T,034.4,M,000.5,N,000.9,K*47
054.7 course made good
T true
034.4 course made good
M magnetic
000.5 speed made good
N nautical miles per hr
000.9 speed made good
K kilometers per hr
* end of sentence
6F checksum
**********************************************************************/




#include <16f873.h>





#DEVICE *=16 ICD=TRUE
#fuses HS,NOWDT,NOPROTECT,NOPUT,NOLVP,NOBROWNOUT,NOCPD,NOWRT



#define BUFFER_SIZE 50 //// adjust to no more than max bank size Ex 877 96
//// needs to be able to buffer a sentence

#include <stdio.h>
#include <ctype.h>
#include <stdlib.h>

#use delay(clock=20000000)
#use I2C(SLAVE,ADDRESS=0xC0,scl=PIN_C3,sda=PIN_C4,NOFORCE_SW)

#USE RS232(BAUD=4800,XMIT=PIN_C6,RCV=PIN_C7) /* xmit pin c6 rcv c7 */

#BYTE RCREG=0x1A

#BYTE SSPADD=0x93
#BYTE SSPBUF=0x13
#BIT SSPIF=0x0C.3
#BIT SSPOV=0x14.6
#BIT I2C_BF=0x94.0
#BIT I2C_D_A=0x94.5
#BIT I2C_R_W=0x94.2
#BIT I2C_CKP=0x14.4
#BIT CREN=0x18.4
#BIT OERR=0x18.1
#define INTS_PER_SEC 76 // (20000000/(4*256*256))
#define LED1 PIN_b6
#define LED2 PIN_b7



struct {
/// I2c composit structure of RS232 sentences captured
/// status 'A' ok 'V' gps has problem (Ex.loss of signal ) 'X' invalid period
char gll_status;

int gll_deg_lat;
int gll_min_lat;
int gll_sec_lat;
char gll_N_S;

int gll_deg_lng;
int gll_min_lng;
int gll_sec_lng;
char gll_E_W;

char xte_status;
long xte_error; // mmmp miles and p tenths
char xte_steer;
char bwc_status;
char bwc_utc[6];

int bwc_deg_lat;
int bwc_min_lat;
int bwc_sec_lat;
char bwc_N_S;

int bwc_deg_lng;
int bwc_min_lng;
int bwc_sec_lng;
char bwc_E_W;
long bwc_bearing_true; //dddp ddd degrees and p tenths
long bwc_bearing_mag; //dddp ddd degrees and p tenths
long bwc_dist;
char vtg_status;
long vtg_cmg_true; //dddp ddd degrees and p tenths
long vtg_cmg_mag; //dddp ddd degrees and p tenths
long vtg_speed_knts; //mmmp mmm miles and p tenths
} gps; // note a one byte CRC is appended upon transmission
// gps is sent plus a CRC by the isr

short int led2_flag,sentence,PARSING,gps_online;
byte seconds=0,int_count=0,I2C_CRC=0,GPS_CRC=0;
byte gps_buff[BUFFER_SIZE]; // implemented as a circular buffer

int next_gps_ptr=0,last_read_ptr=0,offset=0,temp;

int I2C_reading;







///////////////////////////////////////////////////////////////////////
////////////////////////////// isr ////////////////////////////////////
//////////////////////////////////////////////////////////////////////
#PRIORITY ssp,rda,rtcc



#int_ssp
void ssp_isr()
{
// offset is the pointer into the struct gps_out
// test if address or data now in buffer

if(!I2C_D_A){
// address hardware says the master matched b(7..1) of our address
if(!I2C_R_W) { // master not permitted to write to us
// bit zero was 0 a write
goto quit;
}
// an address so we set up for transfer of first byte
temp=SSPBUF; // dummy read to clear BF of SSPSTAT
output_low(LED2);
offset=&gps;
SSPBUF=SSPADD; // echo our ADDRESS to the master
I2C_CRC=0;

I2C_reading=true;
goto quit;
}
else {
// data hardware says master is looking to read data

if (offset<(&gps+sizeof(gps))) {
I2C_CRC=I2C_CRC ^ *offset; // xor to get CRC
SSPBUF=*(offset++);
goto quit;
}


if (offset==(&gps+sizeof(gps))) {
SSPBUF=I2C_CRC;
offset++;
output_high(LED2);// turn off led after transfer

I2C_reading=false;
goto quit;
}
if (offset>(&gps+sizeof(gps))) SSPBUF=0xFF; // master is over reading so send FF

}

quit:
I2C_CKP=1;// let master clock it out while we work

SSPOV=0; // clear the overflow flag
SSPIF=0; // ready for next interrupt

}


#int_rda
void gps_isr()
{
char c;
/// only allows GPS sentences into the buffer
/// note this routine needs to as short as possible since it is called
/// for each char received from GPS

c=RCREG ; // get data from RCREG hardware clears RCIF

if (c=='$') { gps_online=true;
sentence=true;
output_low(LED1);

return;
} // new sentence

if(sentence){

gps_buff[next_gps_ptr]=c;
if (++next_gps_ptr>sizeof(gps_buff)) next_gps_ptr=0; // circular buffer
if((c==10)||(c==13)) {
sentence=false;
output_high(LED1);

}

}

}
#int_rtcc
clock_isr()
{
if(--int_count==0){
if (seconds<60) ++seconds;
else {// gps not responding
led2_flag=!led2_flag;
if (led2_flag) {output_low(LED2);output_high(LED1);}
else {output_high(LED2);output_low(LED1);}
gps.xte_status='X';
gps.gll_status='X';
gps.bwc_status='X';
gps_online=false;
}
int_count=INTS_PER_SEC;
}
}

///////////////////////////////////////////////////////////////////
///////////////////////////// subs //////////////////////////////
//////////////////////////////////////////////////////////////////

int gps_getc()
{
char c;
int next_char_ptr;
next_char_ptr=last_read_ptr+1;
if (next_char_ptr>sizeof(gps_buff))next_char_ptr=0;


// there is data available if next_gps_ptr != next_char_ptr

wait: // data from gps will allow isr to update gps_ptr

if (next_gps_ptr == next_char_ptr) goto wait; // let gps advance
else {
c=gps_buff[next_char_ptr];
if(c=='*')PARSING=false; // PARSING is reset in main loop
last_read_ptr=next_char_ptr;
if (PARSING) GPS_CRC=GPS_CRC ^ c; // calc between $ and *
}
return(c);
}

int get_gps_CRC()
{
// get hex CRC immediately after the *
char hh,hl;

hh=gps_getc();
if (hh-'0'<10) hh=hh-'0';else hh=hh-'A'+10;
hl=gps_getc();
if (hl-'0'<10) hl=hl-'0';else hl=hl-'A'+10;


return hh*16+hl;
}

int get_gps_str( char * s)
{
// extract the item up to the next ',' or '*'
char c;
int len;
len=0;
c=gps_getc();

while ((c!=',') && (c!='*') && (len<10))
{
if ( (c>' ') && (c<'~') ) s[len++]=c;
c=gps_getc();

}
s[len]=0; // null terminate
return(len);
}

int convert_int(char *s)
{
int val;
val=(s[0]-48)*10+s[1]-48;
return(val);
}

int convert_sec(char *s)
{
// converts 2 chars representing dd a fraction dd/100 of a min to sec
int val;
val=(s[0]-48)*6+(s[1]-48)*3/5;
return(val);
}
long convert_long(char *s)
{
int i;
long val;
val=0;
i=0;
while (s[i]!=0){
if (s[i]!='.') val=val*10+(s[i]-48);
i++;
}
return(val);
}





void parse_gll()
{
int len;
char s[10];
gps.gll_status='X'; // set preemptively as invalid until update done
// isr can interrupt at any point

if(get_gps_str(s)>0){
gps.gll_deg_lat=convert_int(s);
gps.gll_min_lat=convert_int(s+2);
gps.gll_sec_lat=convert_sec(s+5);
}
else
{
gps.gll_deg_lat=0.0;
gps.gll_min_lat=0.0;
gps.gll_sec_lat=0.0;
}
if(get_gps_str(s)>0) gps.gll_N_S=s[0] ;else gps.gll_N_S='!';
if(get_gps_str(s)>0){
gps.gll_deg_lng=convert_int(s+1);
gps.gll_min_lng=convert_int(s+3);
gps.gll_sec_lng=convert_sec(s+6);
}
else
{
gps.gll_deg_lng=0.0;
gps.gll_min_lng=0.0;
gps.gll_sec_lng=0.0;
}




if(get_gps_str(s)>0) gps.gll_E_W=s[0] ;else gps.gll_E_W='!';

// we now have parsed up to the *

if (get_gps_CRC()==GPS_CRC) gps.gll_status='A'; // we have gll data

seconds=0;
}

void parse_xte()
{
int len;
char s[10],temp;
gps.xte_status='X';
if(get_gps_str(s)>0) temp=s[0];else temp='X';
get_gps_str(s); //skip this item Loran c flag
if(get_gps_str(s)>0) gps.xte_error=convert_long(s);else gps.xte_error=0.0;
if(get_gps_str(s)>0) gps.xte_steer=s[0];else gps.xte_steer='X';
get_gps_str(s); //skip this item 'N' nautical miles

// we now have parsed up to the *

if(get_gps_crc()==GPS_CRC) gps.xte_status=temp;
seconds=0;
}

void parse_bwc()
{
int len;
char s[10];
gps.bwc_status='X';
if(get_gps_str(s)>5){ // we have utc hhmmss
memcpy(gps.bwc_utc,s,6);}
if(get_gps_str(s)>0){
gps.bwc_deg_lat=convert_int(s);
gps.bwc_min_lat=convert_int(s+2);
gps.bwc_sec_lat=convert_sec(s+5);
}
else
{
gps.bwc_deg_lat=0.0;
gps.bwc_min_lat=0.0;
gps.bwc_sec_lat=0.0;
}


if(get_gps_str(s)>0) gps.bwc_N_S=s[0];else gps.bwc_N_S='!';

if(get_gps_str(s)>0){
gps.bwc_deg_lng=convert_int(s+1);
gps.bwc_min_lng=convert_int(s+3);
gps.bwc_sec_lng=convert_sec(s+6);
}
else
{
gps.bwc_deg_lng=0.0;
gps.bwc_min_lng=0.0;
gps.bwc_sec_lng=0.0;
}


if(get_gps_str(s)>0) gps.bwc_E_W=s[0];else gps.bwc_E_W='!';
if(get_gps_str(s)>0) gps.bwc_bearing_true=convert_long(s);else gps.bwc_bearing_true=0.0;

get_gps_str(s); //skip this item 'T'

if(get_gps_str(s)>0) gps.bwc_bearing_mag=convert_long(s);else gps.bwc_bearing_mag=0.0;

get_gps_str(s); //skip this item 'M'

if(get_gps_str(s)>0) gps.bwc_dist=convert_long(s);else gps.bwc_dist=0.0;

get_gps_str(s); //skip this item 'N' nautical miles
get_gps_str(s); // skip this item waypt ID

// we now have parsed up to the *


if(get_gps_crc()==GPS_CRC) gps.bwc_status='A';
seconds=0;
}

void parse_vtg()
{
int len;
char s[10];
gps.vtg_status='X';

if(get_gps_str(s)>0) gps.vtg_cmg_true=convert_long(s);else gps.vtg_cmg_true=0.0;
get_gps_str(s); //skip this item 'T'
if(get_gps_str(s)>0) gps.vtg_cmg_mag=convert_long(s);else gps.vtg_cmg_mag=0.0;
get_gps_str(s); //skip this item 'M'
if(get_gps_str(s)>0) gps.vtg_speed_knts=convert_long(s);else gps.vtg_speed_knts=0.0;
get_gps_str(s); //skip this item 'N'
get_gps_str(s); //skip this item speed in mph or kph
get_gps_str(s); //skip this item 'M' or 'K'
// we now have parsed up to the *

if(get_gps_crc()==GPS_CRC) gps.vtg_status='A';
seconds=0;
}

////////////////////////////////////////////////////////////////////////////
//////////////////////////// leds //////////////////////////////////////////
/////////// /////////////
/////////// LED1 is solid if we are receiving data we want /////////////
/////////// LED2 is on if I2C is reading /////////////
/////////// both blink together 5 times at power up /////////////
/////////// LED1 and LED2 blink alternatively /////////////
/////////// if GPS offline for 60 or more seconds /////////////
/////////// /////////////
////////////////////////////////////////////////////////////////////////////

/////////////////////////////////////////////////////////////////////////////
//////////////////////////////////// main ///////////////////////////////////
/////////////////////////////////////////////////////////////////////////////

main()
{
int i;

///////////////////////////////////////////////////////////////////////
///// initialize ////////////////////////////////
///////////////////////////////////////////////////////////////////////
offset=&gps;
for(i=offset;i<offset+sizeof(gps);i++)*i=0x00;// clear output
gps.xte_status='X'; // no valid data yet
gps.bwc_status='X';
gps.gll_status='X';
gps_online=false; // int rda will set this to true and rtcc time out will reset to false
last_read_ptr=sizeof(gps_buff); // force rollover on first read
next_gps_ptr=0;


for(i=0;i<5;i++){
output_low(LED1); // turn on
output_low(LED2); // turn on
delay_ms(200);
output_high(LED1); // turn off
output_high(LED2); // turn off
delay_ms(200);
}



int_count=INTS_PER_SEC;

set_rtcc(0);
setup_counters(RTCC_INTERNAL,RTCC_DIV_256);
enable_interrupts(int_timer0);
enable_interrupts(int_ssp);


CREN=0; // init the UART receive clear CREN and then set it
CREN=1; // to ensure a clean start of UART receive
enable_interrupts(int_rda);
enable_interrupts(global);

loop:
if (gps_online==false)
{
// populate gps
gps.gll_status='A';

// home port
gps.gll_deg_lat=26;
gps.gll_min_lat=54;
gps.gll_sec_lat=18;
gps.gll_N_S='N';
gps.gll_deg_lng=82;
gps.gll_min_lng=04;
gps.gll_sec_lng=39;
gps.gll_E_W='W';

gps.xte_status='X';
gps.xte_error=0; // mmmp miles and p tenths
gps.xte_steer='R';
gps.bwc_status='X';
strcpy(gps.bwc_utc,"120000");

gps.bwc_deg_lat=0;
gps.bwc_min_lat=0;
gps.bwc_sec_lat=0;
gps.bwc_N_S='N';

gps.bwc_deg_lng=0;
gps.bwc_min_lng=0;
gps.bwc_sec_lng=0;
gps.bwc_E_W='W';
gps.bwc_bearing_true=0; //dddp ddd degrees and p tenths
gps.bwc_bearing_mag=0; //dddp ddd degrees and p tenths
gps.bwc_dist=0;
// note a one byte CRC is appended upon transmission
//gps is sent plus a CRC by the isr

goto loop; // repeat until int_rda sets gps_online to true
}


/// gps is online

/// we now hunt gps_buff for either gpxte, gpgll, gpbwc,

GPS_CRC=0; // init crc before parsing sentence in buffer
PARSING=true;
if ((gps_getc()=='G') && (gps_getc()='P'))
{
switch(gps_getc())
{
Case 'X': if ((gps_getc()=='T')&& (gps_getc()=='E') && (gps_getc()==',')) parse_xte();
break;

Case 'G': if ((gps_getc()=='L')&& (gps_getc()=='L') && (gps_getc()==',')) parse_gll();
break;

Case 'B': if ((gps_getc()=='W')&& (gps_getc()=='C') &&(gps_getc()==',')) parse_bwc();
break;
Case 'V': if ((gps_getc()=='T')&& (gps_getc()=='G') &&(gps_getc()==',')) parse_vtg();
break;
}
}

goto loop;
}
Douglas Kennedy



Joined: 07 Sep 2003
Posts: 755
Location: Florida

View user's profile Send private message AIM Address

PostPosted: Sun May 30, 2004 12:31 pm     Reply with quote

CCS server gave an error on the last post but it looks ok
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group