Skip to content. | Skip to navigation

Personal tools

m3.cpp

m3.cpp

m3.cpp

/////////////////////////////////////////////////////////////////////////////
// M3 Control Program
//
//  Last updated: 2 / 07 / 2009
//              by Pablo Castro P. 
//      Original program by Greg Bredthauer
//      The Observatories of the Carnegie Institution of Washington
//
//  Compile using Open Watcom C/C++32 1.5 using CauseWay
//    Compile command:
//                    wcl386 /l=causeway m3.cpp
//
//  Note: This program also uses the general-purpose source code files
//        SERCLOCK.CPP, and one of the video driver files such as
//        VIDEO.CPP (for VESA 2.0 cards) or ET4000.CPP.
/////////////////////////////////////////////////////////////////////////////

#define Version 3.18

// Keep all structures byte-aligned, not dword aligned
#pragma pack(1)

//// NOTES FOR THE FUTURE
//
// - Tilt position measurement / function
// - serial commands
// - Up current on tilt steppers?
// - Test rewired limits to see if noise is gone
// - Fix screw/chain interference on ADC A
// - Measure ADC angles more carefully?
// - Power to the ADC Steppers wil be kept on all the time, since the only way 
//   the ADC rotators hold their positions is with the stepper controller's
//   power AND current on. Just the power OR the current is not enough.

//// NOTES FOR THE M3 COMPUTER
//
// PCM-UIO48A:
// Address: 0x230  IRQ: 5
//
// Mesa 4A22:
// Address: 0x220  IRQ: 9
//
//  - Address 0x200-0x21F is for EMS
//  - Mesa: Input 0 is TILT LVDT C, Input 1 is TILT LVDT B,
//          Input 2 is TILT LVDT A, and Input 3 is +12VDC
//  - Mesa: You have to run "4A22DRVR 220 9 61"
//          followed by "4A22DCFG ST 61" before running M3
//  - Flash disk: Insert with the chip on the upper side towards the floppy
//    connector
//  - Format flash disk with "DLFMT 80" or "DLFMT C:"
//  - Enter the Bios (CTRL[hold] then ALT[hold] then S over and over), then
//    set one floppy to DLAG FLASH
//  - Disable Video and Bios Shadow
//  - Parallel Port is at 0x378 regardless of BIOS setting (BIOS 1.41)
//    Parallel port was fixed at 0x278 in BIOS 1.40.
//  - CO ouputs turn motor current OFF when set to 0
//  - Motor power outputs turn motors ON when set to 0
//  - Brakes/Pressure/Vacuum on when set to 1
//  - Digital I/O: limits active low, Moni/Step active high,
//    Pin In/Out Up/Down commands active high, indexes active low
//  - ADCA/ADCB index mark is +logic
//
// Flash disk:
//  Set drive B to type Flash
//  Use the FFSFORM program (on the digital logic FLASH diskette)
//   to format B:, a 512k flash disk

