/**
**************************************************************************
* @dir ../MCU_Wrapper
* @brief <b> Папка с исходным кодом оболочки МК. </b>
* @details
В этой папке содержаться оболочка(англ. wrapper) для запуска и контроля
эмуляции микроконтроллеров в MATLAB (любого МК, не только STM).
Оболочка представляет собой S-Function - блок в Simulink, который работает
по скомпилированому коду. Компиляция происходит с помощью MSVC-компилятора.
**************************************************************************/

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

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


/**
    * @defgroup	MCU_WRAPPER     MCU Wrapper
    * @brief 		Всякое для оболочки МК
    */

    /**
        * @addtogroup	WRAPPER_CONF    Wrapper Configuration
        * @ingroup		MCU_WRAPPER
        * @brief 		Параметры конфигурации для оболочки МК
        * @details		Здесь дефайнами задается параметры оболочки, которые определяют как она будет работать
        * @{
        */

        // Parametrs of MCU simulator
//#define RUN_APP_MAIN_FUNC_THREAD                    ///< Enable using thread for MCU main() func
//#define DEKSTOP_CYCLES_FOR_MCU_APP      0xFF      ///< number of for() cycles after which MCU thread would be suspended 
//#define MCU_CORE_CLOCK                  72000000


//#define DEINITIALIZE_AFTER_SIM                    ///< Enable deinitializing structures at simulation ends


#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           (9)                         ///< 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

/** WRAPPER_CONF
  * @}
  */


  /**
    * @addtogroup	MCU_WRAPPER
    * @{
    */

    // Fixed parameters(?) of S_Function
#define NPARAMS                 1                               ///< number of input parametrs (only Ts)
#define DISC_STATES_WIDTH       OUT_PORT_WIDTH*OUT_PORT_NUMB    ///< width of discrete states array (outbup buffer)
/**
  * @brief      Define for creating thread in suspended state.
  * @details    Define from WinBase.h. We dont wanna include "Windows.h" or smth like this, because of HAL there are a lot of redefine errors.
  */
#define CREATE_SUSPENDED                0x00000004
typedef void* HANDLE; ///< MCU handle typedef

/**
  * @brief  MCU handle Structure definition.
  * @note 	Prefixes: h - handle, s - settings, f - flag
  */
typedef struct {
    // MCU Thread
    HANDLE          hMCUThread;                 ///< Хендл для потока МК
    uint32_t        idMCUThread;                ///< id потока МК (unused)
    // Flags
    unsigned        fMCU_Stop : 1;              ///< флаг для выхода из потока программы МК
    double          SIM_Sample_Time;            ///< sample time of simulation

    double          SystemClockDouble;          ///< Счетчик в формате double для точной симуляции системных тиков С промежуточными значений
    uint64_t        SystemClock;                ///< Счетчик тактов для симуляции системных тиков (в целочисленном формате)
    double          SystemClock_step;           ///< Шаг тиков для их симуляции, в формате double
    double          SimTime;
}SIM__MCUHandleTypeDef;
extern SIM__MCUHandleTypeDef hmcu;              // extern для видимости переменной во всех файлах

//-------------------------------------------------------------//
//------------------  SIMULINK WHILE DEFINES  -----------------//
#ifdef RUN_APP_MAIN_FUNC_THREAD
/* DEFINE TO WHILE WITH SIMULINK WHILE */
/**
  * @brief      Redefine C while statement with sim_while() macro.
  * @param      _expression_ - expression for while.
  * @details    Это while который будет использоваться в симулинке @ref sim_while для подробностей.
  */
#define while(_expression_)                          sim_while(_expression_) 
#endif
  /* SIMULINK WHILE */
  /**
    * @brief      While statement for emulate MCU code in Simulink.
    * @param      _expression_ - expression for while.
    * @details    Данный while необходим, чтобы в конце симуляции, завершить поток МК:
    *             При выставлении флага окончания симуляции, все while будут пропускаться
    *             и поток сможет дойти до конца функции main и завершить себя.
    */
#define sim_while(_expression_)                     while((_expression_)&&(hmcu.fMCU_Stop == 0))

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

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



    //-------------------------------------------------------------//
    //---------------- SIMULATE FUNCTIONS PROTOTYPES  -------------//
    /* Step simulation */
void MCU_Step_Simulation(SimStruct* S, time_T time);

/* MCU peripheral simulation */
void MCU_Periph_Simulation(void);

/* Initialize MCU simulation */
void SIM_Initialize_Simulation(void);

/* Deinitialize MCU simulation */
void SIM_deInitialize_Simulation(void);

/* Read inputs S-function  */
void MCU_readInputs(SimStruct* S);
void app_readInputs(real_T* in);

/* Write pre-outputs S-function (out_buff states) */
void MCU_writeOutputs(SimStruct* S);
void app_writeOutputBuffer(real_T* disc);

/* Write outputs of block of S-Function*/
void SIM_writeOutput(SimStruct* S);
//---------------- SIMULATE FUNCTIONS PROTOTYPES  -------------//
//-------------------------------------------------------------//

/** MCU_WRAPPER
    * @}
    */
#endif // _WRAPPER_CONF_H_


    //-------------------------------------------------------------//
    //---------------------BAT FILE DESCRIBTION--------------------//
    /**
      * @file run_mex.bat
      * @brief Батник для компиляции оболочки МК.
      * @details
      * Вызывается в матлабе из mexing.m.
      *
      * Исходный код батника:
      * @include F:\Work\Projects\MATLAB\matlab_stm_emulate\MCU_Wrapper\run_mex.bat
      */