#ifndef __PORTS_H
#define __PORTS_H
/******************************************************************************
 *
 *                  PORTS PERIPHERAL LIBRARY HEADER FILE
 *
 ******************************************************************************
 * FileName:        ports.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 IO ports */
/* This list contains the SFRs with default (POR) values to be used for configuring IOports */
/* The user can modify this based on the requirement */
#define CNEN1_VALUE             0x0000
#define CNPU1_VALUE             0x0000

#define CNEN2_VALUE             0x0000
#define CNPU2_VALUE             0x0000

#define IEC0_VALUE              0x0000
#define IEC1_VALUE              0x0000
#define IEC2_VALUE              0x0000

#define IFS0_VALUE              0x0000
#define IFS1_VALUE              0x0000
#define IFS2_VALUE              0x0000

#define IPC0_VALUE              0x4444
#define IPC1_VALUE              0x4444
#define IPC2_VALUE              0x4444
#define IPC3_VALUE              0x4444
#define IPC4_VALUE              0x4444
#define IPC5_VALUE              0x4444
#define IPC6_VALUE              0x4444
#define IPC7_VALUE              0x4444
#define IPC8_VALUE              0x4444
#define IPC9_VALUE              0x4444
#define IPC10_VALUE             0x4444
#define IPC11_VALUE             0x4444

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

/* Config Bit Defines to be used for CN interrupt configuration */
#define CHANGE_INT_ON           0x08000000  /* interrupts on  */
#define CHANGE_INT_OFF          0x00000000  /* interrupts off */
#define CHANGE_INT_MASK         (~CHANGE_INT_ON)

/* Setting the priority of CN interrupt */
#define CHANGE_INT_PRI_0        0x00000000
#define CHANGE_INT_PRI_1        0x01000000
#define CHANGE_INT_PRI_2        0x02000000
#define CHANGE_INT_PRI_3        0x03000000
#define CHANGE_INT_PRI_4        0x04000000
#define CHANGE_INT_PRI_5        0x05000000
#define CHANGE_INT_PRI_6        0x06000000
#define CHANGE_INT_PRI_7        0x07000000


/* Setting the priority of External interrupt */
#define EXT_INT_PRI_0           0x0000
#define EXT_INT_PRI_1           0x0001
#define EXT_INT_PRI_2           0x0002
#define EXT_INT_PRI_3           0x0003
#define EXT_INT_PRI_4           0x0004
#define EXT_INT_PRI_5           0x0005
#define EXT_INT_PRI_6           0x0006
#define EXT_INT_PRI_7           0x0007

/* enable / disable External interrupt */
#define EXT_INT_ENABLE          0x0008
#define EXT_INT_DISABLE         0x0000
#define EXT_INT_MASK            (~EXT_INT_ENABLE)

/* External interrupts edge selection defines */
#define RISING_EDGE_INT         0x0000    /*Interrupt is set by a
                                                     positive edge */
#define FALLING_EDGE_INT        0x0010    /*Interrupt is set by a 
                                                    negative edge  */
#define EDGE_INT_MASK           (~FALLING_EDGE_INT)

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

/* Config Bit Defines to be used for CN interrupt configuration */
#define CHANGE_INT_ON           0xFFFFFFFF    /* interrupts on  */
#define CHANGE_INT_OFF          0xF7FFFFFF    /* interrupts off */

/* Setting the priority of CN interrupt */
#define CHANGE_INT_PRI_0        0xF8FFFFFF
#define CHANGE_INT_PRI_1        0xF9FFFFFF
#define CHANGE_INT_PRI_2        0xFAFFFFFF
#define CHANGE_INT_PRI_3        0xFBFFFFFF
#define CHANGE_INT_PRI_4        0xFCFFFFFF
#define CHANGE_INT_PRI_5        0xFDFFFFFF
#define CHANGE_INT_PRI_6        0xFEFFFFFF
#define CHANGE_INT_PRI_7        0xFFFFFFFF


