/*  
  FB_REG_Monitor.c
  Application Test companion Code for FoxBone Development
  on FOX VHDL Board to continuously monitor the state of
  a FoxBone register on a console.
	This program accepts a single parameter for the register address
  to monitor. It reads that register every second and prints its value.
  (based on FoxBone protocol interface specifications rel 0.7)

  For more info see: http://www.acmesystems.it/?id=120
  Author: Roberto Asquini
  Copyright (C) 2006 ACME Systems srl (http://www.acmesystems.it)
  
  This 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 of the License, or
  (at your option) any later version.
    
  This example 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.
    
  To have a copy of the GNU General Public License write to the Free Software
  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
*/

#include "stdio.h"
#include "stdlib.h"
#include "unistd.h"
#include "sys/ioctl.h"
#include "fcntl.h"
#include "time.h"
#include "string.h"
#include "foxbone_userspace.h"
#include <linux/foxbone_syscalls.h>

#include <sys/select.h>

int kbhit(void)  /* by Alan Cox - http://www.linuxjournal.com/article/1138 */
{
  struct timeval tv;
  fd_set read_fd;

  /* Do not wait at all, not even a microsecond */
  tv.tv_sec=0;
  tv.tv_usec=0;

  /* Must be done first to initialize read_fd */
  FD_ZERO(&read_fd);

  /* Makes select() ask if input is ready:
   * 0 is the file descriptor for stdin    */
  FD_SET(0,&read_fd);

  /* The first parameter is the number of the
   * largest file descriptor to check + 1. */
  if(select(1, &read_fd,
            NULL, /*No writes*/
            NULL, /*No exceptions*/
            &tv)
     == -1)
    return 0;	/* An error occured */

  /*	read_fd now holds a bit map of files that are
   * readable. We test the entry for the standard
   * input (file 0). */
  if(FD_ISSET(0,&read_fd))
    /* Character pending on stdin */
    return 1;

  /* no characters were pending */
  return 0;
}

  
void print_usage(void){
	printf("\nFB_REG_Monitor usage: FB_REG_Monitor addressnumpulses\n"
     " foxbone register address has to be entered in hexadecimal \n"
     "To exit press ENTER. \n" 
	   "Typical usage: \n"
           "FB_REG_Monitor 40 41 42 43  (monitors FoxBone registers 0x40, 0x41, 0x42, 0x43)\n");
};


int main(int argc, char **argv) {

  // minimal input validation
  int retval, addr1=0, addr2=0, addr3=0, addr4=0;
  unsigned int value1, value2, value3, value4;
  if (argc<2) {
    print_usage();
    return(1);
  }
  if (argc > 1) {
    retval = sscanf(argv[1],"%x", &addr1);
  }
  if (argc > 2) {
    retval = sscanf(argv[2],"%x", &addr2);
  }
  if (argc > 3) {
    retval = sscanf(argv[3],"%x", &addr3);
  }
  if (argc > 4) {
    retval = sscanf(argv[4],"%x", &addr4);
  }
  if (argc > 1) {
    while(1) {
      value1 = foxboneread(addr1);                                                                      
      printf("FoxBone in 0x%04x:0x%04x; ",addr1, value1);                           
      if (argc > 2 ) {
        value2 = foxboneread(addr2);                                                                      
        printf("0x%04x:0x%04x; ",addr2, value2);                           
      }
      if (argc > 3 ) {
        value3 = foxboneread(addr3);                                                                      
        printf("0x%04x:0x%04x; ",addr3, value3);                           
      }
      if (argc > 4 ) {
        value4 = foxboneread(addr4);                                                                      
        printf("0x%04x:0x%04x; ",addr4, value4);                           
      }
      printf("\n");                           
      sleep(1);
      if (kbhit()==1) break;
    }
  }

	return(0);
} // end main()


