/*******************************************************************************
  GPIO PLIB

  Company:
    Microchip Technology Inc.

  File Name:
    plib_gpio.h UUUUUUUUU

  Summary:
    GPIO PLIB Header File

  Description:
    This library provides an interface to control and interact with Parallel
    Input/Output controller (GPIO) module.

*******************************************************************************/

/*******************************************************************************
* Copyright (C) 2019 Microchip Technology Inc. and its subsidiaries.
*
* Subject to your compliance with these terms, you may use Microchip software
* and any derivatives exclusively with Microchip products. It is your
* responsibility to comply with third party license terms applicable to your
* use of third party software (including open source software) that may
* accompany Microchip software.
*
* THIS SOFTWARE IS SUPPLIED BY MICROCHIP "AS IS". NO WARRANTIES, WHETHER
* EXPRESS, IMPLIED OR STATUTORY, APPLY TO THIS SOFTWARE, INCLUDING ANY IMPLIED
* WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY, AND FITNESS FOR A
* PARTICULAR PURPOSE.
*
* IN NO EVENT WILL MICROCHIP BE LIABLE FOR ANY INDIRECT, SPECIAL, PUNITIVE,
* INCIDENTAL OR CONSEQUENTIAL LOSS, DAMAGE, COST OR EXPENSE OF ANY KIND
* WHATSOEVER RELATED TO THE SOFTWARE, HOWEVER CAUSED, EVEN IF MICROCHIP HAS
* BEEN ADVISED OF THE POSSIBILITY OR THE DAMAGES ARE FORESEEABLE. TO THE
* FULLEST EXTENT ALLOWED BY LAW, MICROCHIP'S TOTAL LIABILITY ON ALL CLAIMS IN
* ANY WAY RELATED TO THIS SOFTWARE WILL NOT EXCEED THE AMOUNT OF FEES, IF ANY,
* THAT YOU HAVE PAID DIRECTLY TO MICROCHIP FOR THIS SOFTWARE.
*******************************************************************************/

#ifndef PLIB_GPIO_H
#define PLIB_GPIO_H

#include <device.h>
#include <stdint.h>
#include <stdbool.h>
#include <stddef.h>

