#ifndef __Output_Test_OrthOsc2_h__
#define __Output_Test_OrthOsc2_h__
/**This file describes data which are used in the Simulink module Test_OrthOsc2.
 * From this header some buses in simulink are generated
 * and some ObjectOriented access blocks are genrated.
 */

/**regards system conventions different between Simulink modell test level 
 * and target system.
 */
#include <applstdefJc.h>  
#include <os_AtomicAccess.h>
#include <Fwc/fw_SimpleC.h>

/**The used Sfunc modules.
 */
//#include <AngleBlocks_FB.h>       
//#include <OrthOsc_FB.h>

/**The macro OS_HandlePtr for handles in Simulink or pointer in target.*/
#include <Fwc/fw_handle_ptr64.h>  



/*@CLASS_C Output_Test_OrthOsc2 @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@q*/

/**This is the structure which contains the output data of the example module.
 * The output data are that data which may be used by another module.
 * For enhancements, you can add more data. 
 * @simulink bus
 */
typedef struct Data_Output_Test_OrthOsc2_t
{
  /**A sequence number.
   *
   * You can check whether it is the same seqNr before first read of data and after last read.
   * If the seq is changed, the data are renewed. The seq steps in bit 4 (0x10) per write cycle.
   * The bits 0..3 contains the double buffer index and two lock bits, able to use for debugging.
   * You can calculate the number of writes between 2 read operations by operating
   * nrofWrites = ((seqLast & ~0xf) - (seq & ~0xf)) >> 4.
   */
  int32 seq;
  
  int32 spare;

  /**The static values of fundamental osciallation, calculated from the oscillation inputs. */
  float_complex pq1[2];
  
  /**Offset value of the oscillation*/
  float m0[2];

  /**Magnitude of the fundamental oscillation*/
  float m1[2];

  /**Magnitude of the fundamental 2. harmonics*/
  float m2[2];
  
  /**Magnitude of the fundamental 2. harmonics*/
  float m3[2];
  
  /**For debugging and further evaluation: 
   * The error value between x and all oscillators. 
   */
  float e[2];
  
} Data_Output_Test_OrthOsc2;

//should be defined for Simulink Accelerator to prevent twice struct definition: 
#define DEFINED_TYPEDEF_FOR_Data_Output_Test_OrthOsc2_


/**This is the structure which contains the output data of the example module.
 * The output data are that data which may be used by another module.
 * The connection between the output of Test_OrthOsc2 and any other module
 * is only a uint32 handle, processed only initially (Tinit step time).
 * Do not change this struct if only other data should be transfered. 
 */
typedef struct Output_Test_OrthOsc2_t
{
  /**Base data, reflection, type validation. */  
  ObjectJc obj;
    
  /**Index of buffer with lock functionality: Bit 1 set: locked. */
  int32 seq_ixBuffer;
  
  int32 spare;
  
  /**Two data buffers for data consistence. */
  Data_Output_Test_OrthOsc2 dBuffer[2];
} Output_Test_OrthOsc2;



extern_C struct ClassJc_t const reflection_Output_Test_OrthOsc2;

/**ObjectFB which contains the outputs.
 * The connection between the output of Test_OrthOsc2 and any other module
 * is only a uint32 handle, processed only initially (Tinit step time).
 * @param idenntObj for debugging
 * @simulink ctor
 */
INLINE_Fwc void ctor_Output_Test_OrthOsc2(Output_Test_OrthOsc2* thiz, int identObj) {
#ifndef __reflectionHidden__ 
  initReflection_ObjectJc(&thiz->obj, thiz, sizeof(*thiz), &reflection_Output_Test_OrthOsc2, identObj);
  setInitialized_ObjectJc(&thiz->obj);  //should be set in ctor if init_fn() does not exists.
#endif
}

/**Sets the values of the ObjectFB which contains the outputs.
 * @simulink Object-FB, accel-tlc
 */
INLINE_Fwc void set_Output_Test_OrthOsc2(Output_Test_OrthOsc2* thiz, float_complex pq1[2]
        , float m0[2], float m1[2], float m2[2], float m3[2], float e[2]
        )
{
  int32 seqix = lockWrite_DoubleBufferingJc(&thiz->seq_ixBuffer);
  int ix = seqix & 1;
  int32 seq = seqix >> kBitSeq_DoubleBufferingJc; 
  Data_Output_Test_OrthOsc2* data = &thiz->dBuffer[ix]; //index 0 or 1 of dBuffer   
  data->seq = seq;
  //This lines should be modified to store other data:
  memcpy(data->pq1, pq1, sizeof(data->pq1));  //use memcopy for array copy
  memcpy(data->m0, m0, sizeof(data->m0));
  memcpy(data->m1, m1, sizeof(data->m1));
  memcpy(data->m2, m2, sizeof(data->m2));
  memcpy(data->m3, m3, sizeof(data->m3));
  memcpy(data->e, e, sizeof(data->e));
  unlockWrite_DoubleBufferingJc(&thiz->seq_ixBuffer, ix);
}



