[Bug report] Wrong conversion from float_t to int16_t in MCI_ExecTorqueRamp_F
MCSDK 6.2.0 introduced erronous conversions from float_t to int16_t in:
- MCI_ExecTorqueRamp_F
- MCI_ExecSpeedRamp_F
- MCI_SetCurrentReferences_F
The bug persist in MCSDK 6.2.1.
MCI_ExecTorqueRamp_F is implemented mc_interface.c.ftl
/**
* @brief Programs a motor torque ramp
*
* pHandle Pointer on the component instance to work on.
* FinalTorque is the value of motor torque reference at the end of
* the ramp. This value represents actually the $I_q$ current expressed in
* Ampere.
* Here the formula for conversion from current in Ampere to digit:
* I(s16) = [i(Amp) * 65536 * Rshunt * Aop] / Vdd_micro.
* hDurationms the duration of the ramp expressed in milliseconds. It
* is possible to set 0 to perform an instantaneous change in the
* value.
*
* This command is executed immediately if the target motor's state machine is in
* the #RUN state. Otherwise, it is buffered and its execution is delayed until This
* state is reached.
*
* Users can check the status of the command by calling the MCI_IsCommandAcknowledged()
* function.
*
* MCI_ExecTorqueRamp
*/
__weak void MCI_ExecTorqueRamp_F(MCI_Handle_t *pHandle, const float_t FinalTorque, uint16_t hDurationms)
{
#ifdef NULL_PTR_CHECK_MC_INT
if (MC_NULL == pHandle)
{
/* Nothing to do */
}
else
{
#endif
int16_t hFinalTorque = ((int16_t)FinalTorque * (int16_t)CURRENT_CONV_FACTOR);
MCI_ExecTorqueRamp(pHandle, hFinalTorque, hDurationms);
#ifdef NULL_PTR_CHECK_MC_INT
}
#endif
}
The conversion on line 33 truncates FinalTorque before scaling to the internal representation. This means that a ramp to e.g. 1.7A will actually only execute a 1.0A ramp.
In MCSDK 6.1.2, the conversion was handled correctly.
int16_t hFinalTorque = (int16_t) (FinalTorque * CURRENT_CONV_FACTOR);
Similar wrong conversions has been introduced to MCI_ExecSpeedRamp_F and MCI_SetCurrentReferences_F.
I suspect that the bug was introduces when fixing a bug in the opposite conversions in functions such as MCI_GetLasRampFinalSpeed_F.
// Wrong conversion in MCSDK 6.1.2
RetVal = (float)((pHandle->hFinalSpeed * U_RPM) / SPEED_UNIT);
// Correct conversion in MCSDK 6.2.0
reVal = (((float_t)pHandle->hFinalSpeed * (float_t)U_RPM) / (float_t)SPEED_UNIT);
