#ifndef SIMULINK_INTERFACE_H
#define SIMULINK_INTERFACE_H

#include <stddef.h>
#include <stdint.h>

#include "ad_parameter_identification.h"

#define SIMULINK_INTERFACE_VERSION       (1U)
#define SIMULINK_TELEMETRY_MAGIC         (0x41444944UL)
#define SIMULINK_TELEMETRY_MAX_BYTES     (256U)

typedef struct
{
    AD_Measurements_t measurements;
    AD_MotorParameters_t motor_parameters;
    uint32_t param_id_status;
    uint32_t param_id_faults;
    uint8_t param_id_mode;
    uint8_t reserved[3];
} SimulinkInterface_InputBus_t;

typedef struct
{
    AD_Command_t command;
    uint32_t telemetry_size_bytes;
    uint8_t telemetry_ready;
    uint8_t reserved[3];
} SimulinkInterface_OutputBus_t;

typedef struct
{
    uint32_t magic;
    uint16_t version;
    uint16_t payload_size;
    uint32_t sequence;
    uint16_t crc16;
    uint16_t reserved;
} SimulinkTelemetryHeader_t;

typedef struct
{
    AD_Measurements_t measurements;
    AD_MotorParameters_t motor_parameters;
    uint32_t param_id_status;
    uint32_t param_id_faults;
    uint8_t param_id_mode;
    uint8_t command_enable;
    uint8_t command_test_mode;
    uint8_t reserved;
} SimulinkTelemetryPayload_t;

typedef struct
{
    SimulinkTelemetryHeader_t header;
    SimulinkTelemetryPayload_t payload;
} SimulinkTelemetryPacket_t;

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);

void SimulinkInterface_SetMeasurements(const AD_Measurements_t *meas);
void SimulinkInterface_SetCommand(const AD_Command_t *command);
const SimulinkInterface_InputBus_t* SimulinkInterface_GetInputBus(void);
SimulinkInterface_OutputBus_t* SimulinkInterface_GetOutputBus(void);
const SimulinkTelemetryPacket_t* SimulinkInterface_GetTelemetryPacket(void);
const uint8_t* SimulinkInterface_GetTelemetryBytes(void);
size_t SimulinkInterface_GetTelemetrySize(void);

#endif
