/*
 * Copyright (C) 2010, Freescale Semiconductor, Inc. All Rights Reserved
 * THIS SOURCE CODE IS CONFIDENTIAL AND PROPRIETARY AND MAY NOT
 * BE USED OR DISTRIBUTED WITHOUT THE WRITTEN PERMISSION OF
 * Freescale Semiconductor, Inc.
*/

/*!
 * @file functions.h
 * @brief This header file contains functions info.
 *
 */
#ifndef FUNCTIONS_H
#define FUNCTIONS_H
//#include "typedefs.h"
#include "common.h"

/***********************************************************************/
/*
 * The basic data types
 */
typedef unsigned char		uint8;  /*  8 bits */
typedef unsigned short int	uint16; /* 16 bits */
typedef unsigned long int	uint32; /* 32 bits */

typedef char			    int8;   /*  8 bits */
typedef short int	        int16;  /* 16 bits */
typedef int		            int32;  /* 32 bits */

typedef volatile int8		vint8;  /*  8 bits */
typedef volatile int16		vint16; /* 16 bits */
typedef volatile int32		vint32; /* 32 bits */

typedef volatile uint8		vuint8;  /*  8 bits */
typedef volatile uint16		vuint16; /* 16 bits */
typedef volatile uint32		vuint32; /* 32 bits */

/***********************
 * Memory Size Defines
 ***********************/
#define SIZE_1KB				0x00000400					// 1KB
#define SIZE_4KB				0x00001000					// 4KB
#define SIZE_8KB				0x00002000					// 8KB
#define SIZE_16KB				0x00004000					// 16KB
#define SIZE_32KB				0x00008000					// 32KB
#define SIZE_48KB   			0x0000C000					// 48KB
#define SIZE_64KB   			0x00010000					// 64KB
#define SIZE_128KB 				0x00020000					// 128KB
#define SIZE_256KB 				0x00040000					// 256KB
#define SIZE_512KB				0x00080000					// 512KB
#define SIZE_1MB	     		0x00100000	            	// 1 MB
#define SIZE_2MB				0x00200000					// 2 MB
#define SIZE_3MB	        	0x00300000	       	    	// 3 MB

/**************************************************************************************/
/**************************************************************************************/
/**************************************************************************************/
/* 	Defines to support Characterization 	*/
/**************************************************************************************/
/**************************************************************************************/
/**************************************************************************************/

/*************************************/
/* Define method for data transfer */
/* for cpu to cpu interrupt test   */
/*************************************/
#define PASS_DATA_NO_DMA		1
//#define PASS_DATA_WITH_DMA	`	1
//#define PASS_POINTER_NO_DMA		1

/*************************************************************************/
/* Defines for shared memory location.  add linker file support later
 * quick method - hard code shared locations for experiment */
/* for cpu to cpu characterization 	*/
/*************************************************************************/
#define USE_DDR_FOR_SHARED_MEMORY				1
#define MAX_SHARED_DATA_BYTES					SIZE_64KB		//(64*1024)

