 /**********************************  dwarfcore.h  *****************************
 * $Source: /home/cvs/ESP/gen2/software/msp430/include/dwarfcore.h,v $
 *  Copyright (C) 2003 MBARI
 *
 *  MBARI Proprietary Information. All rights reserved.
 * $Id: dwarfcore.h,v 1.18 2005/08/31 18:30:50 brent Exp $
 *
 * This header documents the hardware interface between the
 * MSP430F1xx microcontroller and the "Dwarf Core" board,
 * particularly the registers in the board's CPLD.
 *
 *****************************************************************************/

#ifndef dwarfcore_h
#define dwarfcore_h

#include "dwarf.h"      //register and I/O definitions common to all dwarves

// Direct I/O bits unique to dwarfcore
// PWM control is on port 4 (TIMER B)
#define DCORPWMOUT  P4OUT
#define DCORPWMSEL  P4SEL
#define DCORPWMDIR  P4DIR
#define DCOR0PWM    0x01 
#define DCOR1PWM    0x02
#define DCOR2PWM    0x04
#define DCOR3PWM    0x08
#define DCOR4PWM    0x10
#define DCOR5PWM    0x20
#define DCOR6PWM    0x40
#define DCORPWMCLK  0x80    //external PWM clock input

// Motor PWM direction control
#define DCORMOTOROUT  P5OUT
#define DCORMOTORDIR  P5DIR
#define DCOR0DIR    0x01    //forward=1, backward=0
#define DCOR0BRAKE  0x02    //active high, overrides DIR
#define DCOR1DIR    0x04    //forward=1, backward=0
#define DCOR1BRAKE  0x08    //active high, overrides DIR

#define PWMmaxCOUNT 100    //this is the value that the PWM
                              //will count up to
#define MAXPWM      PWMmaxCOUNT - 5 //need to leave some off time ~ 95%
                              
#define PWMMODE 0x0240      //configures each of the PWM modules
                              
// CPLD Registers unique to Dwarf Core
#define DCORIFG		1
#define DCORIE		0

/*
  Additional Interrupt Flags in DWRFIFG (all are active high)
*/
#define DCORPWRBAD  0x02   //encoder power fault
#define DCOR0HOMED  0x04   //ch0 homed
#define DCOR1HOMED  0x08   //ch1 homed
#define DCORCRASHED 0x10   //either channel hit limit switch
#define DCOR0PASSED 0x20   //ch0 passed threshold
#define DCOR1PASSED 0x40   //ch1 passed threshold
// DCORxHOMED is set after the channel's encoder count has been cleared.
// a channel's encoder count cannot be cleared while DCORxHOMED is set.
// DCORCRASHED set after either channel's hard limit was reached.
// Limit switch status in DCORLIMITS remain set until DCORCRASHED is cleared.
// DCORxPASSED is set after the channel's position reached a threshold.
// DCORxCNT* registers remain frozen while DCORxPASSED is set

//limit Switch Status register
#define DCORLINT    2

/*
   Read only limit status registers
*/
#define DCORLIMITS   3
#define DCOR0RLS     0x01   //ch0 reverse limit [latched] (active low)
#define DCOR0FLS     0x02   //ch0 forward limit [latched] (active low)
#define DCOR0HOME    0x04   //ch0 home switch [unlatched]
#define DCOR0CRASHED 0x08   //ch0 hit limit switch [latched] (active high)
#define DCOR1RLS     0x10   //ch1 reverse limit [latched] (active low)
#define DCOR1FLS     0x20   //ch1 forward limit [latched] (active low)
#define DCOR1HOME    0x40   //ch1 home switch [unlatched]
#define DCOR1CRASHED 0x80   //ch1 hit limit switch [latched] (active high)


/*
  Write Only Encoder Control register
*/
#define DCORENCCTL   3
#define DCOR0HMEDGE  0x01   //ch0 set homed flag on rising=1/falling=0 edge
#define DCOR0HMLATCH 0x02   //ch0 latch position when homed [active high]
#define DCOR0PSEDGE  0x04   //ch0 set passed flag on rising=1/falling=0 edge
#define DCOR0ENCDIR  0x08   //ch0 encoder direction or quadrature phase
#define DCOR1HMEDGE  0x10   //ch1 set home flag on rising=1/falling=0 edge
#define DCOR1HMLATCH 0x20   //ch1 latch position when homed [active high]
#define DCOR1PSEDGE  0x40   //ch0 set passed flag on rising=1/falling=0 edge
#define DCOR1ENCDIR  0x80   //ch1 encoder "sense" or quadrature phase ??


/* 
  Read only current encoder count registers.
  (optionally zeroed when HOMED) 
*/
#define DCOR0CNTLOW  4
#define DCOR0CNTHIGH 5
#define DCOR1CNTLOW  6
#define DCOR1CNTHIGH 7

