# Simulink Integration

## Existing Simulink artifacts

| Artifact | Status | Notes |
|----------|--------|-------|
| `Inu_im_1wnd_3lvl/inu_im_1wnd_3lvl.slx` | FOUND | Simulink model |
| `Inu_im_1wnd_3lvl/inu_im_1wnd_3lvl_r2021b.slx` | FOUND | Simulink model copy/version |
| `Inu_im_1wnd_3lvl/Inu/wrapper_inu.c` | FOUND | Level-2 C S-function wrapper |
| `Inu_im_1wnd_3lvl/Inu/controller.c` | FOUND | Model-side processor/peripheral simulation |
| ERT generated code (`ert_main.c`, `model.c`, `model.h`, `rtwtypes.h`) | NOT FOUND | Only `slprj` cache/accel artifacts are present |

## Existing S-function mapping

Wrapper:

- S-function name: `wrapper_inu`.
- Main update path: `mdlUpdate()` calls `controller(S, u, xD, rW, iW)`.
- Input width: `17`.
- Output width: `35`.
- Sample time: first and only S-function parameter, read in `mdlInitializeSampleTimes()`.

Input vector unpacking in `Inu/controller.c:28..47`:

| Index | Existing signal | Meaning |
|-------|-----------------|---------|
| 0 | `udc1_ml` | DC-link voltage, V |
| 1 | `ia1_ml` | Phase current A, A |
| 2 | `ib1_ml` | Phase current B, A |
| 3 | `ic1_ml` | Phase current C, A |
| 4 | `wm_ml` | Mechanical speed, rad/s |
| 5 | `mst.faultReset` | Fault reset |
| 6 | `mst.start` | Start command |
| 7 | `mst.pzMode` | Speed/power mode |
| 8 | `mst.wmZz` | Speed reference, p.u. |
| 9 | `mst.pmZz` | Power reference, scaled |
| 10 | `mst.wmLim` | Speed limit, p.u. |
| 11 | `mst.pmLim` | Power limit, scaled |
| 12 | `mst.pIncrMaxTy` | Power ramp up |
| 13 | `mst.pDecrMaxTy` | Power ramp down |
| 14 | `iref` | Current reference, p.u. |
| 15..16 | `paramNew[]` | Parameter writes |

Output vector packing in `Inu/controller.c:615..662`:

- PWM logical outputs for ePWM1..ePWM6 A/B after dead-time/trip simulation.
- State and fault signals.
- Start/work/mode status.
- Flux, speed, power, current, torque and limits.
- `theta_out`.

## New wrapper API

Files:

- `Core/Inc/simulink_interface.h`
- `Core/Src/simulink_interface.c`
- `Core/Inc/ad_parameter_identification.h`
- `Core/Src/ad_parameter_identification.c`

Functions:

```c
void SimulinkInterface_Init(void);
void SimulinkInterface_StepFast(void);
void SimulinkInterface_StepSlow(void);
void SimulinkInterface_UpdateInputs(void);
void SimulinkInterface_UpdateOutputs(void);
void SimulinkInterface_PackTelemetry(void);
void SimulinkInterface_UnpackCommand(void);
```

## Bus Object proposal

Create Simulink Bus Objects that exactly match:

- `AD_Measurements_t`
- `AD_MotorParameters_t`
- `AD_Command_t`
- `SimulinkInterface_InputBus_t`
- `SimulinkInterface_OutputBus_t`

Keep field order and fixed-width integer types identical to the C headers.

## MCU-to-Simulink signals

Use `SimulinkInterface_InputBus_t`:

- `measurements`: raw physical measurements already scaled to SI units.
- `motor_parameters`: known or estimated AD parameters; validity is controlled by `valid_mask`.
- `param_id_status`: identification status bits.
- `param_id_faults`: latched fault bits.
- `param_id_mode`: current identification mode.

## Simulink-to-MCU signals

Use `SimulinkInterface_OutputBus_t.command`:

- `enable`: software enable request.
- `test_mode`: one of `AD_PARAM_ID_MODE_*`.
- `reset_faults`: clears the software fault latch.
- `pwm_duty_limit`, `current_limit_A`, `voltage_limit_V`, `speed_limit_rpm`: safety/control limits.

## Loop rates

Current STM32 timing is UNKNOWN because the STM32G474 project is not present.

Recommended mapping after CubeMX/Keil project is available:

- `SimulinkInterface_StepFast()`: call from ADC/PWM control interrupt, typically current-loop rate.
- `SimulinkInterface_StepSlow()`: call from main loop or a slower timer, typically telemetry/diagnostics rate.
- `SimulinkInterface_UpdateInputs()`: after ADC/speed/temperature measurement update.
- `SimulinkInterface_UpdateOutputs()`: after Simulink command unpacking and safety state update.

## Safety behavior

- Generated Simulink files are not modified.
- New wrapper does not enable power hardware.
- `AD_PARAM_ID_ENABLE_POWER_TESTS` defaults to `0`.
- With the default setting, requested power tests fall back to data logging and set `AD_PARAM_ID_STATUS_POWER_TEST_BLOCKED`.

## TODO

- Add real STM32G474 generated code or `.ioc`.
- Identify generated model step function if ERT code is later generated.
- Decide whether the Simulink model will consume the new Bus Objects directly or through a C Caller/S-function layer.
- Map STM32 ADC/TIM/DMA data into `AD_Measurements_t`.
- Map final motor-control outputs to a verified motor-driver abstraction, not directly to PWM registers.