#if USE_DDR_FOR_SHARED_MEMORY
/* DDR For shared mem - does not require cache synchronization when both run from SRAM */
#define SHARED_DATA_LOCATION_A5					0x81000000		//A5 shared data hard coded address for experiments only up to 64Kb (0x1_0000)
#define SHARED_DATA_LOCATION_M4					0x81020000		//A5 shared data hard coded address for experiments only up to 64Kb (0x1_0000)
#define SHARED_DATA_TIMESTAMP_LOCATION_0		0x81030000		//Temporary M4/A5 shared data hard coded address for timestamp experiments only
#define SHARED_DATA_TIMESTAMP_LOCATION_1		0x81030004		//Temporary M4/A5 shared data hard coded address for timestamp experiments only
#define SHARED_DATA_TIMESTAMP_LOCATION_2		0x81030008		//Temporary M4/A5 shared data hard coded address for timestamp experiments only
#define SHARED_DATA_TIMESTAMP_LOCATION_3		0x8103000C		//Temporary M4/A5 shared data hard coded address for timestamp experiments only
#define SHARED_DATA_TIMESTAMP_LOCATION_4		0x81030010		//Temporary M4/A5 shared data hard coded address for timestamp experiments only
//#define SHARED_DATA_SIZE0_LOCATION				0x81030014		//Temporary A5 location which holds address of start of memory block
//#define SHARED_DATA_SIZE1_LOCATION				0x81030018		//Temporary M4 location which holds address of start of memory block
#else
/* Internal SRAM for shared mem - may require cache synchronization/flush to see data written by other core when both running from SRAM */
#define SHARED_DATA_LOCATION_A5					0x3F020000		//A5 shared data hard coded address for experiments only up to 64Kb (0x1_0000)
#define SHARED_DATA_LOCATION_M4					0x3F060000		//A5 shared data hard coded address for experiments only up to 64Kb (0x1_0000)
#define SHARED_DATA_TIMESTAMP_LOCATION_0		0x3F01FF00		//Temporary M4/A5 shared data hard coded address for timestamp experiments only
#define SHARED_DATA_TIMESTAMP_LOCATION_1		0x3F01FF04		//Temporary M4/A5 shared data hard coded address for timestamp experiments only
#define SHARED_DATA_TIMESTAMP_LOCATION_2		0x3F01FF08		//Temporary M4/A5 shared data hard coded address for timestamp experiments only
#define SHARED_DATA_TIMESTAMP_LOCATION_3		0x3F01FF0C		//Temporary M4/A5 shared data hard coded address for timestamp experiments only
#define SHARED_DATA_TIMESTAMP_LOCATION_4		0x3F01FF10		//Temporary M4/A5 shared data hard coded address for timestamp experiments only
//#define SHARED_DATA_SIZE0_LOCATION				0x3F01FF14		//Temporary A5 location which holds address of start of memory block
//#define SHARED_DATA_SIZE1_LOCATION				0x3F01FF18		//Temporary M4 location which holds address of start of memory block

#endif //#if USE_DDR_FOR_SHARED_MEMORY
/* define which cpu to cpu vector to use when asserted - up to 4 available */
/* This value gets written to MSCM->IRCPGIR.INTID to select which vector (out of 4) to take */
/* CPUTL field designates which core and INTID designates which vector */
#define CPU_TO_CPU_VECTOR_NUM		 	0
//#define CPU_TO_CPU_VECTOR_NUM		 	1
//#define CPU_TO_CPU_VECTOR_NUM		 	2
//#define CPU_TO_CPU_VECTOR_NUM		 	3

/*******************************************************************/
/* Core operations and semaphore definitions */
/*******************************************************************/
#define A5_CORE_ID					0x00434135
#define A5_CORE_CHECK				((MSCM->CPxTYPE>>MSCM_CPxTYPE_Personality_SHIFT) == A5_CORE_ID) /* run-time method to determine core ID */
#define M4_CORE_ID					0x00434D34
#define M4_CORE_CHECK				((MSCM->CPxTYPE>>MSCM_CPxTYPE_Personality_SHIFT) == M4_CORE_ID)	/* run-time method to determine core ID */
#define CORE_UNLOCK					0	/* Semaphore Lock ID for no core assigned */
#define CORE0_LOCK					1	/* Semaphore Lock ID Value for A5 */
#define CORE1_LOCK					2	/* Semaphore Lock ID Value for M4 */
#define CORE0_ID					0	/* Core ID */
#define CORE1_ID					1	/* Core ID */
#define CORE_NUM					((A5_CORE_CHECK) ? 0 : 1);	/* run-time method to determine core ID */
//#define MCC_CORE_NUMBER			CORE_NUM
#define CORE_ID_ERROR				0x0E0E0E0E
#define SEMA4_LOCK_ERROR			0x05050505
#define SEMA4_UNLOCK_ERROR			0x15151515
#define SEMA4_LOCK_OK				0xAA55AA55
#define SEMA4_UNLOCK_OK				0xAA66AA66

/*******************************************************************/
/* change if you want to use a different counter */
/*******************************************************************/
#define TIMER_COUNTER				PIT->CHANNEL[0].CVAL
/***********************************************************************/

