/*******************************************************************************
*
*  FREESCALE SEMICONDUCTOR INC. 2009-2011
*  ALL RIGHTS RESERVED
*  COPYRIGHT (c)
*  
********************************************************************************
*
*  DESCRIPTION:
*  
*  The function represents the software interface for the resolver.  The
*  software interface can be viewed as a callable discrete routine, which
*  implements the Angle Tracking Observer algorithm.
*
*  For more detailed description of the resolver interface  please refer to the
*  cpu API description (etpu_rslv.c). Here some implementation details are
*  provided.
*
*  FM0 bit is used to enable or disable periodic invocation of the Angle
*  Tracking Observer routine.
*
*  FM1 bit is used to enable or disable issuing link to another channel.
*
*  In order to force the channel to drive its output low incase of simultanous
*  events the fact is used that action on MatchA takes precedence over action
*  on MatchB.  This is the reason why MatchA handles end of the pulse.
*
*  Because eTPU engine does not have a barrel shifter, shifting was implemented
*  as an ordinary multiplication. This applies to K1_SCALE, K2_SCALE and scale
*  parameters.
*
********************************************************************************
*
*  REVISION HISTORY:
*                                                         
*  REVISION    AUTHOR       DATE        DESCRIPTION OF CHANGE                  
*  --------    -----------  ---------   ------------------------------------                  
*       0.1    r29302       11 FEB 09   Initial version
*       0.2    r29302       16 MAR 09   Alfa release, several featured added
*       1.0    r29302       25 APR 09   First official release
*       1.1    r54529       26 JAN 10   Diagnostics added.
*       1.2    r54529       08 DEC 11   resAngleWithOffset added for PMSMVC
*
*******************************************************************************/

#ifndef __ETPUC_H
#include <etpuc.h>          /* Defines eTPU hardware */
#endif

#ifndef __ETPUC_COMMON_H
#include <eTPUc_common.h>   /* Standard way to use eTPU */
#endif

#ifdef RSLV_FUNCTION_NUMBER /* function is being compiled as part of a set? */
#pragma ETPU_function RSLV, standard @ RSLV_FUNCTION_NUMBER;
#else
#pragma ETPU_function RSLV, standard;
#endif


/************************************************************************
*  Includes.
************************************************************************/

#include "etpuc_mc_util.c"
#include "etpuc_mc_sin.c"

/************************************************************************
*  Definitions. 
*************************************************************************/

/* HSR values */
#define RSLV_HSR_INIT               7
#define RSLV_HSR_STOP               6
#define RSLV_HSR_CMPT               5
#define RSLV_HSR_RST                4
#define RSLV_HSR_UPD                3
#define RSLV_HSR_TST                2

#define RSLV_STATE_DATA_MSK         0x00000f
#define RSLV_STATE_DATAIN_POS       1
#define RSLV_STATE_DATAIN           0x000001
#define RSLV_STATE_DATAIN_MSK       0x000001
/* Defined for inline assembler unable to accept binary negation ~ */
#define RSLV_STATE_DATAIN_NOMSK     0xfffffe
#define RSLV_STATE_DATAOUT          0x000002
#define RSLV_STATE_DATAOUT_MSK      0x000002

#define RSLV_STATE_CMPT_MSK         0x000010
#define RSLV_STATE_CMPT             0x000010
#define RSLV_STATE_NOCMPT           0x000000

#define RSLV_STATE_TIMEBASE_MSK     0x000030
#define RSLV_STATE_TIMEBASE_TCR1    0x000000
#define RSLV_STATE_TIMEBASE_TCR2    0x000010

#define RSLV_STATE_START_MSK        0x000200
#define RSLV_STATE_START_REL        0x000000
#define RSLV_STATE_START_ABS        0x000200

#define RSLV_STATE_DIGNOSTICS_MSK   0x000400
#define RSLV_STATE_DIGNOSTICS_OFF   0x000000
#define RSLV_STATE_DIGNOSTICS_ON    0x000400

#define RSLV_STATE_PERIODIC_MSK     0x001000
#define RSLV_STATE_PERIODIC         0x001000
#define RSLV_STATE_NOPERIODIC       0x000000
#define RSLV_STATE_ONREQUEST        0x000000

#define RSLV_STATE_CONTROL_MSK      0x002000
#define RSLV_STATE_CONTROL_SLAVE    0x000000
#define RSLV_STATE_CONTROL_MASTER   0x002000

#define RSLV_STATE_LINK_MSK         0x004000
#define RSLV_STATE_NOLINK           0x000000
#define RSLV_STATE_LINK             0x004000

#define RSLV_STATE_DESYNC_MSK       0x008000
#define RSLV_STATE_NODESYNC         0x000000
#define RSLV_STATE_DESYNC           0x008000

#define RSLV_STATE_DBLEVN_MSK       0x010000
#define RSLV_STATE_NODBLEVN         0x000000
#define RSLV_STATE_DBLEVN           0x010000

/* General macro for operating mode tests (not used, as less efficient
 * than specialized macros
 */
#define RSLV_STATE_ISSET(state, what, msk) \
    (((state) & (msk)) == what)

/* Operating modes tests */
#define RSLV_IS_ONREQUEST           (!IsFunctionMode0())
#define RSLV_IS_NOPERIODIC          (!IsFunctionMode0())
#define RSLV_IS_PERIODIC            IsFunctionMode0()

#define RSLV_IS_LINK                IsFunctionMode1()
#define RSLV_IS_NOLINK              (!IsFunctionMode1())

#define RSLV_IS_TCR2                (state & RSLV_STATE_TIMEBASE_TCR2)
#define RSLV_IS_TCR1                (!RSLV_IS_TCR2)
#define RSLV_IS_TIMEBASE_TCR2       (state & RSLV_STATE_TIMEBASE_TCR2)
#define RSLV_IS_TIMEBASE_TCR1       (!RSLV_IS_TCR2)

#define RSLV_IS_PWM                 (state & RSLV_STATE_PWM)
#define RSLV_IS_NOPWM               (!RSLV_IS_PWM)

#define RSLV_IS_START_ABS           (state & RSLV_STATE_START_ABS)
#define RSLV_IS_START_REL           (!RSLV_IS_START_ABS)

#define RSLV_IS_CONTROL_MASTER      (state & RSLV_STATE_CONTROL_MASTER)
#define RSLV_IS_CONTROL_SLAVE       (!RSLV_IS_CONTROL_MASTER)
#define RSLV_IS_MASTER              (state & RSLV_STATE_CONTROL_MASTER)
#define RSLV_IS_SLAVE               (!RSLV_IS_CONTROL_MASTER)

#define RSLV_IS_DIGNOSTICS_ON       (state & RSLV_STATE_DIGNOSTICS_ON)
#define RSLV_IS_DIGNOSTICS_OFF      (!RSLV_IS_DIGNOSTICS_ON)

/* RSLV Faults */
#define RSLV_DIAG_SINA_ZERO         0x000001
#define RSLV_DIAG_SINA_POS          0x000002
#define RSLV_DIAG_SINA_NEG          0x000004
#define RSLV_DIAG_SINA_AMPL         0x000008
#define RSLV_DIAG_COSA_ZERO         0x000010
#define RSLV_DIAG_COSA_POS          0x000020
#define RSLV_DIAG_COSA_NEG          0x000040
#define RSLV_DIAG_COSA_AMPL         0x000080
#define RSLV_DIAG_SIN_MEAN_NEG      0x000100
#define RSLV_DIAG_SIN_MEAN_POS      0x000200
#define RSLV_DIAG_COS_MEAN_NEG      0x000400
#define RSLV_DIAG_COS_MEAN_POS      0x000800
#define RSLV_DIAG_UNIT_CIRCLE_MIN   0x001000
#define RSLV_DIAG_UNIT_CIRCLE_MAX   0x002000
#define RSLV_DIAG_OBSERVER_ERROR    0x004000

