# 6.3. Integration with Custom Code

## 6.3.1. Overview

The Motor Control Application Framework is designed so that code generated from motorBench™ Development Suite may be used as-is with no changes as a demonstration project with the dsPICDEM® MCLV‑2 Development Board, dsPICDEM® MCHV‑2 Development Board, and dsPICDEM® MCHV‑3 Development Board. Use of the MCAF in other projects usually requires integration with custom code. Although we have organized the Motor Control Application Framework in a modular fashion, this integration with custom code is a manual process, and requires understanding of the different components and modules of the MCAF.

Please note: The functions, modules, and components in the MCAF are still subject to change, and as of v1.0, no interfaces have been frozen. Upgrading to future versions of the MCAF may require changes to any code integrated with MCAF v1.0.

Please note: The initial version of motorBench™ Development Suite does not contain any mechanism to warn against overwriting modified code. Files generated from motorBench™ Development Suite and later modified must be treated with care; subsequent usage of motorBench™ Development Suite to generate code has the potential to overwrite these modifications.

Finally: if integration with custom code is important to you, we encourage your feedback to help guide future development in this area. Please contact `motorbench-support@microchip.com` with any comments or suggestions.

## 6.3.2. General Guidelines

Below are some general guidelines for the components that are likely candidates for modification; more specific information follows in later sections.

- Main Application — You will need to assess whether the scheduling of the ISR and main loop is appropriate for your needs, and integrate this with your own code, accordingly.
- Field-oriented Control — Modifications to the field-oriented control algorithms (for example, changes to the PI controllers, addition of new algorithms such as Maximum Torque Per Ampere or field-weakening) are not recommended.
- External Interface — MCAF v1.0 uses the buttons and potentiometer on Microchip development boards as command inputs. Redirecting these to another source requires modifications to the `ui` and `foc` modules.
- Hardware Abstraction Layer — the MCAF v1.0 HAL is created for the dsPICDEM® MCLV‑2 Development Board, dsPICDEM® MCHV‑2 Development Board, and dsPICDEM® MCHV‑3 Development Board, and would have to be modified for use with other boards.
- State Machine — the MCAF v1.0 state machine and its cycle of `STOPPING` → `STOPPED` → `STARTING` → `RUNNING` → `STOPPING` supports a typical use case. Alternative behaviors would require the state machine to be modified.
- Supervisory Algorithms — the supervisory algorithms provided may not be appropriate for all applications and may need to be modified for custom applications.

## 6.3.3. Modifying the Main Application

The `main` and `isr` modules are intentionally very simple and, in general, should be replaced by custom code. The requirements for the MCAF to work properly are for the modified main application to:

- allocate `MCAF_MOTOR_DATA` for the motor state variables, and `MCAF_SYSTEM_DATA` for the overall system. Pointers to these need to be passed in to the various `MCAF_` functions, with the exception of the control ISR, which has no arguments but still needs to know where to access its data.
- `MCAF_MainInit()` should be called at system startup
- `MCAF_MainLoop()` should be called at each iteration of the main loop. This does not have to be executed periodically, but the minimum repetition rate should be approximately 100Hz to service the various features.
- Control ISR: This should be executed at the same frequency as the PWM waveforms and triggered upon completion of ADC acquisition each cycle. The subfunctions in the `isr` module have these requirements:
  - `MCAF_SystemStateMachine_StepIsr()` – must be called early enough that it finishes PWM register updates in time for the next PWM cycle. Adding code before this function is not recommended.
  - `MCAF_UiStepIsr()` – required for timing purposes
  - `MCAF_MonitorStepIsr()` – required for fault detection
  - `MCAF_WatchdogManageIsr()` – required for watchdog timer management
  - `MCAF_TestHarnessStepIsr()` – required for the test harness
  - `MCAF_DiagnosticsStepIsr()` – required for real-time diagnostics. This should be called last in order to ensure that samples of RAM are taken consistently from the same control cycle.

## 6.3.4. Modifying the FOC module

Because of tight coupling that remains in MCAF v1.0 between the state machine, FOC, and supervisory algorithms, modifications to the FOC module (aside from the specific modifications mentioned later in this section to set the velocity command, and under Supervisory Algorithms) are not recommended. This includes changes to the sensorless estimators or the PI controllers, or additions of flux weakening.

## 6.3.5. Modifying the External Interface

A typical use case is to communicate with some top-level controller (whether located in the same microcontroller or in a remote device that exchanges data over a communication port such as UART or CAN).

MCAF v1.0 still has some coupling between the `ui` and `foc` modules in the way that it handles command inputs. Improvements to this mechanism are planned for a future version of the MCAF. Here are some guidelines for changing the way the MCAF gets its command inputs:

- The velocity command is located in `motor.velocityControl.velocityCmd` and in MCAF v1.0 is updated in foc.c in `MCAF_AcquireADCMuxChannel()` by calling `MCAF_DetermineVelocityCommand()` with one of the ADC values. To use alternate inputs, comment out this line and update the `motor.velocityControl.velocityCmd` variable via another mechanism.
- The enable/disable command is located in `motor.ui.run` and in MCAF v1.0 is updated in ui.c in `MCAF_UiStepMain()` by reading the state of one of the input buttons. It should be set to `true` if the application needs to run the motor, and to `false` if the application needs to stop the motor. This is an input command which is interpreted by the state machine to go through startup/shutdown states.

For feedback information: all the state variable information is located within the `MCAF_MOTOR_DATA` and `MCAF_SYSTEM_DATA` hierarchical structures. In general, these are updated in the control ISR, so to obtain a consistent snapshot of some particular items stored in these structures, a copy of the desired items should be made inside the control ISR after the MCAF ISR code has completed. (Alternatively, disable interrupts while copying, but this has the potential to add latency to the start of the control ISR while interrupts are disabled.)

## 6.3.6. Using Custom Boards

Use of custom boards is not recommended with MCAF v1.0. The mechanism for operating motorBench™ Development Suite with custom boards has not yet been completed. Support for custom boards requires updates to the Hardware Abstraction Layer, and an adjustment of the scaling factors used in motorBench™ Development Suite and the MCAF.

Manual adjustment of any parameter that is automatically computed by motorBench™ Development Suite is not recommended.

## 6.3.7. Modifying the State Machine

Because of tight coupling that remains in MCAF v1.0 between the state machine, FOC, and supervisory algorithms, modifications to the state machine are not recommended.

## 6.3.8. Modifying the Supervisory Algorithms

Supervisory algorithms, with the exception of watchdog management, are executed within `MCAF_MonitorSysDiagnose()` which is implemented in monitor.c and called in state_machine.c in the `MCAF_MotorControllerOnAllStates()` function. The `MCAF_MonitorSysDiagnose()` function may be replaced or modified; presently it calls `MCAF_FaultDetect()` for overvoltage, undervoltage, and hardware overcurrent detection, and `MCAF_StallDetect()` for stall detection.

Watchdog management involves several areas of the MCAF; to change this behavior, see the section on watchdog management and/or search the code for `watchdog`; the relevant sections are in the `traps`, `ui`, `isr`, and `main` modules.