/* Setting the priority of External interrupt */
#define EXT_INT_PRI_0           0xFFF8
#define EXT_INT_PRI_1           0xFFF9
#define EXT_INT_PRI_2           0xFFFA
#define EXT_INT_PRI_3           0xFFFB
#define EXT_INT_PRI_4           0xFFFC
#define EXT_INT_PRI_5           0xFFFD
#define EXT_INT_PRI_6           0xFFFE
#define EXT_INT_PRI_7           0xFFFF

/* enable / disable External interrupt */
#define EXT_INT_ENABLE          0xFFFF
#define EXT_INT_DISABLE         0xFFF7

/* External interrupts edge selection defines */
#define RISING_EDGE_INT         0xFFEF    /*Interrupt is set by a 
                                                    rising edge  */
#define FALLING_EDGE_INT        0xFFFF    /*Interrupt is set by a
                                                     falling edge */

#endif /* USE_AND_OR */

/* Macros to Enable CN interrupts */
#define EnableCN0               asm ("BSET CNEN1,#0")
#define EnableCN1               asm ("BSET CNEN1,#1")
#define EnableCN2               asm ("BSET CNEN1,#2")
#define EnableCN3               asm ("BSET CNEN1,#3")
#define EnableCN4               asm ("BSET CNEN1,#4")
#define EnableCN5               asm ("BSET CNEN1,#5")
#define EnableCN6               asm ("BSET CNEN1,#6")
#define EnableCN7               asm ("BSET CNEN1,#7")
#define EnableCN8               asm ("BSET CNEN1,#8")
#define EnableCN9               asm ("BSET CNEN1,#9")
#define EnableCN10              asm ("BSET CNEN1,#10")
#define EnableCN11              asm ("BSET CNEN1,#11")
#define EnableCN12              asm ("BSET CNEN1,#12")
#define EnableCN13              asm ("BSET CNEN1,#13")
#define EnableCN14              asm ("BSET CNEN1,#14")
#define EnableCN15              asm ("BSET CNEN1,#15")
#define EnableCN16              asm ("BSET CNEN2,#0")
#define EnableCN17              asm ("BSET CNEN2,#1")
#define EnableCN18              asm ("BSET CNEN2,#2")
#define EnableCN19              asm ("BSET CNEN2,#3")
#define EnableCN20              asm ("BSET CNEN2,#4")
#define EnableCN21              asm ("BSET CNEN2,#5")

/* Macros to Disable CN interrupts */
#define DisableCN0              asm ("BCLR CNEN1,#0")
#define DisableCN1              asm ("BCLR CNEN1,#1")
#define DisableCN2              asm ("BCLR CNEN1,#2")
#define DisableCN3              asm ("BCLR CNEN1,#3")
#define DisableCN4              asm ("BCLR CNEN1,#4")
#define DisableCN5              asm ("BCLR CNEN1,#5")
#define DisableCN6              asm ("BCLR CNEN1,#6")
#define DisableCN7              asm ("BCLR CNEN1,#7")
#define DisableCN8              asm ("BCLR CNEN1,#8")
#define DisableCN9              asm ("BCLR CNEN1,#9")
#define DisableCN10             asm ("BCLR CNEN1,#10")
#define DisableCN11             asm ("BCLR CNEN1,#11")
#define DisableCN12             asm ("BCLR CNEN1,#12")
#define DisableCN13             asm ("BCLR CNEN1,#13")
#define DisableCN14             asm ("BCLR CNEN1,#14")
#define DisableCN15             asm ("BCLR CNEN1,#15")
#define DisableCN16             asm ("BCLR CNEN2,#0")
#define DisableCN17             asm ("BCLR CNEN2,#1")
#define DisableCN18             asm ("BCLR CNEN2,#2")
#define DisableCN19             asm ("BCLR CNEN2,#3")
#define DisableCN20             asm ("BCLR CNEN2,#4")
#define DisableCN21             asm ("BCLR CNEN2,#5")


/* Function Prototypes */

/* ConfigCNPullups
 * Enable/ disable pull up registers
 */
void ConfigCNPullups(long int) __attribute__ ((section (".libperi")));

/* ConfigIntCN
 * Enable/Disable CN interrupt and set priority
 */
void ConfigIntCN(long int) __attribute__ ((section (".libperi")));


#ifdef _INT0