#define RSLV_DIAG_FAULT (RSLV_DIAG_SINA_AMPL \
                         | RSLV_DIAG_COSA_AMPL \
                         | RSLV_DIAG_SIN_MEAN_NEG \
                         | RSLV_DIAG_SIN_MEAN_POS \
                         | RSLV_DIAG_COS_MEAN_NEG \
                         | RSLV_DIAG_COS_MEAN_POS \
                         | RSLV_DIAG_UNIT_CIRCLE_MIN \
                         | RSLV_DIAG_UNIT_CIRCLE_MAX \
                         | RSLV_DIAG_OBSERVER_ERROR)


/************************************************************************
* NAME: RSLV 
*
* DESCRIPTION: Software interface for resolver.  
* 
* FUNCTION PARAMETERS:
*   period    - Period in time base ticks
*
*   duty      - Duty cycle expressed in time base ticks. It is an unsigned
*               integer with the valid range from 0 to period - 1.
*
*   delay     - Delay, as portion of period, against the beginning of cycle
*               at which periodic computation of the Angle Tracking Observer
*               routine is performed. The delay is expressed in time base
*               ticks. It is an unsigned integer with the valid range from 0
*               to period - 1.
*
*   start_offset - The time before the channel starts to generate the
*               left-aligned PWM wave. The start latency is expressed in
*               time base ticks. Note that the full start latency consists
*               of this parameter plus one period. The parameter can be
*               positive or negative.
*
*   gain_sin  - Gain applied to the sin signal from the resolver. 
*               This gain has 2 purposes:
*               1. scale the sin sample into 24-bit signed fractional range
*               2. compensate possible amplitude difference between sin and cos. 
*   
*   gain_cos  - Gain applied to the cos signal from the resolver. 
*               This gain has 2 purposes:
*               1. scale the cos sample into 24-bit signed fractional range
*               2. compensate possible amplitude difference between sin and cos. 
* 
*   dc_offset_sin - Value added to the sin signal from the resolver after 
*               applying the gain. 
*
*   dc_offset_cos - Value added to the cos signal from the resolver after 
*               applying the gain. 
*
*   link_chan - A channel number to send the link to after single iteration
*               of Angle Tracking Observer
*
*   rate_irq  - Rate at which CPU interrupt request will be issued. At 0, the
*               CPU interrupt request will be issued at each invocation of 
*               the Angle Tracking Observer routine. At 1 at every second,
*               at 2 at every third ... and so on.
*
*   rate_link - Rate at which link request will be issued. At 0, the
*               link request will be issued at each invocation of the Angle
*               Tracking Observer routine. At 1 at every second, at 2 at every
*               third ... and so on.
*
*   K1_D      - Multiplication factor of the first Angle Tracking Observer
*               coefficient expressed in the 24-bit signed fractional
*               format (-1.0 = 0xff800000, 1.0 - 2^-23 = 0x007fffff).
*               The K1_D can be expressed as:
*               
*                   K1_SCALE_shift = floor(log2(1/K1)
*                   K1_D = K1*K1_SCALE_shift
*
*               where K1_SCALE_shift is the shifting amount (see below).
*
*   K1_SCALE  - Scaling constant of the first Angle Tracking
*               Observer coefficient. NOTE: due to computation reasons
*               the K1_SCALE needs to be expressed as multiplication
*               factor and not as a shifting amount. The actual value
*               of the K1_SCALE needs to be calculated as:
*
*                   K1_SCALE_shift = floor(log2(1/K1)
*                   K1_SCALE = 1<<(25 - K1_SCALE_shift)
*
*               where K1_SCALE_shift is the shifting amount.
*
*   K2_D      - Multiplication factor of the second Angle Tracking
*               Observer coefficient expressed in the 24-bit signed
*               fractional format (-1.0 = 0xff800000,
*               1.0 - 2^-23 = 0x007fffff).
*
*               The K2_D can be calculated as:
*
*                   K2_SCALE_shift = ceil(log2(K2))
*                   K2_D = K2/2^K2_SCALE_shift
*
*               where K2_SCALE_shift is the shifting amount.
*
*   K2_SCALE  - Scaling constant of the second Angle Tracking
*               Observer coefficient. NOTE: due to computation reasons
*               the K1_SCALE needs to be expressed as multiplication
*               factor and not as a shifting amount. The actual value
*               of the K1_SCALE needs to be calculated as:
*
*                   K2_SCALE_shift = ceil(log2(K2)
*                   K2_SCALE = 1<<K2_SCALE_shift
*
*               where K2_SCALE_shift is the shifting amount.
*
*    sinA_smpl, sinB_smpl - The sine signal from the resolver expressed in 24-bit
*                signed integer format. This signal needs to be sampled and 
*                supplied to the Angle Tracking Observer routine.
*                sinA_smpl should be sampled at the maximum amplitude point, 
*                          together with motor phase currents.  
*                sinB_smpl should be sampled 180deg apart.
*                sinA_smpl is used by the Angle Tracking Observer algorithm.
*                sinB_smpl is used for dignostics and signal plausability checks.
*
*    cosA_smpl, cosB_smpl - The cose signal from the resolver expressed in 24-bit
*                signed integer format. This signal needs to be sampled and 
*                supplied to the Angle Tracking Observer routine.
*                cosA_smpl should be sampled at the maximum amplitude point, 
*                          together with motor phase currents.  
*                cosB_smpl should be sampled 180deg apart.
*                cosA_smpl is used by the Angle Tracking Observer algorithm.
*                cosB_smpl is used for dignostics and signal plausability checks.
*
*    sinA, sinB - The sine signal from the resolver transformed into 24-bit
*                signed fractional format (-1.0 = 0x800000,
*                1.0 - 2^-23 = 0x7fffff) by applying the gain_sin and 
*                dc_offset_sin.
*                               sinA = (sinA_smpl * gain_sin) + dc_offset_sin 
*                               sinB = (sinB_smpl * gain_sin) + dc_offset_sin 
*
*    cosA, cosB - The sine signal from the resolver transformed into 24-bit
*                signed fractional format (-1.0 = 0x800000,
*                1.0 - 2^-23 = 0x7fffff) by applying the gain_cos and 
*                dc_offset_cos.
*                               cosA = (cosA_smpl * gain_cos) + dc_offset_cos 
*                               cosB = (cosB_smpl * gain_cos) + dc_offset_cos 
*
*    resAngle  - Computed resolver angle. Note that the resolver position
*                need to be adjusted by the resOffset. The angle is 
*                expressed in 24-bit signed fraction format (-1.0 = 
*                0xff800000, 1.0 - 2^-23 = 0x007fffff). The angle is
*                scaled by pi, so that -1.0 corresponds to -pi and
*                +1.0 corresponds to pi. Note that the variable shows
*                the resolver angle within -pi to pi range.
*                 
*    integAcc1 - The first internal state variable of the Angle Tracking
*                Observer routine. Equivalent to resolver speed.
*
*    resOffset - Offset for adjustment of the computed resolver angle.
*                It needs to be subtracted from resAngle.
*
*    resRevolutions - Number of revolutions of the resolver. The actual
*                The actual resolver angle can be expressed as:
*
*                angle = resRevolutions*2*pi + resAngle - resOffset.
*
*    error     - Angle Tracking Observer error.
*
*    integAcc2 - the second internal state variable of the Angle Tracking
*                Observer
*
*    state     - Flags for signalling the state of the computation as
*                well as mode of operation (intended to be read
*                rectospectively).
*
*************************************************************************/


