//dSPIN_commands.ino - Contains high-level command implementations- movement
// and configuration commands, for example.
// Realize the "set parameter" function, to write to the various registers in
// the dSPIN chip.
void dSPIN_SetParam(byte param, unsigned long value)
{
dSPIN_Xfer(dSPIN_SET_PARAM | param);
dSPIN_ParamHandler(param, value);
}
// Realize the "get parameter" function, to read from the various registers in
// the dSPIN chip.
unsigned long dSPIN_GetParam(byte param)
{
dSPIN_Xfer(dSPIN_GET_PARAM | param);
return dSPIN_ParamHandler(param, 0);
}
// Much of the functionality between "get parameter" and "set parameter" is
// very similar, so we deal with that by putting all of it in one function
// here to save memory space and simplify the program.
unsigned long dSPIN_ParamHandler(byte param, unsigned long value)
{
unsigned long ret_val = 0; // This is a temp for the value to return.
// This switch structure handles the appropriate action for each register.
// This is necessary since not all registers are of the same length, either
// bit-wise or byte-wise, so we want to make sure we mask out any spurious
// bits and do the right number of transfers. That is handled by the dSPIN_Param()
// function, in most cases, but for 1-byte or smaller transfers, we call
// dSPIN_Xfer() directly.
switch (param)
{
// ABS_POS is the current absolute offset from home. It is a 22 bit number expressed
// in two's complement. At power up, this value is 0. It cannot be written when
// the motor is running, but at any other time, it can be updated to change the
// interpreted position of the motor.
case dSPIN_ABS_POS:
ret_val = dSPIN_Param(value, 22);
break;
// EL_POS is the current electrical position in the step generation cycle. It can
// be set when the motor is not in motion. Value is 0 on power up.
case dSPIN_EL_POS:
ret_val = dSPIN_Param(value, 9);
break;
// MARK is a second position other than 0 that the motor can be told to go to. As
// with ABS_POS, it is 22-bit two's complement. Value is 0 on power up.
case dSPIN_MARK:
ret_val = dSPIN_Param(value, 22);
break;
// SPEED contains information about the current speed. It is read-only. It does
// NOT provide direction information.
case dSPIN_SPEED:
ret_val = dSPIN_Param(0, 20);
break;
// ACC and DEC set the acceleration and deceleration rates. Set ACC to 0xFFF
// to get infinite acceleration/decelaeration- there is no way to get infinite
// deceleration w/o infinite acceleration (except the HARD STOP command).
// Cannot be written while motor is running. Both default to 0x08A on power up.
// AccCalc() and DecCalc() functions exist to convert steps/s/s values into
// 12-bit values for these two registers.
case dSPIN_ACC:
ret_val = dSPIN_Param(value, 12);
break;
case dSPIN_DEC:
ret_val = dSPIN_Param(value, 12);
break;
// MAX_SPEED is just what it says- any command which attempts to set the speed
// of the motor above this value will simply cause the motor to turn at this
// speed. Value is 0x041 on power up.
// MaxSpdCalc() function exists to convert steps/s value into a 10-bit value
// for this register.
case dSPIN_MAX_SPEED:
ret_val = dSPIN_Param(value, 10);
break;
// MIN_SPEED controls two things- the activation of the low-speed optimization
// feature and the lowest speed the motor will be allowed to operate at. LSPD_OPT
// is the 13th bit, and when it is set, the minimum allowed speed is automatically
// set to zero. This value is 0 on startup.
// MinSpdCalc() function exists to convert steps/s value into a 12-bit value for this
// register. SetLSPDOpt() function exists to enable/disable the optimization feature.
case dSPIN_MIN_SPEED:
ret_val = dSPIN_Param(value, 12);
break;
// FS_SPD register contains a threshold value above which microstepping is disabled
// and the dSPIN operates in full-step mode. Defaults to 0x027 on power up.
// FSCalc() function exists to convert steps/s value into 10-bit integer for this
// register.
case dSPIN_FS_SPD:
ret_val = dSPIN_Param(value, 10);
break;
// KVAL is the maximum voltage of the PWM outputs. These 8-bit values are ratiometric
// representations: 255 for full output voltage, 128 for half, etc. Default is 0x29.
// The implications of different KVAL settings is too complex to dig into here, but
// it will usually work to max the value for RUN, ACC, and DEC. Maxing the value for
// HOLD may result in excessive power dissipation when the motor is not running.
case dSPIN_KVAL_HOLD:
ret_val = dSPIN_Xfer((byte)value);
break;
case dSPIN_KVAL_RUN:
ret_val = dSPIN_Xfer((byte)value);
break;
case dSPIN_KVAL_ACC:
ret_val = dSPIN_Xfer((byte)value);
break;
case dSPIN_KVAL_DEC:
ret_val = dSPIN_Xfer((byte)value);
break;
// INT_SPD, ST_SLP, FN_SLP_ACC and FN_SLP_DEC are all related to the back EMF
// compensation functionality. Please see the datasheet for details of this
// function- it is too complex to discuss here. Default values seem to work
// well enough.
case dSPIN_INT_SPD:
ret_val = dSPIN_Param(value, 14);
break;
case dSPIN_ST_SLP:
ret_val = dSPIN_Xfer((byte)value);
break;
case dSPIN_FN_SLP_ACC:
ret_val = dSPIN_Xfer((byte)value);
break;
case dSPIN_FN_SLP_DEC:
ret_val = dSPIN_Xfer((byte)value);
break;
// K_THERM is motor winding thermal drift compensation. Please see the datasheet
// for full details on operation- the default value should be okay for most users.
case dSPIN_K_THERM:
ret_val = dSPIN_Xfer((byte)value & 0x0F);
break;
// ADC_OUT is a read-only register containing the result of the ADC measurements.
// This is less useful than it sounds; see the datasheet for more information.
case dSPIN_ADC_OUT:
ret_val = dSPIN_Xfer(0);
break;
// Set the overcurrent threshold. Ranges from 375mA to 6A in steps of 375mA.
// A set of defined constants is provided for the user's convenience. Default
// value is 3.375A- 0x08. This is a 4-bit value.
case dSPIN_OCD_TH:
ret_val = dSPIN_Xfer((byte)value & 0x0F);
break;
// Stall current threshold. Defaults to 0x40, or 2.03A. Value is from 31.25mA to
// 4A in 31.25mA steps. This is a 7-bit value.
case dSPIN_STALL_TH:
ret_val = dSPIN_Xfer((byte)value & 0x7F);
break;
// STEP_MODE controls the microstepping settings, as well as the generation of an
// output signal from the dSPIN. Bits 2:0 control the number of microsteps per
// step the part will generate. Bit 7 controls whether the BUSY/SYNC pin outputs
// a BUSY signal or a step synchronization signal. Bits 6:4 control the frequency
// of the output signal relative to the full-step frequency; see datasheet for
// that relationship as it is too complex to reproduce here.
// Most likely, only the microsteps per step value will be needed; there is a set
// of constants provided for ease of use of these values.
case dSPIN_STEP_MODE:
ret_val = dSPIN_Xfer((byte)value);
break;
// ALARM_EN controls which alarms will cause the FLAG pin to fall. A set of constants
// is provided to make this easy to interpret. By default, ALL alarms will trigger the
// FLAG pin.
case dSPIN_ALARM_EN:
ret_val = dSPIN_Xfer((byte)value);
break;
// CONFIG contains some assorted configuration bits and fields. A fairly comprehensive
// set of reasonably self-explanatory constants is provided, but users should refer
// to the datasheet before modifying the contents of this register to be certain they
// understand