/*******************************************************************************
 *
 * Freescale Semiconductor Inc.
 * (c) Copyright 2015 Freescale Semiconductor, Inc.
 * ALL RIGHTS RESERVED.
 *
 ****************************************************************************//*!
*
* @file    reacm2_util.h
*
* @author  Marketa Venclikova [b52107]
* 
* @version 1.0
* 
* @date    11-Nov-2015
*
* @brief   This file contains useful macros and prototypes for using the REACM2
*
*
*******************************************************************************/
#ifndef _REACM2_UTIL_H_
#define _REACM2_UTIL_H_

/*******************************************************************************
 * Includes
 *******************************************************************************/
#include "../headers/typedefs.h"  /* standard types */
#include "../headers/mpc5746r.h"  /* MPC5746R register definitions */

/*******************************************************************************
 * Macros
 *******************************************************************************/
/* BOOLEAN DEFINE */
#ifndef TRUE
#define TRUE  1
#endif

#ifndef FALSE
#define FALSE 0
#endif

#define ERROR   -1
#define CORRECT  1

#define NO_VAL   0
#define NAN     -1

/* NULL needed */
#ifndef NULL
#ifdef __cplusplus
#define NULL (0)
#else
#define NULL ((void *) 0)
#endif
#endif

/* module enable/disable defines */
#define FS_REACM2_ENABLE  1
#define FS_REACM2_DISABLE 0

/* bank status defines */ 
#define FS_REACM2_BANK_FULL  0
#define FS_REACM2_BANK_OK    1

/* bank size defines */ 
#define FS_REACM2_MOD_WORD_BANK_SIZE   32
#define FS_REACM2_THRESHOLD_BANK_SIZE  32
#define FS_REACM2_SH_TIMER_BANK_SIZE    5
#define FS_REACM2_HOLD_TIMER_BANK_SIZE  5

/* Channel Priority values */
#define FS_REACM2_CH_0      0  // highest priority channel
#define FS_REACM2_CH_1      1
#define FS_REACM2_CH_2      2
#define FS_REACM2_CH_3      3
#define FS_REACM2_CH_4      4
#define FS_REACM2_CH_5      5
#define FS_REACM2_CH_6      6
#define FS_REACM2_CH_7      7
#define FS_REACM2_CH_8      8
#define FS_REACM2_CH_9      9  // lowest priority channel


/* modulation word defines */
#define FS_REACM2_LOOP_ON     0x80000000
#define FS_REACM2_LOOP_OFF    0x00000000

#define FS_REACM2_IOSS_LOD    0x00000000
#define FS_REACM2_IOSS_HOD    0x40000000

#define FS_REACM2_MM_TT       0x00000000  // threshold/threshold modulation 
#define FS_REACM2_MM_THOFF    0x08000000  // threshold/hod-off modulation
#define FS_REACM2_MM_THON     0x10000000  // threshold/hold-on modulation
#define FS_REACM2_MM_TLOWP    0x18000000  // threshold/period modulation

#define FS_REACM2_SM_NO_TRANSITION    0x00000000  // current modulation word is used
#define FS_REACM2_SM_TIMER_EVENT      0x01000000  // next modulation word is step on timer time-out event
#define FS_REACM2_SM_HOLD_TIMER_EVENT 0x02000000  // next modulation word step on hold timer time-out event, only for 
#define FS_REACM2_SM_THRESHOLD_EVENT  0x03000000  // next modulation word step when threshold defined with THRESPT is achieved

#define FS_REACM2_HOD_C_LOW     0x00000000
#define FS_REACM2_HOD_C_HIGH    0x00400000
#define FS_REACM2_HOD_B_LOW     0x00000000
#define FS_REACM2_HOD_B_HIGH    0x00200000
#define FS_REACM2_HOD_A_LOW     0x00000000
#define FS_REACM2_HOD_A_HIGH    0x00100000

#define FS_REACM2_LOD_C_LOW     0x00000000
#define FS_REACM2_LOD_C_HIGH    0x00040000
#define FS_REACM2_LOD_B_LOW     0x00000000
#define FS_REACM2_LOD_B_HIGH    0x00020000
#define FS_REACM2_LOD_A_LOW     0x00000000
#define FS_REACM2_LOD_A_HIGH    0x00010000

/* MCR - Module Configuration Register */
#define FS_REACM2_MDIS_DISABLE    0x40000000  /* reaction module disable */
#define FS_REACM2_MDIS_ENABLE     0x00000000  /* reaction module enable */