// DOM-IGNORE-BEGIN
#ifdef __cplusplus  // Provide C++ Compatibility

    extern "C" {

#endif
// DOM-IGNORE-END

// *****************************************************************************
// *****************************************************************************
// Section: Data types and constants
// *****************************************************************************
// *****************************************************************************


/*** Macros for SPI_SCK2 pin ***/
#define SPI_SCK2_Get()               ((PORTA >> 7) & 0x1U)
#define SPI_SCK2_PIN                  GPIO_PIN_RA7

/*** Macros for SPI_SS2 pin ***/
#define SPI_SS2_Set()               (LATBSET = (1U<<14))
#define SPI_SS2_Clear()             (LATBCLR = (1U<<14))
#define SPI_SS2_Toggle()            (LATBINV= (1U<<14))
#define SPI_SS2_OutputEnable()      (TRISBCLR = (1U<<14))
#define SPI_SS2_InputEnable()       (TRISBSET = (1U<<14))
#define SPI_SS2_Get()               ((PORTB >> 14) & 0x1U)
#define SPI_SS2_PIN                  GPIO_PIN_RB14

/*** Macros for SPI_SDO2 pin ***/
#define SPI_SDO2_Get()               ((PORTB >> 15) & 0x1U)
#define SPI_SDO2_PIN                  GPIO_PIN_RB15

/*** Macros for LCD_E pin ***/
#define LCD_E_Set()               (LATASET = (1U<<12))
#define LCD_E_Clear()             (LATACLR = (1U<<12))
#define LCD_E_Toggle()            (LATAINV= (1U<<12))
#define LCD_E_OutputEnable()      (TRISACLR = (1U<<12))
#define LCD_E_InputEnable()       (TRISASET = (1U<<12))
#define LCD_E_Get()               ((PORTA >> 12) & 0x1U)
#define LCD_E_PIN                  GPIO_PIN_RA12

/*** Macros for LCD_RW pin ***/
#define LCD_RW_Set()               (LATASET = (1U<<11))
#define LCD_RW_Clear()             (LATACLR = (1U<<11))
#define LCD_RW_Toggle()            (LATAINV= (1U<<11))
#define LCD_RW_OutputEnable()      (TRISACLR = (1U<<11))
#define LCD_RW_InputEnable()       (TRISASET = (1U<<11))
#define LCD_RW_Get()               ((PORTA >> 11) & 0x1U)
#define LCD_RW_PIN                  GPIO_PIN_RA11

/*** Macros for Voltage_Sense pin ***/
#define Voltage_Sense_Get()               ((PORTA >> 0) & 0x1U)
#define Voltage_Sense_PIN                  GPIO_PIN_RA0

/*** Macros for Current_Sense pin ***/
#define Current_Sense_Get()               ((PORTA >> 1) & 0x1U)
#define Current_Sense_PIN                  GPIO_PIN_RA1

/*** Macros for Reference_Neg pin ***/
#define Reference_Neg_Get()               ((PORTB >> 0) & 0x1U)
#define Reference_Neg_PIN                  GPIO_PIN_RB0

/*** Macros for Current_Sense_High_Gain pin ***/
#define Current_Sense_High_Gain_Get()               ((PORTB >> 1) & 0x1U)
#define Current_Sense_High_Gain_PIN                  GPIO_PIN_RB1

/*** Macros for Resistance_Hi_Gain pin ***/
#define Resistance_Hi_Gain_Get()               ((PORTC >> 0) & 0x1U)
#define Resistance_Hi_Gain_PIN                  GPIO_PIN_RC0

/*** Macros for FF_D pin ***/
#define FF_D_Set()               (LATCSET = (1U<<11))
#define FF_D_Clear()             (LATCCLR = (1U<<11))
#define FF_D_Toggle()            (LATCINV= (1U<<11))
#define FF_D_OutputEnable()      (TRISCCLR = (1U<<11))
#define FF_D_InputEnable()       (TRISCSET = (1U<<11))
#define FF_D_Get()               ((PORTC >> 11) & 0x1U)
#define FF_D_PIN                  GPIO_PIN_RC11

/*** Macros for START pin ***/
#define START_Set()               (LATASET = (1U<<8))
#define START_Clear()             (LATACLR = (1U<<8))
#define START_Toggle()            (LATAINV= (1U<<8))
#define START_OutputEnable()      (TRISACLR = (1U<<8))
#define START_InputEnable()       (TRISASET = (1U<<8))
#define START_Get()               ((PORTA >> 8) & 0x1U)
#define START_PIN                  GPIO_PIN_RA8

/*** Macros for SPI_SDI1 pin ***/
#define SPI_SDI1_Get()               ((PORTB >> 4) & 0x1U)
#define SPI_SDI1_PIN                  GPIO_PIN_RB4

/*** Macros for Resistance_Lo_Gain pin ***/
#define Resistance_Lo_Gain_Get()               ((PORTA >> 4) & 0x1U)
#define Resistance_Lo_Gain_PIN                  GPIO_PIN_RA4

/*** Macros for DUT_Discharge pin ***/
#define DUT_Discharge_Set()               (LATDSET = (1U<<8))
#define DUT_Discharge_Clear()             (LATDCLR = (1U<<8))
#define DUT_Discharge_Toggle()            (LATDINV= (1U<<8))
#define DUT_Discharge_OutputEnable()      (TRISDCLR = (1U<<8))
#define DUT_Discharge_InputEnable()       (TRISDSET = (1U<<8))
#define DUT_Discharge_Get()               ((PORTD >> 8) & 0x1U)
#define DUT_Discharge_PIN                  GPIO_PIN_RD8

/*** Macros for SPI_SDI2 pin ***/
#define SPI_SDI2_Get()               ((PORTB >> 5) & 0x1U)
#define SPI_SDI2_PIN                  GPIO_PIN_RB5

/*** Macros for DOWN pin ***/
#define DOWN_Set()               (LATBSET = (1U<<6))
#define DOWN_Clear()             (LATBCLR = (1U<<6))
#define DOWN_Toggle()            (LATBINV= (1U<<6))
#define DOWN_OutputEnable()      (TRISBCLR = (1U<<6))
#define DOWN_InputEnable()       (TRISBSET = (1U<<6))
#define DOWN_Get()               ((PORTB >> 6) & 0x1U)
#define DOWN_PIN                  GPIO_PIN_RB6

/*** Macros for FF_CLK pin ***/
#define FF_CLK_Set()               (LATCSET = (1U<<10))
#define FF_CLK_Clear()             (LATCCLR = (1U<<10))
#define FF_CLK_Toggle()            (LATCINV= (1U<<10))
#define FF_CLK_OutputEnable()      (TRISCCLR = (1U<<10))
#define FF_CLK_InputEnable()       (TRISCSET = (1U<<10))
#define FF_CLK_Get()               ((PORTC >> 10) & 0x1U)
#define FF_CLK_PIN                  GPIO_PIN_RC10

/*** Macros for SPI_SCK1 pin ***/
#define SPI_SCK1_Get()               ((PORTB >> 7) & 0x1U)
#define SPI_SCK1_PIN                  GPIO_PIN_RB7

/*** Macros for SPARE_GPIO pin ***/
#define SPARE_GPIO_Set()               (LATCSET = (1U<<13))
#define SPARE_GPIO_Clear()             (LATCCLR = (1U<<13))
#define SPARE_GPIO_Toggle()            (LATCINV= (1U<<13))
#define SPARE_GPIO_OutputEnable()      (TRISCCLR = (1U<<13))
#define SPARE_GPIO_InputEnable()       (TRISCSET = (1U<<13))
#define SPARE_GPIO_Get()               ((PORTC >> 13) & 0x1U)
#define SPARE_GPIO_PIN                  GPIO_PIN_RC13

/*** Macros for Up pin ***/
#define Up_Set()               (LATBSET = (1U<<8))
#define Up_Clear()             (LATBCLR = (1U<<8))
#define Up_Toggle()            (LATBINV= (1U<<8))
#define Up_OutputEnable()      (TRISBCLR = (1U<<8))
#define Up_InputEnable()       (TRISBSET = (1U<<8))
#define Up_Get()               ((PORTB >> 8) & 0x1U)
#define Up_PIN                  GPIO_PIN_RB8

/*** Macros for LCD_DB5 pin ***/
#define LCD_DB5_Set()               (LATBSET = (1U<<9))
#define LCD_DB5_Clear()             (LATBCLR = (1U<<9))
#define LCD_DB5_Toggle()            (LATBINV= (1U<<9))
#define LCD_DB5_OutputEnable()      (TRISBCLR = (1U<<9))
#define LCD_DB5_InputEnable()       (TRISBSET = (1U<<9))
#define LCD_DB5_Get()               ((PORTB >> 9) & 0x1U)
#define LCD_DB5_PIN                  GPIO_PIN_RB9

/*** Macros for SPI_SS1 pin ***/
#define SPI_SS1_Set()               (LATCSET = (1U<<6))
#define SPI_SS1_Clear()             (LATCCLR = (1U<<6))
#define SPI_SS1_Toggle()            (LATCINV= (1U<<6))
#define SPI_SS1_OutputEnable()      (TRISCCLR = (1U<<6))
#define SPI_SS1_InputEnable()       (TRISCSET = (1U<<6))
#define SPI_SS1_Get()               ((PORTC >> 6) & 0x1U)
#define SPI_SS1_PIN                  GPIO_PIN_RC6

/*** Macros for SPI_SDO1 pin ***/
#define SPI_SDO1_Get()               ((PORTC >> 7) & 0x1U)
#define SPI_SDO1_PIN                  GPIO_PIN_RC7

/*** Macros for LDAC_L pin ***/
#define LDAC_L_Set()               (LATCSET = (1U<<8))
#define LDAC_L_Clear()             (LATCCLR = (1U<<8))
#define LDAC_L_Toggle()            (LATCINV= (1U<<8))
#define LDAC_L_OutputEnable()      (TRISCCLR = (1U<<8))
#define LDAC_L_InputEnable()       (TRISCSET = (1U<<8))
#define LDAC_L_Get()               ((PORTC >> 8) & 0x1U)
#define LDAC_L_PIN                  GPIO_PIN_RC8

/*** Macros for LCD_DB4 pin ***/
#define LCD_DB4_Set()               (LATCSET = (1U<<9))
#define LCD_DB4_Clear()             (LATCCLR = (1U<<9))
#define LCD_DB4_Toggle()            (LATCINV= (1U<<9))
#define LCD_DB4_OutputEnable()      (TRISCCLR = (1U<<9))
#define LCD_DB4_InputEnable()       (TRISCSET = (1U<<9))
#define LCD_DB4_Get()               ((PORTC >> 9) & 0x1U)
#define LCD_DB4_PIN                  GPIO_PIN_RC9

/*** Macros for LCD_DB6 pin ***/
#define LCD_DB6_Set()               (LATBSET = (1U<<10))
#define LCD_DB6_Clear()             (LATBCLR = (1U<<10))
#define LCD_DB6_Toggle()            (LATBINV= (1U<<10))
#define LCD_DB6_OutputEnable()      (TRISBCLR = (1U<<10))
#define LCD_DB6_InputEnable()       (TRISBSET = (1U<<10))
#define LCD_DB6_Get()               ((PORTB >> 10) & 0x1U)
#define LCD_DB6_PIN                  GPIO_PIN_RB10

/*** Macros for LCD_DB7 pin ***/
#define LCD_DB7_Set()               (LATBSET = (1U<<11))
#define LCD_DB7_Clear()             (LATBCLR = (1U<<11))
#define LCD_DB7_Toggle()            (LATBINV= (1U<<11))
#define LCD_DB7_OutputEnable()      (TRISBCLR = (1U<<11))
#define LCD_DB7_InputEnable()       (TRISBSET = (1U<<11))
#define LCD_DB7_Get()               ((PORTB >> 11) & 0x1U)
#define LCD_DB7_PIN                  GPIO_PIN_RB11

/*** Macros for LCD_RS pin ***/
#define LCD_RS_Set()               (LATASET = (1U<<10))
#define LCD_RS_Clear()             (LATACLR = (1U<<10))
#define LCD_RS_Toggle()            (LATAINV= (1U<<10))
#define LCD_RS_OutputEnable()      (TRISACLR = (1U<<10))
#define LCD_RS_InputEnable()       (TRISASET = (1U<<10))
#define LCD_RS_Get()               ((PORTA >> 10) & 0x1U)
#define LCD_RS_PIN                  GPIO_PIN_RA10


// *****************************************************************************
/* GPIO Port

  Summary:
    Identifies the available GPIO Ports.

  Description:
    This enumeration identifies the available GPIO Ports.

  Remarks:
    The caller should not rely on the specific numbers assigned to any of
    these values as they may change from one processor to the next.

    Not all ports are available on all devices.  Refer to the specific
    device data sheet to determine which ports are supported.
*/


#define    GPIO_PORT_A  (0)
#define    GPIO_PORT_B  (1)
#define    GPIO_PORT_C  (2)
#define    GPIO_PORT_D  (3)
typedef uint32_t GPIO_PORT;

typedef enum
{
    GPIO_INTERRUPT_ON_MISMATCH,
    GPIO_INTERRUPT_ON_RISING_EDGE,
    GPIO_INTERRUPT_ON_FALLING_EDGE,
    GPIO_INTERRUPT_ON_BOTH_EDGES,
}GPIO_INTERRUPT_STYLE;

// *****************************************************************************
/* GPIO Port Pins

  Summary:
    Identifies the available GPIO port pins.

  Description:
    This enumeration identifies the available GPIO port pins.

  Remarks:
    The caller should not rely on the specific numbers assigned to any of
    these values as they may change from one processor to the next.

    Not all pins are available on all devices.  Refer to the specific
    device data sheet to determine which pins are supported.
*/


#define     GPIO_PIN_RA0  (0U)
#define     GPIO_PIN_RA1  (1U)
#define     GPIO_PIN_RA4  (4U)
#define     GPIO_PIN_RA7  (7U)
#define     GPIO_PIN_RA8  (8U)
#define     GPIO_PIN_RA10  (10U)
#define     GPIO_PIN_RA11  (11U)
#define     GPIO_PIN_RA12  (12U)
#define     GPIO_PIN_RB0  (16U)
#define     GPIO_PIN_RB1  (17U)
#define     GPIO_PIN_RB2  (18U)
#define     GPIO_PIN_RB3  (19U)
#define     GPIO_PIN_RB4  (20U)
#define     GPIO_PIN_RB5  (21U)
#define     GPIO_PIN_RB6  (22U)
#define     GPIO_PIN_RB7  (23U)
#define     GPIO_PIN_RB8  (24U)
#define     GPIO_PIN_RB9  (25U)
#define     GPIO_PIN_RB10  (26U)
#define     GPIO_PIN_RB11  (27U)
#define     GPIO_PIN_RB12  (28U)
#define     GPIO_PIN_RB13  (29U)
#define     GPIO_PIN_RB14  (30U)
#define     GPIO_PIN_RB15  (31U)
#define     GPIO_PIN_RC0  (32U)
#define     GPIO_PIN_RC1  (33U)
#define     GPIO_PIN_RC2  (34U)
#define     GPIO_PIN_RC6  (38U)
#define     GPIO_PIN_RC7  (39U)
#define     GPIO_PIN_RC8  (40U)
#define     GPIO_PIN_RC9  (41U)
#define     GPIO_PIN_RC10  (42U)
#define     GPIO_PIN_RC11  (43U)
#define     GPIO_PIN_RC12  (44U)
#define     GPIO_PIN_RC13  (45U)
#define     GPIO_PIN_RC15  (47U)
#define     GPIO_PIN_RD8  (56U)

    /* This element should not be used in any of the GPIO APIs.
       It will be used by other modules or application to denote that none of the GPIO Pin is used */
#define    GPIO_PIN_NONE   (-1)

typedef uint32_t GPIO_PIN;


void GPIO_Initialize(void);

// *****************************************************************************
// *****************************************************************************
// Section: GPIO Functions which operates on multiple pins of a port
// *****************************************************************************
// *****************************************************************************

uint32_t GPIO_PortRead(GPIO_PORT port);

void GPIO_PortWrite(GPIO_PORT port, uint32_t mask, uint32_t value);

uint32_t GPIO_PortLatchRead ( GPIO_PORT port );

void GPIO_PortSet(GPIO_PORT port, uint32_t mask);

void GPIO_PortClear(GPIO_PORT port, uint32_t mask);

void GPIO_PortToggle(GPIO_PORT port, uint32_t mask);

void GPIO_PortInputEnable(GPIO_PORT port, uint32_t mask);

void GPIO_PortOutputEnable(GPIO_PORT port, uint32_t mask);

// *****************************************************************************
// *****************************************************************************
// Section: GPIO Functions which operates on one pin at a time
// *****************************************************************************
// *****************************************************************************

static inline void GPIO_PinWrite(GPIO_PIN pin, bool value)
{
	 uint32_t xvalue = (uint32_t)value;
    GPIO_PortWrite((pin>>4U), (uint32_t)(0x1U) << (pin & 0xFU), (xvalue) << (pin & 0xFU));
}

static inline bool GPIO_PinRead(GPIO_PIN pin)
{
    return ((((GPIO_PortRead((GPIO_PORT)(pin>>4U))) >> (pin & 0xFU)) & 0x1U) != 0U);
}

static inline bool GPIO_PinLatchRead(GPIO_PIN pin)
{
    return (((GPIO_PortLatchRead((GPIO_PORT)(pin>>4U)) >> (pin & 0xFU)) & 0x1U) != 0U);
}

static inline void GPIO_PinToggle(GPIO_PIN pin)
{
    GPIO_PortToggle((pin>>4U), (uint32_t)0x1U << (pin & 0xFU));
}

static inline void GPIO_PinSet(GPIO_PIN pin)
{
    GPIO_PortSet((pin>>4U), (uint32_t)0x1U << (pin & 0xFU));
}

static inline void GPIO_PinClear(GPIO_PIN pin)
{
    GPIO_PortClear((pin>>4U), (uint32_t)0x1U << (pin & 0xFU));
}

static inline void GPIO_PinInputEnable(GPIO_PIN pin)
{
    GPIO_PortInputEnable((pin>>4U), (uint32_t)0x1U << (pin & 0xFU));
}

static inline void GPIO_PinOutputEnable(GPIO_PIN pin)
{
    GPIO_PortOutputEnable((pin>>4U), (uint32_t)0x1U << (pin & 0xFU));
}


// DOM-IGNORE-BEGIN
#ifdef __cplusplus  // Provide C++ Compatibility

    }

#endif
// DOM-IGNORE-END
#endif // PLIB_GPIO_H
