G30 Design Project Continued

You said the same thing twice. Move() you mean GoUntil? what is the value of the speed parameter that you are using with the GoUntil command? Is it the same value as the one stored in MAX_Speed?

Sorry I meant GoUntil is creeping. I am using the same value for MAX SPEED and GoUntil. As soon as I get GoUntil moving the right speed smoothly, Move() starts making a grinding noise. I can’t tell if it’s under powered or overpowered. I increase the K’s and it starts smoothing out then GoUntil stops working.

I am also getting this weird thing where the motor locks up and skips its move command even though it usually works with that speed / K values - it’s the smoothest I have gotten and yet it still does that. It’s making it really hard to increase speed because I can’t tell if it’s underpowered or glitching.

Do you have video of that behaviour? Also, is the driver IC getting very hot?

I don’t have any video - it either moves or it doesn’t move. The IC is not warm at all.

The fastest I can get it to go is 960 steps/s (I always set min and max equal otherwise everything moves at the minimum for some reason).

Can you please double check my register setting code? I noticed that sometimes the speed registers will be set to different numbers even though I am inputting the same values (this does not happen all the time but when it does it gets stuck doing this).

Here is the full class (minus the conversion macro), I know it’s long but wanted to include the full class just to be safe. Just ctrl+F for WriteRead() I think that is the main method.

namespace Drivers
{
/// <summary>
/// Contains configuration and control functions for dSpin device
/// </summary>
/// 
public class dSpin
{
    private SPI port = null;
    InputPort busy = null;
    InputPort flag = null;
    SPI.Configuration config;

    public dSpin(SPI spiPort, InputPort busyPort, InputPort flagPort)
    {
        port = spiPort;
        busy = busyPort;
        flag = flagPort;
    }

    public dSpin(SPI spiPort, SPI.Configuration config)
    {
        port = spiPort;
        this.config = config;
    }

    public dSpin(SPI spiPort)
    {
        port = spiPort;
    }

    /// <summary>
    /// Fills-in dSPIN configuration structure with default values.
    /// </summary>
    /// <param name="dSPIN_RegsStruct">Structure address (pointer to struct)</param>
    public static void dSPIN_Regs_Struct_Reset(ref dSPIN_RegsStruct_TypeDef dSPIN_RegsStruct)
    {
        dSPIN_RegsStruct.ABS_POS = 0;
        dSPIN_RegsStruct.EL_POS = 0;
        dSPIN_RegsStruct.MARK = 0;
        dSPIN_RegsStruct.SPEED = 0;
        dSPIN_RegsStruct.ACC = 0x08A;
        dSPIN_RegsStruct.DEC = 0x08A;
        dSPIN_RegsStruct.MAX_SPEED = 0x041;
        dSPIN_RegsStruct.MIN_SPEED = 0;
        dSPIN_RegsStruct.FS_SPD = 0x027;
        dSPIN_RegsStruct.KVAL_HOLD = 0x29;
        dSPIN_RegsStruct.KVAL_RUN = 0x29;
        dSPIN_RegsStruct.KVAL_ACC = 0x29;
        dSPIN_RegsStruct.KVAL_DEC = 0x29;
        dSPIN_RegsStruct.INT_SPD = 0x0408;
        dSPIN_RegsStruct.ST_SLP = 0x19;
        dSPIN_RegsStruct.FN_SLP_ACC = 0x29;
        dSPIN_RegsStruct.FN_SLP_DEC = 0x29;
        dSPIN_RegsStruct.K_THERM = 0;
        dSPIN_RegsStruct.OCD_TH = 0x8;
        dSPIN_RegsStruct.STALL_TH = 0x40;
        dSPIN_RegsStruct.STEP_MODE = 0x7;
        dSPIN_RegsStruct.ALARM_EN = 0xFF;
        dSPIN_RegsStruct.CONFIG = 0x2E88;
    }