void RSLV(  unsigned int24    period, 
            unsigned int24    duty,
            unsigned int24    delay,
            unsigned int24    start_offset,
            unsigned int24    sample_delay,
                     fract24  resOffset,
            unsigned int24    gain_sin,
            unsigned int24    gain_cos,
              signed int24    dc_offset_sin,
              signed int24    dc_offset_cos,
            unsigned int8     link_chan,
            unsigned int24    rate_irq,
            unsigned int24    rate_link,
                     fract24  K1_D,
                     int24    K1_SCALE,
                     fract24  K2_D,
                     int24    K2_SCALE,
                     int24    sinA_smpl,
                     int24    cosA_smpl,
                     int24    sinB_smpl,
                     int24    cosB_smpl,
                     fract24  sinA,
                     fract24  sinB,
                     fract24  cosA,
                     fract24  cosB,
                     fract24  sin_mean,
                     fract24  cos_mean,
                     fract24  unit_circle,
                     fract24  sinA_min,
                     fract24  sinA_max,
                     fract24  cosA_min,
                     fract24  cosA_max,
                     fract24  integAcc1,
            unsigned int24    time_sample,
                     fract24  resAngle,
                     fract24  resAngleWithOffset,
                     int24    resRevolutions,
                     fract24  error,
                     fract24  resAnglePrev,
                     fract24  integAcc2,
                     int24    state,
            unsigned int24    diags_actual,
            unsigned int24    diags_cumulative,
                     fract24  error_max,
                     fract24  ampl_max,
                     fract24  zero_max,
                     fract24  mean_max,
                     fract24  unit_circle_max,
                     fract24  unit_circle_min
                   )
{
    static int24 time_pulseon;
    static int24 time_pulseoff;
    static int24 time_duty;
    static int24 time_compute;
    static int24 time_delay;

    static int24 pulseonflg;
    static unsigned int24 counter_irq;
    static unsigned int24 counter_link;

    int24 temp1;
    int24 temp2;

/*******************************************************************************
* THREAD NAME: TST
* DESCRIPTION: Test
*******************************************************************************/
    if (hsr==RSLV_HSR_TST)
    {
RSLV_test:
    }
/*******************************************************************************
* THREAD NAME: UPD
* DESCRIPTION: Test
*******************************************************************************/
    else if (hsr==RSLV_HSR_UPD)
    {
RSLV_update:
        time_delay = delay;
        time_duty = duty;
        time_pulseoff = time_pulseon + time_duty;
        if(pulseonflg == 0)
        {
            SetupMatchA(time_pulseoff);
        }
    }
/*******************************************************************************
* THREAD NAME: RST
* DESCRIPTION: Reset. Reset the Angle Tracking Observer algorithm to
*              steady-state zero.
*******************************************************************************/
    else if (hsr==RSLV_HSR_RST)
    {
RSLV_reset:
        /* Reset Angle Tracking Observer */
        integAcc1 = 0;
        integAcc2 = 0;
        resAngle = 0;
        resAnglePrev = 0;
        resRevolutions = 0;
        resOffset = 0;

        sinA = 0.0;
        cosA = 0.99999988079071045;
    }
/*******************************************************************************
* THREAD NAME: CMPT
* DESCRIPTION: Compute Angle Tracking Observer routine.
*******************************************************************************/
    else if ((lsr == 1) || (hsr==RSLV_HSR_CMPT))
    {
        /* The label below is used as branch destination for 
         * periodic Angle Tracking Observer computation.
         */
RSLV_compute:
        /* Clear LSR */
        Clear(lsr);

        /*integAcc2 = integAcc2 + integAcc1;*/
        #asm( ram p <- integAcc2. )
        #asm( ram diob <- integAcc1. )
        #asm( alu p = p + diob; ram p -> integAcc2. )

        /*integAcc1 = integAcc1 + error;*/
        #asm( ram p <- error. )
        #asm( alu p = p + diob, ccs. )

        //integAcc1 = saturate(integAcc1);
        #asm( if V == 0 then goto RSLV_saturate_end, flush. )
        #asm( alu a = max. )
        #asm( alu_if N == 1 then a = a - 1. )
        #asm( alu p = a. )
        RSLV_saturate_end:
        #asm( ram p -> integAcc1. )
       
        /*temp1 = integAcc1*K2_D;*/
        #asm( ram diob <- integAcc1. )
        #asm( ram p <- K2_D. )
        #asm( mdu p mults diob. )
        RSLV_wait7:
        #asm( if mb == 1 then goto RSLV_wait7, flush. )

        /*error = temp1 << K2_SCALE;*/
        #asm( alu a =<< mach + 0x0. )
        #asm( ram p <- K2_SCALE. )
        #asm( mdu p mults a. )
        RSLV_wait8:
        #asm( if mb == 1 then goto RSLV_wait8, flush. )
        #asm( alu a = macl + 0x0. )

        /*error = integAcc2 + error;*/
        #asm( ram diob <- integAcc2. )
        #asm( alu p = a + diob. )
        #asm( ram p -> error. )

        /*resAnglePrev = resAngle;*/
        #asm( ram diob <- resAngle. )
        #asm( ram diob -> resAnglePrev. )

        /*time_sample = time_pulseon + sample_delay - period;*/
        #asm( ram diob <- time_pulseon. )
        #asm( alu a = diob; ram diob <- sample_delay. )
        #asm( alu a = a + diob; ram diob <- period. )
        #asm( alu diob = a - diob. )  /* makes next 2 ram writes coherent */
        #asm( ram diob -> time_sample. )

        /*resAngle = error;*/
        #asm( ram p -> resAngle. )

        /*RSLV_SINPIX(resAngle, sinAngle);*/
        /*#asm(ram p <- resAngle.)*/
        #asm(call MC_LUT, no_flush.)
        #asm(alu d = p; ram diob <- p_mc_sin_lt.)
        #asm( alu b = a; ram p <- resAngle. )
        /* Now b = sinAngle */

        /*RSLV_COSPIX(resAngle, cosAngle);*/
        /* The next line is commented out due to optimization, see the
         * line above
         */
        /*#asm(ram p <- resAngle.)*/
        #asm(alu d = p; ram diob <- p_mc_sin_lt.)
        #asm(alu a = 0x400000.)
        #asm(alu d = d + a.)
        #asm(call MC_LUT,flush.)
        #asm( alu c = a. )
        /* Now c = cosAngle */
        
        /* sinA = sinA_smpl*gain_sin + dc_offset_sin; */
        #asm( ram p <- gain_sin. )
        #asm( alu a = p; ram p <- sinA_smpl. )
        #asm( mdu a mults p(16). )
        #asm( ram p <- sinB_smpl. )
        #asm( alu sr = p; ram diob <- dc_offset_sin. )
        #asm( alu p = macl + diob. ) /* sinA */
        #asm( ram p -> sinA. )

        /* sinB = sinB_smpl*gain_sin + dc_offset_sin; */
        #asm( mdu a mults sr(16). )
        /* if(sinA > sinA_max) sinA_max = sinA; */
        #asm( alu a = p; ram p <- sinA_max. )
        #asm( alu nil = a - p, ccs. )
        #asm( if lt then goto RSLW_SINMAX, flush. )
        #asm( alu p = a; ram p -> sinA_max. )
RSLW_SINMAX:
        #asm( alu diob = macl + diob, ccs. )   /* sinB */
        /* sin_mean = (sinA + sinB) >> 1; */
        #asm( alu p = diob + a, ccs; ram diob -> sinB. )
        #asm( alu p =>> p + #0. )
        #asm( if lt == 0 then goto RSLW_SINMEAN, flush. )
        #asm( alu p = p + 0x800000. )
RSLW_SINMEAN:
        #asm( ram p -> sin_mean. )

        /*error = sinA*cosAngle;*/
        #asm( mdu c mults a. )
        /* if(sinA < sinA_min) sinA_min = sinA; */
        #asm( ram p <- sinA_min. )
        #asm( alu nil = a - p, ccs. )
        #asm( if lt == 0 then goto RSLW_SINMIN, flush. )
        #asm( alu p = a; ram p -> sinA_min. )
RSLW_SINMIN:
        #asm( alu c =<< mach + 0x0. )
        /* Now c = sinA*cosAngle */

        /* cosA = cosA_smpl*gain_cos + dc_offset_cos; */
        #asm( ram p <- gain_cos. )
        #asm( alu a = p; ram p <- cosA_smpl. )
        #asm( mdu a mults p(16). )
        #asm( ram p <- cosB_smpl. )
        #asm( alu sr = p; ram diob <- dc_offset_cos. )
        #asm( alu p = macl + diob. ) /* cosA */
        #asm( ram p -> cosA. )

        /* cosB = cosB_smpl*gain_cos + dc_offset_cos; */
        #asm( mdu a mults sr(16). )
        /* if(cosA > cosA_max) cosA_max = cosA; */
        #asm( alu a = p; ram p <- cosA_max. )
        #asm( alu nil = a - p, ccs. )
        #asm( if lt then goto RSLW_COSMAX, flush. )
        #asm( alu p = a; ram p -> cosA_max. )
RSLW_COSMAX:
        #asm( alu diob = macl + diob. )   /* cosB */
        /* cos_mean = (cosA + cosB) >> 1; */
        #asm( alu p = diob + a, ccs; ram diob -> cosB. )
        #asm( alu p =>> p + #0. )
        #asm( if lt == 0 then goto RSLW_COSMEAN, flush. )
        #asm( alu p = p + 0x800000. )
RSLW_COSMEAN:
        #asm( ram p -> cos_mean. )

        /*error = error - cosA*sinAngle;*/
        #asm( mdu b mults a. )
        /* if(cosA < cosA_min) cosA_min = cosA; */
        #asm( ram p <- cosA_min. )
        #asm( alu nil = a - p, ccs. )
        #asm( if lt == 0 then goto RSLW_COSMIN, flush. )
        #asm( alu p = a; ram p -> cosA_min. )
RSLW_COSMIN:
        #asm( alu a =<< mach + 0x0. )
        #asm( alu a = c - a. )
        /* Now c = error = sinA*cosAngle - cosA*sinAngle */

        /*
         * error = error*K1_D;
         * error = error>>K1_SCALE;
         */
        #asm( ram p <- K1_D. )
        #asm( mdu p mults a. )
        /* At this point the input data have been used
         * and the DATAIN flag can be cleared
         */
        #asm( ram p <- state. )
        #asm( alu diob = RSLV_STATE_DATAIN_NOMSK. )
        #asm( alu p = p & diob. )
        #asm( ram p -> state. )
        /* Shift left to decrease the minimum of K1_SCALE */
        #asm( alu a =<< mach; ram p <- K1_SCALE. )
        #asm( mdu p mults a. )
        RSLV_wait4:
        #asm( if mb == 1 then goto RSLV_wait4, flush. )
        /* Shift left to decrease the minimum of K1_SCALE */
        #asm( alu p =<< mach + 0.0. )
        #asm( ram p -> error. )

        /* update revolutions */
        temp1 = resAnglePrev + resOffset;
        temp2 = resAngle + resOffset;
        resAngleWithOffset = temp2;
        temp1 = temp2 - temp1;
        if(CC.V)
        {
            if(CC.N)
            {
                resRevolutions -= 1;
            }
            else
            {
                resRevolutions += 1;
            }
        }

        /******************** Diagnostics *********************/
        if(RSLV_IS_DIGNOSTICS_ON)
        {
        /* unit_circle = sinA*sinA + cosA*cosA; */
        #asm( ram p <- sinA. )
        #asm( mdu p mults p. )
        RSLV_CIRC1:
        #asm( if mb == 1 then goto RSLV_CIRC1, flush. )
        #asm( alu diob = 0; ram p <- cosA. )
        #asm( mdu p macs p. )
        RSLV_CIRC2:
        #asm( if mb == 1 then goto RSLV_CIRC2, flush. )
        #asm( alu p = mach; ram p -> unit_circle. )
        
        /* State checks */
        /* if(unit_circle_max < unit_circle) diags_actual |= RSLV_DIAG_UNIT_CIRCLE_MAX; */
        #asm( alu a = p; ram p <- unit_circle_max. )
        #asm( alu nil = p - a, ccs. )
        #asm( if lt == 0 then goto RSLV_CHECK_UNIT_CIRCLE_MAX, flush. )
        #asm( alu sr = RSLV_DIAG_UNIT_CIRCLE_MAX. )
        #asm( alu diob = diob | sr. )
RSLV_CHECK_UNIT_CIRCLE_MAX:
        /* if(unit_circle < unit_circle_min) diags_actual |= RSLV_DIAG_UNIT_CIRCLE_MIN; */
        #asm( ram p <- unit_circle_min. )
        #asm( alu nil = a - p, ccs; ram p <- zero_max. )
        #asm( if lt == 0 then goto RSLV_CHECK_UNIT_CIRCLE_MIN, flush. )
        #asm( alu sr = RSLV_DIAG_UNIT_CIRCLE_MIN. )
        #asm( alu diob = diob | sr. )
RSLV_CHECK_UNIT_CIRCLE_MIN:
        
        /* Range checks */
        /* if(Abs(sinA) < zero_max) diags_actual |= RSLV_DIAG_SINA_ZERO; */
        #asm( alu a = p; ram p <- sinA. )    // a = zero_max,  p = sinA
        #asm( alu d = abs(p). )              // d = abs(sinA)
        #asm( alu nil = d - a, ccs. )
        #asm( if lt == 0 then goto RSLW_CHECK_SINA_ZERO, flush. )
        #asm( alu sr = RSLV_DIAG_SINA_ZERO. )
        #asm( goto RSLW_CHECK_SINA_AMPL, no_flush. )
        #asm( alu diob = diob | sr. )
RSLW_CHECK_SINA_ZERO:
        /* if(sinA < 0) diags_actual |= RSLV_DIAG_SINA_NEG
           else         diags_actual |= RSLV_DIAG_SINA_POS */
        #asm( alu nil = p, ccs; ram p <- ampl_max. )
        #asm( if n == 1 then goto RSLW_CHECK_SINA_NEG, no_flush. )
        #asm( alu sr = RSLV_DIAG_SINA_NEG. )
        #asm( alu sr = RSLV_DIAG_SINA_POS. )
RSLW_CHECK_SINA_NEG:
        #asm( alu diob = diob | sr. )
        /* if(ampl_max < Abs(sinA)) diags_actual |= RSLV_DIAG_SINA_AMPL; */
        #asm( alu nil = d - p, ccs. )
        #asm( if lt == 1 then goto RSLW_CHECK_SINA_AMPL, flush. )
        #asm( alu sr = RSLV_DIAG_SINA_AMPL. )
        #asm( alu diob = diob | sr. )
RSLW_CHECK_SINA_AMPL:

        /* if(Abs(cosA) < zero_max) diags_actual |= RSLV_DIAG_COSA_ZERO; */
        #asm( ram p <- zero_max. )
        #asm( alu a = p; ram p <- cosA. )    // a = zero_max,  p = cosA
        #asm( alu d = abs(p). )              // d = abs(cosA)
        #asm( alu nil = d - a, ccs. )
        #asm( if lt == 0 then goto RSLW_CHECK_COSA_ZERO, flush. )
        #asm( alu sr = RSLV_DIAG_COSA_ZERO. )
        #asm( goto RSLW_CHECK_COSA_AMPL, no_flush. )
        #asm( alu diob = diob | sr. )
RSLW_CHECK_COSA_ZERO:
        /* if(cosA < 0) diags_actual |= RSLV_DIAG_COSA_NEG
           else         diags_actual |= RSLV_DIAG_COSA_POS */
        #asm( alu nil = p, ccs; ram p <- ampl_max. )
        #asm( if n == 1 then goto RSLW_CHECK_COSA_NEG, no_flush. )
        #asm( alu sr = RSLV_DIAG_COSA_NEG. )
        #asm( alu sr = RSLV_DIAG_COSA_POS. )
RSLW_CHECK_COSA_NEG:
        #asm( alu diob = diob | sr. )
        /* if(ampl_max < Abs(cosA)) diags_actual |= RSLV_DIAG_COSA_AMPL; */
        #asm( alu nil = d - p, ccs. )
        #asm( if n == 1 then goto RSLW_CHECK_COSA_AMPL, flush. )
        #asm( alu sr = RSLV_DIAG_COSA_AMPL. )
        #asm( alu diob = diob | sr. )
RSLW_CHECK_COSA_AMPL:

        /* Plausability checks */
        /* if(mean_max < Abs(sin_mean)) 
             if (sin_mean < 0) diags_actual |= RSLV_DIAG_SIN_MEAN_NEG
             else              diags_actual |= RSLV_DIAG_SIN_MEAN_POS */
        #asm( ram p <- mean_max. )
        #asm( alu d = p; ram p <- sin_mean. )
        #asm( alu a = abs(p). )
        #asm( alu nil = d - a, ccs. )
        #asm( if lt == 0 then goto RSLW_CHECK_SIN_MEAN, flush. )
        #asm( alu nil = p, ccs. )
        #asm( if n == 1 then goto RSLW_CHECK_SIN_MEAN_NEG, no_flush. )
        #asm( alu sr = RSLV_DIAG_SIN_MEAN_NEG. )
        #asm( alu sr = RSLV_DIAG_SIN_MEAN_POS. )
RSLW_CHECK_SIN_MEAN_NEG:
        #asm( alu diob = diob | sr. )
RSLW_CHECK_SIN_MEAN:

        /* if(mean_max < Abs(cos_mean)) 
             if (sin_mean < 0) diags_actual |= RSLV_DIAG_COS_MEAN_NEG
             else              diags_actual |= RSLV_DIAG_COS_MEAN_POS */
        #asm( ram p <- cos_mean. )
        #asm( alu a = abs(p). )
        #asm( alu nil = d - a, ccs. )
        #asm( if lt == 0 then goto RSLW_CHECK_COS_MEAN, flush. )
        #asm( alu nil = p, ccs. )
        #asm( if n == 1 then goto RSLW_CHECK_COS_MEAN_NEG, no_flush. )
        #asm( alu sr = RSLV_DIAG_COS_MEAN_NEG. )
        #asm( alu sr = RSLV_DIAG_COS_MEAN_POS. )
RSLW_CHECK_COS_MEAN_NEG:
        #asm( alu diob = diob | sr. )
RSLW_CHECK_COS_MEAN:

        /* Dynamics checks */
        /* if(error_max < Abs(error)) diags_actual |= RSLV_DIAG_OBSERVER_ERROR; */
        #asm( ram p <- error_max. )
        #asm( alu d = p; ram p <- error. )
        #asm( alu a = abs(p). )
        #asm( alu nil = d - a, ccs. )
        #asm( if lt == 0 then goto RSLW_CHECK_OBSERVER_ERROR, flush. )
        #asm( alu sr = RSLV_DIAG_OBSERVER_ERROR. )
        #asm( alu diob = diob | sr. )
RSLW_CHECK_OBSERVER_ERROR:

        #asm( ram p <- diags_cumulative. )
        #asm( alu sr = #RSLV_DIAG_FAULT. )
        #asm( alu nil = p & sr, ccs. )
        #asm( if z == 0 then goto RSLV_DIAG_NEW_FAULT1, no_flush. )
        #asm( ram diob -> diags_actual. )
        #asm( goto RSLV_DIAG_NEW_FAULT2, no_flush. )
        #asm( alu p = diob & sr. )
RSLV_DIAG_NEW_FAULT1:
        #asm( alu p = diob | p. )
RSLV_DIAG_NEW_FAULT2:
        #asm( ram p -> diags_cumulative. )
        }

        /******************************************************/

        /* At this point the output data have been computed
         * and the DATAOUT flag can be set
         */
        #asm( ram p <- state. )
        #asm( alu diob = RSLV_STATE_DATAOUT. )
        #asm( alu p = p | diob. )
        #asm( ram p -> state. )

        /* Trigger an interrupt */
        if( counter_irq == 0)
        {
            SetChannelInterrupt();
            counter_irq = rate_irq;
        }
        else
        {
            counter_irq--;
        }

        /* Issue DMA request */
        SetChannelDMARequest();

        /* Link to channel */
        if( RSLV_IS_LINK )
        {
            if( counter_link == 0 )
            {
                LinkTo(link_chan);
                counter_link = rate_link;
            }
            else
            {
                counter_link--;
            }
        }
RSLV_compute_end:
    }
/*******************************************************************************
* THREAD NAME: STOP
* DESCRIPTION: Stop generation of left-aligned PWM wave.
*******************************************************************************/
    else if (hsr==RSLV_HSR_STOP)
    {
RSLV_stop:
        DisableMatchDetection();
        DisableEventHandling();
        ClearAllLatches();
        SetPinLow();
        Clear(flag0);
    }
  
/*******************************************************************************
* THREAD NAME: INIT
* DESCRIPTION: Initialize the channel: reset the Angle Tracking observer
*              and start wave generation.
*******************************************************************************/
    else if (hsr==RSLV_HSR_INIT)
    {
RSLV_init:
        /* Catch the current clock value as soon as possible */
        time_pulseon = tcr1;

        /* Force channel to a defined state */
        DisableMatchesInThread();
        DisableMatchDetection();
        DisableEventHandling();
        ClearAllLatches();
        SetPinLow();
        Clear(flag0);

        /* Reset Angle Tracking Observer */
        integAcc1 = 0;
        integAcc2 = 0;
        resAngle = 0;
        resAnglePrev = 0;
        resRevolutions = 0;
        resOffset = 0;

        sinA = 0.0;
        cosA = 0.99999988079071045;

        /* Rate counter */
        counter_irq = rate_irq;
        counter_link = rate_link;

        /* If periodic then start wave generation */
        if( RSLV_IS_MASTER )
        {
            /* Initilize wave generation */
            SetPinLow();
            OnTransA(NoDetect);
            OnTransB(NoDetect);
            OnMatchA(PinLow);
            OnMatchB(PinHigh);

            if( RSLV_IS_TCR2 )
            {
                ActionUnitA(MatchTCR2, CaptureTCR2, GreaterEqual);
                ActionUnitB(MatchTCR2, CaptureTCR2, GreaterEqual);
            }
            else
            {
                ActionUnitA(MatchTCR1, CaptureTCR1, GreaterEqual);
                ActionUnitB(MatchTCR1, CaptureTCR1, GreaterEqual);
            }

            EitherMatchNonBlockingSingleTransition();
            
            pulseonflg = 0;
            /*
            time_duty = period*duty;
            time_delay = period*delay;
            */
            time_duty = duty;
            time_delay = delay;

            if( RSLV_IS_START_ABS )
            {
                time_pulseon = start_offset;
            }
            else /* RSLV_IS_START_REL */
            {
                time_pulseon += start_offset + period;
            }
            time_compute = time_pulseon + time_delay;
            time_pulseoff = time_pulseon + time_duty;

            SetupMatchB(time_pulseon);
            SetupMatchA(time_pulseoff);

            Clear(flag0);

            ClearAllLatches();

            EnableEventHandling();
        }
    }
/*******************************************************************************
* THREAD NAME: S1
* DESCRIPTION: Start of the PWM cycle and beginning of the pulse within the
*              cycle. Also calculation of time for computation of Angle
*              Tracking Observer.
*******************************************************************************/
    else if( ((lsr == 0) && (m1 == 0) && (m2 == 1) && (flag0 == 0)) )
    {
RSLV_pulse_start:
        /* It is possible, that m1 match was set before it actually
         * passed through timer counter value. In this case the thread
         * is scheduled however pin is not driven, because there is no
         * match trigger. In this case it is necessary to force pin
         * to be set according to opac2/b. Otherwise the instruction
         * does not have any affect.
         */
        SetPinPerPacB();

        /* Compute is performed within the same cycle */
        time_compute = time_pulseon + time_delay;
        time_pulseon += period;
        time_pulseoff = time_pulseon + time_duty;

        SetupMatchB(time_compute);
        OnMatchB(NoChange);
        Set(flag0);
        pulseonflg = 1;
    }
/*******************************************************************************
* THREAD NAME: S2
* DESCRIPTION: End of pulse for PWM signal.
*******************************************************************************/
    else if( (lsr == 0) && (m1 == 1) && (m2 == 0) )
    {
RSLV_pulse_end:
        SetupMatchA(time_pulseoff);
        pulseonflg = 0;
    }
/*******************************************************************************
* THREAD NAME: S3
* DESCRIPTION: Periodic compute of Angle Tracking Observer.
*******************************************************************************/
    else if( (lsr == 0) && (m1 == 0) && (m2 == 1) && (flag0 == 1) )
    {
RSLV_periodic_cmpt:
        SetupMatchB(time_pulseon);
        OnMatchB(PinHigh);
        Clear(flag0);

        if( RSLV_IS_PERIODIC )
        {
            goto RSLV_compute;
        }
    }
/*******************************************************************************
* THREAD NAME: S4
* DESCRIPTION: Something gone wrong.
*     Detection of both matches means that due to huge latency, the
*     conditions for S1, S2 or S3 have not been detected. In this case
*     treat the period as dead and compute times and setup match for
*     the next period hoping that it will be ok.
*
*     Note that in case of both matches on A and B the output
*     pin behaviour of A prevails, and as A is configured to go
*     on match low, the pin will go low.
*******************************************************************************/
    else if( (lsr == 0) && (m2 == 1) && (m1 == 1) && (flag0 == 0))
    {
RSLV_bothmatch0:
        state = state | RSLV_STATE_DBLEVN;
        /* m1 == 0, m2 == 1 */
        if(pulseonflg == 0)
        {
            time_compute = time_pulseon + time_delay;
            time_pulseon += period;
            time_pulseoff = time_pulseon + time_duty;

            OnMatchB(NoChange);
            SetupMatchB(time_compute);
            Set(flag0);
            pulseonflg = 1;
        }
        else
        {
            SetupMatchA(time_pulseoff);
            pulseonflg = 0;
        }
    }
/*******************************************************************************
* THREAD NAME: S4
* DESCRIPTION: Something gone wrong.
*     Detection of both matches means that due to huge latency, the
*     conditions for S1, S2 or S3 have not been detected. In this case
*     treat the period as dead and compute times and setup match for
*     the next period hoping that it will be ok.
*
*     Note that in case of both matches on A and B the output
*     pin behaviour of A prevails, and as A is configured to go
*     on match low, the pin will go low.
*******************************************************************************/
    else if( (lsr == 0) && (m2 == 1) && (m1 == 1) && (flag0 == 1))
    {
RSLV_bothmatch1:
        /* Note:
         *   Order of SetupMatchB() and OnMatchB() is significant.
         *   If changed, then the pin will go high, due to immediate
         *   match on B, which is not a desirable action.
         */

        state = state | RSLV_STATE_DBLEVN;
        /* m1 == 0, m2 == 1 */
        if(pulseonflg == 0)
        {
            /* Compute is performed within the same cycle */
            time_compute = time_pulseon + time_delay;
            time_pulseon += period;
            time_pulseoff = time_pulseon + time_duty;

            pulseonflg = 1;

            //SetPinPerPacB();
            SetupMatchB(time_pulseon);
            OnMatchB(NoChange);
            Clear(flag0);
        }
        else /* pulseonflg != 0 */
        {
            SetupMatchA(time_pulseoff);
            pulseonflg = 0;

            SetupMatchB(time_pulseon);
            OnMatchB(PinHigh);
            Clear(flag0);
        }

        /* m1 == 1, m2 == 0 */

        if( tcr1 < time_pulseon)
        {
            // In synch
            if( RSLV_IS_PERIODIC )
            {
                goto RSLV_compute;
            }
        }
        else
        {
            // Not in synch
            state = state | RSLV_STATE_DESYNC;
        }

    }
/*******************************************************************************
* THREAD NAME: UNHANDLED_EVENTS
*******************************************************************************/
    else
    {
RSLV_global_error:
#ifdef GLOBAL_ERROR_RSLV
		Global_Error_Func();
#else
		ClearAllLatches();
#endif
    }
} /* End of RSLV() */

