/**************************************************************************
Главный заголовочный файл для матлаба. Включает дейфайны для S-Function,
объявляет базовые функции для симуляции МК и подключает базовые библиотеки:
для симуляции		"stm32fxxx_matlab_conf.h"
для S-Function		"simstruc.h"
для потоков			<process.h>

**************************************************************************/
#ifndef _CONTROLLER_H_
#define _CONTROLLER_H_

// Includes
#include "stm32f4xx_matlab_conf.h"  // For stm simulate functions
#include "simstruc.h"               // For S-Function variables
#include <process.h>                // For threads


// Parametrs of MCU simulator
#define CREATE_SUSPENDED                0x00000004  // define from WinBase.h 
// We dont wanna include "Windows.h" or smth like this, because a lot of redefine errors appear.

#define DEKSTOP_CYCLES_FOR_MCU_APP      0xFFFF        // number of for() cycles after which MCU thread would be suspended 
#define PORT_WIDTH                      16          // width of one port
#define PORT_NUMB                       3           // amount of ports

// Parameters of S_Function
#define NPARAMS                 1                           // number of input parametrs (only Ts)
#define IN_PORT_WIDTH           (8)                  // width of input ports
#define IN_PORT_NUMB            1                           // number of input ports
#define OUT_PORT_WIDTH          PORT_WIDTH                  // width of output ports
#define OUT_PORT_NUMB           PORT_NUMB                   // number of output ports
#define DISC_STATES_WIDTH       PORT_WIDTH*PORT_NUMB        // width of discrete states array


// Externs
extern double SIM_Sample_Time;                   // sample time

/** MCU HANDLE STRUCTURE */
/**
  * @brief  MCU handle Structure definition.
  * @vars   MCU Thread - handle for MCUThread and id of MCUThread (unused).
  * @vars   Flags and counters - flags and counter that control MCU app.
  * 
  */
typedef void* HANDLE;
typedef struct _DEL_MCUHandleTypeDef {
    // MCU Thread
    HANDLE          hMCUThread;                 /* Хендл для потока МК */
    uint32_t        idMCUThread;                /* id потока МК (unused) */
    // Flags
    unsigned        MCU_Stop : 1;               /* флаг для выхода из потока программы МК */

}SIM__MCUHandleTypeDef;
extern SIM__MCUHandleTypeDef hmcu;              /* extern для видимости переменной во всех файлах */

//-------------------------------------------------------------//
//------------------  SIMULINK WHILE DEFINES  -----------------//
/** DEFINE TO WHILE WITH SIMULINK WHILE */
/**
  * @brief  Redefine C while statement with sim_while() macro.
  * @param  _expression_ - expression for while.
  * @note   @ref sim_while для подробностей.
  */
#define while(_expression_)                          sim_while(_expression_) /* while который будет использоваться в симулинке */

/** SIMULINK WHILE */
/**
  * @brief  While statement for emulate MCU code in Simulink.
  * @param  _expression_ - expression for while.
  * @note   Данный while необходим, чтобы в конце симуляции, завершить поток МК:
  *         При выставлении флага окончания симуляции, все while будут пропускаться 
  *         и поток сможет дойти до конца своей функции и завершить себя. 
  */    
#define sim_while(_expression_)                     while((_expression_)&&(hmcu.MCU_Stop == 0))

/** DEFAULT WHILE */
/**
  * @brief  Default/Native C while statement.
  * @param  _expression_ - expression for while.
  * @note   Данный while - аналог обычного while, без дополнительного функционала.
  */
#define native_while(_expression_)                   for(; (_expression_); )
  /***************************************************************/

//------------------  SIMULINK WHILE DEFINES  -----------------//
//-------------------------------------------------------------//



//-------------------------------------------------------------//
//---------------- SIMULATE FUNCTIONS PROTOTYPES  -------------//
/** SIMULATE MCU STEP */
/**
  * @brief  Read from simulink S-Block Inputs and write to MCU I/O ports.
  * @param  in - inputs of S-Function.
  * @param  disc - discrete array of S-Function. Outputs would be written from disc.
  * @param  time - current time of simulation (in second).
  * @note   Запускает поток, который выполняет код МК и управляет ходом потока:
  *         Если прошел таймаут, поток прерывается, симулируется периферия
  *         и на следующем шаге поток возобнавляется.
  */
void MCU_Step_Simulation(SimStruct *S, time_T time);     /* step simulation */

/** SIMULATE MCU PERIPHERAL */
/**
  * @brief  Simulate peripheral of MCU
  * @note   Пользовательский код, который симулирует работу периферии МК.
  */
void MCU_Periph_Simulation(void);                               /* MCU peripheral simulation */

/** MCU WRAPPER INITIALIZATION */
/**
  * @brief  Initialize structures and variables for simulating MCU.
  * @note   Пользовательский код, который будет настраивать все структуры.
  */
void SIM_Initialize_Simulation(void);                           /* initialize MCU simulation */
/** MCU WRAPPER DEINITIALIZATION */
/**
  * @brief  Deinitialize structures and variables for simulating MCU.
  * @note   Пользовательский код, который будет очищать все структуры.
  */
void SIM_deInitialize_Simulation(void);                         /* SIM_deInitialize_Simulation MCU simulation */
/** READ INPUTS S-FUNCTION */
/**
  * @brief  Read from simulink S-Block Inputs and write to MCU I/O ports.
  * @param  in - inputs of S-Function.
  * @note   Пользовательский код, который записывает в порты ввода-вывода из disc.
  */
void MCU_readInputs(real_T* in);
/** WRITE OUTPUTS S-FUNCTION */
/**
  * @brief  Read from MCU I/O ports and write to simulink S-Block Outputs.
  * @param  disc - discrete array of S-Function. Outputs would be written from disc.
  * @note   Пользовательский код, который записывает в disc порты ввода-вывода.
  */
void MCU_writeOutputs(real_T* disc);
/** WRITE OUTPUTS OF S-BLOCK */
/**
  * @brief  Write S-Function Output ports to inputs.
  * @param  disc - discrete array of S-Function. Outputs would be written from disc.
  * @note   Пользовательский код, который записывает выходы S-Function.
  */
void SIM_writeOutput(SimStruct* S);
//---------------- SIMULATE FUNCTIONS PROTOTYPES  -------------//
//-------------------------------------------------------------//

#endif // _CONTROLLER_H_