/**This routine can be adapted by the user if more or other data are necessary on simulink level. */
INLINE_Fwc void _get_Output_Test_OrthOsc2(Output_Test_OrthOsc2* thiz, int ix, float_complex pq1_y[2], float m0_y[2], float m1_y[2], float m2_y[2], float m3_y[2])
{
  Data_Output_Test_OrthOsc2* data = &thiz->dBuffer[ix];   //get the correct dBuffer buffer
  //data is the location where the last write was done. 
  memcpy(pq1_y, data->pq1, sizeof(pq1_y));
  memcpy(m0_y, data->m0, sizeof(m0_y));
  memcpy(m1_y, data->m1, sizeof(m1_y));
  memcpy(m2_y, data->m2, sizeof(m2_y));
  memcpy(m3_y, data->m3, sizeof(m3_y));
}




/**Gets the values of the ObjectFB which contains the outputs from Output_Test_OrthOsc2.
 * This operation locks the double buffering during access. It should be used for non-synchronized access (in another thread).
 * @simulink Operation-FB, accel-tlc
 */
INLINE_Fwc void getLocked_Output_Test_OrthOsc2(Output_Test_OrthOsc2* thiz, float_complex pq1_y[2], float m0_y[2], float m1_y[2], float m2_y[2], float m3_y[2])
{
  int ix = lockRead_DoubleBufferingJc(&thiz->seq_ixBuffer);        //set index locked, get the locked index.
  _get_Output_Test_OrthOsc2(thiz, ix, pq1_y, m0_y, m1_y, m2_y, m3_y);
  unlockRead_DoubleBufferingJc(&thiz->seq_ixBuffer); 
}


/**Gets the values of the ObjectFB which contains the outputs from Output_Test_OrthOsc2.
 * This operation locks the double buffering during access. It should be used for non-synchronized access (in another thread).
 * @simulink Operation-FB
 */
INLINE_Fwc void getSyncBus_Output_Test_OrthOsc2(Output_Test_OrthOsc2* thiz, Data_Output_Test_OrthOsc2* y_ybus)
{
  int ix = lockRead_DoubleBufferingJc(&thiz->seq_ixBuffer);  //set index locked, get the locked index.
  memcpy(y_ybus, &thiz->dBuffer[ix], sizeof(*y_ybus));        //copy the content to the output bus. 
  unlockRead_DoubleBufferingJc(&thiz->seq_ixBuffer); 
}


/**Gets the values of the ObjectFB which contains the outputs from Output_Test_OrthOsc2.
 * This operation locks the double buffering during access. It should be used for non-synchronized access (in another thread).
 * @simulink Operation-FB
 */
INLINE_Fwc void getBus_Output_Test_OrthOsc2(Output_Test_OrthOsc2* thiz, Data_Output_Test_OrthOsc2* y_ybus)
{
  int ix = thiz->seq_ixBuffer &1;                          //last write index
  memcpy(y_ybus, &thiz->dBuffer[ix], sizeof(*y_ybus));     //copy the content to the output bus. 
}


/**Gets the values of the ObjectFB which contains the outputs from Output_Test_OrthOsc2.
 * This operation uses the last write buffer. It should be used for synchronized access (divided step times in the same thread or interrupt).
 * @simulink Operation-FB, accel-tlc
 */
INLINE_Fwc void getSync_Output_Test_OrthOsc2(Output_Test_OrthOsc2* thiz, float_complex pq1_y[2], float m0_y[2], float m1_y[2], float m2_y[2], float m3_y[2])
{
  int ix = thiz->seq_ixBuffer & 1;                          //get last write index, bit 0 for value 0 or 1
  _get_Output_Test_OrthOsc2(thiz, ix, pq1_y, m0_y, m1_y, m2_y, m3_y);
}

/**Get one of the pq value.
 * @param ix 0 or 1
 * @param pq_y output. 
 * @simulink Operation-FB, accel-tlc
 */
INLINE_Fwc void get_pq1_Output_Test_OrthOsc2(Output_Test_OrthOsc2* thiz, float_complex* pq_y)
{
  int ix = thiz->seq_ixBuffer & 1;                          //get last write index, bit 0 for value 0 or 1
  Data_Output_Test_OrthOsc2* data = &thiz->dBuffer[ix];   //get the correct dBuffer buffer
  //data is the location where the last write was done. 
  ASSERT_Fwc(ix >=0 && ix < ARRAYLEN_SimpleC(data->pq1));  //
  *pq_y = data->pq1[ix];  //note: memcopy, pq1[] is a struct.
}








#endif //__Output_Test_OrthOsc2_h__