/**************************************************************************************/
/**************************************************************************************/
/**************************************************************************************/
/**************************************************************************************/
/* End - Characterization definitions 	*/
/**************************************************************************************/
/**************************************************************************************/
/**************************************************************************************/
/**************************************************************************************/

/**************************************************************************
 *  Some Genaral Macros
 **************************************************************************/
#define FALSE 0
#define TRUE  1

#define BIT0 0
#define BIT1 1
#define BIT2 2
#define BIT3 3
#define BIT4 4
#define BIT5 5
#define BIT6 6
#define BIT7 7
#define BIT8 8
#define BIT9 9
#define BIT10 10
#define BIT11 11
#define BIT12 12
#define BIT13 13
#define BIT14 14
#define BIT15 15
#define BIT16 16
#define BIT17 17
#define BIT18 18
#define BIT19 19
#define BIT20 20
#define BIT21 21
#define BIT22 22
#define BIT23 23
#define BIT24 24
#define BIT25 25
#define BIT26 26
#define BIT27 27
#define BIT28 28
#define BIT29 29
#define BIT30 30
#define BIT31 31

#define PIN_MASK            0x1Fu
#define PIN(x)              (unsigned)(((1)<<(x & PIN_MASK)))

#define reg8_read(addr)       (*((vuint8_t *)(addr)))
#define reg16_read(addr)      (*((vuint16_t *)(addr)))
#define reg32_read(addr)      (*(vuint32_t *)((addr)))

#define reg8_write(addr,val)  (*((vuint8_t *)(addr)) = (val))
#define reg16_write(addr,val) (*((vuint16_t *)(addr)) = (val))
#define reg32_write(addr,val) (*((vuint32_t *)(addr)) = (val))

#define mem8_read(addr)       (*((vuint8_t *)(addr)))
#define mem16_read(addr)      (*((vuint16_t *)(addr)))
#define mem32_read(addr)      (*(vuint32_t *)((addr)))

#define mem8_write(addr,val)  (*((vuint8_t *)(addr)) = (val))
#define mem16_write(addr,val) (*((vuint16_t *)(addr)) = (val))
#define mem32_write(addr,val) (*((vuint32_t *)(addr)) = (val))

#define  reg8setbit(addr,bitpos) \
         reg8_write((addr),(reg8_read((addr)) | (1<<(bitpos))))

#define  reg16setbit(addr,bitpos) \
         reg16_write((addr),(reg16_read((addr)) | (1<<(bitpos))))

#define  reg32setbit(addr,bitpos) \
         reg32_write((addr),(reg32_read((addr)) | (1<<(bitpos))))

#define  reg8clrbit(addr,bitpos) \
         reg8_write((addr),(reg8_read((addr)) & (0xFF ^ (1<<(bitpos)))))

#define  reg16clrbit(addr,bitpos) \
         reg16_write((addr),(reg16_read((addr)) & (0xFFFF ^ (1<<(bitpos)))))

#define  reg32clrbit(addr,bitpos) \
         reg32_write((addr),(reg32_read((addr)) & (0xFFFFFFFF ^ (1<<(bitpos)))))
		 
#define  reg8testbit(addr,bitpos) (((*((vuint8_t *)(addr))) & (1<<(bitpos))) >> bitpos)

#define  reg16testbit(addr,bitpos) (((*((vuint16_t *)(addr))) & (1<<(bitpos))) >> bitpos)

#define  reg32testbit(addr,bitpos) (((*((vuint32_t *)(addr))) & (1<<(bitpos))) >> bitpos)

#define byte_swap32(word) \
  ( ((word&0x000000FF) << 24)|			\
  ((word&0x0000FF00) << 8) |			\
  ((word&0x00FF0000) >> 8) |			\
  ((word&0xFF000000) >> 24)  )

#define byte_swap16(word) \
  ( ((word&0x00FF) << 8) |			\
  ((word&0xFF00) >> 8) )

/**************************************************************************
 *  Write With Mask (write only certain bits)
 **************************************************************************/
void reg8_write_mask(uint32_t addr, uint8_t wdata, uint8_t mask);
void reg16_write_mask(uint32_t addr, uint16_t wdata, uint16_t mask);
void reg32_write_mask(uint32_t addr, uint32_t wdata, uint32_t mask);

#endif 