    /// <summary>
    /// Configures dSPIN internal registers with values in the config structure.
    /// </summary>
    /// <param name="dSPIN_RegsStruct">Configuration structure address (pointer to configuration structure)</param>
    public void dSPIN_Registers_Set(ref dSPIN_RegsStruct_TypeDef dSPIN_RegsStruct)
    {
        dSPIN_Set_Param(dSPIN_Registers_TypeDef.dSPIN_ABS_POS, dSPIN_RegsStruct.ABS_POS);
        dSPIN_Set_Param(dSPIN_Registers_TypeDef.dSPIN_EL_POS, dSPIN_RegsStruct.EL_POS);
        dSPIN_Set_Param(dSPIN_Registers_TypeDef.dSPIN_MARK, dSPIN_RegsStruct.MARK);
        dSPIN_Set_Param(dSPIN_Registers_TypeDef.dSPIN_SPEED, dSPIN_RegsStruct.SPEED);
        dSPIN_Set_Param(dSPIN_Registers_TypeDef.dSPIN_ACC, dSPIN_RegsStruct.ACC);
        dSPIN_Set_Param(dSPIN_Registers_TypeDef.dSPIN_DEC, dSPIN_RegsStruct.DEC);
        dSPIN_Set_Param(dSPIN_Registers_TypeDef.dSPIN_MAX_SPEED, dSPIN_RegsStruct.MAX_SPEED);
        dSPIN_Set_Param(dSPIN_Registers_TypeDef.dSPIN_MIN_SPEED, dSPIN_RegsStruct.MIN_SPEED);
        dSPIN_Set_Param(dSPIN_Registers_TypeDef.dSPIN_FS_SPD, dSPIN_RegsStruct.FS_SPD);
        dSPIN_Set_Param(dSPIN_Registers_TypeDef.dSPIN_KVAL_HOLD, dSPIN_RegsStruct.KVAL_HOLD);
        dSPIN_Set_Param(dSPIN_Registers_TypeDef.dSPIN_KVAL_RUN, dSPIN_RegsStruct.KVAL_RUN);
        dSPIN_Set_Param(dSPIN_Registers_TypeDef.dSPIN_KVAL_ACC, dSPIN_RegsStruct.KVAL_ACC);
        dSPIN_Set_Param(dSPIN_Registers_TypeDef.dSPIN_KVAL_DEC, dSPIN_RegsStruct.KVAL_DEC);
        dSPIN_Set_Param(dSPIN_Registers_TypeDef.dSPIN_INT_SPD, dSPIN_RegsStruct.INT_SPD);
        dSPIN_Set_Param(dSPIN_Registers_TypeDef.dSPIN_ST_SLP, dSPIN_RegsStruct.ST_SLP);
        dSPIN_Set_Param(dSPIN_Registers_TypeDef.dSPIN_FN_SLP_ACC, dSPIN_RegsStruct.FN_SLP_ACC);
        dSPIN_Set_Param(dSPIN_Registers_TypeDef.dSPIN_FN_SLP_DEC, dSPIN_RegsStruct.FN_SLP_DEC);
        dSPIN_Set_Param(dSPIN_Registers_TypeDef.dSPIN_K_THERM, dSPIN_RegsStruct.K_THERM);
        dSPIN_Set_Param(dSPIN_Registers_TypeDef.dSPIN_OCD_TH, dSPIN_RegsStruct.OCD_TH);
        dSPIN_Set_Param(dSPIN_Registers_TypeDef.dSPIN_STALL_TH, dSPIN_RegsStruct.STALL_TH);
        dSPIN_Set_Param(dSPIN_Registers_TypeDef.dSPIN_STEP_MODE, dSPIN_RegsStruct.STEP_MODE);
        dSPIN_Set_Param(dSPIN_Registers_TypeDef.dSPIN_ALARM_EN, dSPIN_RegsStruct.ALARM_EN);
        dSPIN_Set_Param(dSPIN_Registers_TypeDef.dSPIN_CONFIG, dSPIN_RegsStruct.CONFIG);
    }

    /// <summary>
    /// Issues dSPIN NOP command.
    /// </summary>
    public void dSPIN_Nop()
    {
        /* Send NOP operation code to dSPIN */
        dSPIN_Write_Byte((byte)dSPIN_Commands_TypeDef.dSPIN_NOP);
    }

    /// <summary>
    /// Issues dSPIN Set Param command.
    /// </summary>
    /// <param name="param">dSPIN register address</param>
    /// <param name="value">value to be set</param>
    public void dSPIN_Set_Param(dSPIN_Registers_TypeDef param, UInt32 value)
    {
        /* Send SetParam operation code to dSPIN */
        dSPIN_Write_Byte((byte)(((byte)dSPIN_Commands_TypeDef.dSPIN_SET_PARAM) | ((byte)param)));
        switch (param)
        {
            case dSPIN_Registers_TypeDef.dSPIN_ABS_POS:
            case dSPIN_Registers_TypeDef.dSPIN_MARK:
            case dSPIN_Registers_TypeDef.dSPIN_SPEED:
                /* Send parameter - byte 2 to dSPIN */
                dSPIN_Write_Byte((byte)(value >> 16));
                goto case dSPIN_Registers_TypeDef.dSPIN_ACC;
            case dSPIN_Registers_TypeDef.dSPIN_ACC:
            case dSPIN_Registers_TypeDef.dSPIN_DEC:
            case dSPIN_Registers_TypeDef.dSPIN_MAX_SPEED:
            case dSPIN_Registers_TypeDef.dSPIN_MIN_SPEED:
            case dSPIN_Registers_TypeDef.dSPIN_FS_SPD:
            case dSPIN_Registers_TypeDef.dSPIN_INT_SPD:
            case dSPIN_Registers_TypeDef.dSPIN_CONFIG:
            case dSPIN_Registers_TypeDef.dSPIN_STATUS:
                /* Send parameter - byte 1 to dSPIN */
                dSPIN_Write_Byte((byte)(value >> 8));
                goto default;
            default:
                /* Send parameter - byte 0 to dSPIN */
                dSPIN_Write_Byte((byte)(value));
                break;
        }
        UInt32 _val = dSPIN_Get_Param(param);
        if (_val != value)
        {
            //  throw new ApplicationException("Configuration parameter failed to take the correct value.");
            Debug.Print("**** Register " + param.ToString() + " setting to " + value.ToString() + " returned " + _val.ToString() + "****");
        }
        else
        {
            Debug.Print("Register " + param.ToString() + " setting to " + value.ToString() + " returned " + _val.ToString());


        }

    }