/////////////////////////////////////////////////////////////////////////////
// LOG OF CHANGES
//
//   02/07/09: Added new class which allows to automaticly convert between steps, ttps and lvdt
//             voltages while adjusting the mirror position. 
//   05/10/07: Fixed detail when reporting expected steps in homing of the ADC lenses.
//             Now when ADC lens index sensor is active, the expected steps are reported
//             correctly as twice the back-off distance. 
//   05/02/07: Fixed bad interlock, that was not letting to lock the ADC turret
//             manually in the NOADC position (file ATPIN.CPP)
//   09/05/06: Recompiled same source with newer compiler version, OpenWatcom ver.1.5
//             Program version is 3.15.
//   06/29/06: Added a sanity check for lost steps in the ADC rotators positioning.
//   04/20/06: Improved ADC lenses motion status onscreen.
//             Also changed to OpenWatcom compiler ver 1.4
//   02/09/06: Checked several routines during the engineering.
//             Also changed to OpenWatcom compiler ver 1.3
//   02/02/06: Sincronized ADC rotators angle with telescope elevation angle
//   01/12/06: Updated display with real ADCs position, added combined motion
//   01/11/06: Returned to original Greg's ADC.H, ADC.CPP files
//             Changed total variable from dword to double in ADC.CPP routine.
//   12/09/05: Added J5 message to receive elevation from TCS.
//             Also main log buffer size augmented to contain 1000 positions
//             Modified PARSE.CPP, ADC.H, M3.CPP.
//   10/20/03: M3 Turret routines updated (MTURRET.CPP)
//             Three new index sensors A-B-C are active high (opposite as before)
//             Homing/positioning rotuines modified, since M3 turret
//             FWD-REV limit switches were eliminated.
//   10/17/03: M3 turret lock pin routines updated (MTPIN.CPP).
//             Only one bit commands motion now. Turret pin logic is reversed.
//             Now high means release clamp, low engage clamp.
//   10/16/03: Improved M3 mirror routines, flip up/down, lock/unlock (MIRROR.CPP).
//             Logic updated for mirror latches.
//             Now high is unlock, low is lock (opposite as before).
//   10/10/03: Several hardware changes were made during october engineering
//             run in the M3 Turret.
//             New air actuated clamp was installed to lock the turret.
//             Electric driven one was eliminated, along with its electronics.
//             Pin in/out signals are now sensed by Hall magnetic switches.
//             Same thing for index signals (A-B-C).
//             Total of five Sony sensors were eliminated.
//             End of travel (forward/reverse) limit switches were eliminated.
//    2/16/03: Added NASE/NASW/AUX1/AUX2/AUX3 commands to move M3Turret
//             to different ports and adjust tilts simultaneously (INI values).
//    2/15/03: Max speed for M3 turret moves is 500steps/sec for now
//              2/14/03: Fixed Tilt movements. You have to set Mycom direction right
//                                               before you command the steps.
//              3/22/02: Ported Pascal-based 4A22DRVR (the Mesa analog card interrupt
//             driver) to C (CMESADRV).  This prevents lockups when calling
//             the old driver from a protected-mode program.
//              3/15/02: Added TILTS command to servo all tilts simultaneously
//        3/12/02: Added msTimer to SERCLOCK, switched all routines from using
//                                               Timer to using msTimer, switched to 4kHz clock,
//             Mirror latches now lock/unlock in the background,
//                                               Motion profiles now "dithered" for smoother acceleration
//              3/11/02: Switch to 586SEV board, now compiles under Watcom
//    2/11/99: Added cartoons to display
//        1/25/99: Added DGH communication
//   10/19/98: Development begins
/////////////////////////////////////////////////////////////////////////////

/////////////////////////////////////////////////////////////////////////////
// Port Communication Control
//
//  Uncomment the "#define ENABLEIO" line to enable reading/writing
//  to all ports.  Comment it out to test the software on a computer without
//  the hardware.
//
#define ENABLEIO
//
/////////////////////////////////////////////////////////////////////////////

/////////////////////////////////////////////////////////////////////////////
// Video graphics driver usage
//
//  Select from one of the following video drivers
//#include "d:\magellan\magcode\good\slovideo.cpp" // Compatible (slow) graphics
//#include "d:\magellan\magcode\good\et4000.cpp"   // Tseng ET-4000 graphics routines
//#include "d:\magellan\magcode\good\video.cpp"      // Fast VESA graphics routines
#include "..\libmag\video.cpp"      // Fast VESA graphics routines
//#include "d:\magellan\magcode\good\ct655xx.cpp"  // C&T 655xx graphics routines
/////////////////////////////////////////////////////////////////////////////

// Macros for easier-to-read source code
#define setvect _dos_setvect
#define getvect _dos_getvect
#define enable _enable
#define disable _disable
#define getdate _dos_getdate
#define time dostime_t
#define date dosdate_t
#define PI 3.14159265359
#define BRIEF 0
#define EXTRA 1
#define VERBOSE 2

