/*******************************************************************************
* FILE NAME: etpu_bc.c       COPYRIGHT (c) Freescale Semiconductor 2005
*                                         All Rights Reserved
* DESCRIPTION:
* This file contains the eTPU Break Controller(BC) API.
*===============================================================================
* REV      AUTHOR      DATE        DESCRIPTION OF CHANGE
* ---   -----------  ----------    ---------------------
* 0.1   V.Philippov  23/Feb/04     Initial version.
* 0.2   A.Butok      12/May/04     Corrected.
* 2.0   M. Brejl     21/Feb/05     Updated for new implementation and new
*                                  build structure.
*******************************************************************************/
#include "etpu_util.h"          /* Utility routines for working with the eTPU */
#include "etpu_bc.h"            /* eTPU BC API */

extern uint32_t fs_etpu_data_ram_start;

/*******************************************************************************
*FUNCTION     : fs_etpu_bc_init
*PURPOSE      : This routine is used to initialize the eTPU channel for the BC
*               function.
*INPUTS NOTES : This function has 10 parameters:
*   channel          - This is the Break Controller (BC) channel number.
*                      0-31 for ETPU_A and 64-95 for ETPU_B.
*   priority         - This is the priority to assign to the BC function.
*                      This parameter should be assigned a value of:
*                      FS_ETPU_PRIORITY_HIGH or
*                      FS_ETPU_PRIORITY_MIDDLE or
*                      FS_ETPU_PRIORITY_LOW or
*                      FS_ETPU_PRIORITY_DISABLED.
*   mode             - This is the function mode.
*                      This parameter should be assigned a value of:
*                      FS_ETPU_BC_SLAVE_ON_OFF or
*                      FS_ETPU_BC_SLAVE_PWM or
*                      FS_ETPU_BC_MASTER_ON_OFF.
*   polarity         - This is the BC output polarity.
*                      This parameter should be assigned a value of:
*                      ETPU_BC_ON_HIGH or
*                      ETPU_BC_ON_LOW.
*   period           - In Master Mode (mode=FS_ETPU_BC_MASTER_ON_OFF)
*                      this is the update period, as number of TCR1 clocks.
*                      In Slave Mode PWM (mode=FS_ETPU_BC_SLAVE_PWM)
*                      this is the PWM period, as number of TCR1 clocks.
*                      In Slave Mode ON/OFF (mode=FS_ETPU_BC_SLAVE_ON_OFF)
*                      this parameter does not apply.
*   start_offset     - This parameter is used to synchronize various
*                      eTPU functions that generate a signal.
*                      The first BC update starts the start_offset TCR1
*                      clocks after initialization. This parameter applies
*                      in the Master Mode only (mode=FS_ETPU_BC_MASTER_ON_OFF).
*   services_per_irq - This parameter defines the number of updates after
*                      which an interrupt service request is generated
*                      to the CPU.
*   u_dc_bus_ON      - This is the threshold value of U_DC_BUS
*                      above which the BC output is ON.
*   u_dc_bus_OFF     - This is the threshold value of U_DC_BUS
*                      bellow which the BC output is OFF.
*
* RETURNS NOTES: Error codes which can be returned are: FS_ETPU_ERROR_VALUE,
*                FS_ETPU_ERROR_MALLOC
*                
* PROJECT NOTES: Break Controller (BC) function must be periodically supplied by 
*                the actual measured DC-bus voltage. This can be done either by 
*                CPU or using the Analog Sensing for DC Motors (ASDC) function
*                which needs to be initialized here!
*******************************************************************************/
int32_t fs_etpu_bc_init(uint8_t    channel,
                        uint8_t    priority,
                        uint8_t    mode,
                        uint8_t    polarity,
                        uint24_t   period,
                        uint24_t   start_offset,
                        uint24_t   services_per_irq,
                        ufract24_t u_dc_bus_ON,
                        ufract24_t u_dc_bus_OFF)
{
   uint32_t * pba;
   ufract24_t PWM_slope;

   /***************************************
    * Parameters bounds check.
    **************************************/
   #ifdef FS_ETPU_MC_PARAM_CHECK
   if(((channel>31)&&(channel<64))||(channel>95)||
      (priority>FS_ETPU_PRIORITY_HIGH)||
      ((mode!=FS_ETPU_BC_SLAVE_ON_OFF)&&(mode!=FS_ETPU_BC_SLAVE_PWM)&&
       (mode!=FS_ETPU_BC_MASTER_ON_OFF))||
      (polarity>ETPU_BC_ON_LOW)||
      (period>0x800000)||
      (start_offset>0x800000)||
      (u_dc_bus_ON<u_dc_bus_OFF))
   {
      return(FS_ETPU_ERROR_VALUE);
   }
   #endif

   /***************************************
    * PRAM allocation.
    **************************************/
   if ((pba=fs_etpu_malloc(FS_ETPU_BC_NUM_PARMS))== 0)
   {
      return(FS_ETPU_ERROR_MALLOC);
   }

   /***************************************
    * Calculation PWM_slope.
    **************************************/
   PWM_slope = 0x1000000/(u_dc_bus_ON - u_dc_bus_OFF)*period;

   /***************************************
    * Write chan config register.
    **************************************/
   eTPU->CHAN[channel].CR.R = (FS_ETPU_BC_TABLE_SELECT << 24) +
                              (FS_ETPU_BC_FUNCTION_NUMBER << 16) +
                              (((uint32_t)pba - fs_etpu_data_ram_start) >> 3);
   eTPU->CHAN[channel].SCR.R = polarity;

   /***************************************
    * Write parameters.
    **************************************/
   *(pba + ((FS_ETPU_BC_PERIOD_OFFSET - 1)>>2)) = period;
   *(pba + ((FS_ETPU_BC_STARTOFFSET_OFFSET - 1)>>2)) = start_offset;
   *(pba + ((FS_ETPU_BC_SERVICESPERIRQ_OFFSET - 1)>>2)) = services_per_irq;
   *(pba + ((FS_ETPU_BC_UDCBUSMEASURED_OFFSET - 1)>>2)) = 0;
   *(pba + ((FS_ETPU_BC_UDCBUSON_OFFSET - 1)>>2)) = u_dc_bus_ON;
   *(pba + ((FS_ETPU_BC_UDCBUSOFF_OFFSET - 1)>>2)) = u_dc_bus_OFF;
   *(pba + ((FS_ETPU_BC_PWMSLOPE_OFFSET - 1)>>2)) = PWM_slope;

   /***************************************
    * Write HSR.
    **************************************/
   eTPU->CHAN[channel].HSRR.R = mode;

   /****************************************
    * Set channel priority and enable.
    ***************************************/
   fs_etpu_enable(channel, priority);

   return(0);
}