    /// <summary>
    /// Issues dSPIN Get Param command.
    /// </summary>
    /// <param name="param">dSPIN register address</param>
    /// <returns>Register value - 1 to 3 bytes (depends on register)</returns>
    public UInt32 dSPIN_Get_Param(dSPIN_Registers_TypeDef param)
    {
        UInt32 temp = 0;
        UInt32 rx = 0;

        /* Send GetParam operation code to dSPIN */
        temp = dSPIN_Write_Byte((byte)(((byte)dSPIN_Commands_TypeDef.dSPIN_GET_PARAM) | ((byte)param)));
        /* MSB which should be 0 */
        temp = temp << 24;
        rx |= temp;
        switch (param)
        {
            case dSPIN_Registers_TypeDef.dSPIN_ABS_POS:
            case dSPIN_Registers_TypeDef.dSPIN_MARK:
            case dSPIN_Registers_TypeDef.dSPIN_SPEED:
                temp = dSPIN_Write_Byte((byte)(0x00));
                temp = temp << 16;
                rx |= temp;
                goto case dSPIN_Registers_TypeDef.dSPIN_ACC;
            case dSPIN_Registers_TypeDef.dSPIN_ACC:
            case dSPIN_Registers_TypeDef.dSPIN_DEC:
            case dSPIN_Registers_TypeDef.dSPIN_MAX_SPEED:
            case dSPIN_Registers_TypeDef.dSPIN_MIN_SPEED:
            case dSPIN_Registers_TypeDef.dSPIN_FS_SPD:
            case dSPIN_Registers_TypeDef.dSPIN_INT_SPD:
            case dSPIN_Registers_TypeDef.dSPIN_CONFIG:
            case dSPIN_Registers_TypeDef.dSPIN_STATUS:
                temp = dSPIN_Write_Byte((byte)(0x00));
                temp = temp << 8;
                rx |= temp;
                goto default;
            default:
                temp = dSPIN_Write_Byte((byte)(0x00));
                rx |= temp;
                break;
        }
        return rx;
    }

    /// <summary>
    /// Issues dSPIN Run command.
    /// </summary>
    /// <param name="direction">Movement direction (FWD, REV)</param>
    /// <param name="speed"> Speed - 3 bytes</param>
    public void dSPIN_Run(dSPIN_Direction_TypeDef direction, UInt32 speed)
    {
        /* Send RUN operation code to dSPIN */
        dSPIN_Write_Byte((byte)(((byte)dSPIN_Commands_TypeDef.dSPIN_RUN) | ((byte)direction)));
        /* Send speed - byte 2 data dSPIN */
        dSPIN_Write_Byte((byte)(speed >> 16));
        /* Send speed - byte 1 data dSPIN */
        dSPIN_Write_Byte((byte)(speed >> 8));
        /* Send speed - byte 0 data dSPIN */
        dSPIN_Write_Byte((byte)(speed));
    }

    /// <summary>
    /// Issues dSPIN Step Clock command.
    /// </summary>
    /// <param name="direction">Movement direction (FWD, REV)</param>
    public void dSPIN_Step_Clock(dSPIN_Direction_TypeDef direction)
    {
        /* Send StepClock operation code to dSPIN */
        dSPIN_Write_Byte((byte)(((byte)dSPIN_Commands_TypeDef.dSPIN_STEP_CLOCK) | ((byte)direction)));
    }

    /// <summary>
    /// Issues dSPIN Move command.
    /// </summary>
    /// <param name="direction">Movement direction</param>
    /// <param name="n_step">Number of steps</param>
    public void dSPIN_Move(dSPIN_Direction_TypeDef direction, UInt32 n_step)
    {
        /* Send Move operation code to dSPIN */
        dSPIN_Write_Byte((byte)(((byte)dSPIN_Commands_TypeDef.dSPIN_MOVE) | ((byte)direction)));
        /* Send n_step - byte 2 data dSPIN */
        dSPIN_Write_Byte((byte)(n_step >> 16));
        /* Send n_step - byte 1 data dSPIN */
        dSPIN_Write_Byte((byte)(n_step >> 8));
        /* Send n_step - byte 0 data dSPIN */
        dSPIN_Write_Byte((byte)(n_step));
    }

    /// <summary>
    /// Issues dSPIN Go To command.
    /// </summary>
    /// <param name="abs_pos">Absolute position where requested to move</param>
    public void dSPIN_Go_To(UInt32 abs_pos)
    {
        /* Send GoTo operation code to dSPIN */
        dSPIN_Write_Byte((byte)dSPIN_Commands_TypeDef.dSPIN_GO_TO);
        /* Send absolute position parameter - byte 2 data to dSPIN */
        dSPIN_Write_Byte((byte)(abs_pos >> 16));
        /* Send absolute position parameter - byte 1 data to dSPIN */
        dSPIN_Write_Byte((byte)(abs_pos >> 8));
        /* Send absolute position parameter - byte 0 data to dSPIN */
        dSPIN_Write_Byte((byte)(abs_pos));
    }

    /// <summary>
    /// Issues dSPIN Go To Dir command.
    /// </summary>
    /// <param name="direction">Movement direction</param>
    /// <param name="abs_pos">Absolute position where requested to move</param>
    public void dSPIN_Go_To_Dir(dSPIN_Direction_TypeDef direction, UInt32 abs_pos)
    {
        /* Send GoTo_DIR operation code to dSPIN */
        dSPIN_Write_Byte((byte)(((byte)dSPIN_Commands_TypeDef.dSPIN_GO_TO_DIR) | ((byte)direction)));
        /* Send absolute position parameter - byte 2 data to dSPIN */
        dSPIN_Write_Byte((byte)(abs_pos >> 16));
        /* Send absolute position parameter - byte 1 data to dSPIN */
        dSPIN_Write_Byte((byte)(abs_pos >> 8));
        /* Send absolute position parameter - byte 0 data to dSPIN */
        dSPIN_Write_Byte((byte)(abs_pos));
    }