// Global variables and constants
// Global quit flag
int Quit = 0;                                                   // Set to 1 to quit from main loop
int ClockPPM = 0;                                               // Speed up or slow down clock in PPM (for accuracy)
#define M3ClockRate 2000                // Clock rate used in Hz
#define MainLogSize 1000                // Number of entries in the main log (memory limited)
#define InputLogSize 10                 // Number of entries in the keyboard command log
#define MotionProfile 5000      // Motion profile array sizes
#define TestSteps 1000

// Includes
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <math.h>
#include <ctype.h>
#include <string.h>
#include <i86.h>
//#include "d:\magellan\magcode\good\serclock.cpp" // Serial/Clock interrupt routines
//#include "d:\magellan\magcode\good\math.cpp"     // Various math routines
//#include "d:\magellan\magcode\good\log.cpp"      // Message logging routines
//#include "d:\magellan\magcode\good\chart.cpp"    // Data charting routines
#include "..\libmag\serclock.cpp" // Serial/Clock interrupt routines
#include "..\libmag\math.cpp"     // Various math routines
#include "..\libmag\log.cpp"      // Message logging routines
#include "..\libmag\chart.cpp"    // Data charting routines

// Digital I/O card provided routines
#define inportb inp
#define outportb outp
#include "UIO48.H"
#include "UIO48.C"

// Global variables
CLog * Log;
CLog * InputLog;

// Code
#include "io.h"        // Low level I/O routines
#include "ini.h"       // INI file manipulation
#include "display.h"   // Main on-screen display routines
#include "parse.h"     // Serial and keyboard command parsing
#include "mirror.h"    // Mirror control and status
#include "mtpin.h"     // M3 Turret Pin control and status
#include "mturret.h"   // M3 Turret control and status
#include "atpin.h"     // ADC Turret Pin control and status
#include "aturret.h"   // ADC Turret control and status
#include "adc.h"       // ADC Rotatators control and status
#include "tilt.h"      // M3 Mirror Tilt control and status
#include "dgh.h"       // Low level DGH module control and status
#include "edslog.h"    // Engineering data stream routines
#include "presvac.h"   // Pressure/vacuum control behind the mirror
#include "SAVTrans.h"  // Steps/TTPS/LVDT coordinates converter

// Dynamically allocates global variables
CADCTurret * ADCTurret;
CM3Turret * M3Turret;

#include "io.cpp"
#include "ini.cpp"
#include "display.cpp"
#include "parse.cpp"
#include "mirror.cpp"
#include "mtpin.cpp"
#include "mturret.cpp"
#include "atpin.cpp"
#include "aturret.cpp"
#include "adc.cpp"
#include "tilt.cpp"
#include "dgh.cpp"
#include "edslog.cpp"
#include "presvac.cpp"
#include "SAVTrans.cpp"

// M3 Clock interrupt - performs all tasks necessary during a clock interrupt
void M3ClockInterrupt()
{
  // Pressure/Vaccuum control
  PresVacClockInterrupt();
  // M3 Turret Motion
  M3TurretInterrupt();
  // ADC Turret Motion
  ADCTurretInterrupt();
  // ADC Motion
  ADCInterrupt();
  // Tilt Motion
  TiltInterrupt();
}

