public void Write(GpioPort port, GpioPin pin, GpioPinValue value)
    {
        byte olatRegister;
        byte olatRegisterValues;

        if (port == GpioPort.A)
        {
            olatRegister = OLATA;
        }
        else
        {
            olatRegister = OLATB;
        }

        olatRegisterValues = _readRegister(olatRegister);

        var pinAddress = _pins[pin.ToString()];

        if (value == GpioPinValue.Low)
        {
            var pinMask = (byte)(0xFF ^ pinAddress);
            olatRegisterValues &= pinMask;
        }
        else
        {
            //high
            olatRegisterValues |= pinAddress;
        }
        _writeRegister(olatRegister, olatRegisterValues);
    }
    public GpioPinValue Read(GpioPort port, GpioPin pin)
    {
        byte gpioRegister;
        byte gpioRegisterValues;

        if (port == GpioPort.A)
        {
            gpioRegister = GPIOA;
        }
        else
        {
            gpioRegister = GPIOB;
        }

        gpioRegisterValues = _readRegister(gpioRegister);
        var pinAddress = _pins[pin.ToString()];

        if ((byte)(gpioRegisterValues & pinAddress) == 0x00)
        {
            return(GpioPinValue.Low);
        }
        else
        {
            return(GpioPinValue.High);
        }
    }
    /// <summary>
    /// This method preserves the OLAT / GPIO settings of all pins and
    /// will only modify the pin requested and set it to the directionality specified
    /// </summary>
    /// <param name="port">Port A or Port B</param>
    /// <param name="pin">GPIO 0-7</param>
    /// <param name="mode">Input or Output</param>
    public void SetGpioPinDriveMode(GpioPort port, GpioPin pin, GpioPinDriveMode mode)
    {
        byte olatRegister;
        byte iodirRegister;
        byte olatRegisterValues;
        byte iodirRegisterValues;

        if (port == GpioPort.A)
        {
            olatRegister  = OLATA;
            iodirRegister = IODIRA;
        }
        else
        {
            olatRegister  = OLATB;
            iodirRegister = IODIRB;
        }

        //get read values to preserve
        olatRegisterValues  = _readRegister(olatRegister);
        iodirRegisterValues = _readRegister(iodirRegister);

        var pinAddress = _pins[pin.ToString()];

        switch (mode)
        {
        case GpioPinDriveMode.Input:
            var inputPinMask = (byte)(0x00 ^ pinAddress);     //exclusive OR so that we only change the one pin - others remain unchanged
            iodirRegisterValues |= inputPinMask;
            break;

        case GpioPinDriveMode.Output:
            //output logic needs to be low prior to switching to output
            var outputPinMask = (byte)(0xFF ^ pinAddress);
            olatRegisterValues &= outputPinMask;
            _writeRegister(olatRegister, olatRegisterValues);
            iodirRegisterValues &= outputPinMask;
            break;

        default:
            Debug.WriteLine("Pin mode not current supported");
            throw new Exception("Pin mode not currently supported");
            break;
        }
        _writeRegister(iodirRegister, iodirRegisterValues);
    }