/* -*- c++ -*- */
/*
 * Copyright 2003,2004 Free Software Foundation, Inc.
 * 
 * This file is part of GNU Radio
 * 
 * GNU Radio is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2, or (at your option)
 * any later version.
 * 
 * GNU Radio is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with GNU Radio; see the file COPYING.  If not, write to
 * the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA.
 */


#include "usrp_stuff.h"
#include "usrp_bytesex.h"


void test_output (usrp_standard_tx *utx, usrp_standard_rx *urx, FILE *fp);

static void
die (const char *msg)
{
  fprintf (stderr, "die: %s\n", msg);
  exit (1);
}


int
main (int argc, char **argv)
{
  int	which_board = 0;
  int	interp = 256;			// 2 MB/sec USB
  int	decim = 128;			// 2 MB/sec USB
  double  center_freq = 0;


  usrp_standard_tx *utx;

  utx = usrp_standard_tx::make (which_board, interp, 1, -1, 2048, 64);

  //  utx->set_pga(0,-20);

  if (utx == 0)
    die ("usrp_standard_tx::make");
    
  if (!utx->set_tx_freq (0, center_freq))
    die ("utx->set_tx_freq");
    
  //////// receiver //////////
  FILE *fp = 0;

  fp = fopen ("out.dat", "w");
  if (fp == 0)
     perror ("out.dat");

      
  int mode = 0;

  usrp_standard_rx *urx = 
         usrp_standard_rx::make (which_board, decim, 1, -1, mode, 2048, 64);

  if (urx == 0)
    die ("usrp_standard_rx::make");

  if (!urx->set_rx_freq (0, center_freq))
    die ("urx->set_rx_freq");

  if (!urx->set_dc_offset_cl_enable(0x0,0xf))
    die ("urx->set_dc_offset_cl");

  fflush (stdout);
  fflush (stderr);

  utx->start();		// start data xfers
  urx->start();		// start data xfers

  test_output (utx, urx, fp);

  delete utx;
  delete urx;

  fclose(fp);

  return 0;
}


void test_output (usrp_standard_tx *utx, usrp_standard_rx *urx, FILE *fp)

{
  static const int BUFSIZE_tx = utx->block_size();
  static const int N_tx = BUFSIZE_tx/sizeof(short);
  short 	   buf_tx[N_tx];
  int		   counter = 0;

  static const int BUFSIZE_rx = urx->block_size();
  static const int N_rx = BUFSIZE_rx/sizeof(short);
  short 	   buf_rx[N_rx];


  bool 	underrun, overrun;
  int 	nunderruns = 0, noverruns = 0;
  int i, ret, flag = 0;
  int data_counter = 0;

  int PERIOD = 2048;

  printf("tx_blocksize = %d, rx_blocksize = %d\n", 
	 utx->block_size(), urx->block_size());

  printf("N_tx = %d, N_rx = %d\n",N_tx, N_rx);

  printf("sizeof(buf_tx) = %d, sizeof(buf_rx) = %d\n",
         sizeof(buf_tx), sizeof(buf_rx));

  fflush (stdout);
  fflush (stderr);

  while(1)
    {

    ////// transmitter ///////

    for (i = 0; i < N_tx; i++)
      {
       if ((counter % 1000000) == 0)
	  flag = flag == 0 ? 1 : 0;

       if (flag == 0)
          buf_tx[i] = host_to_usrp_short (counter & 0x0fff);
       else
	 //          buf_tx[i] = host_to_usrp_short (counter & 0x0fff);
               buf_tx[i] = host_to_usrp_short (0);

       /*
       if (i % 2 == 0)
	 {
	  if (flag == 0)
	    {
             buf_tx[i] = 
                host_to_usrp_short ((short) (4000.0 * cos (2.0*3.14159 * ((double) counter) /((double) PERIOD))));
	    }
          else
	    {
             buf_tx[i] = 
                host_to_usrp_short ((short) (4000.0 * (1.0 + cos (2.0*3.14159 * ((double) counter) /((double) PERIOD)))));
	    }
	 }
       else
	 {
	  if (flag == 0)
	    {
             buf_tx[i] = 
               host_to_usrp_short ((short) (4000.0 * sin (2.0*3.14159 * ((double) counter) / ((double) PERIOD))));
	    }
	  else
	    {
             buf_tx[i] = 
               host_to_usrp_short ((short) (4000.0 * (1.0 + sin (2.0*3.14159 * ((double) counter) / ((double) PERIOD)))));
	    }
	 }
       */

       counter++;
      }

    ret = utx->write (buf_tx, sizeof (buf_tx), &underrun);

    if ((unsigned) ret != sizeof (buf_tx)){
      fprintf (stderr, "test_output: error, ret = %d\n", ret);
    }

    if (underrun){
      nunderruns++;
      printf ("tx_underrun\n");
      //printf ("tx_underrun %9d %6d\n", nbytes, nbytes/BUFSIZE);
    }

    ////// receiver ///////

    ret = urx->read (buf_rx, sizeof (buf_rx), &overrun);
    if (ret != sizeof (buf_rx)){
      fprintf (stderr, "test_input: error, ret = %d\n", ret);
    }

    if (overrun){
      printf ("rx_overrun\n");
      noverruns++;
    }

    for (i = 0; i < N_rx; i++)
      {
	buf_rx[i] = usrp_to_host_short (buf_rx[i]);
        fprintf(fp,"%d %d\n",(int) buf_tx[i], (int) buf_rx[i]);
        data_counter++;
      }
    if (data_counter >= 2e6)
      break;


  }

  utx->wait_for_completion ();

  printf ("%d underruns\n", nunderruns);
  printf ("noverruns = %d\n", noverruns);

}
