/*******************************************************************************
*
* Freescale Semiconductor Inc.
* (c) Copyright 2004-2010 Freescale Semiconductor, Inc.
* ALL RIGHTS RESERVED.
*
********************************************************************************
*
* File Name:  hscmp.h
*
* $Date:      Oct-12-2010$
*
* $Version:   2.5.16.0$
*
* Description: Header file for the HSCMP driver
* 
* HSCMP_VERSION_1 .. 56F800x devices, see MC56F8006RM.pdf
* HSCMP_VERSION_2 .. 56F82xx devices, see MC56F82xxRM.pdf
*
*******************************************************************************/

#ifndef __HSCMP_H
#define __HSCMP_H

/* qs.h is a master header file, which must be included */
#if !defined(__ARCH_H) || !defined(__PERIPH_H) || !defined(__APPCONFIG_H)
#error Please include qs.h before hscmp.h
#endif

#ifdef __cplusplus
extern "C" {
#endif

/******************************************************************************
*
*                      General Interface Description
*
*
* The comparator (HSCMP) includes a digital control interface and an analog 
* comparator module. The analog comparator also includes a four-input analog 
* switching matrix with the continuous-time differential-input analog
* comparator function. 
*
******************************************************************************/

/************************************************************
* HSCMP module identifiers
*************************************************************/

#ifdef HSCMP0_BASE
#define HSCMP_0 (&ArchIO.Hscmp0)
#endif
#ifdef HSCMP1_BASE
#define HSCMP_1 (&ArchIO.Hscmp1)
#endif
#ifdef HSCMP2_BASE
#define HSCMP_2 (&ArchIO.Hscmp2)
#endif

#ifdef HSCMPA_BASE
#define HSCMP_A (&ArchIO.HscmpA)
#endif

#ifdef HSCMPB_BASE
#define HSCMP_B (&ArchIO.HscmpB)
#endif

#ifdef HSCMPC_BASE
#define HSCMP_C (&ArchIO.HscmpC)
#endif

/*************************************************************
* arch.h should define device-specific information about HSCMP
**************************************************************/

#if !defined(HSCMP_VERSION)
#error HSCMP not properly described in arch.h
#endif

/****************************************************
* Configurable items, i.e. defines for appconfig.h
*****************************************************

  #define HSCMP_x_CR0_INIT
  #define HSCMP_x_CR1_INIT
  #define HSCMP_x_FPR_INIT
  #define HSCMP_x_SCR_INIT

*/

/*****************************************************************
* Single-Instruction ioctl() commands
*
*  Word16 ioctl( HSCMP_module_identifier, Command_name, Parameter );
*
******************************************************************

 COMMAND NAME                         PARAMETERS, COMMENTS
----------------------------------------------------------------*/
#define HSCMP_MODULE                 /* HSCMP_ENABLE/HSCMP_DISABLE, enables /disables comparator module (CR1->EN) */
#define HSCMP_SET_INVERT             /* HSCMP_ENABLE/HSCMP_DISABLE, enables /disables inverter on output (CR1->INV) */
#define HSCMP_SET_SAMPLE             /* HSCMP_ENABLE/HSCMP_DISABLE, enables /disables Sampling Mode (CR1->SE) */
#define HSCMP_SET_WINDOWING          /* HSCMP_ENABLE/HSCMP_DISABLE, enables /disables Windowing Mode (CR1->WE) */
#define HSCMP_SET_HIGH_SPEED         /* HSCMP_ENABLE/HSCMP_DISABLE, enables /disables High Speed Mode (CR1->PMODE) */
#define HSCMP_SET_OUTPUT_PIN         /* HSCMP_COUNT/HSCMP_COUNTA, Selects comparator ouput pin (CR1->COS) */
#define HSCMP_SET_OUTPUT_ACTIVE      /* HSCMP_ENABLE/HSCMP_DISABLE, Selects comparator ouput pin (CR1->OPE) */
#define HSCMP_TEST_INT_FLAGS         /* HSCMP_FLAG_RISING_EDGE/HSCMP_FLAG_FALLING_EDGE, tests interrupt flags (SCR->CFR,CFF) */
#define HSCMP_CLEAR_INT_FLAGS        /* HSCMP_FLAG_RISING_EDGE/HSCMP_FLAG_FALLING_EDGE, clears interrupt flags (SCR->CFR,CFF) */
#define HSCMP_TEST_OUTPUT            /* NULL, returns zero/nonzero current comparator state (SCR->COUNT) */
#define HSCMP_READ_FILT_REG          /* NULL, returns value of filter register */
#define HSCMP_WRITE_FILT_REG         /* UWord16, writes filter register */


/*****************************************************************
* Multi-Instruction ioctl() commands
*
*  Word16 ioctl( HSCMP_module_identifier, Command_name, Parameter );
*
******************************************************************

 COMMAND NAME                         PARAMETERS, COMMENTS
----------------------------------------------------------------*/
#define HSCMP_SELECT_POS_INPUT       /* HSCMP_PIN_x (1/2/3/4), selects positive HSCMP input  (CR0->PMC)*/
#define HSCMP_SELECT_NEG_INPUT       /* HSCMP_PIN_x (1/2/3/4), selects negative HSCMP input (CR0->MMC)*/
#define HSCMP_WRITE_FILT_COUNTER     /* HSCMP_FILTR_COUNTER_x (0/1/2/3/4/5/6/7), writes filter counter (CR0->FILTER_CNT) */
#define HSCMP_INT_RISING_EDGE        /* HSCMP_ENABLE/HSCMP_DISABLE, enables / disables rising edge interrupt (SCR->IER) */
#define HSCMP_INT_FALLING_EDGE       /* HSCMP_ENABLE/HSCMP_DISABLE, enables / disables rising edge interrupt (SCR->IEF) */
#define HSCMP_READ_FILT_COUNER       /* NULL, returns value of filter counter (CR0->FILTER_CNT) */


#if HSCMP_VERSION >= 2
#define HSCMP_SET_INT_MODE_IN_STOP   /* HSCMP_xxx_SENSITIVE (EDGE/LEVEL), sets interrupt option in stop mode (SCR->SMELB) */
#define HSCMP_SET_HYSTERESIS         /* HSCMP_LEVEL_X (1/ 2/ 3/ 4), selects hystresis of analog comparator (SCR->HYST_SEL) */
#endif


/*****************************************************************
* Software Layer ioctl() commands
*
*  Word16 ioctl( HSCMP_module_identifier, Command_name, Parameter );
*
******************************************************************

 COMMAND NAME                         PARAMETERS, COMMENTS
----------------------------------------------------------------*/
#define HSCMP_INIT                   /* NULL */


/*****************************************************************************
* HSCMP ioctl command parameters 
******************************************************************************/

#define HSCMP_ENABLE            1
#define HSCMP_DISABLE           0

/* CR0 */
#define HSCMP_FILTR_COUNTER_0   HSCMP_CR0_FILTTER_CNT_0
#define HSCMP_FILTR_COUNTER_1   HSCMP_CR0_FILTTER_CNT_1
#define HSCMP_FILTR_COUNTER_2   HSCMP_CR0_FILTTER_CNT_2
#define HSCMP_FILTR_COUNTER_3   HSCMP_CR0_FILTTER_CNT_3
#define HSCMP_FILTR_COUNTER_4   HSCMP_CR0_FILTTER_CNT_4
#define HSCMP_FILTR_COUNTER_5   HSCMP_CR0_FILTTER_CNT_5
#define HSCMP_FILTR_COUNTER_6   HSCMP_CR0_FILTTER_CNT_6
#define HSCMP_FILTR_COUNTER_7   HSCMP_CR0_FILTTER_CNT_7

#define HSCMP_PIN_1             0
#define HSCMP_PIN_2             1
#define HSCMP_PIN_3             2
#define HSCMP_PIN_4             3

/* CR1 */
#define HSCMP_COUNT             0
#define HSCMP_COUNTA            1

/* SCR */
#define HSCMP_FLAG_RISING_EDGE  HSCMP_SCR_CFR  
#define HSCMP_FLAG_FALLING_EDGE HSCMP_SCR_CFF
#define HSCMP_FLAG_ALL          (HSCMP_SCR_CFF | HSCMP_SCR_CFR)
#if HSCMP_VERSION >= 2
#define HSCMP_LEVEL_SENSITIVE   0
#define HSCMP_EDGE_SENSITIVE    1
#define HSCMP_LEVEL_1           0
#define HSCMP_LEVEL_2           1
#define HSCMP_LEVEL_3           2
#define HSCMP_LEVEL_4           3
#endif

/****************************************************************************
* register and bit names used in the ioctl functions below
*****************************************************************************/

/* HSCMP Control register */
/* CR0 */
#define HSCMP_CR0_FILTTER_CNT_MASK    0x0070
#define HSCMP_CR0_FILTTER_CNT_0       0x0000
#define HSCMP_CR0_FILTTER_CNT_1       0x0010
#define HSCMP_CR0_FILTTER_CNT_2       0x0020
#define HSCMP_CR0_FILTTER_CNT_3       0x0030
#define HSCMP_CR0_FILTTER_CNT_4       0x0040
#define HSCMP_CR0_FILTTER_CNT_5       0x0050
#define HSCMP_CR0_FILTTER_CNT_6       0x0060
#define HSCMP_CR0_FILTTER_CNT_7       0x0070

#define HSCMP_CR0_PMC_MASK            0x000C
#define HSCMP_CR0_MMC_MASK            0x0003

/* CR1 */
#define HSCMP_CR1_SE                  0x0080
#define HSCMP_CR1_WE                  0x0040
#define HSCMP_CR1_PMODE               0x0010
#define HSCMP_CR1_INV                 0x0008
#define HSCMP_CR1_COS                 0x0004
#define HSCMP_CR1_OPE                 0x0002
#define HSCMP_CR1_EN                  0x0001
              
/* SCR */
#define HSCMP_SCR_IER                 0x0010
#define HSCMP_SCR_IEF                 0x0008
#define HSCMP_SCR_CFR                 0x0004
#define HSCMP_SCR_CFF                 0x0002
#define HSCMP_SCR_COUNT               0x0001
              
#if HSCMP_VERSION >= 2
#define HSCMP_SCR_SMELB               0x0020
#define HSCMP_SCR_HYST_SEL_MASK       0x00C0
#endif

/****************************************************************************
* HSCMP ioctl macro implementation
*****************************************************************************/

/***********************************************************************
* HSCMP init
***********************************************************************/

void hscmpInit(arch_sHSCMP *pHscmpBase);
#define ioctlHSCMP_INIT(pHscmpBase, param) hscmpInit(pHscmpBase)

/* CR0 */
/* reads filter sample count */
#define ioctlHSCMP_READ_FILT_COUNER(pHscmpBase, param) \
  (periphMemRead(&((pHscmpBase)->cr0)))>>4

/* writes filter sample count */
#define ioctlHSCMP_WRITE_FILT_COUNTER(pHscmpBase, param) \
  periphBitGrpSet(HSCMP_CR0_FILTTER_CNT_MASK, param ,  &((pHscmpBase)->cr0))

/* selects positive HSCMP input pin */
#define ioctlHSCMP_SELECT_POS_INPUT(pHscmpBase, param) \
  periphBitGrpSet(HSCMP_CR0_PMC_MASK, (param) << 2,  &((pHscmpBase)->cr0))

/* selects positive HSCMP input pin */
#define ioctlHSCMP_SELECT_NEG_INPUT(pHscmpBase, param) \
  periphBitGrpSet(HSCMP_CR0_MMC_MASK, param ,  &((pHscmpBase)->cr0))

/* CR1 */
/* Enables/Disables CMP module */
#define ioctlHSCMP_MODULE(pHscmpBase, param) \
  if (param) periphBitSet(HSCMP_CR1_EN, &((pHscmpBase)->cr1)); \
  else periphBitClear(HSCMP_CR1_EN, &((pHscmpBase)->cr1))

#define ioctlHSCMP_SET_INVERT(pHscmpBase, param) \
  if (param) periphBitSet(HSCMP_CR1_INV, &((pHscmpBase)->cr1)); \
  else periphBitClear(HSCMP_CR1_INV, &((pHscmpBase)->cr1))

/* Sets sample mode */
#define ioctlHSCMP_SET_SAMPLE(pHscmpBase, param) \
  if (param) periphBitSet(HSCMP_CR1_SE, &((pHscmpBase)->cr1)); \
  else periphBitClear(HSCMP_CR1_SE, &((pHscmpBase)->cr1))

/* Sets windowing mode */
#define ioctlHSCMP_SET_WINDOWING(pHscmpBase, param) \
  if (param) periphBitSet(HSCMP_CR1_WE, &((pHscmpBase)->cr1)); \
  else periphBitClear(HSCMP_CR1_WE, &((pHscmpBase)->cr1))

/* Sets power mode */
#define ioctlHSCMP_SET_HIGH_SPEED(pHscmpBase, param) \
  if (param) periphBitSet(HSCMP_CR1_PMODE, &((pHscmpBase)->cr1)); \
  else periphBitClear(HSCMP_CR1_PMODE, &((pHscmpBase)->cr1))

/* Selects comparator output  */
#define ioctlHSCMP_SET_OUTPUT_PIN(pHscmpBase, param) \
  if (param) periphBitSet(HSCMP_CR1_COS, &((pHscmpBase)->cr1)); \
  else periphBitClear(HSCMP_CR1_COS, &((pHscmpBase)->cr1))

/* Sets power mode */
#define ioctlHSCMP_SET_OUTPUT_ACTIVE(pHscmpBase, param) \
  if (param) periphBitSet(HSCMP_CR1_OPE, &((pHscmpBase)->cr1)); \
  else periphBitClear(HSCMP_CR1_OPE, &((pHscmpBase)->cr1))

/* SCR */
/* Enables/Disables rising edge interrupt */
#define ioctlHSCMP_INT_RISING_EDGE(pHscmpBase, param) \
  if (param) {periphSafeBitSet(HSCMP_FLAG_ALL, HSCMP_SCR_IER, &((pHscmpBase)->scr));} \
  else periphSafeBitClear(HSCMP_FLAG_ALL, HSCMP_SCR_IER, &((pHscmpBase)->scr))

/* Enables/Disables falling edge interrupt */
#define ioctlHSCMP_INT_FALLING_EDGE(pHscmpBase, param) \
 if (param) {periphSafeBitSet(HSCMP_FLAG_ALL, HSCMP_SCR_IEF, &((pHscmpBase)->scr));} \
  else periphSafeBitClear(HSCMP_FLAG_ALL, HSCMP_SCR_IEF, &((pHscmpBase)->scr))

/* HSCMP clears Interrupt flags  */
#define ioctlHSCMP_CLEAR_INT_FLAGS(pHscmpBase, param) \
  periphSafeAckByOne(HSCMP_FLAG_ALL, param, &((pHscmpBase)->scr))

/* HSCMP tests interrupt flag  */
#define ioctlHSCMP_TEST_INT_FLAGS(pHscmpBase, param) \
  periphBitTest(param & HSCMP_FLAG_ALL, &((pHscmpBase)->scr))

/* HSCMP tests interrupt flag  */
#define ioctlHSCMP_TEST_OUTPUT(pHscmpBase, param) \
  periphBitTest(HSCMP_SCR_COUNT, &((pHscmpBase)->scr))

/* FPR */
#define ioctlHSCMP_READ_FILT_REG(pHscmpBase, param) \
  periphMemRead(&((pHscmpBase)->fpr))
  
#define ioctlHSCMP_WRITE_FILT_REG(pHscmpBase, param) \
  periphMemWrite(param,  &((pHscmpBase)->fpr))

#if HSCMP_VERSION >= 2
/* Sets power mode */
#define ioctlHSCMP_SET_INT_MODE_IN_STOP(pHscmpBase, param) \
  if (param) {periphSafeBitSet(HSCMP_FLAG_ALL, HSCMP_SCR_SMELB, &((pHscmpBase)->scr));} \
  else periphSafeBitClear(HSCMP_FLAG_ALL, HSCMP_SCR_SMELB, &((pHscmpBase)->scr))

/* Sets analog comparator hysteresis */
#define ioctlHSCMP_SET_HYSTERESIS(pHscmpBase, param) \
  periphSafeBitGrpSet(HSCMP_FLAG_ALL, HSCMP_SCR_HYST_SEL_MASK, (param)<<6, &((pHscmpBase)->scr))

#endif

#ifdef __cplusplus
}
#endif

#endif                                      