/************************************************************************
*  Information exported to Host CPU program.
************************************************************************/
#pragma write h, (::ETPUfilename (cpu/etpu_rslv_auto.h));
#pragma write h, (/**************************************************************** );
#pragma write h, (* WARNING this file is automatically generated DO NOT EDIT IT!    );
#pragma write h, (*                                                                 );
#pragma write h, (* This file provides an interface between eTPU code and CPU       );
#pragma write h, (* code. All references to the RSLV function should be made with     );
#pragma write h, (* information in this file. This allows only symbolic             );
#pragma write h, (* information to be referenced which allows the eTPU code to be   );
#pragma write h, (* optimized without effecting the CPU code.                       );
#pragma write h, (*****************************************************************/);
#pragma write h, (#ifndef _ETPU_RSLV_AUTO_H_);
#pragma write h, (#define _ETPU_RSLV_AUTO_H_);
#pragma write h, ( );
#pragma write h, (/****************************************************************);
#pragma write h, (* Function Configuration Information. );
#pragma write h, (****************************************************************/);
#pragma write h, (::ETPUliteral(#define FS_ETPU_RSLV_FUNCTION_NUMBER       ) RSLV_FUNCTION_NUMBER );
#pragma write h, (::ETPUliteral(#define FS_ETPU_RSLV_TABLE_SELECT          ) ::ETPUentrytype(RSLV) );
#pragma write h, (::ETPUliteral(#define FS_ETPU_RSLV_NUM_PARMS             ) ::ETPUram(RSLV) );
#pragma write h, ( );
#pragma write h, (/****************************************************************);
#pragma write h, (* Host Service Request Definitions. );
#pragma write h, (****************************************************************/);
#pragma write h, (::ETPUliteral(#define FS_ETPU_RSLV_INIT                  ) RSLV_HSR_INIT);
#pragma write h, (::ETPUliteral(#define FS_ETPU_RSLV_STOP                  ) RSLV_HSR_STOP);
#pragma write h, (::ETPUliteral(#define FS_ETPU_RSLV_CMPT                  ) RSLV_HSR_CMPT);
#pragma write h, (::ETPUliteral(#define FS_ETPU_RSLV_RST                   ) RSLV_HSR_RST);
#pragma write h, (::ETPUliteral(#define FS_ETPU_RSLV_UPD                   ) RSLV_HSR_UPD);
#pragma write h, (::ETPUliteral(#define FS_ETPU_RSLV_TST                   ) RSLV_HSR_TST);
#pragma write h, ( );
#pragma write h, (/****************************************************************);
#pragma write h, (* Parameter Definitions. );
#pragma write h, (****************************************************************/);
#pragma write h, (::ETPUliteral(#define FS_ETPU_RSLV_PERIOD_OFFSET         )::ETPUlocation(RSLV, period) );
#pragma write h, (::ETPUliteral(#define FS_ETPU_RSLV_DUTY_OFFSET           )::ETPUlocation(RSLV, duty) );      
#pragma write h, (::ETPUliteral(#define FS_ETPU_RSLV_DELAY_OFFSET          )::ETPUlocation(RSLV, delay) );      
#pragma write h, (::ETPUliteral(#define FS_ETPU_RSLV_START_OFFSET_OFFSET   )::ETPUlocation(RSLV, start_offset) );      
#pragma write h, (::ETPUliteral(#define FS_ETPU_RSLV_SAMPLE_DELAY_OFFSET   )::ETPUlocation(RSLV, sample_delay) );      
#pragma write h, (::ETPUliteral(#define FS_ETPU_RSLV_TIME_SAMPLE_OFFSET    )::ETPUlocation(RSLV, time_sample) );      
#pragma write h, (::ETPUliteral(#define FS_ETPU_RSLV_GAIN_SIN_OFFSET       )::ETPUlocation(RSLV, gain_sin) );      
#pragma write h, (::ETPUliteral(#define FS_ETPU_RSLV_GAIN_COS_OFFSET       )::ETPUlocation(RSLV, gain_cos) );      
#pragma write h, (::ETPUliteral(#define FS_ETPU_RSLV_DC_OFFSET_SIN_OFFSET  )::ETPUlocation(RSLV, dc_offset_sin) );      
#pragma write h, (::ETPUliteral(#define FS_ETPU_RSLV_DC_OFFSET_COS_OFFSET  )::ETPUlocation(RSLV, dc_offset_cos) );      
#pragma write h, (::ETPUliteral(#define FS_ETPU_RSLV_LINK_CHAN_OFFSET      )::ETPUlocation(RSLV, link_chan) );      
#pragma write h, (::ETPUliteral(#define FS_ETPU_RSLV_RATE_IRQ_OFFSET       )::ETPUlocation(RSLV, rate_irq) );      
#pragma write h, (::ETPUliteral(#define FS_ETPU_RSLV_RATE_LINK_OFFSET      )::ETPUlocation(RSLV, rate_link) );
#pragma write h, (::ETPUliteral(#define FS_ETPU_RSLV_MC_SIN_LUT            )::ETPUlocation (mc_sin_lut) );      
#pragma write h, (::ETPUliteral(#define FS_ETPU_RSLV_P_MC_SIN_LT_OFFSET    )::ETPUlocation (p_mc_sin_lt) );      
#pragma write h, (::ETPUliteral(#define FS_ETPU_RSLV_SINA_SMPL_OFFSET      )::ETPUlocation (RSLV, sinA_smpl) );      
#pragma write h, (::ETPUliteral(#define FS_ETPU_RSLV_SINB_SMPL_OFFSET      )::ETPUlocation (RSLV, sinB_smpl) );      
#pragma write h, (::ETPUliteral(#define FS_ETPU_RSLV_COSA_SMPL_OFFSET      )::ETPUlocation (RSLV, cosA_smpl) );      
#pragma write h, (::ETPUliteral(#define FS_ETPU_RSLV_COSB_SMPL_OFFSET      )::ETPUlocation (RSLV, cosB_smpl) );      
#pragma write h, (::ETPUliteral(#define FS_ETPU_RSLV_SINA_OFFSET           )::ETPUlocation (RSLV, sinA) );      
#pragma write h, (::ETPUliteral(#define FS_ETPU_RSLV_SINB_OFFSET           )::ETPUlocation (RSLV, sinB) );      
#pragma write h, (::ETPUliteral(#define FS_ETPU_RSLV_COSA_OFFSET           )::ETPUlocation (RSLV, cosA) );      
#pragma write h, (::ETPUliteral(#define FS_ETPU_RSLV_COSB_OFFSET           )::ETPUlocation (RSLV, cosB) );      
#pragma write h, (::ETPUliteral(#define FS_ETPU_RSLV_SIN_MEAN_OFFSET       )::ETPUlocation (RSLV, sin_mean) );      
#pragma write h, (::ETPUliteral(#define FS_ETPU_RSLV_COS_MEAN_OFFSET       )::ETPUlocation (RSLV, cos_mean) );      
#pragma write h, (::ETPUliteral(#define FS_ETPU_RSLV_UNIT_CIRCLE_OFFSET    )::ETPUlocation (RSLV, unit_circle) );      
#pragma write h, (::ETPUliteral(#define FS_ETPU_RSLV_SINA_MIN_OFFSET       )::ETPUlocation (RSLV, sinA_min) );      
#pragma write h, (::ETPUliteral(#define FS_ETPU_RSLV_SINA_MAX_OFFSET       )::ETPUlocation (RSLV, sinA_max) );      
#pragma write h, (::ETPUliteral(#define FS_ETPU_RSLV_COSA_MIN_OFFSET       )::ETPUlocation (RSLV, cosA_min) );      
#pragma write h, (::ETPUliteral(#define FS_ETPU_RSLV_COSA_MAX_OFFSET       )::ETPUlocation (RSLV, cosA_max) );      
#pragma write h, (::ETPUliteral(#define FS_ETPU_RSLV_K1_D_OFFSET           )::ETPUlocation (RSLV, K1_D) );      
#pragma write h, (::ETPUliteral(#define FS_ETPU_RSLV_K1_SCALE_OFFSET       )::ETPUlocation (RSLV, K1_SCALE) );      
#pragma write h, (::ETPUliteral(#define FS_ETPU_RSLV_K2_D_OFFSET           )::ETPUlocation (RSLV, K2_D) );      
#pragma write h, (::ETPUliteral(#define FS_ETPU_RSLV_K2_SCALE_OFFSET       )::ETPUlocation (RSLV, K2_SCALE) );      
#pragma write h, (::ETPUliteral(#define FS_ETPU_RSLV_RESANGLE_OFFSET       )::ETPUlocation (RSLV, resAngle) );
#pragma write h, (::ETPUliteral(#define FS_ETPU_RSLV_RESANGLEWITHOFFSET_OFFSET )::ETPUlocation (RSLV, resAngleWithOffset) );
#pragma write h, (::ETPUliteral(#define FS_ETPU_RSLV_INTEGACC1_OFFSET      )::ETPUlocation (RSLV, integAcc1) );      
#pragma write h, (::ETPUliteral(#define FS_ETPU_RSLV_ERROR_OFFSET          )::ETPUlocation (RSLV, error) );      
#pragma write h, (::ETPUliteral(#define FS_ETPU_RSLV_RESOFFSET_OFFSET      )::ETPUlocation (RSLV, resOffset) );      
#pragma write h, (::ETPUliteral(#define FS_ETPU_RSLV_RESREVOLUTIONS_OFFSET )::ETPUlocation (RSLV, resRevolutions) );      
#pragma write h, (::ETPUliteral(#define FS_ETPU_RSLV_RESANGLEPREV_OFFSET   )::ETPUlocation (RSLV, resAnglePrev) );      
#pragma write h, (::ETPUliteral(#define FS_ETPU_RSLV_INTEGACC2_OFFSET      )::ETPUlocation (RSLV, integAcc2) );      
#pragma write h, (::ETPUliteral(#define FS_ETPU_RSLV_STATE_OFFSET          )::ETPUlocation (RSLV, state) );      
#pragma write h, (::ETPUliteral(#define FS_ETPU_RSLV_DIAGS_ACTUAL_OFFSET  )::ETPUlocation (RSLV, diags_actual) );      
#pragma write h, (::ETPUliteral(#define FS_ETPU_RSLV_DIAGS_CUMULATIVE_OFFSET )::ETPUlocation (RSLV, diags_cumulative) );      
#pragma write h, (::ETPUliteral(#define FS_ETPU_RSLV_ERROR_MAX_OFFSET      )::ETPUlocation (RSLV, error_max) );      
#pragma write h, (::ETPUliteral(#define FS_ETPU_RSLV_AMPL_MAX_OFFSET       )::ETPUlocation (RSLV, ampl_max) );      
#pragma write h, (::ETPUliteral(#define FS_ETPU_RSLV_ZERO_MAX_OFFSET       )::ETPUlocation (RSLV, zero_max) );      
#pragma write h, (::ETPUliteral(#define FS_ETPU_RSLV_MEAN_MAX_OFFSET       )::ETPUlocation (RSLV, mean_max) );      
#pragma write h, (::ETPUliteral(#define FS_ETPU_RSLV_UNIT_CIRCLE_MAX_OFFSET )::ETPUlocation (RSLV, unit_circle_max) );      
#pragma write h, (::ETPUliteral(#define FS_ETPU_RSLV_UNIT_CIRCLE_MIN_OFFSET )::ETPUlocation (RSLV, unit_circle_min) );      
#pragma write h, ( );
#pragma write h, (/****************************************************************);
#pragma write h, (* Value Definitions. );
#pragma write h, (****************************************************************/);
#pragma write h, (::ETPUliteral(#define FS_ETPU_RSLV_STATE_DATAIN          ) RSLV_STATE_DATAIN );
#pragma write h, (::ETPUliteral(#define FS_ETPU_RSLV_STATE_DATAOUT         ) RSLV_STATE_DATAOUT );

