//
//  spindle.cpp - machine spindle implementation
//
//  $Id: spindle.cpp 53 2014-02-07 19:39:59Z brian $ 
//
//  Copyright (c) 1999-2014 by Precision Micro Control Corp. All rights reserved.
//
#include "stdafx.h"

Spindle::Spindle(void)
{
// Initialize member Application Variables so they can save and restore themselves	
	CtrlrAxis.Init(0, SPINDLE_SECTION, CTRLR_AXIS_NUM_ENTRY);
	Mode.Init(0, SPINDLE_SECTION, SPINDLE_MODE_ENTRY);
	Polarity.Init(1, SPINDLE_SECTION, SPINDLE_POLARITY_ENTRY);
	EncoderScale.Init(REVOLUTION_UNIT, 0.0, SPINDLE_SECTION, SPINDLE_SCALE_ENTRY);
	SpeedConstant.Init(REVOLUTION_UNIT, DEFAULT_PER_UNIT, 0.0, SPINDLE_SECTION, SPINDLE_CONSTANT_ENTRY);
	DefaultSpeed.Init(REVOLUTION_UNIT, DEFAULT_PER_UNIT, 0.0, SPINDLE_SECTION, SPINDLE_SPEED_ENTRY);
	Accel.Init(REVOLUTION_UNIT, DEFAULT_PER_UNIT, 0.0, SPINDLE_SECTION, SPINDLE_ACCEL_ENTRY);
	Decel.Init(REVOLUTION_UNIT, DEFAULT_PER_UNIT, 0.0, SPINDLE_SECTION, SPINDLE_DECEL_ENTRY);
	// Provide a default readout format string	
	ReadoutFormat = "%#+ 14.1f";
}

void Spindle::Initialize(int axis_num)
{
	CtrlrAxis = axis_num;
	Mode = 1;
	Polarity = 1;
	EncoderScale.Set(REVOLUTION_UNIT, 1.0);
	SpeedConstant.Set(REVOLUTION_UNIT, DEFAULT_PER_UNIT ,0.0);
	DefaultSpeed.Set(REVOLUTION_UNIT, DEFAULT_PER_UNIT, 0.0);
	Accel.Set(REVOLUTION_UNIT, DEFAULT_PER_UNIT, 0.0);
	Decel.Set(REVOLUTION_UNIT, DEFAULT_PER_UNIT, 0.0);
}

void Spindle::SaveData(const char* ini_file)
{
	int precision = theApp.GetMachine()->GetSetupPrecision();
	
	// Clear section for this Spindle
	CtrlrAxis.Erase(ini_file);

	// Save data
	CtrlrAxis.Save(ini_file);
	Mode.Save(ini_file);
	Polarity.Save(ini_file);
	EncoderScale.Save(ini_file, precision);
	SpeedConstant.Save(ini_file, precision);
	DefaultSpeed.Save(ini_file, precision);
	Accel.Save(ini_file, precision);
	Decel.Save(ini_file, precision);
}

void Spindle::RestoreData(const char* ini_file)
{
	CtrlrAxis.Restore(ini_file);
	Mode.Restore(ini_file);
	Polarity.Restore(ini_file);
	EncoderScale.Restore(ini_file);
	SpeedConstant.Restore(ini_file);
	DefaultSpeed.Restore(ini_file);
	Accel.Restore(ini_file);
	Decel.Restore(ini_file);
}

void Spindle::Configure(std::fstream& cfg_file)
{
	// Place comment in configuration file
	cfg_file << ";" << " Spindle configuration" << std::endl;
	
	// Generate configuration string for motion controller
	cfg_file << "SPINDLEAXIS=" << GetCtrlrAxis() << std::endl;
	
	if (GetCtrlrAxis())		// Only configure spindle if it exist (non-zero axis number)
	{
		cfg_file << "SPINDLEMODE=" << (int)Mode << std::endl;
		cfg_file << "SPINDLEPOLARITY=" << (int)Polarity << std::endl;
		
						// Configuration data in both english and metric units
		for (int units = ENGLISH; units <= METRIC; units++)
		{
			cfg_file << (const char*)UnitsName[units] << std::endl;

			PER_UNIT PerUnit;
			if (units == ENGLISH)
				PerUnit = theApp.GetMachine()->PartPrgmEnglishPerUnit.Get();
			else
				PerUnit = theApp.GetMachine()->PartPrgmMetricPerUnit.Get();

			if ((int)Mode == 1)
			{
				cfg_file << "SPINDLESCALE=" << EncoderScale.Get(REVOLUTION_UNIT) << std::endl;
				cfg_file << "SPINDLERATECONV=" << 1.0 / PerUnitMultiplier[PerUnit] << std::endl;
			}
			else if ((int)Mode == 2)
				cfg_file << "SPINDLECONSTANT=" << SpeedConstant.Get(REVOLUTION_UNIT, PerUnit) << std::endl;

			cfg_file << "SPINDLESPEED=" << DefaultSpeed.Get(REVOLUTION_UNIT,PerUnit) << std::endl;
			cfg_file << "SPINDLEACCEL=" << Accel.Get(REVOLUTION_UNIT, PerUnit) << std::endl;
			cfg_file << "SPINDLEDECEL=" << Decel.Get(REVOLUTION_UNIT, PerUnit) << std::endl;
		}
	}
}

double Spindle::GetSpeed()
{
	if (CtrlrAxis)
		return theApp.GetMachine()->MtnCtrlr.GetSpindleSpeed();
	else
		return 0.0;
}