#define EnableINT0              asm ("BSET IEC0, #0")
#define DisableINT0             asm ("BCLR IEC0, #0")
#define SetPriorityInt0(priority)     (IPC0bits.INT0IP = priority)
/* ConfigINT0
 * Enable/disable INT0 interrupts,set priority and falling edge/rising edge
 */
void ConfigINT0(unsigned int) __attribute__ ((section (".libperi")));

/* CloseINT0
 * Disable INT0 interrupts, registers
 */
void CloseINT0() __attribute__ ((section (".libperi")));
#else
#warning "Does not build for _INT0"
#endif /* _INT0 */

#ifdef _INT1

#define EnableINT1              asm ("BSET IEC1, #0")
#define DisableINT1             asm ("BCLR IEC1, #0")
#define SetPriorityInt1(priority)     (IPC4bits.INT1IP = priority)

/* ConfigINT1
 * Enable/disable INT1 interrupt,set priority and falling edge/rising edge
 */
void ConfigINT1(unsigned int) __attribute__ ((section (".libperi")));

/* CloseINT1
 * Disable INT1 interrupts, registers
 */
void CloseINT1() __attribute__ ((section (".libperi")));

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

#ifdef _INT2

#define EnableINT2              asm ("BSET IEC1, #7")
#define DisableINT2             asm ("BCLR IEC1, #7")
#define SetPriorityInt2(priority)     (IPC5bits.INT2IP = priority)

/* ConfigINT2
 * Enable/disable INT2 interrupt,set priority and falling edge/rising edge
 */
void ConfigINT2(unsigned int) __attribute__ ((section (".libperi")));

/* CloseINT2
 * Disable INT2 interrupts, registers
 */
void CloseINT2() __attribute__ ((section (".libperi")));

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

#ifdef _INT3

#define DisableINT3             asm ("BCLR IEC2, #4")
#define EnableINT3              asm ("BSET IEC2, #4")
#define SetPriorityInt3(priority)     (IPC9bits.INT3IP = priority)

/* ConfigINT3
 * Enable/disable INT3 interrupt,set priority and falling edge/rising edge
 */
void ConfigINT3(unsigned int) __attribute__ ((section (".libperi")));

/* CloseINT3
 * Disable INT3 interrupts, registers
 */
void CloseINT3() __attribute__ ((section (".libperi")));
#else
#warning "Does not build for _INT3"
#endif /* _INT3 */

#ifdef _INT4

#define EnableINT4              asm ("BSET IEC2, #5")
#define DisableINT4             asm ("BCLR IEC2, #5")
#define SetPriorityInt4(priority)     (IPC9bits.INT4IP = priority)

/* ConfigINT4
 * Enable/disable INT4 interrupt,set priority and falling edge/rising edge
 */
void ConfigINT4(unsigned int) __attribute__ ((section (".libperi")));

/* CloseINT4
 * Disable INT4 interrupts, registers
 */
void CloseINT4() __attribute__ ((section (".libperi")));

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


// PORT macros and defines

#define IOPORT_BIT_0                        0x0001
#define IOPORT_BIT_1                        0x0002
#define IOPORT_BIT_2                        0x0004
#define IOPORT_BIT_3                        0x0008
#define IOPORT_BIT_4                        0x0010
#define IOPORT_BIT_5                        0x0020
#define IOPORT_BIT_6                        0x0040
#define IOPORT_BIT_7                        0x0080
#define IOPORT_BIT_8                        0x0100
#define IOPORT_BIT_9                        0x0200
#define IOPORT_BIT_10                       0x0400
#define IOPORT_BIT_11                       0x0800
#define IOPORT_BIT_12                       0x1000
#define IOPORT_BIT_13                       0x2000
#define IOPORT_BIT_14                       0x4000
#define IOPORT_BIT_15                       0x8000

// PORTA

