4.10. Motion Control API (MCAPI)¶
MCAPI provides a set of high-level interfaces that can be used by an application to control the motor and obtain feedback information from it while requiring no underlying knowledge of MCAF and its inner-workings.
4.10.1. Overview¶
MCAPI provides the following interfaces for an application to use:
- Public functions to interact with MCAF — defined in
mcapi.h
enum
andstruct
typedefs to work with these MCAPI functions — defined inmcapi_types.h
All MCAPI functions are designed with following goals:
- Minimize CPU execution time
- Non-blocking implementation
- Do not need to be called at any particular rate and do not require any timing reference
- Do not require access to any of the device peripherals
4.10.2. API Description¶
All MCAPI functions that are defined in mcapi.h
also include doc comments with relevant information. The table below shows a list of these functions and a brief summary of their description.
Top-level API feature | API description |
---|---|
Start the motor | Starts the specified motor. There will be no change if the motor is already running. If there is an active MCAF fault, this function will have no effect. |
Stop the motor | Stops the specified motor. There will be no change if the motor is already in fault, stopped or stopping states. |
Set velocity reference | Uses the specified value to update velocity reference for the motor. Input value is a signed Q15 number that has the same scaling factor for velocity as used within MCAF. Sign of the input value will determine the direction of rotation. Changes in velocity command when the motor is not in Before this function is called for the first time after initialization, the set value of velocity reference is either zero, or equal to the minimum value of velocity reference that is valid for MCAF. Note:
|
Get velocity reference | Returns a signed Q15 value of velocity reference for the motor. The return value will exactly match the set value set by “set velocity” function and have the same scaling factor for velocity as used within MCAF. Sign of the return value will determine the direction of rotation. Before the “set velocity” function is called for the first time after initialization, the return value of velocity reference is either zero, or equal to the minimum value of velocity reference that is valid for MCAF. |
Get motor velocity | Returns a signed Q15 value of velocity for the motor as measured by an estimator in MCAF. The return value will have the same scaling factor for velocity as used within MCAF. Sign of the return value will determine the direction of rotation. |
Get magnitude of current | Returns a signed Q15 value that represents the amplitude of current in the motor. The return value is scaled in terms of the same scaling factor for full-scale current as used in MCAF. Since this value is derived from signals with low pass filtering, this is not an instantaneous value and will have some delay compared to the actual current in the motor. The filter time constant used in this case can be changed in the |
Get fault status | Returns a MCAPI_FAULT_FLAGS type bit-field with individual flags for each fault type. |
Clear fault status | Clears the specified fault flag or a given set of fault flags. This function does not implicitly start the motor after clearing all pending faults. |
Get motor status | Returns MCAPI_MOTOR_STATE type motor status. |
Get current Iq | Returns a signed Q15 value that represents the q-axis current in the motor. This return value is scaled in terms of the same scaling factor for full-scale current as used in MCAF. Since this value is derived from signals with low pass filtering, this is not an instantaneous value and will have some delay compared to the actual current in the motor. The filter time constant used in this case can be changed in the |
Get float value of full-scale current |
Returns a floating point formatted full-scale value of current that is being used by MCAF. |
Get float value of full-scale voltage |
Returns a floating point formatted full-scale value of voltage that is being used by MCAF. |
Get float value of full-scale torque |
Returns a floating point formatted full-scale value of electromagnetic torque for the given hardware system being used with MCAF. Factors such as reluctance torque, iron saturation and changes in magnet flux due to temperature can impact the accuracy of this scaling factor. Hence, this is to be consumed by the application on a “for indication only” basis. |
Get float value of full-scale velocity |
Returns a floating point formatted full-scale value of velocity that is being used by MCAF. |
Pre-ADC ISR function | This is a place-holder implementation of the pre-ADC ISR function that will get called at the beginning of ADC ISR that is used by MCAF. This interface is intended to support the need for functional safety features that check for periodicity of interrupts and execute some test cases. |
Post-ADC ISR functions | This is a place-holder implementation of the post-ADC ISR function that will get called at the end of ADC ISR that is used by MCAF. This interface is intended to support the need for functional safety features that check for periodicity of interrupts and execute some test cases. |
Get DC link voltage | Returns a signed Q15 value that represents DC link voltage in the system. This return value is scaled in terms of the same scaling factor for full-scale voltage as used in MCAF. |
Get upper current saturation limit | Returns a signed Q15 value that represents upper bound of the current saturation limit that is implemented in MCAF. |
Get lower current saturation limit | Returns a signed Q15 value that represents lower bound of the current saturation limit that is implemented in MCAF. |
Get maximum value of velocity reference | Gets the maximum command value of velocity reference that is currently supported in the given configuration of MCAF. |
Get minimum value of velocity reference | Gets the minimum command value of velocity reference that is currently supported in the given configuration of MCAF. |
4.10.3. Usage Notes¶
This guidance is available for application developers accessing MCAF through MCAPI functions.
- Do not use any of the interfaces defined in
mcapi_internal.h
. - Do not use the types
MCAPI_MOTOR_DATA
orMCAPI_FEEDBACK_SIGNALS
or access their contents. - After device startup, call
MCAPI_Initialize()
once before calling any MCAPI functions from the application. - All MCAPI functions have certain latency limits. Latency for a setter function or command function is the time delay between the beginning of MCAPI function call and the instant the corresponding MCAF control variable is set (note that because of interaction between main thread and ISR, this change may not take effect until some time after MCAPI function call has completed). Latency for a getter function or feedback function is the time delay between the instant MCAF ISR samples a value from its internal state, and the instant MCAPI returns that value as a result of MCAPI function call.
- Despite this latency limitation, calling one of the
get
functions immediately after calling its counterpartset
function will promptly return the set value. In this case, the return value fromget
function represents the request and not necessarily the state of the motor. - Latency limits of MCAPI functions are not bounded in MCAF R6. However, latency for both getter and setter functions are typically within 2 ISR cycles.
- Calling one or more MCAPI functions in quick succession, for instance, less than 1 ms apart, can cause latency to increase. Similarly, calling one of the MCAPI functions within a
while()
loop without any delay will cause MCAPI to lose synchronization with MCAF. - Since MCAPI interacts with sections of MCAF that execute from an interrupt, the application cannot assume the motor state to be unchanged in between successive calls to the MCAPI.
See Main Application for a description of an example application that is included with MCAF.
4.10.4. Implementation Notes¶
4.10.4.1. MCAPI Architecture¶
MCAPI uses a single data buffer approach in MCAPI motor data in order to reliably communicate in between the application, which is asynchronous to the ADC ISR, and MCAF routines that execute from the ADC ISR.
- On the application-facing side of MCAPI: all MCAPI functions that are called by the application write to and read from MCAPI motor data.
- On the MCAF-facing side of MCAPI: an API service routine that is called from the ADC ISR synchronizes MCAPI motor data with control variables within MCAF motor data.
4.10.4.1.1. MCAPI Data Access¶
MCAPI motor data, defined by the type MCAPI_MOTOR_DATA
, is allocated within the MCAF motor structure of type MCAF_MOTOR_DATA
.
MCAF ADC ISR accesses MCAPI motor data structure through MCAPI internal function, MCAF_ApiServiceIsr()
, from a function call in isr.c
.
The application should use one of the public MCAPI functions to indirectly access MCAPI motor data structure using the pointer &motor.apiData
. This should be treated as an opaque data structure, and the application should not access its contents directly.
MCAF_MOTOR_DATA motor; int main(void) { MCAPI_Initialize(&motor.apiData); ... MCAPI_MOTOR_STATE motorState = MCAPI_OperatingStatusGet(&motor.apiData); switch (motorState) { case MCAPI_MOTOR_STOPPED: # do something ... } ... return 1; }
4.10.4.1.2. Handling Concurrency¶
The application may execute at some arbitrary rate, with calls to MCAPI that are asynchronous to the ADC ISR. Shared MCAPI motor data that is used in both MCAPI function calls and the ADC ISR must be protected against unsynchronized concurrent memory access, known as a data race.
For example, the following sequence of events could occur within MCAPI function MCAPI_FaultStatusClear()
, which sets a series of bit flags in motor.apiData.faultClearFlags
to request clearing faults:
- The application calls
MCAPI_FaultStatusClear(&motor.apiData, 2)
MCAPI_FaultStatusClear()
reads a preexisting value of 8 (bit 3 is set) fromfaultClearFlags
in MCAPI motor dataMCAPI_FaultStatusClear()
is interrupted by the ADC ISR andMCAF_ApiServiceIsr()
clears bit 3, writingfaultClearFlags
to 0MCAPI_FaultStatusClear()
calculates a value of 10 from 8 OR 2MCAPI_FaultStatusClear()
writes the value 10 tofaultClearFlags
In this case, the write made by the ADC ISR was lost.
To prevent data races, MCAPI functions use the apiBusy
flag to claim ownership of MCAPI motor data structure while they are executing a critical section of code. The API service routine is designed to skip execution when it sees that the apiBusy
flag is set.
4.10.4.2. MCAPI errata¶
MCAPI will not individually clear
MCAPI_FAULT_FLAG_OVERCURRENT
fault orMCAPI_FAULT_FLAG_MOTOR_DRIVE
fault if there are other active faults. (DB_MC-3012; Applicability: MCAF R6)For example, if there are three active faults at a given instance of time:
MCAPI_FAULT_FLAG_OVERCURRENT
faultMCAPI_FAULT_FLAG_MOTOR_DRIVE
faultMCAPI_FAULT_FLAG_OVERVOLTAGE
fault
Then, in this case the following code snippet will not clear
MCAPI_FAULT_FLAG_OVERCURRENT
fault orMCAPI_FAULT_FLAG_MOTOR_DRIVE
fault.void APP_ApplicationStep(volatile MCAPI_MOTOR_DATA *api) { ... MCAPI_FaultStatusClear(api, MCAPI_FAULT_FLAG_OVERCURRENT); ... MCAPI_FaultStatusClear(api, MCAPI_FAULT_FLAG_MOTOR_DRIVE); ... }
Application can workaround this issue by clearing all faults in one attempt as shown in the code snippet below.
void APP_ApplicationStep(volatile MCAPI_MOTOR_DATA *api) { ... uint16_t faultFlags = MCAPI_FaultStatusGet(api); MCAPI_FaultStatusClear(api, faultFlags); ... }
MCAPI may drop fault events from MCAF under certain corner-cases. (DB_MC-2978; Applicability: MCAF R6)
This issue may occur if these two events occur in the same ADC interrupt:
- MCAPI clears a particular fault condition.
- MCAF raises another instance of the same fault condition.
In the existing implementation of MCAPI, the application does not have a workaround for this issue.
4.10.4.3. Modules¶
Module | Files | Description | Comments |
---|---|---|---|
parameters/mcapi_params |
parameters/mcapi_params.h |
||
mcapi |
mcapi.c mcapi.h mcapi_types.h |
MCAPI source | |
mcapi_internal |
mcapi_internal.h |
MCAPI routines internal to MCAF |