File: GpioConfig

Details

File: GpioConfig.cs
Dir: C:\Projects\RPICSIO_All\RPICSIOSource_0100\RPICSIO
Date: Fri, Jan 13, 2017
using System;
using System.Text;
using System.IO;

/// +------------------------------------------------------------------------------------------------------------------------------+
/// |                                                   TERMS OF USE: MIT License                                                  |
/// +------------------------------------------------------------------------------------------------------------------------------|
/// |Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation    |
/// |files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy,    |
/// |modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software|
/// |is furnished to do so, subject to the following conditions:                                                                   |
/// |                                                                                                                              |
/// |The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.|
/// |                                                                                                                              |
/// |THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE          |
/// |WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR         |
/// |COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,   |
/// |ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                         |
/// +------------------------------------------------------------------------------------------------------------------------------+

namespace RPICSIO
{

    /// +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=
    /// +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=
    /// <summary>
    /// Provides a container to correlate HeaderPinNumber, RegisterOffsets etc
    /// for the GPIO and also contain the configuration state of the GPIO
    /// </summary>
    /// <history>
    ///    01 Dec 16  Cynic - Started
    /// </history>
    public class GpioConfig
    {
        public const int NO_GPIOBANK = -1;
        public const int NO_GPIOBIT = -1;
        public const int NO_GPIOMASK = 0;
        public const int NO_HEADER = -1;
        public const int NO_GPIO = -1;
        public const int NO_HEADERPIN = -1;
        public const int NO_MUXPIN = -1;
        public const int NO_PINMUXREGISTEROFFSET = -1;
        public const int NO_GPIOSETTING = -1;
        public const string MUX_UNCLAIMED = "UNCLAIMED";
        public const string GPIO_UNCLAIMED = "UNCLAIMED";

        private GpioEnum gpio = GpioEnum.GPIO_NONE;
        private int gpioNum = NO_GPIO;
        private int headerPin = NO_HEADERPIN;
        private int muxPin = NO_MUXPIN;
        private bool isDefaultGPIOOnHeader = false;
        private int gpioBank = NO_GPIOBANK;
        private int gpioBit = NO_GPIOBIT;

        private int gpioSetting = NO_GPIOSETTING;
 
        /// +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=
        /// <summary>
        /// Constructor - only used to set up a dummy default GpioConfig object
        /// </summary>
        /// <history>
        ///    01 Dec 16  Cynic - Started
        /// </history>
        public GpioConfig()
        {
        }
            
        /// +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=
        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="headerPinIn">the number of the header pin
        /// <param name="isDefaultGPIOOnHeaderIn">if true it is available as a GPIO by default on the header. False it is not</param>
        /// <param name="gpioNumIn">The gpio as a number</param>
        /// <param name="gpioIn">The gpio as an enum</param>
        /// <history>
        ///    01 Dec 16  Cynic - Started
        /// </history>
        public GpioConfig(int headerPinIn, bool isDefaultGPIOOnHeaderIn, int gpioNumIn, GpioEnum gpioIn)
        {
            // set some values, ignore others - they are for future use
            headerPin = headerPinIn;
            isDefaultGPIOOnHeader = isDefaultGPIOOnHeaderIn;
            gpioNum = gpioNumIn;
            gpio = gpioIn;

            // these values are pre-calculated. We use them a lot
            gpioBank = GpioNum / 32; // the bank number in the pinmux is the GPIO/32
            gpioBit = GpioNum % 32; // the bit number in the pinmux is the remainder of GPIO/32
 
        }

        /// +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=
        /// <summary>
        /// Gets the Gpio
        /// </summary>
        /// <history>
        ///    01 Dec 16  Cynic - Started
        /// </history>
        public GpioEnum Gpio
        {
            get
            {
                return gpio;
            }
        }

        /// +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=
        /// <summary>
        /// Gets the gpioNum
        /// </summary>
        /// <history>
        ///    01 Dec 16  Cynic - Started
        /// </history>
        public int GpioNum
        {
            get
            {
                return gpioNum;
            }
        }
            
        /// +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=
        /// <summary>
        /// Gets the gpioBank
        /// </summary>
        /// <history>
        ///    01 Dec 16  Cynic - Started
        /// </history>
        public int GpioBank
        {
            get
            {
                return gpioBank;
            }
        }

        /// +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=
        /// <summary>
        /// Gets the gpioBank offset
        /// </summary>
        /// <history>
        ///    01 Dec 16  Cynic - Started
        /// </history>
        public int GpioBankOffset
        {
            get
            {
                // There are 54 GPIOs, most of the functions they use
                // are in two consecutive 32 bit registers. GPIOs 0-31
                // are in the low register and 32-53 in the high register
                // this just provides a central location to calculate this offset
                if (GpioNum >= 32) return 4;
                else return 0;
            }
        }