#if defined _PORTA
#define mPORTAConfig(tris)                  { TRISA = (unsigned int)tris;   }
#define mPORTARead()                        (PORTA)
#define mPORTAWrite(lat)                    { LATA = (unsigned int)lat;}
#define mPORTAReadLatch()                   (LATA)
#define mPORTAGetConfig()                   (TRISA)
#define mPORTAReadBit(_bit)                 (PORTA & (unsigned int)_bit)
#define mPORTAReadLatchBit(_bit)            (LATA & (unsigned int)_bit)
#define mPORTAReadConfigBit(_bit)           (TRISA & (unsigned int)_bit)
#define mPORTAOutputConfig(outputs)         { TRISA &= ~(unsigned int)outputs;  }
#define mPORTAInputConfig(inputs)           { TRISA |= (unsigned int)inputs;    }
#define mPORTASetBits(_bits)                { LATA |= (unsigned int)_bits;      }
#define mPORTAClearBits(_bits)              { LATA &= ~(unsigned int)_bits;     }
#define mPORTAToggleBits(_bits)             { LATA ^= (unsigned int)_bits;      }
#define mPORTACloseAll()                    { TRISA = 0xFFFF; LATA = 0;         }
#define mPORTACloseBits(_bits)              { TRISA |= (unsigned int)_bits; LATA &= ~(unsigned int)_bits;     }

#else
#warning "Does not build for PORTA"
#endif  //end PORTA

#if defined _PORTB
#define mPORTBConfig(tris)                  { TRISB = (unsigned int)tris;   }
#define mPORTBRead()                        (PORTB)
#define mPORTBWrite(lat)                    { LATB = (unsigned int)lat;}
#define mPORTBReadLatch()                   (LATB)
#define mPORTBGetConfig()                   (TRISB)
#define mPORTBReadBit(_bit)                 (PORTB & (unsigned int)_bit)
#define mPORTBReadLatchBit(_bit)            (LATB & (unsigned int)_bit)
#define mPORTBReadConfigBit(_bit)           (TRISB & (unsigned int)_bit)
#define mPORTBOutputConfig(outputs)         { TRISB &= ~(unsigned int)outputs;  }
#define mPORTBInputConfig(inputs)           { TRISB |= (unsigned int)inputs;    }
#define mPORTBSetBits(_bits)                { LATB |= (unsigned int)_bits;      }
#define mPORTBClearBits(_bits)              { LATB &= ~(unsigned int)_bits;     }
#define mPORTBToggleBits(_bits)             { LATB ^= (unsigned int)_bits;      }
#define mPORTBCloseAll()                    { TRISB = 0xFFFF; LATB = 0;         }
#define mPORTBCloseBits(_bits)              { TRISB |= (unsigned int)_bits; LATB &= ~(unsigned int)_bits;     }

#else
#warning "Does not build for PORTB"
#endif  //end PORTB

#if defined _PORTC
#define mPORTCConfig(tris)                  { TRISC = (unsigned int)tris;   }
#define mPORTCRead()                        (PORTC)
#define mPORTCWrite(lat)                    { LATC = (unsigned int)lat;}
#define mPORTCReadLatch()                   (LATC)
#define mPORTCGetConfig()                   (TRISC)
#define mPORTCReadBit(_bit)                 (PORTC & (unsigned int)_bit)
#define mPORTCReadLatchBit(_bit)            (LATC & (unsigned int)_bit)
#define mPORTCReadConfigBit(_bit)           (TRISC & (unsigned int)_bit)
#define mPORTCOutputConfig(outputs)         { TRISC &= ~(unsigned int)outputs;  }
#define mPORTCInputConfig(inputs)           { TRISC |= (unsigned int)inputs;    }
#define mPORTCSetBits(_bits)                { LATC |= (unsigned int)_bits;      }
#define mPORTCClearBits(_bits)              { LATC &= ~(unsigned int)_bits;     }
#define mPORTCToggleBits(_bits)             { LATC ^= (unsigned int)_bits;      }
#define mPORTCCloseAll()                    { TRISC = 0xFFFF; LATC = 0;         }
#define mPORTCCloseBits(_bits)              { TRISC |= (unsigned int)_bits; LATC &= ~(unsigned int)_bits;     }

#else
#warning "Does not build for PORTC"
#endif  //end PORTC

