#ifndef I2C_H /*I2C_H  */
#define I2C_H
/******************************************************************************
 *
 *                  I2C PERIPHERAL LIBRARY HEADER FILE
 *
 ******************************************************************************
 * FileName:        i2c.h
 * Dependencies:    See include below
 * Processor:       PIC24
 * Compiler:        MPLAB C30
 * Company:         Microchip Technology, Inc.
 *
 * Software License Agreement
 * The software supplied herewith by Microchip Technology Incorporated
 * (the “Company”) for its PICmicro® Microcontroller is intended and
 * supplied to you, the Company’s customer, for use solely and
 * exclusively on Microchip PICmicro Microcontroller products. The
 * software is owned by the Company and/or its supplier, and is
 * protected under applicable copyright laws. All rights are reserved.
 * Any use in violation of the foregoing restrictions may subject the
 * user to criminal sanctions under applicable laws, as well as to
 * civil liability for the breach of the terms and conditions of this
 * license.
 *
 * THIS SOFTWARE IS PROVIDED IN AN “AS IS” CONDITION. NO WARRANTIES,
 * WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING, BUT NOT LIMITED
 * TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
 * PARTICULAR PURPOSE APPLY TO THIS SOFTWARE. THE COMPANY SHALL NOT,
 * IN ANY CIRCUMSTANCES, BE LIABLE FOR SPECIAL, INCIDENTAL OR
 * CONSEQUENTIAL DAMAGES, FOR ANY REASON WHATSOEVER.
 *
 *****************************************************************************/
#include "Generic.h"
#include "PIC24F_periph_features.h"

/* List of SFRs for I2C1 module */
/* This list contains the SFRs with default (POR) values to be used for configuring I2C1 module */
/* The user can modify this based on the requirement */
#define I2C1RCV_VALUE               0x0000
#define I2C1TRN_VALUE               0x00FF
#define I2C1BRG_VALUE               0x0000
#define I2C1CON_VALUE               0x0000
#define I2C1STAT_VALUE              0x0000
#define I2C1ADD_VALUE               0x0000

/* List of SFRs for I2C2 module */
/* This list contains the SFRs with default (POR) values to be used for configuring I2C1 module */
/* The user can modify this based on the requirement */
#define I2C2RCV_VALUE               0x0000
#define I2C2TRN_VALUE               0x00FF
#define I2C2BRG_VALUE               0x0000
#define I2C2CON_VALUE               0x0000
#define I2C2STAT_VALUE              0x0000
#define I2C2ADD_VALUE               0x0000

#ifdef USE_AND_OR /* Format for AND_OR based bit setting */

// I2CxCON Register Configuration Bit Definitions

#define I2C_ON           0x8000 /*I2C module enabled */ 
#define I2C_OFF          0x0000 /*I2C module disabled */
#define I2C_EN_DIS_MASK  (~I2C_EN)

#define I2C_IDLE_STOP    0x2000 /*stop I2C module in Idle mode */    
#define I2C_IDLE_CON     0x0000 /*continue I2C module in Idle mode */
#define I2C_IDLE_MASK    (~I2C_IDLE_CON)

#define I2C_CLK_REL      0x1000 /*release clock */ 
#define I2C_CLK_HLD     0x0000 /*hold clock  */   
#define I2C_CLK_MASK     (~I2C_CLK_REL)

#define I2C_IPMI_EN      0x0800 /*IPMI mode enabled */     
#define I2C_IPMI_DIS     0x0000 /*IPMI mode not enabled */ 
#define I2C_IPMI_MASK    (~I2C_IPMI_EN)

#define I2C_10BIT_ADD    0x0400 /*I2CADD is 10-bit address */
#define I2C_7BIT_ADD     0x0000 /*I2CADD is 7-bit address */ 
#define I2C_7BIT_MASK    (~I2C_10BIT_ADD)

