/* Copyright 1994-2016 The MathWorks, Inc. */

/*
 * File: rtw_capi.h
 *
 * Abstract:
 *   Provides structure types and constants generated by CAPI.
 *   Macros for accessing the fields of the structures are also provided.
 *   This header file is included in MODEL_capi.c
 *
 */

#ifndef _RTW_CAPI_H_  
# define _RTW_CAPI_H_

#ifdef SL_INTERNAL
# include "simstruct/simstruc_types.h"
#else
#ifdef HOST_CAPI_BUILD
#include "simstruc_types.h"
#else
#include "rtwtypes.h"
#endif
#endif

#define SS_ENUM_TYPE (((uint8_T)(255U))-1)
#define SS_STRUCT    (((uint8_T)(255U)))
#define rt_offsetof(s,el) ((uint32_T)((char_T *)&((s *)0)->el - (char_T *)(s *)0))

/* Enumeration for fixed point scaling type*/
typedef enum {
  rtwCAPI_FIX_UNIFORM_SCALING,
  rtwCAPI_FIX_NONUNIFORM_SCALING,
  rtwCAPI_FIX_RESERVED
} rtwCAPI_FixPtScalingType;

/* Enumeration for data orientation */
typedef enum {
  rtwCAPI_SCALAR,
  rtwCAPI_VECTOR,
  rtwCAPI_MATRIX_ROW_MAJOR,
  rtwCAPI_MATRIX_COL_MAJOR,
  rtwCAPI_MATRIX_COL_MAJOR_ND,
  rtwCAPI_MATRIX_ROW_MAJOR_ND
} rtwCAPI_Orientation;

/* function pointers for matfile logging */
typedef void(*RTWLoggingFcnPtr)(void*, const void*);

/* Signals Structure */
/* Fields of this structure can be used to monitor block output signals*/
typedef struct rtwCAPI_Signals_tag {
  uint_T    addrMapIndex;  /* index into the data address map                */
  uint_T    sysNum;        /* system identification number, where 0 = root   */
  const char_T *blockPath; /* block's full path name (RTW mangled version)   */
  const char_T *signalName;/* signal label (unmangled, NULL if not present)  */
  uint16_T  portNumber;    /* port number  (starts at 0)                     */
  uint16_T  dataTypeIndex; /* index into DataTypeMap, gives signal data type */
  uint16_T  dimIndex;      /* index into DimensionMap, gives signal dimension*/
  uint16_T  fxpIndex;      /* index into FixPtMap, gives Fixed point info    */
  uint8_T   sTimeIndex;    /* index into SampleTimeMap, gives Task info      */  
} rtwCAPI_Signals;

/* Macros for accessing Signals structure fields */
/* bio is a pointer to array of Signals structures */
#define rtwCAPI_GetSignalAddrIdx(bio, i)       ((bio)[(i)].addrMapIndex)
#define rtwCAPI_GetSignalBlockPath(bio, i)     ((bio)[(i)].blockPath)
#define rtwCAPI_GetSignalName(bio, i)          ((bio)[(i)].signalName)
#define rtwCAPI_GetSignalPortNumber(bio, i)    ((bio)[(i)].portNumber)
#define rtwCAPI_GetSignalDataTypeIdx(bio, i)   ((bio)[(i)].dataTypeIndex)
#define rtwCAPI_GetSignalDimensionIdx(bio, i)  ((bio)[(i)].dimIndex)
#define rtwCAPI_GetSignalFixPtIdx(bio, i)      ((bio)[(i)].fxpIndex)
#define rtwCAPI_GetSignalSampleTimeIdx(bio, i) ((bio)[(i)].sTimeIndex)
#define rtwCAPI_GetSignalSysNum(bio, i)        ((bio)[(i)].sysNum)