#define FS_REACM2_FRZ_NORMAL_MODE 0x00000000  /* freeze control not active */
#define FS_REACM2_FRZ_DEBUG_MODE  0x20000000  /* freeze control active */

#define FS_REACM2_FREN_ENABLE     0x08000000  /* debug mode enable */
#define FS_REACM2_FREN_DISABLE    0x00000000  /* debug mode disable */

#define FS_REACM2_TPREN_ENABLE    0x04000000  /* timer prescaler enable */
#define FS_REACM2_TPREN_DISABLE   0x00000000  /* timer prescaler disable */

#define FS_REACM2_HPREN_ENABLE    0x02000000  /* hold timer prescaler enable */
#define FS_REACM2_HPREN_DISABLE   0x00000000  /* hold timer prescaler disable */

#define FS_REACM2_GIEN_ENABLE     0x01000000  /* global interrupt enable */
#define FS_REACM2_GIEN_DISABLE    0x00000000  /* global interrupt disable */

#define FS_REACM2_OVREN_ENABLE    0x00800000  /* overrun detection interrupt enable */
#define FS_REACM2_OVREN_DISABLE   0x00000000  /* overrun detection interrupt disable */

/* TCR - Timer Configuration Register */
#define FS_REACM2_HPRE(x)   (((x - 1) & 0xFFF) << 16)  /* Hold Timer Prescaler value settings */
#define FS_REACM2_TPRE(x)   ((x - 1) & 0xF)  /* Timer Prescaler value settings */

/* THRR - Threshold Router Register */
#define FS_REACM2_WREN1_ENABLE    0x02000000  /* write received ADC result to Threshold bank address 1 enable */
#define FS_REACM2_WREN1_DISABLE   0x00000000  /* write received ADC result to Threshold bank address 1 disable */

#define FS_REACM2_WREN0_ENABLE    0x01000000  /* write received ADC result to Threshold bank address 0 enable */
#define FS_REACM2_WREN0_DISABLE   0x00000000  /* write received ADC result to Threshold bank address 0 disabled*/

#define FS_REACM2_THRADC1(x)    (((x) & 0xF) << 8) /* set the TAG for THRADC1 */
#define FS_REACM2_THRADC0(x)    ((x) & 0xF)  /* set the TAG for THRADC1 */



/* PCR - Period Generator Configuration Register */
#define FS_REACM2_PERPRESC(x)   (((x - 1)& 0xFF) << 16)  /* set the prescaler for Period/Delay Generator */
#define FS_REACM2_PER(x)        ((x ) & 0xFFFF)  /* set the period time value for Period/Delay Generator */

/* PSCR - Period Shift Delay Configuration Register */
#define FS_REACM2_DLY(x)       ((x) & 0xFFFF)  /* set the delay value for Period/Delay Generator */

/* CHCR - Channel Configuration Register */
#define FS_REACM2_CHEN_ENABLE   0x40000000  /* channel enable */
#define FS_REACM2_CHEN_SWMC     0x80000000  /* sw channel mode control */
#define FS_REACM2_CHEN_DISABLE  0x00000000  /* channel is disable */

#define FS_REACM2_SWMC_ON       0x20000000  /* initiate sw modulation */
#define FS_REACM2_SWMC_OFF      (~(1 << 29))  /* clear the SWMC bit, thus terminate sw modulation */

#define FS_REACM2_MAXLEN_ENABLE   0x10000000  /* enable ADC result Maximum Limit interrupt */
#define FS_REACM2_MAXLEN_DISABLE  0x00000000  /* disable ADC result Maximum Limit interrupt */

#define FS_REACM2_OCDFEN_ENABLE   0x08000000  /* enable Open Circuit Detection Flag interrupt */
#define FS_REACM2_OCDFEN_DISABLE  0x00000000  /* disable Open Circuit Detection Flag interrupt */

#define FS_REACM2_SCDFEN_ENABLE   0x04000000  /* enable Short Circuit Detection Flag interrupt */
#define FS_REACM2_SCDFEN_DISABLE  0x00000000  /* disable Short Circuit Detection Flag interrupt */

#define FS_REACM2_TAEREN_ENABLE   0x02000000  /* enable Timer Allocation Error interrupt */
#define FS_REACM2_TAEREN_DISABLE  0x00000000  /* disable Timer Allocation Error interrupt */

#define FS_REACM2_SQER_ENABLE     0x01000000  /* enable Modulation Word Sequence Error Flag interrupt */
#define FS_REACM2_SQER_DISABLE    0x00000000  /* disable Modulation Word Sequence Error Flag interrupt */