    /// <summary>
    /// Issues dSPIN Go Until command.
    /// </summary>
    /// <param name="action">Action</param>
    /// <param name="direction">Movement direction</param>
    /// <param name="speed">Speed</param>
    public void dSPIN_Go_Until(dSPIN_Action_TypeDef action, dSPIN_Direction_TypeDef direction, UInt32 speed)
    {
        /* Send GoUntil operation code to dSPIN */
        dSPIN_Write_Byte((byte)(((byte)dSPIN_Commands_TypeDef.dSPIN_GO_UNTIL) | ((byte)action) | ((byte)direction)));
        /* Send speed parameter - byte 2 data to dSPIN */
        dSPIN_Write_Byte((byte)(speed >> 16));
        /* Send speed parameter - byte 1 data to dSPIN */
        dSPIN_Write_Byte((byte)(speed >> 8));
        /* Send speed parameter - byte 0 data to dSPIN */
        dSPIN_Write_Byte((byte)(speed));
    }

    /// <summary>
    /// Issues dSPIN Release SW command.
    /// </summary>
    /// <param name="action">Action</param>
    /// <param name="direction">Movement direction</param>
    public void dSPIN_Release_SW(dSPIN_Action_TypeDef action, dSPIN_Direction_TypeDef direction)
    {
        /* Send ReleaseSW operation code to dSPIN */
        dSPIN_Write_Byte((byte)(((byte)dSPIN_Commands_TypeDef.dSPIN_RELEASE_SW) | ((byte)action) | ((byte)direction)));
    }

    /// <summary>
    /// Issues dSPIN Go Home command. (Shorted path to zero position)
    /// </summary>
    public void dSPIN_Go_Home()
    {
        /* Send GoHome operation code to dSPIN */
        dSPIN_Write_Byte((byte)dSPIN_Commands_TypeDef.dSPIN_GO_HOME);
    }

    /// <summary>
    /// Issues dSPIN Go Mark command.
    /// </summary>
    public void dSPIN_Go_Mark()
    {
        /* Send GoMark operation code to dSPIN */
        dSPIN_Write_Byte((byte)dSPIN_Commands_TypeDef.dSPIN_GO_MARK);
    }

    /// <summary>
    /// Issues dSPIN Reset Pos command.
    /// </summary>
    public void dSPIN_Reset_Pos()
    {
        /* Send ResetPos operation code to dSPIN */
        dSPIN_Write_Byte((byte)dSPIN_Commands_TypeDef.dSPIN_RESET_POS);
    }

    /// <summary>
    /// Issues dSPIN Reset Device command.
    /// </summary>
    public void dSPIN_Reset_Device()
    {
        /* Send ResetDevice operation code to dSPIN */
        dSPIN_Write_Byte((byte)dSPIN_Commands_TypeDef.dSPIN_RESET_DEVICE);
    }

    /// <summary>
    /// Issues dSPIN Soft Stop command.
    /// </summary>
    public void dSPIN_Soft_Stop()
    {
        /* Send SoftStop operation code to dSPIN */
        dSPIN_Write_Byte((byte)dSPIN_Commands_TypeDef.dSPIN_SOFT_STOP);
    }

    /// <summary>
    /// Issues dSPIN Hard Stop command.
    /// </summary>
    public void dSPIN_Hard_Stop()
    {
        /* Send HardStop operation code to dSPIN */
        dSPIN_Write_Byte((byte)dSPIN_Commands_TypeDef.dSPIN_HARD_STOP);
    }

    /// <summary>
    /// Issues dSPIN Soft HiZ command.
    /// </summary>
    public void dSPIN_Soft_HiZ()
    {
        /* Send SoftHiZ operation code to dSPIN */
        dSPIN_Write_Byte((byte)dSPIN_Commands_TypeDef.dSPIN_SOFT_HIZ);
    }

    /// <summary>
    /// Issues dSPIN Hard HiZ command.
    /// </summary>
    public void dSPIN_Hard_HiZ()
    {
        /* Send HardHiZ operation code to dSPIN */
        dSPIN_Write_Byte((byte)dSPIN_Commands_TypeDef.dSPIN_HARD_HIZ);
    }

    /// <summary>
    /// Issues dSPIN Get Status command.
    /// </summary>
    /// <returns>Status Register content</returns>
    public UInt16 dSPIN_Get_Status()
    {
        UInt16 temp = 0;
        UInt16 rx = 0;

        /* Send GetStatus operation code to dSPIN */
        dSPIN_Write_Byte((byte)dSPIN_Commands_TypeDef.dSPIN_GET_STATUS);
        /* Send zero byte / receive MSByte from dSPIN */
        temp = dSPIN_Write_Byte((byte)(0x00));
        temp <<= 8;
        rx |= temp;
        /* Send zero byte / receive LSByte from dSPIN */
        temp = dSPIN_Write_Byte((byte)(0x00));
        rx |= temp;
        return rx;
    }

    /// <summary>
    /// Checks if the dSPIN is Busy by hardware - active Busy signal.
    /// </summary>
    /// <returns>one if chip is busy, otherwise zero</returns>
    public byte dSPIN_Busy_HW()
    {
        if (busy != null)
        {
            return (byte)(busy.Read() == true ? 0x01 : 0x00);
        }
        else
        {
            return 0x00;
        }
        ///if(!(GPIO_ReadInputDataBit(dSPIN_BUSY_Port, dSPIN_BUSY_Pin))) return 0x01;
        ///else return 0x00;
    }