/* BlockParameters Structure */
/* Fields of this structure can be used to monitor/modify block parameters */
typedef struct rtwCAPI_BlockParameters_tag {
  uint_T    addrMapIndex;  /* index into the data address map                */
  const char_T *blockPath; /* block's full path name (RTW mangled version)   */
  const char_T *paramName; /* parameter name                                 */
  uint16_T  dataTypeIndex; /* index into DataTypeMap, gives param data type  */
  uint16_T  dimIndex;      /* index into DimensionMap, gives param dimensions*/
  uint16_T  fxpIndex;      /* index into FixPtMap, gives Fixed point info    */
} rtwCAPI_BlockParameters;

/* Macros for accessing BlockParameter structure fields */
/* prm is a pointer to array of BlockParameter structures */
#define rtwCAPI_GetBlockParameterAddrIdx(prm, i)      ((prm)[(i)].addrMapIndex)
#define rtwCAPI_GetBlockParameterBlockPath(prm, i)    ((prm)[(i)].blockPath)
#define rtwCAPI_GetBlockParameterName(prm, i)         ((prm)[(i)].paramName)
#define rtwCAPI_GetBlockParameterDataTypeIdx(prm, i)  ((prm)[(i)].dataTypeIndex)
#define rtwCAPI_GetBlockParameterDimensionIdx(prm, i) ((prm)[(i)].dimIndex)
#define rtwCAPI_GetBlockParameterFixPtIdx(prm, i)     ((prm)[(i)].fxpIndex)

/* ModelParameter Structure */
/* Fields of this structure can be used to monitor/modify model parameters   *
 * When Inline Parameters is on, you can configure tunable block parameters  *
 * as model parameters.                                                      */
typedef struct rtwCAPI_ModelParameters_tag {
  uint_T    addrMapIndex;  /* index into the data address map                */
  const char_T   *varName; /* variable  name                                 */
  uint16_T  dataTypeIndex; /* index into DataTypeMap, gives param data type  */
  uint16_T  dimIndex;      /* index into DimensionMap, gives param dimensions*/
  uint16_T  fxpIndex;      /* index into FixPtMap, gives Fixed point info    */
} rtwCAPI_ModelParameters;

/* Macros for accessing ModelParameter structure fields */
/* prm is a pointer to array of ModelParameter structures */
#define rtwCAPI_GetModelParameterAddrIdx(prm, i)      ((prm)[(i)].addrMapIndex)
#define rtwCAPI_GetModelParameterName(prm, i)         ((prm)[(i)].varName)
#define rtwCAPI_GetModelParameterDataTypeIdx(prm, i)  ((prm)[(i)].dataTypeIndex)
#define rtwCAPI_GetModelParameterDimensionIdx(prm, i) ((prm)[(i)].dimIndex)
#define rtwCAPI_GetModelParameterFixPtIdx(prm, i)     ((prm)[(i)].fxpIndex)

/* rtwCAPI_States Structure */
/* Fields of this structure can be used to monitor block States */
typedef struct rtwCAPI_States_tag {
  uint_T addrMapIndex;     /* index into the data address map                 */
  int_T  contStateStartIndex; /* starting index in the model's continuous     * 
                               * state and state derivative vectors. This is  *
                               * set to -1 for discrete states                */
  const char_T *blockPath; /* block's full path name (RTW mangled version)    */
  const char_T *stateName; /* state name, Default:DWork/Cont State Identifier */
  const char_T *pathAlias; /* Alias block path */
  uint16_T  dWorkIndex;    /* Index into the Block DWork, 0 for cont. states  */
  uint16_T  dataTypeIndex; /* index into DataTypeMap, gives state data type   */
  uint16_T  dimIndex;      /* index into DimensionMap, gives state dimensions */
  uint16_T  fxpIndex;      /* index into FixPtMap, gives Fixed point info     */
  uint8_T   sTimeIndex;    /* index into SampleTimeMap, gives Task info       */
  uint8_T   isContinuous;  /* if the state is a Continuous state*/
  int_T   hierInfoIdx;   /* the hierInfo associated with this state, -1 if no hierInfo */
  uint_T  flatElemIdx;   /* flat element index in hierarchy */
} rtwCAPI_States;

/* Macros for accessing States structure fields */
/* bState is a pointer to array of States structures */
#define rtwCAPI_GetStateAddrIdx(bState, i)       ((bState)[(i)].addrMapIndex)
#define rtwCAPI_GetContStateStartIndex(bState, i) \
        ((bState)[(i)].contStateStartIndex)