#define I2C_SLW_DIS       0x0200 /*Disable Slew Rate Control for 100KHz */
#define I2C_SLW_EN        0x0000 /*Enable Slew Rate Control for 400KHz */ 
#define I2C_SLW_MASK     (~I2C_SLW_EN)

#define I2C_SM_EN        0x0100 /*Enable SM bus specification */  
#define I2C_SM_DIS       0x0000 /*Disable SM bus specification */ 
#define I2C_SM_MASK      (~I2C_SM_EN)

#define I2C_GCALL_EN     0x0080 /*Enable Interrupt when General call address is received. */
#define I2C_GCALL_DIS    0x0000 /*Disable General call address. */                          
#define I2C_GCALL_MASK   (~I2C_GC_EN)

#define I2C_STR_EN       0x0040 /*Enable clock stretching */ 
#define I2C_STR_DIS      0x0000 /*disable clock stretching */
#define I2C_STR_MASK     (~I2C_STR_EN)

#define I2C_NACK         0x0020 /*Transmit 0 to send ACK as acknowledge */ 
#define I2C_ACK          0x0000 /*Transmit 1 to send NACK as acknowledge*/ 
#define I2C_ACK_MASK     (~I2C_NACK)

#define I2C_ACK_EN       0x0010 /*Initiate Acknowledge sequence */
#define I2C_ACK_DIS      0x0000 /*Acknowledge condition Idle */   
#define I2C_TX_ACK_MASK  (~I2C_ACK_EN)

#define I2C_RCV_EN       0x0008 /*Enable receive mode */              
#define I2C_RCV_DIS      0x0000 /*Receive sequence not in progress */ 
#define I2C_RCV_MASK     (~I2C_RCV_EN)

#define I2C_STOP_EN      0x0004  /*Initiate Stop sequence */
#define I2C_STOP_DIS     0x0000	 /*Stop condition Idle */   
#define I2C_STOP_MASK    (~I2C_STOP_EN)

#define I2C_RESTART_EN   0x0002 /*Initiate Restart sequence */
#define I2C_RESTART_DIS  0x0000 /*Start condition Idle */     
#define I2C_RESTART_MASK (~I2C_RESTART_EN)

#define I2C_START_EN     0x0001 /*Initiate Start sequence */
#define I2C_START_DIS    0x0000 /*Start condition Idle */   
#define I2C_START_MASK   (~I2C_START_EN)

// Slave I2C Interrupt Priority
#define SI2C_INT_PRI_0  0x0000
#define SI2C_INT_PRI_1  0x0001
#define SI2C_INT_PRI_2  0x0002
#define SI2C_INT_PRI_3  0x0003
#define SI2C_INT_PRI_4  0x0004
#define SI2C_INT_PRI_5  0x0005
#define SI2C_INT_PRI_6  0x0006
#define SI2C_INT_PRI_7  0x0007
#define SI2C_SRC_DIS    SI2C_INT_PRI_0

// Slave I2C Interrupt Enable/Disable
#define SI2C_INT_ON     0x0008
#define SI2C_INT_OFF    0x0000

// Master I2C Interrupt Priority
#define MI2C_INT_PRI_0  0x0000
#define MI2C_INT_PRI_1  0x0010
#define MI2C_INT_PRI_2  0x0020
#define MI2C_INT_PRI_3  0x0030
#define MI2C_INT_PRI_4  0x0040
#define MI2C_INT_PRI_5  0x0050
#define MI2C_INT_PRI_6  0x0060
#define MI2C_INT_PRI_7  0x0070
#define MI2C_SRC_DIS    MI2C_INT_PRI_0

// Master I2C Interrupt Enable/Disable
#define MI2C_INT_ON     0x0080
#define MI2C_INT_OFF    0x0000

#else /* Format for backward compatibility (AND based bit setting). */

/* I2CCON register Configuration bit definitions */
#define I2C_ON                    0xFFFF   /*I2C module enabled */ 
#define I2C_OFF                   0x7FFF   /*I2C module disabled */ 

