// @(#) $Header: /home/abrown/public_html/first/first2003chs/software/simulator/RCS/pb_io.c,v 2.9 2006/12/14 19:40:16 abrown Exp $

/***********************************************************************
  * Copyright (C) 2002, 2003  Allen Brown
  * 
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
  * published by the Free Software Foundation.
  * 
  * This program 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 this program; if not, write to the
  *   Free Software Foundation, Inc.
  *   59 Temple Place, Suite 330
  *   Boston, MA  02111-1307  USA
  * 
  * To contact the author of this software:
  *   Allen Brown
  *   PO Box J
  *   Corvallis, OR
  * 
  *   http://brown.armoredpenguin.com/~abrown/contact.html
  ***********************************************************************/

#include <stdio.h>
#include <string.h>
#include "pb.h"

#define MAXSTRING 80
#define SIARRAYSIZE 32

static int dataInitVolt;
static long serincontrol;
static int serincount;
static char sinamearray[SIARRAYSIZE][11] =
    {"oi_swA    ", "oi_swB    ", "rc_swA    ", "rc_swB    ",
     "p2_x      ", "p1_x      ", "p4_x      ", "p3_x      ",
     "PB_mode   ", "packet_num", "sensor1   ", "sensor2   ",
     "p2_y      ", "p1_y      ", "sensor3   ", "sensor4   ",
     "p4_y      ", "p3_y      ", "sensor5   ", "sensor6   ",
     "p2_wheel  ", "p1_wheel  ", "sensor7   ", "sensor8   ",
     "p4_wheel  ", "p3_wheel  ", "p2_aux    ", "p1_aux    ",
     "p4_aux    ", "p3_aux    ", "delta_t   ", "res01     "
    };
static char numbers[] = "0123456789abcdefABCDEF";
static struct pbnumber sioutarray[SIARRAYSIZE];
static struct pbnumber siinarray[SIARRAYSIZE];

// --------------------------------------------------------------
// pbinitio - Initialize I/O structures.
void pbinitio()
{
  int inindex;
  char *firstblank;

  for( inindex=SIARRAYSIZE; inindex; )
    {
      inindex--;
      firstblank = strchr(sinamearray[inindex],' ');
      if( firstblank )
	*firstblank = (char)0;
    }

  // Initialize all vpoints to point to their value.
  for( inindex=SIARRAYSIZE; inindex; )
    {
      inindex--;
      siinarray[inindex].vpoint = &(siinarray[inindex].value);
      sioutarray[inindex].vpoint = &(sioutarray[inindex].value);
    }
} // pbinitio

// --------------------------------------------------------------
// pbhigh - Basic Stamp Manual p.135
void pbhigh(struct pbnumber numbera){}

// --------------------------------------------------------------
// pbinput - Basic Stamp Manual p.155
void pbinput(struct pbnumber numbera){}

// --------------------------------------------------------------
// pblow - Basic Stamp Manual p.187
void pblow(struct pbnumber numbera){}

// --------------------------------------------------------------
// pboutput - Basic Stamp Manual p.195
void pboutput(struct pbnumber numbera){}

// --------------------------------------------------------------
// pbserin - Basic Stamp Manual p.273
// pbserin() reads a number of values from stdin, which is used
// to represent the operator interface.  These numbers are
// assigned to variables in the argument list, in order.
// For convenience, all of the values on the arg list are
// echoed to stdout.
int pbserin(
	    struct pbnumber  sin0, struct pbnumber  sin1,
	    struct pbnumber  sin2, struct pbnumber  sin3,
	    struct pbnumber  sin4, struct pbnumber  sin5,
	    struct pbnumber  sin6, struct pbnumber  sin7,
	    struct pbnumber  sin8, struct pbnumber  sin9,
	    struct pbnumber sin10, struct pbnumber sin11,
	    struct pbnumber sin12, struct pbnumber sin13,
	    struct pbnumber sin14, struct pbnumber sin15,
	    struct pbnumber sin16, struct pbnumber sin17,
	    struct pbnumber sin18, struct pbnumber sin19,
	    struct pbnumber sin20, struct pbnumber sin21,
	    struct pbnumber sin22, struct pbnumber sin23,
	    struct pbnumber sin24, struct pbnumber sin25,
	    struct pbnumber sin26, struct pbnumber sin27,
	    struct pbnumber sin28, struct pbnumber sin29,
	    struct pbnumber sin30, struct pbnumber sin31 )
{
  long flagbit;
  int inindex, outindex;
  struct pbnumber pbtemp = {&pbtemp.value,0,16,0,"pbtemp"};
  char lineoftext[MAXSTRING+1];
  char *linepointer;
  char lineindex;

