// © 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 <Axis.h>

#include <InputPin.h>

#include <LimitSwitch.h>

#include <AxisTimer.h>



void

     Axis::addLimitSwitch(

          char*          data,

          String*          msgPtr ) {

     

     LimitSwitch* limitSwitch = new LimitSwitch( data, msgPtr );

     if ( limitSwitch->valid() ) {

          limitSwitch->fmtPin( msgPtr );


          *msgPtr          += " Limit ";


          if ( limitSwitch->high ) {

               *msgPtr          += "high";

               if ( limitSwHighPin )

                    delete limitSwHighPin;

               limitSwHighPin = limitSwitch; }


          else {

               *msgPtr          += "low";

               if ( limitSwLowPin )

                    delete limitSwLowPin;

               limitSwLowPin = limitSwitch; }; }


     else

          delete limitSwitch; };


bool

     Axis::isSwitchLimited() {


     if (     limitSwLowPin

          &&     limitSwLowPin->readPin() ) {


          switchLimited( SWITCH_LIMIT_LOW );

          return

               true; };


     if     (     limitSwHighPin

          &&     limitSwHighPin->readPin() ) {


          switchLimited( SWITCH_LIMIT_HIGH );

          return

               true; };


     switch ( axisState ) {


          case SWITCH_LIMIT_HIGH :

          AxisTimer::disableAxisInterrupts();

               stopMotor();

               setAxisState( IDLE );

          AxisTimer::enableAxisInterrupts();

          break;

          

          case SWITCH_LIMIT_LOW :

          AxisTimer::disableAxisInterrupts();

               stopMotor();

               setAxisState( IDLE );

          AxisTimer::enableAxisInterrupts(); };


     return

          false; };



void

     Axis::switchLimited( AxisState axisState ) {

     

     AxisTimer::disableAxisInterrupts();

          // Abort interpolation movement

          microStepTargetOffsetI     = 0;

          microStepTargetOffsetF     = 0.0;


          // Brake and move slowly off limit switch

          float backOffVelocity     = stepsPerUnitDistanceF / 60.0;

          if ( axisState == SWITCH_LIMIT_HIGH )

               backOffVelocity = -backOffVelocity;


          runMotor( backOffVelocity );

          setAxisState( axisState );

     AxisTimer::enableAxisInterrupts(); };



void

     Axis::reportDigital( String* msgPtr ) {


     if ( limitSwHighPin )

          limitSwHighPin->reportPinChange( msgPtr );


     if ( limitSwLowPin )

          limitSwLowPin->reportPinChange( msgPtr );

     

     reportHallPinChange( msgPtr ); };