/*******************************************************************************
*
* Freescale Semiconductor Inc.
* (c) Copyright 2004-2007 Freescale Semiconductor, Inc.
* (c) Copyright 2001-2004 Motorola, Inc.
* ALL RIGHTS RESERVED.
*
********************************************************************************
*
* File Name:  cop.h
*
* $Date:      Feb-5-2007$
*
* $Version:   2.3.23.0$
*
* Description: Header file for COP (Computer Operating Properly - Watchdog) 
*              low-level driver 
*
* This file supports different hardware versions of the module. A version
* of module used in your project is defined in the "arch.h" processor 
* architecture definition file.
*
*  COP_VERSION_1 .. 56F83xx and 56F801x devices, see MC56F8300UM.pdf, MC56F8000RM.pdf
*  COP_VERSION_2 .. 56F802x/3x devices, see MC56F802x3xRM.pdf
*
*****************************************************************************/

#ifndef __COP_H
#define __COP_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 cop.h
#endif

#ifdef __cplusplus
extern "C" {
#endif

/************************************************************
* COP module identifier, corresponds to module base address
*************************************************************/

#define COP (&ArchIO.Cop)

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

#if !defined(COP_VERSION)
#error COP not properly described in arch.h (old Quick_Start version?)
#endif

/******************************************************************************
*
*                      General Interface Description
*
*
* The Computer Operating Properly (COP) module is used to help software recover
* from runaway code. The COP is a free-running down counter once enabled is
* designed to generate a reset when reaching zero. Software must periodically
* service the COP to clear the counter and prevent a reset.
*
* For more information, please refer to the user manual for the particular
* chip that you are using, such as the MC56F8300 Peripheral Manual,
* for a description of the COP device.
*
* The COP device driver interface uses "ioctl" call to control specific
* COP functions during operation. For details see "ioctl" call.
*
******************************************************************************/

/***********************************************************************
* COP static configuration items for appconfig.h
***********************************************************************/
/*
    #define COP_COPCTL_INIT 0x0002
    #define COP_COPTO_INIT  0xFFFF

    #define INTERRUPT_VECTOR_ADDR_1  // specify interrupt handler routine
*/

/***************************************************
* COP ioctl commands
****************************************************/
/* command                    |    Param, Description       */

#define COP_INIT                /* NULL, COP peripheral initialization  */
#define COP_DEVICE              /* COP_ENABLE/COP_DISABLE, enable/disable COP watchdog counter */
#define COP_WRITE_PROTECT       /* NULL, Write-protect COP settings (until Reset) */
#define COP_SET_TIMEOUT         /* UWord16, Set COP Timeout Value */

#define COP_RUN_IN_STOP         /* COP_ENABLE/COP_DISABLE, control the state of COP in WAIT mode */  
#define COP_RUN_IN_WAIT         /* COP_ENABLE/COP_DISABLE, control the state of COP in STOP mode */  

#define COP_READ_COUNTER        /* NULL, read current status of COP counter */

#define COP_CLEAR_COUNTER       /* NULL, clear COP counter (both steps are performed) */
#define COP_CLEAR_COUNTER_PART1 /* NULL, clear COP counter (1st step of the sequence) */
#define COP_CLEAR_COUNTER_PART2 /* NULL, clear COP counter (2nd step of the sequence) */

/****************************************************************************
* New COP features (802x3x and later)
*****************************************************************************/

#if COP_VERSION >= 2
#define COP_SET_CLOCK_SOURCE    /* COP_MSTR_OSC/COP_RLX_OSC/COP_IPBUS_CLK, select COP clock source */
#define COP_LOR_WATCHDOG        /* COP_ENABLE/COP_DISABLE, enable Loss-of-reference clock watchdog*/
#endif

/****************************************************************************
* COP constants and type declarations used in the ioctl functions
*****************************************************************************/

#define COP_ENABLE    1
#define COP_DISABLE   0

#define COP_MSTR_OSC  0
#define COP_RLX_OSC   COP_COPCTL_CLKSEL
#define COP_IPBUS_CLK COP_COPCTL_BYPS

/****************************************************************************
* COP registers and bits
*****************************************************************************/

/* COP control register */
#define COP_COPCTL_BYPS    0x0010
#define COP_COPCTL_CSEN    0x0008
#define COP_COPCTL_CWEN    0x0004
#define COP_COPCTL_CEN     0x0002
#define COP_COPCTL_CWP     0x0001

#if COP_VERSION >= 2
#define COP_COPCTL_CLOREN  0x0020
#define COP_COPCTL_CLKSEL  0x0040
#endif

/* COP control register, obsolete macros */
#define COP_BYPS   COP_COPCTL_BYPS
#define COP_CSEN   COP_COPCTL_CSEN
#define COP_CWEN   COP_COPCTL_CWEN
#define COP_CEN    COP_COPCTL_CEN 
#define COP_CWP    COP_COPCTL_CWP 

/***********************************************************************
* COP control command macros
***********************************************************************/

/* COP initialization */
void copInit(arch_sCOP *pCopBase);
#define ioctlCOP_INIT(pCopBase, param) copInit(pCopBase)

/* COP peripheral enable/disable - functional only if COP Write protect Bit (CWP) is not set */
#define ioctlCOP_DEVICE(pCopBase, param) \
  if (param) periphBitSet(COP_COPCTL_CEN, &((pCopBase)->copctl)); \
  else periphBitClear(COP_COPCTL_CEN, &((pCopBase)->copctl))

/* COP peripheral write protect  - functional only if COP Write protect Bit (CWP) is not set */
/* if this command issued any subsequent write to COPCTL (COP Control Reg.) is blocked */
#define ioctlCOP_WRITE_PROTECT(pCopBase, param) \
  periphBitSet(COP_COPCTL_CWP, &((pCopBase)->copctl))

/* COP Run in Stop mode enable/disable */
#define ioctlCOP_RUN_IN_STOP(pCopBase, param) \
  if (param) periphBitSet(COP_COPCTL_CSEN, &((pCopBase)->copctl)); \
  else periphBitClear(COP_COPCTL_CSEN, &((pCopBase)->copctl))

/* COP Run in Stop mode enable/disable */
#define ioctlCOP_RUN_IN_WAIT(pCopBase, param) \
  if (param) periphBitSet(COP_COPCTL_CWEN, &((pCopBase)->copctl)); \
  else periphBitClear(COP_COPCTL_CWEN, &((pCopBase)->copctl))

/* set COP timeout interval, param value is decremented before write to timeout reg */
#define ioctlCOP_SET_TIMEOUT(pCopBase, param) \
  periphMemWrite((param)-1, &((pCopBase)->copto))

/* read current status of COP counter*/
#define ioctlCOP_READ_COUNTER(pCopBase, param) \
  periphMemRead(&((pCopBase)->copctr))

/* clear(service) COP timer */
#define ioctlCOP_CLEAR_COUNTER(pCopBase, param) \
  { periphMemWrite(0x5555, &((pCopBase)->copctr));\
    periphMemWrite(0xAAAA, &((pCopBase)->copctr)); }

#define ioctlCOP_CLEAR_COUNTER_PART1(pCopBase, param) \
  periphMemWrite(0x5555, &((pCopBase)->copctr))

#define ioctlCOP_CLEAR_COUNTER_PART2(pCopBase, param) \
  periphMemWrite(0xAAAA, &((pCopBase)->copctr))

#if COP_VERSION >= 2

/* Select COP clock source */
#define ioctlCOP_SET_CLOCK_SOURCE(pCopBase, param) \
  periphBitGrpSet(COP_COPCTL_CLKSEL | COP_COPCTL_BYPS, param, &((pCopBase)->copctl))

/* Enable Loss-of-reference clock watchdog*/
#define ioctlCOP_LOR_WATCHDOG(pCopBase, param) \
  if (param) periphBitClear(COP_COPCTL_CLOREN, &((pCopBase)->copctl)); \
  else periphBitSet(COP_COPCTL_CLOREN, &((pCopBase)->copctl))

#endif

#ifdef __cplusplus
}
#endif

#endif