#define rtwCAPI_GetStateBlockPath(bState, i)     ((bState)[(i)].blockPath)
#define rtwCAPI_GetStateName(bState, i)          ((bState)[(i)].stateName)
#define rtwCAPI_GetStatePathAlias(bState, i)     ((bState)[(i)].pathAlias)
#define rtwCAPI_GetStateDWorkIdx(bState, i)      ((bState)[(i)].dWorkIndex)
#define rtwCAPI_GetStateDataTypeIdx(bState, i)   ((bState)[(i)].dataTypeIndex)
#define rtwCAPI_GetStateDimensionIdx(bState, i)  ((bState)[(i)].dimIndex)
#define rtwCAPI_GetStateFixPtIndex(bState, i)    ((bState)[(i)].fxpIndex)
#define rtwCAPI_GetStateSampleTimeIdx(bState, i) ((bState)[(i)].sTimeIndex)
#define rtwCAPI_IsAContinuousState(bState, i)    ((bState)[(i)].isContinuous == 1)
#define rtwCAPI_GetStateHierInfoIdx(bState, i)   ((bState)[(i)].hierInfoIdx)
#define rtwCAPI_GetStateFlatElemIdx(bState, i)   ((bState)[(i)].flatElemIdx)

/* DataTypeMap structure */
/* Members provide data type information of a signal or parameter */ 
typedef struct rtwCAPI_DataTypeMap_tag {
  const char_T *cDataName;   /* C language data type name                    */
  const char_T *mwDataName;  /* MathWorks data type, typedef in rtwtypes.h   */
  uint16_T      numElements; /* number of elements, 0 for non-structure data */
  uint16_T      elemMapIndex;/* index into the ElementMap, gives Bus Info    */
  uint16_T      dataSize;    /* data size in Bytes                           */
  uint8_T       slDataId;    /* enumerated data type from simstruc_types.h   */
  unsigned int  isComplex:1; /* is the data type complex (1=Complex, 0=Real) */
  unsigned int  isPointer:1; /* is data accessed Via Pointer (1=yes, 0= no)  */
} rtwCAPI_DataTypeMap;

/* Notes on rtwCAPI_DataTypeMap:
 * cDataName  - The ANSI C equivalent data type. 
 *              For fixed point data
 *                  cDataName = the native integer equivalent
 *              For Complex data or non-virtual structures, 
 *                  cDataName = "struct" 
 * mwDataName - RTW defined data type. Typedef can be found in rtwtypes.h
 *              For fixed point data, 
 *                  mwDataName = the integer type in which the data is stored.
 *                  Use rtwCAPI_FixPtMap to get slope & bias of the data.
 * numElements - Number of elements/members in the data type. If the data type 
 *              represents a non-virtual structure (for e.g, bus structure),
 *              this field gives the number of elements in the structure. 
 *              For non-structure data type, the default value is 0
 *              Complex data types are treated as non-structures
 * elemMapIndex - Index into the rtwCAPI_ElementMap which maps each of the
 *              element/member of a structure data type.
 * slDataId   - Enumerated Simulink Data type defined in simstruc_types.h.
 *              The enumerations are
 *                 o SS_DOUBLE
 *                 o SS_SINGLE
 *                 o SS_INT8
 *                 o SS_UINT8
 *                 o SS_INT16
 *                 o SS_UINT16
 *                 o SS_INT32
 *                 o SS_UINT32
 *                 o SS_BOOLEAN
 *                 o SS_ENUM_TYPE  (for enumerated data types)
 *                 o SS_STRUCT     (for non-virtual structures)
 *              For fixed point data: 
 *                  slDataId = enumeration corresponding to the integer type 
 *                             in which the data is stored
 *              For Complex data: 
 *                  slDataId = enumeration corresponding to the data type of 
 *                             the real part.
 * isComplex  - is the data type complex (1=Complex, 0=Real) 
 * isPointer  - is data accessed Via Pointer (1=yes, 0= no)
 */