#pragma write h, (::ETPUliteral(#define FS_ETPU_RSLV_STATE_TIMEBASE_MSK    ) RSLV_STATE_TIMEBASE_MSK );
#pragma write h, (::ETPUliteral(#define FS_ETPU_RSLV_STATE_TIMEBASE_TCR1   ) RSLV_STATE_TIMEBASE_TCR1 );
#pragma write h, (::ETPUliteral(#define FS_ETPU_RSLV_STATE_TIMEBASE_TCR2   ) RSLV_STATE_TIMEBASE_TCR2 );

#pragma write h, (::ETPUliteral(#define FS_ETPU_RSLV_STATE_CONTROL_MSK     ) RSLV_STATE_CONTROL_MSK );
#pragma write h, (::ETPUliteral(#define FS_ETPU_RSLV_STATE_CONTROL_MASTER  ) RSLV_STATE_CONTROL_MASTER );
#pragma write h, (::ETPUliteral(#define FS_ETPU_RSLV_STATE_CONTROL_SLAVE   ) RSLV_STATE_CONTROL_SLAVE );

#pragma write h, (::ETPUliteral(#define FS_ETPU_RSLV_STATE_START_MSK       ) RSLV_STATE_START_MSK );
#pragma write h, (::ETPUliteral(#define FS_ETPU_RSLV_STATE_START_REL       ) RSLV_STATE_START_REL );
#pragma write h, (::ETPUliteral(#define FS_ETPU_RSLV_STATE_START_ABS       ) RSLV_STATE_START_ABS );