/*******************************************************************************
*FUNCTION     : fs_etpu_bc_update
*PURPOSE      : This function executes the BC update.
*INPUTS NOTES : This function has 1 parameter:
*   channel       - This is the BC channel number.
*                   This parameter must be assigned the same value
*                   as the channel parameter of the initialization
*                   function was assigned.
*
*RETURNS NOTES: Error code that can be returned is: FS_ETPU_ERROR_VALUE.
*******************************************************************************/
int32_t fs_etpu_bc_update(uint8_t channel)
{
   /* Parameters bounds check.  */
   #ifdef FS_ETPU_MC_PARAM_CHECK
       if(((channel>31)&&(channel<64))||(channel>95))
       {
          return(FS_ETPU_ERROR_VALUE);
       }
   #endif

   fs_etpu_set_hsr(channel, FS_ETPU_BC_CALC);

   return(0);
}


/*******************************************************************************
*FUNCTION     : fs_etpu_bc_set_thresholds
*PURPOSE      : This function changes the U_DC_BUS threshold values.
*INPUTS NOTES : This function has 3 parameters:
*   channel       - This is the BC channel number.
*                   This parameter must be assigned the same value
*                   as the channel parameter of the initialization
*                   function was assigned.
*   u_dc_bus_ON   - This is the threshold value of U_DC_BUS
*                   up from which the BC output is ON.
*   u_dc_bus_OFF  - This is the threshold value of U_DC_BUS
*                   bellow to which the BC output is OFF.
*
*RETURNS NOTES: Error code that can be returned is: FS_ETPU_ERROR_VALUE.
*******************************************************************************/
int32_t fs_etpu_bc_set_thresholds(uint8_t channel,
                                  ufract24_t u_dc_bus_ON,
                                  ufract24_t u_dc_bus_OFF)
{
   uint32_t * pba;
   ufract24_t PWM_slope;
   uint32_t   period;

   /* Parameters bounds check.  */
   #ifdef FS_ETPU_MC_PARAM_CHECK
       if(((channel>31)&&(channel<64))||(channel>95)||
          (u_dc_bus_ON<u_dc_bus_OFF))
       {
          return(FS_ETPU_ERROR_VALUE);
       }
   #endif

   pba = fs_etpu_data_ram(channel);

   /***************************************
    * Calculation PWM_slope.
    **************************************/
   period = *(pba + ((FS_ETPU_BC_PERIOD_OFFSET - 1)>>2));
   PWM_slope = 0x1000000/(u_dc_bus_ON - u_dc_bus_OFF)*period;

   /***************************************
    * Write parameters.
    **************************************/
   *(pba + ((FS_ETPU_BC_UDCBUSON_OFFSET - 1)>>2)) = u_dc_bus_ON;
   *(pba + ((FS_ETPU_BC_UDCBUSOFF_OFFSET - 1)>>2)) = u_dc_bus_OFF;
   *(pba + ((FS_ETPU_BC_PWMSLOPE_OFFSET - 1)>>2)) = PWM_slope;

   return(0);
}

/*******************************************************************************
*FUNCTION     : fs_etpu_bc_set_u_dc_bus_measured
*PURPOSE      : This function sets the measured value, as a portion
*               of the maximum value.
*INPUTS NOTES : This function has 2 parameters:
*   channel           - This is the BC channel number.
*                       This parameter must be assigned the same value
*                       as the channel parameter of the initialization
*                       function was assigned.
*   u_dc_bus_measured - Measured (actual) input value, in range
*                       0 to 0xFFFFFF.
*
*RETURNS NOTES: Error code that can be returned is: FS_ETPU_ERROR_VALUE.
*******************************************************************************/
int32_t fs_etpu_bc_set_u_dc_bus_measured(uint8_t   channel,
                                         ufract24_t u_dc_bus_measured)
{
   /* Parameters bounds check */
   #ifdef FS_ETPU_MC_PARAM_CHECK
       if(((channel>31)&&(channel<64))||(channel>95))
       {
          return(FS_ETPU_ERROR_VALUE);
       }
   #endif

   fs_etpu_set_chan_local_24(channel, FS_ETPU_BC_UDCBUSMEASURED_OFFSET,
                             u_dc_bus_measured);

   return(0);
}


/*********************************************************************
 *
 * 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
 ********************************************************************/
