// © 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

#ifndef Axis_h

#define Axis_h

#include <Energia.h>

#include <Machine.h>

#include <driverlib/interrupt.h>

class     SSI;

class     Link;

class     LimitSwitch;

class     StepCounter;

class     ClosedLoopCounter;

#define  MinArmatureOffset     0.5

#define  MaxArmatureOffset     1.5

// flags

#define  ANGULAR               1

#define  STATUS_CHANGED          4

#define  VELOCITY_CHANGED     8

class Axis {

     static Axis*     firstMotorStepAxis;



          char*          data,

          String*          msgPtr );

     uint32_t          parseLength;

    virtual               ~Axis(); // Called automatically after derived class destructor

     enum AxisState {








     // Motor states are aligned with dSpin motor states

     enum MotorState {     // not really needed

          HOLDING,          // mvStepsPerSecF               == 0.0

          ACCELERATING,     // mvStepsPerSecF               != targetStepsPerSecondF

          DECELERATING,     // targetStepsPerSecondF     == 0.0

          CONSTANT_SPEED,     // mvStepsPerSecF               == targetStepsPerSecondF

          DISABLED };

    Axis*               nextAxis;

     static void

          addMotorStepInterrupt( Axis* thisAxis );

     static void

          removeMotorStepInterrupt( Axis* thisAxis );

     static void




    char               axisNameC;

     char               axisFunctionC;

     volatile float     mvStepsPerSecF;               // motor velocity

     float               maxStepsPerSecF;          // for efficiency

     float               stepsPerUnitDistanceF;

    float               microStepsPerUnitDistanceF;     // Inches, mm or degrees - used to scale for feedrate

    float               rotationalRadiusF;               // used to include angular axis in feedrate calculation

     // Current interpolated position before machine transformations

     int32_t               uStepProgramPositionI;

     float               uStepProgramPositionF;

     float               interpolationMicrostepBuffer;

    volatile float     indexerOffsetF;               // microstep error

    Link*               firstSuperiorLink;

    Link*               firstSubordinateLink;

     StepCounter*          slaveStepCounter;

     ClosedLoopCounter*     closedLoopStepCounter;

     // Need 64 bits to maintain microstep accuracy

     // otherwise will overflow 23 bit float precision

     volatile int32_t     microStepTargetOffsetI;     // micro-steps

    // virtual functions can be overriden by derived class

     virtual bool     isTorchAxis();

    virtual bool     isConfigured();

    virtual bool     is8305();

    virtual bool     usesSSI( SSI* ssi );

    virtual void     updateAxis(

          char*          data,

          String*          msgPtr );

    virtual bool     setTargetVelocityWithData(

          char*          data,

          String*          msgPtr );



               float          newTargetStepsPerSecondF );

     // Axis timer interrupt called at 15kHz rate

    virtual void     motorStepIsr() {};

     // Interpolation timer interrupt start and end

     // called at 2kHz rate

    virtual void     interpolationIsr(

          Machine*     machine );

    virtual void     interpolationIsrEnd();

    virtual void     reportAxisStatus(

          String*          msgPtr );

    virtual void     reportAnalog(

          String*          msgPtr );


    bool               angular();

    bool               isSwitchLimited();

    bool               isSeekingPosition();

    bool               velocityChanged();

    bool               statusChanged();

// called on initialization

    void               adjustProgramPosition(

          float          pos );

// called on fixture or tool change

    void               adjustMachinePosition(

          float          offset );




               float microStepsF );

    void               abort();

    void               reportDigital(

          String*          msgPtr );

    void               setFlag(

          uint32_t     flag );

    void               clearFlag(

          uint32_t     flag );

    void               deleteLinks();

    void               deleteSuperiorLinks();

    void               adjustMicroStepTarget(

          float          offset );

     void               updateTimerInterval();

     void               setTargetVelocityForTargetPosition();

     void               calculateTransformedTargets(

          float          microstepDeltaF );

     float               scaledTargetSpeedSquared();

     void               minAndMaxProgress(

          Progress*     progress );

     void               addLimitSwitch(

          char*,          String* );

     void               addSlaveInput(

          char*,          String* );

     void               addSlaveInput();

     void               addClosedLoop(

          char*,          String* );

     virtual void


               char*          data,

               String*          msgPtr );

     virtual void


               char*          data,

               String*          msgPtr );

     virtual void


               char*          data,

               String*          msgPtr,

               char          counterType );

     virtual void

          reportHallPinChange( String* msgPtr ) {};

     virtual void


               char*          data,

               String*          msgPtr );

     virtual void


               char*          data,

               String*          msgPtr );

    void               updateVelocity();

     void               stepped(

          float          microStepsF );

    int32_t               roundToInt(

          float          value );


    volatile uint32_t     flags;

     float               stepProgressF;     // ratio of microstep stop distance to target offset

    // ISR variables

    // enums storage size is same as int or 4 bytes on a 32 bit machine.

    volatile AxisState     axisState;

    volatile MotorState     motorState;


    volatile float     targetStepsPerSecondF;     // target motor velocity

    // Configured Dynamics

     uint32_t          microStepU;

     uint32_t          microStepsPerStepU;

     uint32_t          accelStepsPerSecPerSecU;

     uint32_t          decelStepsPerSecPerSecU;

     uint32_t          maxStepsPerSecU;

     // efficiency variables

     float               microStepsPerStepF;

     float               accelStepsPerSecPerMicroSecF;

     float               decelStepsPerSecPerMicroSecF;

     float               decelStepsPerSecPerSecF;

     // Need 64 bits to maintain microstep accuracy

     // otherwise will overflow 23 bit float precision

     volatile float          microStepTargetOffsetF;     // fractional micro-steps

    volatile int32_t     uStepMachinePositionI;     // unreported position delta

    volatile float          uStepMachinePositionF;     // unreported position delta

     float                    microStepStopDisplacement();

    void                    setAxisState(

          AxisState     newState );

     void                    setMotorState();

    virtual void          motorStateChanged() {};

     virtual void          calculateStopVelocity();

     void                    setMicroStep();

     void                    runMotor(

          float          stepsPerSecondF );

     void                    stopMotor();


    Axis*                    nextMotorStepAxis;

     LimitSwitch*          limitSwLowPin;

    LimitSwitch*          limitSwHighPin;          // ACTIVE_HIGH is limited

     volatile float          accelSpeedStepSizeF;

     volatile float          decelSpeedStepSizeF;

     volatile float          indexerStepSize;


     float                    decelTime_SecPerStepsPerSecF;

     char                    axisStateChar();

     char                    motorStateChar();

     bool                    anyChange();

     void                    switchLimited(

          AxisState );

     void                    addToMicroStepTarget(

          float          microStepsOffsetF );

     void                    interpolating();


     void                    moveMachinePosition(

          float          scaledOffset );

     void                    moveProgramPosition(

          float          scaledOffset );



               char*          data,

               String*          msgPtr );



               char*          data,

               String*          msgPtr );



               char*          data,

               String*          msgPtr );