#pragma write h, (::ETPUliteral(#define FS_ETPU_RSLV_STATE_PERIODIC_MSK    ) RSLV_STATE_PERIODIC_MSK );
#pragma write h, (::ETPUliteral(#define FS_ETPU_RSLV_STATE_PERIODIC        ) RSLV_STATE_PERIODIC );
#pragma write h, (::ETPUliteral(#define FS_ETPU_RSLV_STATE_NOPERIODIC      ) RSLV_STATE_NOPERIODIC );
#pragma write h, (::ETPUliteral(#define FS_ETPU_RSLV_STATE_ONREQUEST       ) RSLV_STATE_ONREQUEST );

#pragma write h, (::ETPUliteral(#define FS_ETPU_RSLV_STATE_LINK_MSK        ) RSLV_STATE_LINK_MSK );
#pragma write h, (::ETPUliteral(#define FS_ETPU_RSLV_STATE_LINK            ) RSLV_STATE_LINK );
#pragma write h, (::ETPUliteral(#define FS_ETPU_RSLV_STATE_NOLINK          ) RSLV_STATE_NOLINK );

#pragma write h, (::ETPUliteral(#define FS_ETPU_RSLV_STATE_DIGNOSTICS_MSK  ) RSLV_STATE_DIGNOSTICS_MSK );
#pragma write h, (::ETPUliteral(#define FS_ETPU_RSLV_STATE_DIGNOSTICS_ON   ) RSLV_STATE_DIGNOSTICS_ON );
#pragma write h, (::ETPUliteral(#define FS_ETPU_RSLV_STATE_DIGNOSTICS_OFF  ) RSLV_STATE_DIGNOSTICS_OFF );
#pragma write h, ( );