  // *** Prompt ***
  printf("pbserin: "); fflush(stdout);  
  //  printf("pbserin %x/%d: ",serincontrol,serincount); fflush(stdout);  
//  flagbit = 1;
//  for(outindex=0; (outindex<SIARRAYSIZE); )
//    {
//      if( flagbit & serincontrol )
//	{
//	  printf(" %s",sinamearray[outindex]);
//	}
//      outindex++;
//      flagbit = flagbit << 1;
//    }; printf(": ");

  // *** Get The Input ***
  if( fgets( lineoftext, MAXSTRING, stdin) == NULL )
    {
      printf("\n");
      return(-1);
    } else {

#define STDIN2PBNUM(a)	\
		{ \
		  if(*linepointer)\
		  { \
		    if( BASEFORMAT == 16 ) \
		    { \
		      sscanf( linepointer, "%x", pbtemp.vpoint ); \
		    } else { \
		      sscanf( linepointer, "%d", pbtemp.vpoint ); \
		    } \
		    pblet((a),pbtemp,#a); \
		    linepointer=linepointer+strspn(linepointer,numbers); \
		    linepointer=linepointer+strcspn(linepointer,numbers); \
		  } \
		}

      linepointer=lineoftext+strcspn(lineoftext,numbers);
      STDIN2PBNUM(sin0);
      STDIN2PBNUM(sin1);
      STDIN2PBNUM(sin2);
      STDIN2PBNUM(sin3);
      STDIN2PBNUM(sin4);
      STDIN2PBNUM(sin5);
      STDIN2PBNUM(sin6);
      STDIN2PBNUM(sin7);
      STDIN2PBNUM(sin8);
      STDIN2PBNUM(sin9);
      STDIN2PBNUM(sin10);
      STDIN2PBNUM(sin11);
      STDIN2PBNUM(sin12);
      STDIN2PBNUM(sin13);
      STDIN2PBNUM(sin14);
      STDIN2PBNUM(sin15);
      STDIN2PBNUM(sin16);
      STDIN2PBNUM(sin17);
      STDIN2PBNUM(sin18);
      STDIN2PBNUM(sin19);
      STDIN2PBNUM(sin20);
      STDIN2PBNUM(sin21);
      STDIN2PBNUM(sin22);
      STDIN2PBNUM(sin23);
      STDIN2PBNUM(sin24);
      STDIN2PBNUM(sin25);
      STDIN2PBNUM(sin26);
      STDIN2PBNUM(sin27);
      STDIN2PBNUM(sin28);
      STDIN2PBNUM(sin29);
      STDIN2PBNUM(sin30);
      STDIN2PBNUM(sin31);
#undef STDIN2PBNUM

#define NUM2STDOUT(a) \
		{ \
		  while( (!(flagbit&serincontrol)) && (inindex<serincount)) \
		    { \
		      flagbit = flagbit << 1; \
		      outindex++; \
		    } \
		  if(inindex<serincount) \
		    { \
		      if( BASEFORMAT == 16 ) \
			{ \
			  printf(" %s=%x",sinamearray[outindex],pbstrip(a)); \
			} else { \
			  printf(" %s=%d",sinamearray[outindex],pbstrip(a)); \
			} \
		    } \
		  flagbit = flagbit << 1; \
		  outindex++; \
		  inindex++; \
		}

      outindex = 0;
      inindex = 0;
      flagbit = 1;
      NUM2STDOUT(sin0);
      NUM2STDOUT(sin1);
      NUM2STDOUT(sin2);
      NUM2STDOUT(sin3);
      NUM2STDOUT(sin4);
      NUM2STDOUT(sin5);
      NUM2STDOUT(sin6);
      NUM2STDOUT(sin7);
      NUM2STDOUT(sin8);
      NUM2STDOUT(sin9);
      NUM2STDOUT(sin10);
      NUM2STDOUT(sin11);
      NUM2STDOUT(sin12);
      NUM2STDOUT(sin13);
      NUM2STDOUT(sin14);
      NUM2STDOUT(sin15);
      NUM2STDOUT(sin16);
      NUM2STDOUT(sin17);
      NUM2STDOUT(sin18);
      NUM2STDOUT(sin19);
      NUM2STDOUT(sin20);
      NUM2STDOUT(sin21);
      NUM2STDOUT(sin22);
      NUM2STDOUT(sin23);
      NUM2STDOUT(sin24);
      NUM2STDOUT(sin25);
      NUM2STDOUT(sin26);
      NUM2STDOUT(sin27);
      NUM2STDOUT(sin28);
      NUM2STDOUT(sin29);
      NUM2STDOUT(sin30);
      NUM2STDOUT(sin31);
#undef NUM2STDOUT
      printf("\n");
    }
  return(0);
} // pbserin

// --------------------------------------------------------------
// pbserout - Basic Stamp Manual p.293
void pbserout(
    struct pbnumber dummy1,
    struct pbnumber dummy2,
    struct pbnumber pwm1,
    struct pbnumber relayA,
    struct pbnumber pwm2,
    struct pbnumber relayB,
    struct pbnumber pwm3,
    struct pbnumber pwm4,
    struct pbnumber pwm5,
    struct pbnumber pwm6,
    struct pbnumber pwm7,
    struct pbnumber pwm8,
    struct pbnumber pwm9,
    struct pbnumber pwm10,
    struct pbnumber pwm11,
    struct pbnumber pwm12,
    struct pbnumber pwm13,
    struct pbnumber pwm14,
    struct pbnumber pwm15,
    struct pbnumber pwm16,
    struct pbnumber dummy17,
    struct pbnumber dummy18
  )
{
  if( BASEFORMAT == 16 )
    {
      printf("pbserout: pwm1=%x relayA=%x pwm2=%x relayB=%x pwm3=%x pwm4=%x pwm5=%x pwm6=%x pwm7=%x pwm8=%x pwm9=%x pwm10=%x pwm11=%x pwm12=%x pwm13=%x pwm14=%x pwm15=%x pwm16=%x\n",
	     pbstrip(pwm1), pbstrip(relayA), pbstrip(pwm2),
	     pbstrip(relayB), pbstrip(pwm3), pbstrip(pwm4),
	     pbstrip(pwm5), pbstrip(pwm6), pbstrip(pwm7),
	     pbstrip(pwm8), pbstrip(pwm9), pbstrip(pwm10),
	     pbstrip(pwm11), pbstrip(pwm12), pbstrip(pwm13),
	     pbstrip(pwm14), pbstrip(pwm15), pbstrip(pwm16)
	     );
    } else {
      printf("pbserout: pwm1=%d relayA=%d pwm2=%d relayB=%d pwm3=%d pwm4=%d pwm5=%d pwm6=%d pwm7=%d pwm8=%d pwm9=%d pwm10=%d pwm11=%d pwm12=%d pwm13=%d pwm14=%d pwm15=%d pwm16=%d\n",
	     pbstrip(pwm1), pbstrip(relayA), pbstrip(pwm2),
	     pbstrip(relayB), pbstrip(pwm3), pbstrip(pwm4),
	     pbstrip(pwm5), pbstrip(pwm6), pbstrip(pwm7),
	     pbstrip(pwm8), pbstrip(pwm9), pbstrip(pwm10),
	     pbstrip(pwm11), pbstrip(pwm12), pbstrip(pwm13),
	     pbstrip(pwm14), pbstrip(pwm15), pbstrip(pwm16)
	     );
    }
  fflush(stdout);
} // pbserout

// --------------------------------------------------------------
// pbshiftout - Basic Stamp Manual p.313
// The values of the args to pbshiftout() determine what args
// pbserin() is expecting.
void pbshiftout(
		struct pbnumber b1,
		struct pbnumber b2,
		struct pbnumber b3,
		struct pbnumber b4,
		struct pbnumber b5
		)
{
  int flagbit, index;

  pbinitio();
  dataInitVolt = pbstrip(b5);
  serincontrol = pbstrip(b4);
  serincontrol = (serincontrol<<8)|pbstrip(b3);
  serincontrol = (serincontrol<<8)|pbstrip(b2);
  serincontrol = (serincontrol<<8)|pbstrip(b1);
  dataInitVolt = pbstrip(b5);
  flagbit = 1;
  serincount = 0;
  for(index=0; (index<SIARRAYSIZE); index++)
    {
      if( flagbit & serincontrol )
	{
	  serincount++;
	}
      flagbit = flagbit << 1;
    };
  printf("serincontrol=0x%x, serincount=%d.\n",serincontrol, serincount);
  printf("shiftout: %d\n", serincontrol);
  return;
} // pbshiftout

// --------------------------------------------------------------
// pbstop - Basic Stamp Manual p.321
void pbstop(){}

// --------------------------------------------------------------
// pbtoggle - Basic Stamp Manual p.327
void pbtoggle(struct pbnumber numbera){}

// --------------------------------------------------------------
// pbrun - Basic Stamp Manual p.
void pbrun(struct pbnumber numbera)
{
  printf("pbrun %d\n",pbstrip(numbera));
  exit(0);
} // pbrun

// --------------------------------------------------------------
/* TODO:
 * - Flesh out more IO funcs.
 */