        /// +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=
        /// <summary>
        /// Gets the mode of the GPIO - this is the setting of the pinmux
        /// </summary>
        /// <history>
        ///    01 Dec 16  Cynic - Started
        /// </history>
        public GPIOPinMuxModeEnum GpioMode
        {
            get
            {
                return ConvertModeIntToEnum(MMDevMem.GetGPIOPinMuxState(this));
            }
        }

        /// +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=
        /// <summary>
        /// Gets the memory mappings for the GPIO banks. Will never return null.
        /// 
        /// NOTE: the MemoryMapDevMem class is a singleton class. This means that 
        /// program wide there can ever only be one instantiation of these. If you 
        /// don't know what a singleton class is, you should look it up. Otherwise 
        /// you will never really understand how this works.
        /// 
        /// </summary>
        /// <history>
        ///    01 Dec 16  Cynic - Originally written
        /// </history>
        protected MemoryMapDevMem MMDevMem
        {
            get
            {
                return MemoryMapDevMem.Instance;
            }
        }

        /// +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=
        /// <summary>
        /// Gets the mode mask for the GPIO 
        /// </summary>
        /// <history>
        ///    01 Dec 16  Cynic - Started
        /// </history>
        public int GpioPinMuxModeMask
        {
            get
            {
                // There are 10 GPIOs of three bits each 
                // per function register. LSB of the register
                // has the lowest GPIO and so in ascending order
                // for example, GPIO_0 is in bits 2-0
                //              GPIO_1 is in bits 5-3
                //              GPIO_10 is in bits 2-0 but in the next register up

                // the mask can be calculated by the formula below
                int mask = 0x07; // (111 in binary)
                mask = mask << GpioPinMuxModeShift;
                return mask;
            }
        }

        /// +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=
        /// <summary>
        /// Gets the number of bits we have to shift the function (pinmux) register to 
        /// convert it to or from an int
        /// </summary>
        /// <history>
        ///    01 Dec 16  Cynic - Started
        /// </history>
        public int GpioPinMuxModeShift
        {
            get
            {
                // There are 10 GPIOs of three bits each 
                // per function register. LSB of the register
                // has the lowest GPIO and so in ascending order
                // for example, GPIO_0 is in bits 2-0
                //              GPIO_1 is in bits 5-3
                //              GPIO_10 is in bits 2-0 but in the next register up

                // the shift can be calculated by the formula below
                return ((GpioNum % 10)*3);
            }
        }

        /// +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=
        /// <summary>
        /// Converts a pinmux mode integer to an enum
        /// </summary>
        /// <param name="gpioModeNum">The GPIO Mode as an integer</param>
        /// <history>
        ///    01 Dec 16  Cynic - Started
        /// </history>
        public GPIOPinMuxModeEnum ConvertModeIntToEnum(int gpioModeNum)
        {
            // the range is 0-7
            if ((gpioModeNum < 0) || (gpioModeNum > 7))
            {
                // probably the safest we can do
                return GPIOPinMuxModeEnum.GPIOMODE_INPUT;
            }
            // the cast should convert it for us
            return (GPIOPinMuxModeEnum)gpioModeNum;
        }

        /// +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=
        /// <summary>
        /// Converts a pinmux mode enum to an integer
        /// </summary>
        /// <param name="gpioModeIn">The GPIO Mode</param>
        /// <history>
        ///    01 Dec 16  Cynic - Started
        /// </history>
        public int ConvertModeEnumToInt(GPIOPinMuxModeEnum gpioModeIn)
        {
             // the cast should convert it for us
            return (int)gpioModeIn;
        }

        /// +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=
        /// <summary>
        /// Detects if the GPIO is a default GPIO on the header rather than a
        /// needing to be muxed in because that pin is used by some other device.
        /// </summary>
        /// <history>
        ///    01 Dec 16  Cynic - Started
        /// </history>
        public bool IsDefaultGPIOOnHeader
        {
            get
            {
                return isDefaultGPIOOnHeader;
            }
        }

        /// +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=
        /// <summary>
        /// Gets the gpioBit
        /// </summary>
        /// <history>
        ///    01 Dec 16  Cynic - Started
        /// </history>
        public int GpioBit
        {
            get
            {
                return gpioBit;
            }
        }
            