/*
  Read only threshold latched encoder count registers
   Note that THRESHIGH is not latched and must be derived from the current count
   Once a channel's threshold is latched, it cannot be latched again
   until the corresponding DCORxPASSED bit in DWRFIFG is cleared 
*/
#define DCOR0THRESLOW  8
#define DCOR0THRESHIGH 9
#define DCOR1THRESLOW  10
#define DCOR1THRESHIGH 11


/*
  Read/Write Sensorboard Interface Register -- 
  Both temperature sensors are powered by setting bit DCORTEMPEN. 
  DCORTEMPSL selects which of the two temperature sensors will feed its output
  to analog channel 5. Note that this just effects which sensors output is being fed into analog
  channel 5.
  DCORPRESSL & DCORPRESEN select and power the pressure sensors, details tbd.

*/
#define DCORSENSOR  12
#define DCORTEMPSL  0x08    //temp. sensor select
#define DCORTEMPEN  0x04    //temp. sensor enable
#define DCORPRESSL  0x02    //pressure sensor select
#define DCORPRESEN  0x01    //pressure sensor enable


/*
  Read/Write Encoder Power Fault/Power Enable register
    Power Fault inputs are active low
    Power Control outputs are active high
    Both a sensor's 5V and 3.3V supplies must never be enabled
*/
#define DCORENCPWR  14
#define DCOR0HOME3  0x01    //ch0 3.3V Power fault/power
#define DCOR0HOME5  0x02    //ch0 5V Power fault/power
#define DCOR0ENC3   0x04    //ch0 3.3V Power fault/power
#define DCOR0ENC5   0x08    //ch0 5V Power fault/power
#define DCOR1HOME3  0x10    //ch1 3.3V Power fault/power
#define DCOR1HOME5  0x20    //ch1 5V Power fault/power
#define DCOR1ENC3   0x40    //ch1 3.3V Power fault/power
#define DCOR1ENC5   0x80    //ch1 5V Power fault/power
 

/*
  Read Only miscelleneous input register
*/
#define DCORIN      15
#define DCORSWS     0x3F    //six switches [closed=high]
#define DCOR0IN     0x40    //ch0 threshold state/motor input [unlatched]
#define DCOR1IN     0x80    //ch1 threshold state/motor input [unlatched]


/*
  Write Only Miscellenous outputs
*/
#define DCOROUT      15
#define DCORLED1     0x01  //status LED output [active low]
#define DCORLED2     0x02  //status LED output [active low]
#define DCORMSGLED   0x04  //toggles on each msg received [active low]
#define DCORSTUCKLED 0x08  //waiting at prompt [active low]
#define DCORALIVELED 0x10  //toggles once a second [active low]
#define DCORMOTORPWR 0x20  //motor power enable for both channels [active high]
#define DCOR0OUT     0x40  //general purpose output for channel 0
#define DCOR1OUT     0x80  //general purpose output for channel 1

/*Write only registers for control of the rotary valves*/

#define DRVCTL		16
#define START		0x01
#define PWRFLG		0x02
#define MTRPWR		0x04
#define ENCPWR0		0x10
#define ENCPWR1		0x20
#define ENCPWR2		0x40
#define ENCPWR3		0x80

#define DRVMTRCTL	25
#define M00	        0x01
#define M01 		0x02
#define M0F         M01
#define M0R         M00
#define M0B         (M01 | M00) 
#define M0S         0xFC
#define M10 		0x04
#define M11         0x08
#define M1F         M11
#define M1R         M10
#define M1B         (M11 | M10) 
#define M1S         0xF3
#define M20 		0x10
#define M21 		0x20
#define M2F         M21
#define M2R         M20
#define M2B         (M21 | M20) 
#define M2S         0xCF
#define M30 		0x40
#define M31 		0x80
#define M3F         M31
#define M3R         M30
#define M3B         (M31 | M30) 
#define M3S         0x3F

#define DRV0LOW     17
#define DRV0HIGH    18
#define DRVVALVE0   26
#define DRVVALVE1   27



#if false
/*
  Usage example:  Update position for encoder channel 0
*/
static int32 position0;  //previous 32-bit counter value
{
  unsigned encoderValue;
  int32 delta, newPosition, oldPosition = position0;
  _DINT(); _NOP();
  encoderValue = readDWRFfirst(DCOR0CNTLOW);
  encoderValue |= readDWRFlast()<<8;
  _EINT();
  newPosition = (oldPosition & 0xffff0000) | encoderValue;  //1st guess at it
  delta = newPosition - oldPosition;  //delta = how far we appear to have moved
  if (delta > 0x7fff)                 //too far forward?
    newPosition -= 0x10000;
  else if (delta < -0x7fff)           //too far backward?
    newPosition += 0x10000;
  position0 = newPosition;
}
#endif

#endif
