typedef struct
{
     int Pupdate,
     int Hupdate,
     uint16 nHold,
     uint16 nPulse,
     uint16 cHold,
     uint16 nHold,
     uint16 Duration,
     uint16 tic
     
} ValveStruct

#define NUMVALVES 8;
#define SETupdate 1
#define UNSETupdate 0;

byte offmask(byte onmask)
{
byte mask = 0xff;
 if (onmask & 0x03) mask &= 0xFC;
 if (onmask & 0x0C) mask &= 0xF3;
 if (onmask & 0x30) mask &= 0xCF;
 if (onmask & 0xC0) mask &= 0x3F;
}//end of offmask

byte gDrvValve0, DrvValve1;
ValveStruct VS;
/*
main gets a hold command
pulls info off of FIFo
locks interrupts
write to VS.Hold
sets update
unlocks interrupts
done
*/
static void doHoldCommand (unsigned cmdLen)
{
 if (cmdLen < 2)
 {
  reportErr("Truncated Solenoid Hold Cmd");
  return;
 }  
 MASK_TIMER_INTERRUPTS(); 
 VS.nHold = FIFOread16(node.events);
 VS.Hupdate = SETupdate;
 UNMASK_TIMER_INTERRUPTS(); 
 reportErr("New Solenoid Hold requested"); 
}//End of doHoldCommand


static void doPulseCommand (unsigned cmdLen)
{
 if (cmdLen < 2)
 {
  reportErr("Truncated Solenoid Pulse Cmd");
  return;
 }  
 MASK_TIMER_INTERRUPTS(); 
 VS.nPulse = FIFOread16(node.events);
 VS.Pupdate = SETupdate;
 UNMASK_TIMER_INTERRUPTS(); 
 reportErr("New Solenoid Pulse requested"); 
}//End of doHoldCommand

void PulseAndHoldISR(void)
{
int masked, updateCPLD = 0x0;

 if (Hupdate == SETupdate)
  {
  Hupdate = UNSETupdate;
  masked = VS.nHold & 0x03;
  if (masked != 0x0)
    {
       if (masked < 0x03) && ((VS.cHold & 0x03) == 0x03)
       {
            VS.cHold = (VS.cHold & 0xFC) | masked;
            gDrvValve0 = (gDrvValve0 & 0xFC) | masked;
            updateCPLD++;
       }
       else if (masked == 0x03)
       {
            VS.cHold = (VS.cHold & 0xFC) | masked;
            gDrvValve0 = (gDrvValve0 & 0xFC);
            updateCPLD++;
       }
    }
  
  }
  
 if (Pupdate == SETupdate)
 {
 Pupdate == UNSETupdate;
 masked = VS.nPulse & 0x03;
  if (masked != 0x0)
    {
       if (masked < 0x03) && ((VS.cPulse & 0x03) == 0x00)
       {
            VS.cPulse = (VS.cPulse & 0xFC) | masked;
            gDrvValve0 = (gDrvValve0 & 0xFC) | masked;
            VS.tic += Duration;
            updateCPLD++;
       }
       else if (masked == 0x03)
       {
            VS.cPulse = VS.cPulse & 0xFC;
            gDrvValve0 = (gDrvValve0 & 0xFC);
            updateCPLD++;
       }
    }
 
 }

 if (VS.tic != 0)
 {
 VS.tic--;
 if (VS.tic == 0)
  {
   if ((VS.cPulse & 0x03) != 0x00)
    {
     VS.cPulse = VS.cPulse & 0xFC;
     gDrvValve0 = (gDrvValve0 & 0xFC);
     updateCPLD++;
    }
  }
 }

 if (updateCPLD > 0)
  {
   _DINT();
   writeDWRFfirst(DRVVALVE0,gDrvValve0);
   writeDWRFlast(gDrvValve1);
   _EINT();
  }
}//End of PulseAndHoldISR