    /// <summary>
    /// Checks if the dSPIN is Busy by SPI - Busy flag bit in Status Register.
    /// </summary>
    /// <returns>one if chip is busy, otherwise zero</returns>
    public byte dSPIN_Busy_SW()
    {
        if (!((dSPIN_Get_Status() & (UInt16)dSPIN_STATUS_Masks_TypeDef.dSPIN_STATUS_BUSY) == (UInt16)dSPIN_STATUS_Masks_TypeDef.dSPIN_STATUS_BUSY))
        {
            return 0x01;
        }
        else
        {
            return 0x00;
        }
    }

    /// <summary>
    /// Checks dSPIN Flag signal.
    /// </summary>
    /// <returns>one if Flag signal is active, otherwise zero</returns>
    public byte dSPIN_Flag()
    {
        if (flag != null)
        {
            return (byte)(flag.Read() ? 0x01 : 0x00);
        }
        else
        {
            return 0x00;
        }
        //if(!(GPIO_ReadInputDataBit(dSPIN_FLAG_Port, dSPIN_FLAG_Pin))) return 0x01;
        //else return 0x00;
    }

    /// <summary>
    /// Transmits/Receives one byte to/from dSPIN over SPI.
    /// </summary>
    /// <param name="byteValue">Transmited byte</param>
    /// <returns>Received byte</returns>
    byte dSPIN_Write_Byte(byte byteValue)
    {
        byte[] _rxData = new byte[1];
        //port.Config = config;
        port.WriteRead(new byte[] { byteValue }, _rxData);
        return _rxData[0];

        ///[Original C code that was replaced by .net functionality]
        ///* nSS signal activation - low */
        //GPIO_ResetBits(dSPIN_nSS_Port, dSPIN_nSS_Pin);
        ///* SPI byte send */
        //SPI_I2S_SendData(dSPIN_SPI, byteValue);
        ///* Wait for SPIx Busy flag */
        //while (SPI_I2S_GetFlagStatus(dSPIN_SPI, SPI_I2S_FLAG_BSY) != RESET);
        ///* nSS signal deactivation - high */
        //GPIO_SetBits(dSPIN_nSS_Port, dSPIN_nSS_Pin);
        //return (byte)(SPI_I2S_ReceiveData(dSPIN_SPI));
    }