#define I2C_IDLE_STOP              0xFFFF  /*stop I2C module in Idle mode */
#define I2C_IDLE_CON               0xDFFF  /*continue I2C module in Idle mode */

#define I2C_CLK_REL                0xFFFF  /*release clock */ 
#define I2C_CLK_HLD                0xEFFF  /*hold clock  */

#define I2C_IPMI_EN                0xFFFF  /*IPMI mode enabled */
#define I2C_IPMI_DIS               0xF7FF  /*IPMI mode not enabled */

#define I2C_10BIT_ADD              0xFFFF  /*I2CADD is 10-bit address */
#define I2C_7BIT_ADD               0xFBFF  /*I2CADD is 7-bit address */

#define I2C_SLW_DIS                0xFFFF  /*Disable Slew Rate Control for 100KHz */
#define I2C_SLW_EN                 0xFDFF  /*Enable Slew Rate Control for 400KHz */

#define I2C_SM_EN                  0xFFFF  /*Enable SM bus specification */
#define I2C_SM_DIS                 0xFEFF  /*Disable SM bus specification */

#define I2C_GCALL_EN               0xFFFF  /*Enable Interrupt when General call address is received. */
#define I2C_GCALL_DIS              0xFF7F  /*Disable General call address. */

#define I2C_STR_EN                 0xFFFF  /*Enable clock stretching */
#define I2C_STR_DIS                0xFFBF  /*disable clock stretching */

#define I2C_ACK                    0xFFDF  /*Transmit 0 to send ACK as acknowledge */
#define I2C_NACK                   0xFFFF  /*Transmit 1 to send NACK as acknowledge*/

#define I2C_ACK_EN                 0xFFFF  /*Initiate Acknowledge sequence */
#define I2C_ACK_DIS                0xFFEF  /*Acknowledge condition Idle */

#define I2C_RCV_EN                 0xFFFF  /*Enable receive mode */
#define I2C_RCV_DIS                0xFFF7  /*Receive sequence not in progress */

#define I2C_STOP_EN                0xFFFF  /*Initiate Stop sequence */
#define I2C_STOP_DIS               0xFFFB  /*Stop condition Idle */

#define I2C_RESTART_EN             0xFFFF  /*Initiate Restart sequence */
#define I2C_RESTART_DIS            0xFFFD  /*Start condition Idle */

#define I2C_START_EN               0xFFFF  /*Initiate Start sequence */
#define I2C_START_DIS              0xFFFE  /*Start condition Idle */


/* Priority for Slave I2C1 Interrupt */

#define SI2C_INT_PRI_7             0xFFFF
#define SI2C_INT_PRI_6             0xFFFE
#define SI2C_INT_PRI_5             0xFFFD
#define SI2C_INT_PRI_4             0xFFFC
#define SI2C_INT_PRI_3             0xFFFB
#define SI2C_INT_PRI_2             0xFFFA
#define SI2C_INT_PRI_1             0xFFF9
#define SI2C_INT_PRI_0             0xFFF8

/* Slave I2C1 Interrupt Enable/Disable */

#define SI2C_INT_ON                0xFFFF
#define SI2C_INT_OFF               0xFFF7

/* Priority for Master I2C1 Interrupt */

#define MI2C_INT_PRI_7             0xFFFF
#define MI2C_INT_PRI_6             0xFFEF
#define MI2C_INT_PRI_5             0xFFDF
#define MI2C_INT_PRI_4             0xFFCF
#define MI2C_INT_PRI_3             0xFFBF
#define MI2C_INT_PRI_2             0xFFAF
#define MI2C_INT_PRI_1             0xFF9F
#define MI2C_INT_PRI_0             0xFF8F

/* Master I2C1 Interrupt Enable/Disable */

#define MI2C_INT_ON                0xFFFF
#define MI2C_INT_OFF               0xFF7F

