// © RiceMotion ( Robert Carl Rice ) 2012-2016 - All rights reserved


// This software makes use of tools and libraries obtained from open source projects or released for

// use by relevant hardware manufactures. However, this software is NOT a part of any open source project.

// It is released only on a "need to know" basis for beta testers of the "RiceCNC Interpolation Engine".

// Recipents of this source code must respect the confidential nature of this software and prevent any

// distribution that could result in counterfeit copies of the "RiceCNC Interpolation Engine".


// © RiceMotion ( Robert Carl Rice ) 2012-2016 - All rights reserved

#include <MachineCommands.h>

#include <Machine.h>

#include <SetSpindleDirection.h>

#include <SetSpindleRun.h>

#include <SetSpindleSpeed.h>

#include <Spindle.h>

#include <InterpolationTimer.h>



void

     Machine::spindleControl(

          char*     commandPtr,

          String* msgPtr ) {


     char* data     = commandPtr + 1;


     switch ( *commandPtr ) {

          case CONFIGURE_SPINDLE :

          configureSpindle(

               data,

               msgPtr );

          break;


// in-band - acknowledge immediately

          case SET_SPINDLE_DIRECTION :

          queueCommand(

               new SetSpindleDirection( data ) );

          *msgPtr

               +=     String( SPINDLE_CONTROL )

               +     String( SET_SPINDLE_DIRECTION );

          break;


          case SPINDLE_START_STOP :

          queueCommand(

               new SetSpindleRun( data ) );

          *msgPtr

               +=     String( SPINDLE_CONTROL )

               +     String( SPINDLE_START_STOP );

          break;


          case SET_SPINDLE_SPEED :

          queueCommand(

               new SetSpindleSpeed( data ) );

          *msgPtr

               +=     String( SPINDLE_CONTROL )

               +     String( SET_SPINDLE_SPEED );

          break;


// out-of-band

          case SPINDLE_SPEED_OVERRIDE :

          spindleSpeedOverride(

               data,

               msgPtr );

          break;


          case SPINDLE_RUN_OVERRIDE :

          spindleRunOverride(

               data,

               msgPtr );

          break;


          case SPINDLE_DIRECTION_OVERRIDE :

          spindleDirectionOverride(

               data,

               msgPtr );

          break;

          

          default :

          *msgPtr

               +=     *commandPtr

               +     "E Invalid Machine Command - Ignored"; }; };


void

     Machine::configureSpindle(

          char*          data,

          String*          msgPtr ) {


     *msgPtr

          +=     String( SPINDLE_CONTROL )

          +     String( CONFIGURE_SPINDLE );


     if ( spindle )

          delete spindle;

  

     spindle = new Spindle(

          this,

          data,

          msgPtr );

     if ( ! spindle->isValid() ) { // must at least have run pin

          delete spindle;

          spindle          = NULL;

          *msgPtr          += " No Spindle"; }; };



void

     Machine::spindleSpeedOverride(

          char*          data,

          String*          msgPtr ) {


     *msgPtr

          +=     String( SPINDLE_CONTROL )

          +     String( SPINDLE_SPEED_OVERRIDE );


     if ( spindle ) {

          float spindleSpeed  = 0.0;

          sscanf( data,

               " %f",

               &spindleSpeed );


          InterpolationTimer::disableInterpolationInterrupts();

               spindle->setSpindleSpeed( spindleSpeed );

          InterpolationTimer::enableInterpolationInterrupts();

          

          *msgPtr     += " Spindle speed ";

          *msgPtr     += String( spindleSpeed ); }; };



void

     Machine::spindleRunOverride(

          char*          data,

          String*          msgPtr ) {


     *msgPtr

          +=     String( SPINDLE_CONTROL )

          +     String( SPINDLE_RUN_OVERRIDE );


     if ( spindle ) {

          uint32_t spindleRun  = 0;

          sscanf( data,

               "%lu",

               &spindleRun );

  

          InterpolationTimer::disableInterpolationInterrupts();

               spindle->setSpindleOn( spindleRun > 0 );

          InterpolationTimer::enableInterpolationInterrupts(); }; };



void

     Machine::spindleDirectionOverride(

          char*          data,

          String*          msgPtr ) {


     *msgPtr

          +=     String( SPINDLE_CONTROL )

          +     String( SPINDLE_DIRECTION_OVERRIDE );


     if ( spindle ) {

          uint32_t spindleDirection  = 0;

          sscanf( data,

               "% lu",

               &spindleDirection );


          InterpolationTimer::disableInterpolationInterrupts();

               spindle->setSpindleDirection( spindleDirection > 0 ); // true is clockwise

          InterpolationTimer::enableInterpolationInterrupts(); }; };