     public byte[] WriteRead(byte[] data)
     {
        byte[] _receive = new byte[data.Length];
         for (int i = 0; i < data.Length; i++)
        {
             byte[] _txData = new byte[1];
            byte[] _rxData = new byte[1];
            _txData[0] = data[i];
             port.Config = config;
             port.WriteRead(_txData, _rxData);
             _receive[i] = _rxData[0];
         }
        return _receive;
     }
}

emphasized text
#region Exported types

/// <summary>
/// dSPIN Init structure definition
/// </summary>
public struct dSPIN_RegsStruct_TypeDef
{
    public UInt32 ABS_POS;
    public UInt16 EL_POS;
    public UInt32 MARK;
    public UInt32 SPEED;
    public UInt16 ACC;
    public UInt16 DEC;
    public UInt16 MAX_SPEED;
    public UInt16 MIN_SPEED;
    public UInt16 FS_SPD;
    public byte KVAL_HOLD;
    public byte KVAL_RUN;
    public byte KVAL_ACC;
    public byte KVAL_DEC;
    public UInt16 INT_SPD;
    public byte ST_SLP;
    public byte FN_SLP_ACC;
    public byte FN_SLP_DEC;
    public byte K_THERM;
    public byte ADC_OUT;
    public byte OCD_TH;
    public byte STALL_TH;
    public byte STEP_MODE;
    public byte ALARM_EN;
    public UInt16 CONFIG;
}

/// <summary>
/// dSPIN overcurrent threshold options
/// </summary>
public enum dSPIN_OCD_TH_TypeDef
{
    dSPIN_OCD_TH_375mA = ((byte)0x00),
    dSPIN_OCD_TH_750mA = ((byte)0x01),
    dSPIN_OCD_TH_1125mA = ((byte)0x02),
    dSPIN_OCD_TH_1500mA = ((byte)0x03),
    dSPIN_OCD_TH_1875mA = ((byte)0x04),
    dSPIN_OCD_TH_2250mA = ((byte)0x05),
    dSPIN_OCD_TH_2625mA = ((byte)0x06),
    dSPIN_OCD_TH_3000mA = ((byte)0x07),
    dSPIN_OCD_TH_3375mA = ((byte)0x08),
    dSPIN_OCD_TH_3750mA = ((byte)0x09),
    dSPIN_OCD_TH_4125mA = ((byte)0x0A),
    dSPIN_OCD_TH_4500mA = ((byte)0x0B),
    dSPIN_OCD_TH_4875mA = ((byte)0x0C),
    dSPIN_OCD_TH_5250mA = ((byte)0x0D),
    dSPIN_OCD_TH_5625mA = ((byte)0x0E),
    dSPIN_OCD_TH_6000mA = ((byte)0x0F)
}

/// <summary>
/// dSPIN STEP_MODE register masks
/// </summary>
public enum dSPIN_STEP_MODE_Masks_TypeDef
{
    dSPIN_STEP_MODE_STEP_SEL = ((byte)0x07),
    dSPIN_STEP_MODE_SYNC_SEL = ((byte)0x70),
    dSPIN_STEP_MODE_SYNC_EN = ((byte)0x80)
}

/// <summary>
/// dSPIN STEP_MODE register options
/// dSPIN STEP_SEL options
/// </summary>
public enum dSPIN_STEP_SEL_TypeDef
{
    dSPIN_STEP_SEL_1 = ((byte)0x00),
    dSPIN_STEP_SEL_1_2 = ((byte)0x01),
    dSPIN_STEP_SEL_1_4 = ((byte)0x02),
    dSPIN_STEP_SEL_1_8 = ((byte)0x03),
    dSPIN_STEP_SEL_1_16 = ((byte)0x04),
    dSPIN_STEP_SEL_1_32 = ((byte)0x05),
    dSPIN_STEP_SEL_1_64 = ((byte)0x06),
    dSPIN_STEP_SEL_1_128 = ((byte)0x07)
}

/// <summary>
/// dSPIN SYNC_SEL options
/// </summary>
public enum dSPIN_SYNC_SEL_TypeDef
{
    dSPIN_SYNC_SEL_1_2 = ((byte)0x00),
    dSPIN_SYNC_SEL_1 = ((byte)0x10),
    dSPIN_SYNC_SEL_2 = ((byte)0x20),
    dSPIN_SYNC_SEL_4 = ((byte)0x30),
    dSPIN_SYNC_SEL_8 = ((byte)0x40),
    dSPIN_SYNC_SEL_16 = ((byte)0x50),
    dSPIN_SYNC_SEL_32 = ((byte)0x60),
    dSPIN_SYNC_SEL_64 = ((byte)0x70)
}

///TODO: Figure out what to do with this line
//#define dSPIN_SYNC_EN    0x80

/// <summary>
/// dSPIN ALARM_EN register options
/// </summary>
public enum dSPIN_ALARM_EN_TypeDef
{
    dSPIN_ALARM_EN_OVERCURRENT = ((byte)0x01),
    dSPIN_ALARM_EN_THERMAL_SHUTDOWN = ((byte)0x02),
    dSPIN_ALARM_EN_THERMAL_WARNING = ((byte)0x04),
    dSPIN_ALARM_EN_UNDER_VOLTAGE = ((byte)0x08),
    dSPIN_ALARM_EN_STALL_DET_A = ((byte)0x10),
    dSPIN_ALARM_EN_STALL_DET_B = ((byte)0x20),
    dSPIN_ALARM_EN_SW_TURN_ON = ((byte)0x40),
    dSPIN_ALARM_EN_WRONG_NPERF_CMD = ((byte)0x80)
}

/// <summary>
/// dSPIN Config register masks
/// </summary>
public enum dSPIN_CONFIG_Masks_TypeDef
{
    dSPIN_CONFIG_OSC_SEL = ((UInt16)0x0007),
    dSPIN_CONFIG_EXT_CLK = ((UInt16)0x0008),
    dSPIN_CONFIG_SW_MODE = ((UInt16)0x0010),
    dSPIN_CONFIG_EN_VSCOMP = ((UInt16)0x0020),
    dSPIN_CONFIG_OC_SD = ((UInt16)0x0080),
    dSPIN_CONFIG_POW_SR = ((UInt16)0x0300),
    dSPIN_CONFIG_F_PWM_DEC = ((UInt16)0x1C00),
    dSPIN_CONFIG_F_PWM_INT = ((UInt16)0xE000)
}

/// <summary>
/// dSPIN Config register options
/// </summary>
public enum dSPIN_CONFIG_OSC_MGMT_TypeDef
{
    dSPIN_CONFIG_INT_16MHZ = ((UInt16)0x0000),
    dSPIN_CONFIG_INT_16MHZ_OSCOUT_2MHZ = ((UInt16)0x0008),
    dSPIN_CONFIG_INT_16MHZ_OSCOUT_4MHZ = ((UInt16)0x0009),
    dSPIN_CONFIG_INT_16MHZ_OSCOUT_8MHZ = ((UInt16)0x000A),
    dSPIN_CONFIG_INT_16MHZ_OSCOUT_16MHZ = ((UInt16)0x000B),
    dSPIN_CONFIG_EXT_8MHZ_XTAL_DRIVE = ((UInt16)0x0004),
    dSPIN_CONFIG_EXT_16MHZ_XTAL_DRIVE = ((UInt16)0x0005),
    dSPIN_CONFIG_EXT_24MHZ_XTAL_DRIVE = ((UInt16)0x0006),
    dSPIN_CONFIG_EXT_32MHZ_XTAL_DRIVE = ((UInt16)0x0007),
    dSPIN_CONFIG_EXT_8MHZ_OSCOUT_INVERT = ((UInt16)0x000C),
    dSPIN_CONFIG_EXT_16MHZ_OSCOUT_INVERT = ((UInt16)0x000D),
    dSPIN_CONFIG_EXT_24MHZ_OSCOUT_INVERT = ((UInt16)0x000E),
    dSPIN_CONFIG_EXT_32MHZ_OSCOUT_INVERT = ((UInt16)0x000F)
}

public enum dSPIN_CONFIG_SW_MODE_TypeDef
{
    dSPIN_CONFIG_SW_HARD_STOP = ((UInt16)0x0000),
    dSPIN_CONFIG_SW_USER = ((UInt16)0x0010)
}

public enum dSPIN_CONFIG_EN_VSCOMP_TypeDef
{
    dSPIN_CONFIG_VS_COMP_DISABLE = ((UInt16)0x0000),
    dSPIN_CONFIG_VS_COMP_ENABLE = ((UInt16)0x0020)
}

public enum dSPIN_CONFIG_OC_SD_TypeDef
{
    dSPIN_CONFIG_OC_SD_DISABLE = ((UInt16)0x0000),
    dSPIN_CONFIG_OC_SD_ENABLE = ((UInt16)0x0080)
}

public enum dSPIN_CONFIG_POW_SR_TypeDef
{
    dSPIN_CONFIG_SR_180V_us = ((UInt16)0x0000),
    dSPIN_CONFIG_SR_290V_us = ((UInt16)0x0200),
    dSPIN_CONFIG_SR_530V_us = ((UInt16)0x0300)
}

public enum dSPIN_CONFIG_F_PWM_INT_TypeDef
{
    dSPIN_CONFIG_PWM_DIV_1 = (((UInt16)0x00) << 13),
    dSPIN_CONFIG_PWM_DIV_2 = (((UInt16)0x01) << 13),
    dSPIN_CONFIG_PWM_DIV_3 = (((UInt16)0x02) << 13),
    dSPIN_CONFIG_PWM_DIV_4 = (((UInt16)0x03) << 13),
    dSPIN_CONFIG_PWM_DIV_5 = (((UInt16)0x04) << 13),
    dSPIN_CONFIG_PWM_DIV_6 = (((UInt16)0x05) << 13),
    dSPIN_CONFIG_PWM_DIV_7 = (((UInt16)0x06) << 13)
}

public enum dSPIN_CONFIG_F_PWM_DEC_TypeDef
{
    dSPIN_CONFIG_PWM_MUL_0_625 = (((UInt16)0x00) << 10),
    dSPIN_CONFIG_PWM_MUL_0_75 = (((UInt16)0x01) << 10),
    dSPIN_CONFIG_PWM_MUL_0_875 = (((UInt16)0x02) << 10),
    dSPIN_CONFIG_PWM_MUL_1 = (((UInt16)0x03) << 10),
    dSPIN_CONFIG_PWM_MUL_1_25 = (((UInt16)0x04) << 10),
    dSPIN_CONFIG_PWM_MUL_1_5 = (((UInt16)0x05) << 10),
    dSPIN_CONFIG_PWM_MUL_1_75 = (((UInt16)0x06) << 10),
    dSPIN_CONFIG_PWM_MUL_2 = (((UInt16)0x07) << 10)
}

/// <summary>
/// Status Register bit masks
/// </summary>
public enum dSPIN_STATUS_Masks_TypeDef
{
    dSPIN_STATUS_HIZ = (((UInt16)0x0001)),
    dSPIN_STATUS_BUSY = (((UInt16)0x0002)),
    dSPIN_STATUS_SW_F = (((UInt16)0x0004)),
    dSPIN_STATUS_SW_EVN = (((UInt16)0x0008)),
    dSPIN_STATUS_DIR = (((UInt16)0x0010)),
    dSPIN_STATUS_MOT_STATUS = (((UInt16)0x0060)),
    dSPIN_STATUS_NOTPERF_CMD = (((UInt16)0x0080)),
    dSPIN_STATUS_WRONG_CMD = (((UInt16)0x0100)),
    dSPIN_STATUS_UVLO = (((UInt16)0x0200)),
    dSPIN_STATUS_TH_WRN = (((UInt16)0x0400)),
    dSPIN_STATUS_TH_SD = (((UInt16)0x0800)),
    dSPIN_STATUS_OCD = (((UInt16)0x1000)),
    dSPIN_STATUS_STEP_LOSS_A = (((UInt16)0x2000)),
    dSPIN_STATUS_STEP_LOSS_B = (((UInt16)0x4000)),
    dSPIN_STATUS_SCK_MOD = (((UInt16)0x8000))
}

/// <summary>
/// Status Register options
/// </summary>
public enum dSPIN_STATUS_TypeDef
{
    dSPIN_STATUS_MOT_STATUS_STOPPED = (((UInt16)0x0000) << 13),
    dSPIN_STATUS_MOT_STATUS_ACCELERATION = (((UInt16)0x0001) << 13),
    dSPIN_STATUS_MOT_STATUS_DECELERATION = (((UInt16)0x0002) << 13),
    dSPIN_STATUS_MOT_STATUS_CONST_SPD = (((UInt16)0x0003) << 13)
}

/// <summary>
/// dSPIN internal register addresses
/// </summary>
public enum dSPIN_Registers_TypeDef
{
    dSPIN_ABS_POS = ((byte)0x01),
    dSPIN_EL_POS = ((byte)0x02),
    dSPIN_MARK = ((byte)0x03),
    dSPIN_SPEED = ((byte)0x04),
    dSPIN_ACC = ((byte)0x05),
    dSPIN_DEC = ((byte)0x06),
    dSPIN_MAX_SPEED = ((byte)0x07),
    dSPIN_MIN_SPEED = ((byte)0x08),
    dSPIN_FS_SPD = ((byte)0x15),
    dSPIN_KVAL_HOLD = ((byte)0x09),
    dSPIN_KVAL_RUN = ((byte)0x0A),
    dSPIN_KVAL_ACC = ((byte)0x0B),
    dSPIN_KVAL_DEC = ((byte)0x0C),
    dSPIN_INT_SPD = ((byte)0x0D),
    dSPIN_ST_SLP = ((byte)0x0E),
    dSPIN_FN_SLP_ACC = ((byte)0x0F),
    dSPIN_FN_SLP_DEC = ((byte)0x10),
    dSPIN_K_THERM = ((byte)0x11),
    dSPIN_ADC_OUT = ((byte)0x12),
    dSPIN_OCD_TH = ((byte)0x13),
    dSPIN_STALL_TH = ((byte)0x14),
    dSPIN_STEP_MODE = ((byte)0x16),
    dSPIN_ALARM_EN = ((byte)0x17),
    dSPIN_CONFIG = ((byte)0x18),
    dSPIN_STATUS = ((byte)0x19),
    dSPIN_RESERVED_REG1 = ((byte)0x1A),
    dSPIN_RESERVED_REG2 = ((byte)0x1B)
}

/// <summary>
/// dSPIN command set
/// </summary>
public enum dSPIN_Commands_TypeDef
{
    dSPIN_NOP = ((byte)0x00),
    dSPIN_SET_PARAM = ((byte)0x00),
    dSPIN_GET_PARAM = ((byte)0x20),
    dSPIN_RUN = ((byte)0x50),
    dSPIN_STEP_CLOCK = ((byte)0x58),
    dSPIN_MOVE = ((byte)0x40),
    dSPIN_GO_TO = ((byte)0x60),
    dSPIN_GO_TO_DIR = ((byte)0x68),
    dSPIN_GO_UNTIL = ((byte)0x82),
    dSPIN_RELEASE_SW = ((byte)0x92),
    dSPIN_GO_HOME = ((byte)0x70),
    dSPIN_GO_MARK = ((byte)0x78),
    dSPIN_RESET_POS = ((byte)0xD8),
    dSPIN_RESET_DEVICE = ((byte)0xC0),
    dSPIN_SOFT_STOP = ((byte)0xB0),
    dSPIN_HARD_STOP = ((byte)0xB8),
    dSPIN_SOFT_HIZ = ((byte)0xA0),
    dSPIN_HARD_HIZ = ((byte)0xA8),
    dSPIN_GET_STATUS = ((byte)0xD0),
    dSPIN_RESERVED_CMD1 = ((byte)0xEB),
    dSPIN_RESERVED_CMD2 = ((byte)0xF8)
}

/// <summary>
/// dSPIN direction options
/// </summary>
public enum dSPIN_Direction_TypeDef
{
    FWD = ((byte)0x01),
    REV = ((byte)0x00)
}

/// <summary>
/// dSPIN action options
/// </summary>
public enum dSPIN_Action_TypeDef
{
    ACTION_RESET = ((byte)0x00),
    ACTION_COPY = ((byte)0x01)
}
#endregion

}