/* Macros for accessing DataTypeMap fields/members */
#define rtwCAPI_GetDataTypeCName(dTypeMap, i)       ((dTypeMap)[(i)].cDataName)
#define rtwCAPI_GetDataTypeMWName(dTypeMap, i)      ((dTypeMap)[(i)].mwDataName)
#define rtwCAPI_GetDataTypeNumElements(dTypeMap, i) ((dTypeMap)[(i)].numElements)
#define rtwCAPI_GetDataTypeElemMapIndex(dTypeMap,i) ((dTypeMap)[(i)].elemMapIndex)
#define rtwCAPI_GetDataTypeSLId(dTypeMap, i)        ((dTypeMap)[(i)].slDataId)
#define rtwCAPI_GetDataTypeSize(dTypeMap, i)        ((dTypeMap)[(i)].dataSize)
#define rtwCAPI_GetDataIsComplex(dTypeMap, i)       ((dTypeMap)[(i)].isComplex)
#define rtwCAPI_GetDataIsPointer(dTypeMap, i)       ((dTypeMap)[(i)].isPointer)

/* Macros for determining whether signals/states support MAT-File logging */
#define rtwCAPI_CanLogSignalToMATFile(dTypeMap, bio, i) \
    (rtwCAPI_GetDataTypeSLId(dTypeMap, rtwCAPI_GetSignalDataTypeIdx(bio, i))   < SS_NUM_BUILT_IN_DTYPE)
#define rtwCAPI_CanLogStateToMATFile(dTypeMap, bState, i) \
    (rtwCAPI_GetDataTypeSLId(dTypeMap, rtwCAPI_GetStateDataTypeIdx(bState, i)) < SS_NUM_BUILT_IN_DTYPE)

/* ElementMap structure */
/* Fields provide information on elements (fields) in Simulink Bus structure */
typedef struct rtwCAPI_ElementMap_tag {
  const char_T   *elementName;   /* name of the element                      */
  uint32_T  elementOffset; /* offset of the structure element in bytes       */
  uint16_T  dataTypeIndex; /* index into DataTypeMap, datatype of the element*/
  uint16_T  dimIndex;      /* index into DimensionMap, element's dimensions  */
  uint16_T  fxpIndex;      /* index into fixPtMap, fixed point information   */
} rtwCAPI_ElementMap;

/* Macros for accessing ElementMap fields */
#define rtwCAPI_GetElementName(elemMap, i)         ((elemMap)[(i)].elementName)
#define rtwCAPI_GetElementOffset(elemMap, i)       ((elemMap)[(i)].elementOffset)
#define rtwCAPI_GetElementDataTypeIdx(elemMap, i)  ((elemMap)[(i)].dataTypeIndex)
#define rtwCAPI_GetElementDimensionIdx(elemMap, i) ((elemMap)[(i)].dimIndex)
#define rtwCAPI_GetElementFixPtIdx(elemMap, i)     ((elemMap)[(i)].fxpIndex)

/* DimensionMap structure */
/* Fields provide dimensions of a signal or a parameter */
typedef struct rtwCAPI_DimensionMap_tag {
  rtwCAPI_Orientation orientation;   
                                 /* orientation of data -scalar/vector/matrix/ND */
  uint_T    dimArrayIndex;       /* index into dimension array                   */
  uint8_T   numDims;             /* number of dimensions                         */
  uint_T    vardimsIndex;        /* index into vardims address array             */
} rtwCAPI_DimensionMap;

/* Macros for accessing DimensionMap fields */
#define rtwCAPI_GetOrientation(dimMap, i)    ((dimMap)[(i)].orientation)
#define rtwCAPI_GetDimArrayIndex(dimMap, i)  ((dimMap)[(i)].dimArrayIndex)
#define rtwCAPI_GetNumDims(dimMap, i)        ((dimMap)[(i)].numDims)
#define rtwCAPI_GetDimsIsVariable(vardimsAddrMap, dimMap, i) (vardimsAddrMap[(dimMap)[(i)].vardimsIndex] != NULL)