/*
main get a Pulse command
pulls info off of FIFO
locks interrupts
write to VS.Pulse
sets update
unlocks interrupts
done


VavleISR

check if update is set
update set - hold or pulse has changed
if Hupdate is set then Hold has been changed
   mask channel 0 nHold
   if (nHold != 0)    - if it is not 0 then must be a change
        if (nHold < 3) && (cHold == 3) if nhold is less then 3 want to set up or down 
             cHold = nHold               but cannot change if already set
             (gDRVValve & 0xFC) | Nhold
        else if (nHold == 3)   would like to relax this channel
             cHold = Nhold
             (gDrvValve & FC)
reset Hupdate
   
 if Pupdate is set then Pulse has been changed
     mask  channel 0 nPulse
     if (nPulse != 0)
          if ((nPulse < 3) && (cPulse == 3)) only if the channel is off
               cPulse = nPulse
             (gDRVValve & 0xFC) | nPulse
             if (pUpdate == set)
                  Tics += Duration

          else if (nPulse == 3) terminate the pulse
               cPulse = nPulse
               (gDrvValve & FC)
             if (pUpdate == set)
                  Tics += Duration

reset Pupdate               


*/
void setHoldValve(byte maskLow, byte maskHigh)
{
  byte nMask, oMask;
  
  nMask = maskLow & 0x03;
  oMask = gHold0 & 0x03;
  if (nMask == 0x03) 
   {
    gHold0 &= 0xFC; //turn it off
     gDrvValve0 &= 0xFC;
   }
  else if ((nMask > 0x0) && (oMask == 0x0)) 
    {
     gHold0 |= nMask;
     gDrvValve0 = (gDrvValve0 & 0x03) | nMask;
    }

  nMask = maskLow & 0x0C;
  oMask = gHold0 & 0x0C;
  if (nMask == 0x00) //turn it off
   {
    gHold0 &= 0xF3; //turn it off
     gDrvValve0 &= 0xF3;
   }
  else if ((nMask < 0x0C) && (oMask == 0x0))
    {
     gHold0 |= nMask;
     gDrvValve0 = (gDrvValve0 & 0x0C) | nMask;
    }

  nMask = maskLow & 0x30;
  oMask = gHold0 & 0x30;
  if (nMask == 0x00) //turn it off
   {
    gHold0 &= 0xCF;/turn it off
     gDrvValve0 &= 0xCF;
   }
  else if ((nMask < 0x30) && (oMask == 0x0))
    {
     gHold0 |= nMask;
     gDrvValve0 = (gDrvValve0 & 0x30) | nMask;
    }

  nMask = maskLow & 0xC0;
  oMask = gHold0 & 0xC0;
  if (nMask == 0x00) //turn it off
   {
    gHold0 &= 0x3F; //turn it off
     gDrvValve0 &= 0x3F;
   }
  else if ((nMask < 0xC0) && (oMask == 0x0))
    {
     gHold0 |= nMask;
     gDrvValve0 = (gDrvValve0 & 0xC0) | nMask;
    }


}//End of setHoldValve


void Pulse(int state, int mask, int Duration)
{
byte nMask, oMask;
  switch (vMode)
  {
     case START: nMask = maskLow & 0x03;
                 oMask = gHold0 & 0x03;
                 if (nMask == 0x00) //turn it off
                       {
                       gHold0 &= 0x3F; //turn it off
                       gDrvValve0 &= 0x3F;
                       }
                 else if ((nMask < 0xC0) && (oMask == 0x0))
                        {
                         gHold0 |= nMask;
                         gDrvValve0 = (gDrvValve0 & 0xC0) | nMask;
                        }

     
     case COUNT:  if (tics != 0)
       {
        tics--;
        if (tics == 0)
        {
          //shut off pulsing valves
        }
   
       }
 } 
}//End of Pulse

void valve(ValveStruct *vs)
{
     int Vcounter;
     
     for (Vcounter = 0; Vcounter ++; Vcounter < NUMVALVES)
     {
          switch(vs[Vcounter)
          {
               case UNCONFIG:break;  //do nothing
               case NLOFF://Turn vavle off
                         vs[Vcounter].state = NLHOFF;
                         break;
               case NLHOFF:break;
               case NLUP://Turn valve on UP
                         vs[Vcounter].state = NLHUP;
                         break;
               case NLHUP:break;
               case NLDOWN://Turn valve on UP
                         vs[Vcounter].state = NLHDOWN;
                         break;
               case NLHDOWN:break;
               case LOFF://Turn Valve off
                         vs[Vcounter].tic = vs[Vcounter].Duration;
                         vs[Vcounter].state = LPOFF;
                         break;
               case LPOFF:
          }//End of Vcounter Switch
     }//End of Vcounter
}//End of Valve