void main(int _argc,const char * _argv[])
{
  int i;
  int Step = 0; // Used to step through subsystem updates

  // Allocate memory for dynamic variables/objects
  Log = new CLog;
  InputLog = new CLog;
  ADCTurret = new CADCTurret;
  M3Turret = new CM3Turret;

  // First set Shec colors for this machine (colors vary with
  // monitor and video card)
  ShecDARKGRAY = 16;      // 16 by default
  ShecMEDGRAY = 38;               // 28 by default
  ShecLIGHTGRAY = 50;     // 40 by default
  ShecWHITE = 62;     // 52 by default
  ShecRED = 79;       // 78 by default
  ShecYELLOW = 95;    // 94 by default
  ShecGREEN = 109;    // 109 by default
  // Switch to 640x480x256 video mode
  if (i = InitVideo())
    {
      CloseVideo();
      printf("Error initializing graphics mode! (Error #%d)\n",i);
      return;
    }

  // Initialize running logs
  Log->Init(MainLogSize,12,430,384,5,1,1,140,364);
  InputLog->Init(InputLogSize,452,632,384,4,0,0,0,0);
  EDSLog.Init(100);
  PresVacChart.Init(412,264,548,303,SHECYELLOW,BLACK,SHECGREEN,WHITE,0.0,0.3,5);

  // Set the log verbose level to maximum if any command-line arguments
  // were given.
  if (_argc > 1)
    Log->VerboseLevel = 2;

  // Read the INI file.
  if (i = ReadINI("M3.INI"))
    {
      CloseVideo();
      printf("Error reading M3.INI! (Error %d)\n",i);
      return;
    }
  else
    EDSLog.Add(997,"M3.INI read success");

  // Initialize digital and analog I/O cards
  InitHardwareIO();

  // Initialize clock interrupt
  InitClock(M3ClockRate); // Enable clock interrupt control

  // Initialize serial port parameters
  InitPorts();

  // Speed up or slow down clock, based on INI file
  SetNewClockPPM(ClockPPM);

  // Initialize subsystems

  Mirror.Init();
  M3Turret->Init();
  M3TurretPin.Init();
  ADCTurret->Init();
  ADCTurretPin.Init();
  ADCA.Init(ADCABitDir,ADCABitStep,ADCABitMon,ADCABitIndex,264,64,1,ADCAR1-7,ADCAR2-7,ADCAAngle);
  ADCB.Init(ADCBBitDir,ADCBBitStep,ADCBBitMon,ADCBBitIndex,280,80,0,ADCBR1+7,ADCBR2+7,ADCBAngle);
  Tilt.Init();
  PresVac.Init();

  // Point clock interrupt to our code
  UserClockInterrupt = &M3ClockInterrupt;

  // Initialize static screen display
  InitDisplay();

  EDSLog.Add(999,"Program startup (v%0.2f)",Version);

  // Main loop
  do
    {
      // Update onscreen timers
      UpdateTime(0);

      // Keep the cursor blinking
      UpdateCursor(kbline);

      // Update periodic EDS entries
      UpdateEDS();

      // Keep the log displays up-to-date
      Log->Update();
      InputLog->Update();

      // Parse serial and keyboard input
      Parse();

      // Update pressure/vacuum control system
      PresVac.Update();

      // Update subsystems
      if (Step == 0)
	{
	  Mirror.Update();
	  Step = 1;
	}
      else if (Step == 1)
	{
	  M3Turret->Update();
	  Step = 2;
	}
      else if (Step == 2)
	{
	  M3TurretPin.Update();
	  Step = 3;
	}
      else if (Step == 3)
	{
	  ADCTurret->Update();
	  Step = 4;
	}
      else if (Step == 4)
	{
	  Step = 5;
	  ADCTurretPin.Update();
	}
      else if (Step == 5)
	{
	  Step = 6;
	  ADCA.Update();
	}
      else if (Step == 6)
	{
	  ADCB.Update();
	  Step = 7;
	}
      else if (Step == 7)
	{
	  Tilt.Update();
	  Step = 0;
	}
    } while (!Quit);

  // Restore all interrupt vectors, and return to text mode
  StepperPowerOffNow();
  ADCStepperPowerOffNow();
  CloseComPorts();
  CloseHardwareIO();
  CloseClock();
  CloseVideo();
  printf(" Clock Overruns: %d\n",Overruns);
  printf("Real Clock Rate: %0.2f Hz\n",RealClockRate);
}


Generated by GNU Enscript 1.6.5.2.
Document Actions