#endif /* USE_AND_OR */

#ifdef _I2C_V2_1
/* Macros to  Enable/Disable interrupts and set Interrupt priority of SI2C1 module*/
#define EnableIntSI2C1                    asm("BSET IEC1,#0")
#define DisableIntSI2C1                   asm("BCLR IEC1,#0")
#define SetPriorityIntSI2C1(priority)     (IPC4bits.SI2C1IP = priority)

/* Macros to  Enable/Disable interrupts and set Interrupt priority of MI2C1 module*/
#define EnableIntMI2C1                    asm("BSET IEC1,#1")
#define DisableIntMI2C1                   asm("BCLR IEC1,#1")
#define SetPriorityIntMI2C1(priority)     (IPC4bits.MI2C1IP = priority)


/* I2C1 module Converter Function Prototypes */

void AckI2C1(void) __attribute__ ((section (".libperi")));

void CloseI2C1(void) __attribute__ ((section (".libperi")));

void ConfigIntI2C1(unsigned int) __attribute__ ((section (".libperi")));

char DataRdyI2C1(void) __attribute__ ((section (".libperi")));

#define SlavegetcI2C1 SlaveReadI2C1

#define MastergetcI2C1 MasterReadI2C1

unsigned int SlavegetsI2C1(unsigned char *, unsigned int) __attribute__ ((section (".libperi")));

unsigned int MastergetsI2C1(unsigned int length, unsigned char * rdptr, unsigned int i2c_data_wait) __attribute__ ((section (".libperi")));

void IdleI2C1(void) __attribute__ ((section (".libperi")));

void NotAckI2C1(void) __attribute__ ((section (".libperi")));

void OpenI2C1(unsigned int,unsigned int) __attribute__ ((section (".libperi")));

char  MasterputsI2C1(unsigned char *) __attribute__ ((section (".libperi")));

unsigned int SlaveputsI2C1(unsigned char *) __attribute__ ((section (".libperi")));

#define SlaveputcI2C1 SlaveWriteI2C1

#define MasterputcI2C1 MasterWriteI2C1

unsigned char SlaveReadI2C1(void) __attribute__ ((section (".libperi")));

unsigned char MasterReadI2C1(void) __attribute__ ((section (".libperi")));

void SlaveWriteI2C1(unsigned char) __attribute__ ((section (".libperi")));

char MasterWriteI2C1(unsigned char) __attribute__ ((section (".libperi")));

void RestartI2C1(void) __attribute__ ((section (".libperi")));

void StartI2C1(void) __attribute__ ((section (".libperi")));

void StopI2C1(void) __attribute__ ((section (".libperi")));


/***********************************************************************
*    Function Name:  SlaveWaitForIntrI2C1
*    Description:    This routine will wait Slave interrupt request and 
*                    then clear interrupt Flag.
*    Parameters:     None
*    Return Value:   None
************************************************************************/
void SlaveWaitForIntrI2C1(void) __attribute__ ((section (".libperi")));

/***********************************************************************
*    Function Name:  MasterWaitForIntrI2C1
*    Description:    This routine will wait for Master interrupt request 
*                    and then clear interrupt Flag.
*    Parameters:     None
*    Return Value:   None
************************************************************************/
void MasterWaitForIntrI2C1(void) __attribute__ ((section (".libperi")));

/***********************************************************************
*    Macro: mI2C1_MasterClearIntr
*    Description: This macro clears the I2C1 Master interrupt flag
************************************************************************/
#define mI2C1_MasterClearIntr()   (IFS1bits.MI2C1IF = 0)

/***********************************************************************
*    Macro: mI2C1_SlaveClearIntr
*    Description: This macro clears the I2C1 Slave interrupt flag
************************************************************************/
#define mI2C1_SlaveClearIntr()   (IFS1bits.SI2C1IF = 0)

#else
#warning "Does not build for _I2C_V2_1"
#endif /* _I2C_V2_1 */

