/*
*************************************************************
*                                                           *
*  WOODS HOLE OCEANOGRAPHIC INSTITUTION                     *
*  UPPER OCEAN PROCESSES GROUP                              *
*  PHYSICAL OCEANOGRAPHY DEPT.                              *
*  WOODS HOLE, MASSACHUSETTS USA  02543                     *
*                                                           *
*  File: vmcm2asc.c             Model: -                    *
*                                                           *
*  Function: VMCM2 binary data file to ASCII converter      *
*            for Firmware Ver 2.5x
*                                                           *
*  Project: VMCM2                                           *
*                                                           *
*  Programmer: G.A.                                         *
*                                                           *
*  Copyright (c) 2002 Woods Hole Oceanographic Institution  *
*                                                           *
*************************************************************
 
*/

/* Additional reserved words not recognized by Source Print.
   <e> uchar
*/

/*
*   Program to read and convert to ascii the binary output file from
*   the VMCM2 FLASH memory card
*
*
*   Usage: vm2asc datafile outputfile
*          datafile   -  binary data file name
*          outputfile - ascii data file name
*/


#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>

/* this is the usage string */
char usage[] = "\nUsage: vm2asc datafile outputfile\n
			 datafile   - VMCM2 binary data file name\n
			 outputfile - ascii data file name\n\n";

/* a structure to hold the time values from the RTC DS1585. */
struct time_type
   {
   unsigned char hour;
   unsigned char min;
   unsigned char sec;
   unsigned char day;
   unsigned char mon;
   unsigned int year;
   };

/* this is the VM data record structure - 34 bytes */
struct VM2_record
   {
   struct time_type time1;      /* 7 bytes of time */
   unsigned char mux_parm;      /* which option parameter in this record */
   short vel_e;  	        /* packed vel east data 0 - 655.35 cm/sec */
   short vel_n;   		/* packed vel north data 0 - 655.35 cm/sec */
   short rotor1;                /* rotor 1 counts 0 - 65535 */
   short rotor2;                /* rotor 2 counts 0 - 65535 */
   unsigned short compass;      /* packed compass direction in
                                    12 ls bits 0 - 359.9 degrees ;
                                    ms bit = tilt x sign,
                                    2nd ms bit = tilt y sign */
   unsigned char tiltx;         /* packed tilt x 0 - 25.5 degrees */
   unsigned char tilty;         /* packed tilt y 0 - 25.5 degrees */
   short sea_temp;              /* packed sea temperature */
   float res_therm;             /* corrected thermistor resistance */
   float opt_parm;              /* reading of a/d channel indicated in rec_mux */
   unsigned short used;         /* set to 0xA5A5 upon record write */
   unsigned short vm2_CRC;      /* CRC of previous bytes */
   };

struct VM2_record VM2_data;
   