#pragma write h, (::ETPUliteral(#define FS_ETPU_RSLV_DIAG_SINA_ZERO        ) RSLV_DIAG_SINA_ZERO      );
#pragma write h, (::ETPUliteral(#define FS_ETPU_RSLV_DIAG_SINA_POS         ) RSLV_DIAG_SINA_POS       );
#pragma write h, (::ETPUliteral(#define FS_ETPU_RSLV_DIAG_SINA_NEG         ) RSLV_DIAG_SINA_NEG       );
#pragma write h, (::ETPUliteral(#define FS_ETPU_RSLV_DIAG_SINA_AMPL        ) RSLV_DIAG_SINA_AMPL      );
#pragma write h, (::ETPUliteral(#define FS_ETPU_RSLV_DIAG_COSA_ZERO        ) RSLV_DIAG_COSA_ZERO      );
#pragma write h, (::ETPUliteral(#define FS_ETPU_RSLV_DIAG_COSA_POS         ) RSLV_DIAG_COSA_POS       );
#pragma write h, (::ETPUliteral(#define FS_ETPU_RSLV_DIAG_COSA_NEG         ) RSLV_DIAG_COSA_NEG       );
#pragma write h, (::ETPUliteral(#define FS_ETPU_RSLV_DIAG_COSA_AMPL        ) RSLV_DIAG_COSA_AMPL      );
#pragma write h, (::ETPUliteral(#define FS_ETPU_RSLV_DIAG_SIN_MEAN_NEG     ) RSLV_DIAG_SIN_MEAN_NEG   );
#pragma write h, (::ETPUliteral(#define FS_ETPU_RSLV_DIAG_SIN_MEAN_POS     ) RSLV_DIAG_SIN_MEAN_POS   );
#pragma write h, (::ETPUliteral(#define FS_ETPU_RSLV_DIAG_COS_MEAN_NEG     ) RSLV_DIAG_COS_MEAN_NEG   );
#pragma write h, (::ETPUliteral(#define FS_ETPU_RSLV_DIAG_COS_MEAN_POS     ) RSLV_DIAG_COS_MEAN_POS   );
#pragma write h, (::ETPUliteral(#define FS_ETPU_RSLV_DIAG_UNIT_CIRCLE_MIN  ) RSLV_DIAG_UNIT_CIRCLE_MIN);
#pragma write h, (::ETPUliteral(#define FS_ETPU_RSLV_DIAG_UNIT_CIRCLE_MAX  ) RSLV_DIAG_UNIT_CIRCLE_MAX);
#pragma write h, (::ETPUliteral(#define FS_ETPU_RSLV_DIAG_OBSERVER_ERROR   ) RSLV_DIAG_OBSERVER_ERROR );
#pragma write h, ( );