#if defined _PORTD
#define mPORTDConfig(tris)                  { TRISD = (unsigned int)tris;   }
#define mPORTDRead()                        (PORTD)
#define mPORTDWrite(lat)                    { LATD = (unsigned int)lat;}
#define mPORTDReadLatch()                   (LATD)
#define mPORTDGetConfig()                   (TRISD)
#define mPORTDReadBit(_bit)                 (PORTD & (unsigned int)_bit)
#define mPORTDReadLatchBit(_bit)            (LATD & (unsigned int)_bit)
#define mPORTDReadConfigBit(_bit)           (TRISD & (unsigned int)_bit)
#define mPORTDOutputConfig(outputs)         { TRISD &= ~(unsigned int)outputs;  }
#define mPORTDInputConfig(inputs)           { TRISD |= (unsigned int)inputs;    }
#define mPORTDSetBits(_bits)                { LATD |= (unsigned int)_bits;      }
#define mPORTDClearBits(_bits)              { LATD &= ~(unsigned int)_bits;     }
#define mPORTDToggleBits(_bits)             { LATD ^= (unsigned int)_bits;      }
#define mPORTDCloseAll()                    { TRISD = 0xFFFF; LATD = 0;         }
#define mPORTDCloseBits(_bits)              { TRISD |= (unsigned int)_bits; LATD &= ~(unsigned int)_bits;     }

#else
#warning "Does not build for PORTD"
#endif  //end PORTD

#if defined _PORTE
#define mPORTEConfig(tris)                  { TRISE = (unsigned int)tris;   }
#define mPORTERead()                        (PORTE)
#define mPORTEWrite(lat)                    { LATE = (unsigned int)lat;}
#define mPORTEReadLatch()                   (LATE)
#define mPORTEGetConfig()                   (TRISE)
#define mPORTEReadBit(_bit)                 (PORTE & (unsigned int)_bit)
#define mPORTEReadLatchBit(_bit)            (LATE & (unsigned int)_bit)
#define mPORTEReadConfigBit(_bit)           (TRISE & (unsigned int)_bit)
#define mPORTEOutputConfig(outputs)         { TRISE &= ~(unsigned int)outputs;  }
#define mPORTEInputConfig(inputs)           { TRISE |= (unsigned int)inputs;    }
#define mPORTESetBits(_bits)                { LATE |= (unsigned int)_bits;      }
#define mPORTEClearBits(_bits)              { LATE &= ~(unsigned int)_bits;     }
#define mPORTEToggleBits(_bits)             { LATE ^= (unsigned int)_bits;      }
#define mPORTECloseAll()                    { TRISE = 0xFFFF; LATE = 0;         }
#define mPORTECloseBits(_bits)              { TRISE |= (unsigned int)_bits; LATE &= ~(unsigned int)_bits;     }

#else
#warning "Does not build for PORTE"
#endif  //end PORTE

#if defined _PORTF
#define mPORTFConfig(tris)                  { TRISF = (unsigned int)tris;   }
#define mPORTFRead()                        (PORTF)
#define mPORTFWrite(lat)                    { LATF = (unsigned int)lat;}
#define mPORTFReadLatch()                   (LATF)
#define mPORTFGetConfig()                   (TRISF)
#define mPORTFReadBit(_bit)                 (PORTF & (unsigned int)_bit)
#define mPORTFReadLatchBit(_bit)            (LATF & (unsigned int)_bit)
#define mPORTFReadConfigBit(_bit)           (TRISF & (unsigned int)_bit)
#define mPORTFOutputConfig(outputs)         { TRISF &= ~(unsigned int)outputs;  }
#define mPORTFInputConfig(inputs)           { TRISF |= (unsigned int)inputs;    }
#define mPORTFSetBits(_bits)                { LATF |= (unsigned int)_bits;      }
#define mPORTFClearBits(_bits)              { LATF &= ~(unsigned int)_bits;     }
#define mPORTFToggleBits(_bits)             { LATF ^= (unsigned int)_bits;      }
#define mPORTFCloseAll()                    { TRISF = 0xFFFF; LATF = 0;         }
#define mPORTFCloseBits(_bits)              { TRISF |= (unsigned int)_bits; LATF &= ~(unsigned int)_bits;     }

#else
#warning "Does not build for PORTF"
#endif  //end PORTF

#endif