#ifdef _I2C_V2_2

/* I2C2 module Converter Function Prototypes */

/* Macros to  Enable/Disable interrupts and set Interrupt priority of SI2C2 module*/
#define EnableIntSI2C2                    asm("BSET IEC3,#1")
#define DisableIntSI2C2                   asm("BCLR IEC3,#1")
#define SetPriorityIntSI2C2(priority)     (IPC12bits.SI2C2IP = priority)

/* Macros to  Enable/Disable interrupts and set Interrupt priority of MI2C1 module*/
#define EnableIntMI2C2                    asm("BSET IEC3,#2")
#define DisableIntMI2C2                   asm("BCLR IEC3,#2")
#define SetPriorityIntMI2C2(priority)     (IPC12bits.MI2C2IP = priority)


void AckI2C2(void) __attribute__ ((section (".libperi")));

void CloseI2C2(void) __attribute__ ((section (".libperi")));

void ConfigIntI2C2(unsigned int) __attribute__ ((section (".libperi")));

char DataRdyI2C2(void) __attribute__ ((section (".libperi")));

#define SlavegetcI2C2 SlaveReadI2C2

#define MastergetcI2C2 MasterReadI2C2

unsigned int SlavegetsI2C2(unsigned char *, unsigned int) __attribute__ ((section (".libperi")));

unsigned int MastergetsI2C2(unsigned int length, unsigned char * rdptr, unsigned int i2c_data_wait) __attribute__ ((section (".libperi")));

void IdleI2C2(void) __attribute__ ((section (".libperi")));

void NotAckI2C2(void) __attribute__ ((section (".libperi")));

void OpenI2C2(unsigned int,unsigned int) __attribute__ ((section (".libperi")));

char MasterputsI2C2(unsigned char *) __attribute__ ((section (".libperi")));

unsigned int SlaveputsI2C2(unsigned char *) __attribute__ ((section (".libperi")));

#define SlaveputcI2C2 SlaveWriteI2C2

#define MasterputcI2C2 MasterWriteI2C2

unsigned char SlaveReadI2C2(void) __attribute__ ((section (".libperi")));

unsigned char MasterReadI2C2(void) __attribute__ ((section (".libperi")));

void SlaveWriteI2C2(unsigned char) __attribute__ ((section (".libperi")));

char MasterWriteI2C2(unsigned char) __attribute__ ((section (".libperi")));

void RestartI2C2(void) __attribute__ ((section (".libperi")));

void StartI2C2(void) __attribute__ ((section (".libperi")));

void StopI2C2(void) __attribute__ ((section (".libperi")));

/***********************************************************************
*    Function Name:  SlaveWaitForIntrI2C2
*    Description:    This routine will wait Slave interrupt request and 
*                    then clear interrupt Flag.
*    Parameters:     None
*    Return Value:   None
************************************************************************/
void SlaveWaitForIntrI2C2(void) __attribute__ ((section (".libperi")));

/***********************************************************************
*    Function Name:  MasterWaitForIntrI2C2
*    Description:    This routine will wait for Master interrupt request 
*                    and then clear interrupt Flag.
*    Parameters:     None
*    Return Value:   None
************************************************************************/
void MasterWaitForIntrI2C2(void) __attribute__ ((section (".libperi")));

/***********************************************************************
*    Macro: mI2C2_MasterClearIntr
*    Description: This macro clears the I2C2 Master interrupt flag
************************************************************************/
#define mI2C2_MasterClearIntr()   (IFS3bits.MI2C2IF = 0)

/***********************************************************************
*    Macro: mI2C2_SlaveClearIntr
*    Description: This macro clears the I2C2 Slave interrupt flag
************************************************************************/
#define mI2C2_SlaveClearIntr()   (IFS3bits.SI2C2IF = 0)

#else
#warning "Does not build for _I2C_V2_2"
#endif /* _I2C_V2_2 */

#endif /*I2C_H  */