#define FS_REACM2_RAEREN_ENABLE   0x00800000  /* enable Resource Allocation Error Flag interrupt */
#define FS_REACM2_RAEREN_DISABLE  0x00000000  /* enable Resource Allocation Error Flag interrupt */

#define FS_REACM2_DMAEN_ENABLE    0x00400000  /* enable channel direct memory access request */
#define FS_REACM2_DMAEN_DISABLE   0x00000000  /* disable channel direct memory access request */

#define FS_REACM2_CHOFF_ENABLE    0x00200000  /* enable disabling the output pin, when enaabled, the output pin state determined by DOFF bits */
#define FS_REACM2_CHOFF_DISABLE   0x00000000  /* output pin disable disabled */

#define FS_REACM2_SCDM_SINGLE_EVENT 0x00100000  /* SCDF is set if a single short detection occurs */
#define FS_REACM2_SDCM_TWO_EVENTS   0x00000000  /* two short detection events causes setting the SCDF field */

#define FS_REACM2_DOFF_C_LOW    0x00000000
#define FS_REACM2_DOFF_C_HIGH   0x00040000
#define FS_REACM2_DOFF_B_LOW    0x00000000
#define FS_REACM2_DOFF_B_HIGH   0x00020000
#define FS_REACM2_DOFF_A_LOW    0x00000000
#define FS_REACM2_DOFF_A_HIGH   0x00010000

#define FS_REACM2_BSB_C_SHARE     0x00000400  /* share the output C of the channel with subsequent cahnnel output C */
#define FS_REACM2_BSB_C_NOT_SHARE 0x00000000  /* do not share the output C to any subsequent channel output C */

#define FS_REACM2_BSB_B_SHARE     0x00000200  /* share the output B of the channel with subsequent cahnnel output B */
#define FS_REACM2_BSB_B_NOT_SHARE 0x00000000  /* do not share the output B to any subsequent channel output B */

#define FS_REACM2_BSB_A_SHARE     0x00000100  /* share the output A of the channel with subsequent cahnnel output A */
#define FS_REACM2_BSB_A_NOT_SHARE 0x00000000  /* do not share the output A to any subsequent channel output A */

#define FS_REACM2_MOD_ADDR(x)     ((x) & 0x1F)  /* address of the fist modulation word to start modulation */

/* CHSR - Channel Status Register */
#define FS_REACM2_MAXLC_CLEAR   0x00001000  /* clear the ADC Maximum Limit Detection Flag */
#define FS_REACM2_OCDFC_CLEAR   0x00000800  /* clear the Open Circuit Detection Flag */
#define FS_REACM2_SCDFC_CLEAR   0x00000400  /* clear the Short Circuit Detection Flag */
#define FS_REACM2_TAERC_CLEAR   0x00000200  /* clear the Timer Allocation Error Flag */
#define FS_REACM2_SQERC_CLEAR   0x00000100  /* clear the Modulation Word Sequence Error Flag */
#define FS_REACM2_RAERC_CLEAR   0x00000080  /* clear the Resource Allocation Error Flag */

#define FS_REACM2_CHSR_CLEAR_ALL  0x00001F80  /* clear all the flags in CHSR register */

/* CHRR - Channel Router Register */
#define FS_REACM2_ADCR(x)   (((x) & 0xF) << 16)  /* set the ADC result TAG - it defines which ADC result is used for modulation */
#define FS_REACM2_CHIR(x)   ((x) & 0xF)  /* selection of the eTPU channel that is used for modulation. */

#define FS_REACM2_ADC_TAG_0   0
#define FS_REACM2_ADC_TAG_1   1 
#define FS_REACM2_ADC_TAG_2   2
#define FS_REACM2_ADC_TAG_3   3 
#define FS_REACM2_ADC_TAG_4   4 
#define FS_REACM2_ADC_TAG_5   5 
#define FS_REACM2_ADC_TAG_6   6 
#define FS_REACM2_ADC_TAG_7   7

/* ADCMAX - ADC Maximum Limit Check */
#define FS_REACM2_ADCMAX(x)   ((x) & 0xFFFF)  /* set the Maximum Limit allowed for the ADC result */

/* RANGE_PWD - Modulation Range Pulse Width */
#define FS_REACM2_RANGE_PWD(x)    ((x) & 0xFFF)  /* set the Modulation Range Pulse Width */

/* MIN_PWD - Modulation Minimum Pulse Width */
#define FS_REACM2_MIN_PWD(x)    ((x) & 0xFFF)  /* set the Modulation Minimum Pulse Width */