/* FixPtMap Structure */
/* Fields provide fixed point information of a signal or parameter */
typedef struct rtwCAPI_FixPtMap_tag {
  const void*       fracSlopePtr;   /* pointer to fractional slope value        */
  const void*       biasPtr;        /* pointer to bias value                    */
  rtwCAPI_FixPtScalingType scaleType;      
                              /* scaling type - uniform/non-uniform       */
  uint8_T     wordLength;     /* number of bits required to store value   *
                               * In MATLAB, word length of the fi object  */
  int8_T      exponent;       /* exponent                                 */
  boolean_T   isSigned;       /* 1 = signed data, 0 = unsigned data       */
} rtwCAPI_FixPtMap;

/* Macros for accessing FixPtMap fields */
#define rtwCAPI_GetFxpFracSlopePtr(fxpMap, i) ((fxpMap)[(i)].fracSlopePtr)
#define rtwCAPI_GetFxpBiasPtr(fxpMap, i)      ((fxpMap)[(i)].biasPtr)
#define rtwCAPI_GetFxpScaling(fxpMap, i)      ((fxpMap)[(i)].scaleType)
#define rtwCAPI_GetFxpWordLength(fxpMap, i)   ((fxpMap)[(i)].wordLength)
#define rtwCAPI_GetFxpExponent(fxpMap, i)     ((fxpMap)[(i)].exponent)
#define rtwCAPI_GetFxpIsSigned(fxpMap, i)     ((fxpMap)[(i)].isSigned)

/* Macros to get the slope and bias values casted to DOUBLE */
#define rtwCAPI_GetFxpFracSlope(fxpMap, i) (*((real_T*) rtwCAPI_GetFxpFracSlopePtr(fxpMap,i)))
#define rtwCAPI_GetFxpBias(fxpMap, i)      (*((real_T*) rtwCAPI_GetFxpBiasPtr(fxpMap, i))) 

/* SampleTimeMap Structure */
typedef struct rtwCAPI_SampleTimeMap_tag {
  const void*     samplePeriodPtr;  /* pointer to sample time period value       */
  const void*     sampleOffsetPtr;  /* pointer to sample time Offset value       */
  int8_T    tid;              /* task identifier                           */
  uint8_T   samplingMode;     /* 1 = FrameBased, 0 = SampleBased           */
} rtwCAPI_SampleTimeMap;

/* Macros for accessing SampleTimeMap fields */

#define rtwCAPI_GetSamplePeriodPtr(sampTimeMap, i) ((sampTimeMap)[(i)].samplePeriodPtr)
#define rtwCAPI_GetSampleOffsetPtr(sampTimeMap, i) ((sampTimeMap)[(i)].sampleOffsetPtr)
#define rtwCAPI_GetSampleTimeTID(sampTimeMap, i)   ((sampTimeMap)[(i)].tid)
#define rtwCAPI_GetSamplingMode(sampTimeMap, i)    ((sampTimeMap)[(i)].samplingMode)

/* Macros to get sample period and offset casted to DOUBLE */
/* if sample period is -3.0 and offset is 1.0, then it represents an initialize function,
   if sample period is -3.0 and offset is 2.0, then it represents a terminate function,
   if sample period is -3.0 and offset > 2.0, then it represents a reset function.
*/
#define rtwCAPI_GetSamplePeriod(sampTimeMap, i) (*((real_T *) rtwCAPI_GetSamplePeriodPtr(sampTimeMap, i)))
#define rtwCAPI_GetSampleOffset(sampTimeMap, i) (*((real_T *) rtwCAPI_GetSampleOffsetPtr(sampTimeMap, i)))

/* Macro to get the actual data address */
#define rtwCAPI_GetDataAddress(dataAddrMap,addrIdx) ((dataAddrMap)[(addrIdx)])

/* Macro to get the actual var dims address */
#define rtwCAPI_GetCurrentDimsAddr(vardimsAddrMap,dimMap,addrIdx) ((vardimsAddrMap)[(dimMap)[(addrIdx)].vardimsIndex])

#endif /* _RTW_CAPI_H_ */

/* EOF - rtw_capi.h */