Why are these two conversions different?

public static UInt16 MaxSpdStepsToPar(UInt16 steps) {
        return ((UInt16)(((steps) * 0.065536) + 0.5));         /* Max Speed conversion, range 15.25 to 15610 steps/s */
    }
    public static UInt16 MinSpdStepsToPar(UInt16 steps) {
        return ((UInt16)(((steps) * 4.194304) + 0.5));         /* Min Speed conversion, range 0 to 976.3 steps/s */
}

It also seems like the SW pin is getting stuck. I hooked the hall sensor directly to the L6470 SW input. I can make it Go_Until() the sensor, then use Move() to back away but then it won’t do Go_Until again unless I shut the power off. How do I reset SW?

The two conversions are different because of the different range of values.

I take it that the switch is connected to SW via a resistor and then to GND via another resistor. If not then the gate will go high and then float there indefinitely. Based on your description of the problem I think that may be the issue. I don’t know what the circuit looks like but I can speculate.

I remember that code. Perhaps its time to upgrade the driver :slight_smile:

It says the max for Min Speed is 967, it won’t let me set to 960 even though I swear it was before…

I have the L6470 eval board so however that is set up.

My hall sensor pulls the SW to 3+V when I move it away. The SW is triggered when pulled low so I am pulling it low then high again.