        /// +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=
        /// <summary>
        /// Gets the gpioMask
        /// </summary>
        /// <history>
        ///    01 Dec 16  Cynic - Started
        /// </history>
        public int GpioMask
        {
            get
            {
                // the gpios are mapped into two sequential registers. GPIOs 0-31
                // are in the first register and 32-53 are in the next one. Usually things
                // are set and reset by writing a 1 to the appropriate register
                // and the position of this bit is determined by the gpio number
                if (GpioNum >= 32)
                {
                    // we are in the second bank, shift it up by 
                    // the gpioNum-32
                    return 0x01 << (GpioNum-32);
                }
                else
                {
                    // just shift it up by the GpioNum
                    return 0x01 << GpioNum;
                }
            }
        }
            
        /// +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=
        /// <summary>
        /// Gets the Gpio Settings as a human readable string
        /// </summary>
        /// <history>
        ///    01 Dec 16  Cynic - Started
        /// </history>
        public string GpioSettingsAsString()
        {
            StringBuilder sb = new StringBuilder();
            sb.Append(Gpio.ToString());
            sb.Append(", MuxMode=" + GpioMode.ToString());

            return sb.ToString();
        }

        /// +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=
        /// <summary>
        /// Gets the headerPin
        /// </summary>
        /// <history>
        ///    01 Dec 16  Cynic - Started
        /// </history>
        public int HeaderPin
        {
            get
            {
                return headerPin;
            }
        }

        /// +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=
        /// <summary>
        /// Gets the muxPin
        /// </summary>
        /// <history>
        ///    01 Dec 16  Cynic - Started
        /// </history>
        public int MuxPin
        {
            get
            {
                return muxPin;
            }
        }

        /// +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=
        /// <summary>
        /// Gets the pinmuxRegisterOffset
        /// </summary>
        /// <history>
        ///    01 Dec 16  Cynic - Started
        /// </history>
        public int PinmuxRegisterOffset
        {
            get
            {
                // GPIOs 0-9 get an offset of 0
                // GPIOs 10-19 get an offset of 4
                // GPIOs 20-29 get an offset of 8
                // and so on. So the formula below works
                return ((GpioNum/10)*4);
            }
        }
            
        /// +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=
        /// <summary>
        /// Gets the pinmuxRegister offset as hex string
        /// </summary>
        /// <history>
        ///    01 Dec 16  Cynic - Started
        /// </history>
        public string PinmuxRegisterOffsetAsHexString
        {
            get
            {
                return PinmuxRegisterOffset.ToString("x3");
            }
        }
                        
        /// +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=
        /// <summary>
        /// Gets the event bank number.  This function just recovers the bank from the calculated 
        /// GPIO number. 
        /// </summary>
        /// <history>
        ///    01 Dec 16  Cynic - Started
        /// </history>
        public int EventBank
        {
            get
            {
                // the bank number in the pinmux is the GPIO/32
                return GpioNum / 32;
            }
        }

        /// +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=
        /// <summary>
        /// Gets the event bit number. This is the offset of a GPIO into its bank. 
        /// </summary>
        /// <history>
        ///    01 Dec 16  Cynic - Started
        /// </history>
        public int EventBit
        {
            get
            {
                // the bit number in the pinmux is the remainder of GPIO/32
                return GpioNum % 32;
            }
        }

        /// +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=
        /// <summary>
        /// Gets the GpioSettings. This is the raw hex bits that determine the various
        /// mode settings
        /// </summary>
        /// <history>
        ///    01 Dec 16  Cynic - Started
        /// </history>
        public int GpioSetting
        {
            get
            {
                return gpioSetting;
            }
        }

        /// +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=
        /// <summary>
        /// Gets the MuxMode. These are the three lsb bits of the gpioSetting. 
        /// </summary>
        /// <history>
        ///    01 Dec 16  Cynic - Started
        /// </history>
        public int MuxMode
        {
            get
            {
                return gpioSetting & 0x07;
            }
        }           

        /// +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=
        /// <summary>
        /// Detects if pullups/pulldowns are enabled
        /// </summary>
        /// <returns>true they are enabled, false they are not</returns>
        /// <history>
        ///    01 Dec 16  Cynic - Started
        /// </history>
        public bool PullupsPulldownsEnabled
        {
            get
            {
                // a 0 at bit 3 means "enabled"
                if ((gpioSetting & 0x08) == 0) return true;
                else return false;    
            }
        }

        /// +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=
        /// <summary>
        /// Detects if the gpio is in pull up or pull down mode. Note the actual
        /// pull up or pull down is only truely operational if PullupsPulldownsEnabled
        /// is true
        /// </summary>
        /// <returns>1 pullup mode active, 0 pull down mode active</returns>
        /// <history>
        ///    01 Dec 16  Cynic - Started
        /// </history>
        public int PullupPulldownMode
        {
            get
            {
                if ((gpioSetting & 0x10) != 0)
                    return 1;
                else
                    return 0;
            }
        }           
    }
}

HTML Code Generated by CoDocker v00.90 Beta