/* main program */
void main(argc,argv)
int argc;
char *argv[];
{

	FILE *fd1,*fd2;
	char outbuf[100];
	char buffer;
	short intbuf;
	unsigned short used;
	long lbuf;
        unsigned char cvar;
        unsigned short ivar;
	float fvar;
	int ret;
	int i,j;
	struct tm *tptr;

   if (argc <  2)
      {
      printf("%s",usage);
      exit(-1);
      }

	/* index to input filename */
   i = 1;

   /* input file name */
   fd1 = fopen(argv[i],"rb");
   if ( fd1 == NULL ) {
      printf("\nUnable to open input file %s\n",argv[i]);
      printf("%s",usage);
      exit(-1);
   }
   printf("\nOpening input file %s\n",argv[i]);
   i++;

   /* output file name */
   fd2 = fopen(argv[i],"w");
   if ( fd2 == NULL ) {
      printf("\nUnable to open output file %s\n",argv[i]);
      printf("%s",usage);
      exit(-1);
   }
   printf("\nOpening output file %s\n",argv[i]);

   /* stay here until EOF, error, or last record aborts */
   while (1)
      {
      /* first are 7 time bytes, first five are char */
      /* read the byte, put a byte */
      ret = fread(&buffer,sizeof(char),1,fd1);
      if ( ret != 1 )
         goto end;

      /* transfer it to temp storage */
      VM2_data.time1.hour = (unsigned char)buffer;

      /* read the byte, put a byte */
      ret = fread(&buffer,sizeof(char),1,fd1);
      if ( ret != 1 )
         goto end;

      /* transfer it to temp storage */
      VM2_data.time1.min = (unsigned char)buffer;

      /* read the byte, put a byte */
      ret = fread(&buffer,sizeof(char),1,fd1);
      if ( ret != 1 )
         goto end;

      /* transfer it to temp storage */
      VM2_data.time1.sec = (unsigned char)buffer;

      /* read the byte, put a byte */
      ret = fread(&buffer,sizeof(char),1,fd1);
      if ( ret != 1 )
         goto end;

      /* transfer it to temp storage */
      VM2_data.time1.day = (unsigned char)buffer;

      /* read the byte, put a byte */
      ret = fread(&buffer,sizeof(char),1,fd1);
      if ( ret != 1 )
         goto end;

      /* transfer it to temp storage */
      VM2_data.time1.mon = (unsigned char)buffer;

      /* next read the 2 "year" bytes */
      ret = fread(&intbuf,sizeof(short),1,fd1);
      if ( ret != 1 )
         goto end;
      /* transfer it to temp storage */
      VM2_data.time1.year = intbuf;

      /* next, read the mux_parm byte, put a byte */
      ret = fread(&buffer,sizeof(char),1,fd1);
      if ( ret != 1 )
         goto end;

      /* transfer it to temp storage */
      VM2_data.mux_parm = (unsigned char)buffer;

      /* next read Ve data value */
      ret = fread(&intbuf,sizeof(short),1,fd1);
      if ( ret != 1 )
         goto end;
      /* transfer it to temp storage */
      VM2_data.vel_e = intbuf; 

      /* next read Vn data value */
      ret = fread(&intbuf,sizeof(short),1,fd1);
      if ( ret != 1 )
         goto end;
      /* transfer it to temp storage */
      VM2_data.vel_n = intbuf; 

      /* next read Rotor 1 value */
      ret = fread(&intbuf,sizeof(short),1,fd1);
      if ( ret != 1 )
         goto end;
      /* transfer it to temp storage */
      VM2_data.rotor1 = intbuf;

      /* next read Rotor 2 value */
      ret = fread(&intbuf,sizeof(short),1,fd1);
      if ( ret != 1 )
         goto end;
      /* transfer it to temp storage */
      VM2_data.rotor2 = intbuf; 

      /* next read LastCompass value */
      ret = fread(&intbuf,sizeof(short),1,fd1);
      if ( ret != 1 )
         goto end;
      /* transfer it to temp storage */
      VM2_data.compass = intbuf;

      /* next read TiltX in unsigned char */
      /* read the byte, put a byte */
      ret = fread(&buffer,sizeof(char),1,fd1);
      if ( ret != 1 )
         goto end;

      /* transfer it to ASCII file */
      VM2_data.tiltx = buffer; 

      /* next read TiltY in unsigned char */
      /* read the byte, put a byte */
      ret = fread(&buffer,sizeof(char),1,fd1);
      if ( ret != 1 )
         goto end;

      /* transfer it to ASCII file */
      VM2_data.tilty = buffer; 

      /* next read SeaTemp data */
      ret = fread(&intbuf,sizeof(short),1,fd1);
      if ( ret != 1 )
         goto end;
      /* transfer it to temp storage */
      VM2_data.sea_temp = intbuf; 

      /* next read 4 float bytes - the thermistor resistance */
      ret = fread(&fvar,sizeof(float),1,fd1);
      if ( ret != 1 )
         goto end;

      /* transfer it to temp storage */
      VM2_data.res_therm = fvar;

      /* next read 4 float bytes - the muxed parameter */
      ret = fread(&fvar,sizeof(float),1,fd1);
      if ( ret != 1 )
         goto end;

      /* transfer it to temp storage */
      VM2_data.opt_parm = fvar;

      /* next read the 2 "used" bytes - they should be A5A5 in a good
         record */
      ret = fread(&used,sizeof(short),1,fd1);
      if ( ret != 1 )
         goto end;

      /* transfer "used" to temp storage */
      VM2_data.used = used;

      /* next read the 2 CRC bytes - unused set to 0 for now */
      ret = fread(&intbuf,sizeof(short),1,fd1);
      if ( ret != 1 )
         goto end;

      /* transfer CRC to ASCII file */
      VM2_data.vm2_CRC = intbuf;

      /* process and write out the record */
      /* first do time */
      fprintf(fd2,"%.2u,",(unsigned int)VM2_data.time1.hour); 
      fprintf(fd2,"%.2u,",(unsigned int)VM2_data.time1.min);  // minute
      fprintf(fd2,"%.2u,",(unsigned int)VM2_data.time1.sec);  // second
      fprintf(fd2,"%.2u,",(unsigned int)VM2_data.time1.day); 
      fprintf(fd2,"%.2u,",(unsigned int)VM2_data.time1.mon); 
      fprintf(fd2,"%.4u,",(unsigned int)VM2_data.time1.year);

      /* now Ve and Vn */
      fprintf(fd2,"%7.2f,",((float)VM2_data.vel_e) / 50.0); 
      fprintf(fd2,"%7.2f,",((float)VM2_data.vel_n) / 50.0);

      /* rotors */
      fprintf(fd2,"%6d,",VM2_data.rotor1); 
      fprintf(fd2,"%6d,",VM2_data.rotor2);

      /* last compass - mask for 12 ls bits only */
      fprintf(fd2,"%6.1f,",((float)(VM2_data.compass & 0xFFF)) / 10.0);

      /* last tilts - sign bit in last compass 2 ms bits */
      if (VM2_data.compass & 0x8000)
         /* negative */
         fprintf(fd2,"%6.1f,",((float)VM2_data.tiltx) / -10.0);
      else
         /* positive */
         fprintf(fd2,"%6.1f,",((float)VM2_data.tiltx) / 10.0);

      if (VM2_data.compass & 0x4000)
         /* negative */
         fprintf(fd2,"%6.1f,",((float)VM2_data.tilty) / -10.0);
      else
         /* positive */
         fprintf(fd2,"%6.1f,",((float)VM2_data.tilty) / 10.0);

      /* sea temp */
      fprintf(fd2,"%7.3f,",(((float)VM2_data.sea_temp) / 100.0) - 25.0);

      /* sea temp thermistor */
      fprintf(fd2,"%7.1f,",VM2_data.res_therm);

      /* muxed parameter number */
      fprintf(fd2,"%3u,",(unsigned int)VM2_data.mux_parm);

      /* muxed parameter */
      fprintf(fd2," %.3f\n",VM2_data.opt_parm);

      /* look for EOf */
      if (feof(fd1))
         break;
      } /* end while */

end:
   printf("\n");
   fclose(fd1);
   fclose(fd2);
}