As far as upgrading the driver goes…I have no idea how or the time. I tried to use yours but it wasn’t working :frowning:

Where does your driver set your default register values? You told me it should be configured for most motors.

What is extra weird is the fact that the flag LED is not on and it would be if the SW event was still on. Also, I tried it with the SW mode set to User which means SW no longer causes interrupts and it was still doing the same thing.

What does it mean if the motor stops halfway through a movement when no interrupts are being used / No Go_Until command?

Go_Until will use the SW pin even if it is set to user.

What is this saying then?

By default, a switch turn-on event causes a HardStop interrupt (SW_MODE bit of CONFIG
register set to ‘0’). Otherwise (SW_MODE bit of CONFIG register set to ‘1’), switch input
events do not cause interrupts and the switch status information is at the user’s disposal

Can you explain what I need to do with the SW pin? Do I still need to use a resistor between my hall effect and the switch even on the eval board? Would adding the resistor make it pull high or low?

Ok I added a resistor so SW is now pulled high when not tripped by the sensor. However, I am still getting the same problem where I go to run my code with GoUntil() being first and it gives a small jolt and flashes the busy light but then does not move. If I restart the code then it runs - this happens every time (or should I say every other time since it runs half of the attempts).

Also I can’t get your driver worker it always says hardware error.

Probably because there is a hardware error :slight_smile:

Is there a place where pins are assigned inside of your class that I am missing?

If my motor accelerates but then stops midway through the motion, is that a sign that Krun is too low? can’t get this thing to run past 1000 step/s

So it’s accelerating, then coming to a dead stop? Does it wine or otherwise vibrate? If it does then that’s a stall. If not then try setting the deceleration rate as well.

I wonder if we should have an entire forum topic for the L6470 :slight_smile:

I have the acceleration and deceleration settings pretty well tuned. It runs incredibly smooth/quiet at 1000 steps/s. If I increase it to 1100 it stops midway. It whines/vibrates when doing this. Sometimes I can get it to run faster (not sure how the hell I did it) but it vibrates extremely bad / is not viable motion.

Ya I think this little bastard deserves its own thread haha

The flag is not being raised when it does this though - it raises BUSY for a blink of an eye that shuts off.