#pragma write h, (#endif);

 /*********************************************************************
 *
 * Copyright:
 *	Freescale Semiconductor, INC. All Rights Reserved.
 *  You are hereby granted a copyright license to use, modify, and
 *  distribute the SOFTWARE so long as this entire notice is
 *  retained without alteration in any modified and/or redistributed
 *  versions, and that such modified versions are clearly identified 
 *  as such. No licenses are granted by implication, estoppel or
 *  otherwise under any patents or trademarks of Freescale
 *  Semiconductor, Inc. This software is provided on an "AS IS"
 *  basis and without warranty.
 *
 *  To the maximum extent permitted by applicable law, Freescale
 *  Semiconductor DISCLAIMS ALL WARRANTIES WHETHER EXPRESS OR IMPLIED,
 *  INCLUDING IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A
 *  PARTICULAR PURPOSE AND ANY WARRANTY AGAINST INFRINGEMENT WITH
 *  REGARD TO THE SOFTWARE (INCLUDING ANY MODIFIED VERSIONS THEREOF)
 *  AND ANY ACCOMPANYING WRITTEN MATERIALS.
 *
 *  To the maximum extent permitted by applicable law, IN NO EVENT
 *  SHALL Freescale Semiconductor BE LIABLE FOR ANY DAMAGES WHATSOEVER
 *  (INCLUDING WITHOUT LIMITATION, DAMAGES FOR LOSS OF BUSINESS PROFITS,
 *  BUSINESS INTERRUPTION, LOSS OF BUSINESS INFORMATION, OR OTHER
 *  PECUNIARY LOSS) ARISING OF THE USE OR INABILITY TO USE THE SOFTWARE.
 *
 *  Freescale Semiconductor assumes no responsibility for the
 *  maintenance and support of this software
 ********************************************************************/