/*******************************************************************************
 * Type Definitions
 *******************************************************************************/
typedef struct {
  uint32_t mcr;
  uint32_t tcr;
  uint32_t thrr;
  uint32_t pcr;
  uint32_t pscr;
  uint32_t adcmax;
  uint32_t range_pwd;
  uint32_t min_pwd;
}REACM2_INIT_T;

typedef struct {
  uint32_t chcr;
  uint32_t chrr;
}REACM2_CHANNEL_INIT_T;

typedef struct {
  uint16_t thrs;
  int8_t idx;
}THRESHOLD_T;

typedef struct {
  uint16_t sh_time;
  int8_t idx;
}SH_TIME_T;

typedef struct {
  uint16_t hold_time;
  int8_t idx;
}HOLD_TIME_T;

typedef struct {
  uint32_t loopback;
  uint32_t init_output_val;
  uint32_t mod_mode;
  uint32_t seq_mode;
  uint32_t hod_c;
  uint32_t hod_b;
  uint32_t hod_a;
  uint32_t lod_c;
  uint32_t lod_b;
  uint32_t lod_a;
  THRESHOLD_T *thrs_val_1;
  THRESHOLD_T *thrs_val_2;
  SH_TIME_T  *sh_time_val;
  HOLD_TIME_T *hold_time_val;
}MODULATION_WORD_T;

/*******************************************************************************
 * Function prototypes
 *******************************************************************************/
/* REACM2 Module Initialization */
void fs_reacm2_module_init(REACM2_INIT_T * p_reacm2_init);

/* REACM2 Channel Initialization */
void fs_reacm2_channel_init( 
  uint8_t ch_num,
  REACM2_CHANNEL_INIT_T *p_channel_init,
  uint8_t modulation_adress
);

int8_t fs_reacm2_modword_set(MODULATION_WORD_T * phases, uint8_t num_of_phases);
uint8_t fs_reacm2_threshold_set_reg ( uint16_t value, uint8_t idx);
uint8_t fs_reacm2_sh_time_set_reg ( uint16_t value, uint8_t idx);
uint8_t fs_reacm2_hold_time_set_reg ( uint16_t value, uint8_t idx);
int8_t fs_reacm2_modword_countpointer_thrs (MODULATION_WORD_T * phases, uint8_t length); 
int8_t fs_reacm2_modword_countpointer_shtime(MODULATION_WORD_T * phases, uint8_t length); 
int8_t fs_reacm2_modword_countpointer_holdtime(MODULATION_WORD_T * phases, uint8_t length); 
uint8_t fs_reacm2_modword_bank_status(uint8_t length);
uint8_t fs_reacm2_threshold_bank_status(uint8_t count);
uint8_t fs_reacm2_sh_time_bank_status(uint8_t count);
uint8_t fs_reacm2_hold_time_bank_status(uint8_t count);

void fs_reacm2_module_enable(void);
void fs_reacm2_module_disable(void);
void fs_reacm2_hold_timer_enable(void);
void fs_reacm2_hold_timer_disable(void);
void fs_reacm2_shared_timer_enable(void);
void fs_reacm2_shared_timer_disable(void);
void fs_reacm2_set_hold_timer_prs(uint16_t prs_value);
void fs_reacm2_set_shared_timer_prs(uint8_t prs_value);
void fs_reacm2_clear_adc_ovr_flag(void);
void fs_reacm2_period_generator_config(uint8_t per_presc, uint16_t period);
void fs_reacm2_period_shift_delay_set(uint16_t delay_value);
void fs_reacm2_set_modulation_range(uint16_t range, uint16_t minimum);
void fs_reacm2_threshold_router_set (uint32_t wren, uint32_t adc_tag);
void fs_reacm2_channel_enable(uint8_t ch_num, REACM2_CHANNEL_INIT_T *p_channel_init);
void fs_reacm2_channel_disable(uint8_t ch_num);
void fs_reacm2_channel_sw_start(uint8_t ch_num);
void fs_reacm2_channel_sw_stop(uint8_t ch_num);

#endif /* _REACM2_UTIL_H_ */

/*******************************************************************************
 *
 * 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
 ******************************************************************************/
/*******************************************************************************
 *
 * REVISION HISTORY:
 *
 * FILE OWNER: Marketa Venclikova [b52107]
 *
 * Revision 1.0  2015/11/11  b52107
 * Initial version.
 *
 ******************************************************************************/
