Ejemplo n.º 1
0
        /// <summary>
        /// Gets the mapped address for a register.
        /// </summary>
        /// <param name="register">The register.</param>
        /// <param name="port">The bank of I/O ports used with the register.</param>
        /// <param name="bankStyle">The bank style that determines how the register addresses are grouped.</param>
        /// <returns>The byte address of the register for the given port bank and bank style.</returns>
        private byte GetMappedAddress(Register register, Port port = Port.PortA,
                                      BankStyle bankStyle          = BankStyle.Sequential)
        {
            if (port != Port.PortA && port != Port.PortB)
            {
                throw new ArgumentOutOfRangeException(nameof(port));
            }

            if (bankStyle != BankStyle.Separated && bankStyle != BankStyle.Sequential)
            {
                throw new ArgumentOutOfRangeException(nameof(bankStyle));
            }

            byte address = (byte)register;

            // There is no mapping for 8 bit expanders
            if (PinCount == 8)
            {
                return(address);
            }

            if (bankStyle == BankStyle.Sequential)
            {
                // Registers for each bank are sequential
                // (IODIRA = 0x00, IODIRB = 0x01, IPOLA = 0x02, IPOLB = 0x03, ...)
                address += address;
                return(port == Port.PortA ? address : ++address);
            }

            // Registers for each bank are separated
            // (IODIRA = 0x00, ... OLATA = 0x0A, IODIRB = 0x10, ... OLATB = 0x1A)
            return(port == Port.PortA ? address : address += 0x10);
        }
Ejemplo n.º 2
0
        public void Get_Mapped_Address(Register register, Port port, BankStyle bankStyle, byte expectedMappedAddress)
        {
            TestMappedBus bus  = new TestMappedBus();
            McpMock       mock = new McpMock(bus, bankStyle);

            mock.Write(register, port);
            Assert.Equal(expectedMappedAddress, bus.LastAddress);
        }
Ejemplo n.º 3
0
        public void Get_Mapped_Address(Register register, Port port, BankStyle bankStyle, byte expectedMappedAddress)
        {
            SpiDeviceMock spiDeviceMock = new SpiDeviceMock(ports: 2);
            BankStyleMock mock          = new BankStyleMock(spiDeviceMock, bankStyle);

            mock.Read(register, port);

            // Reads are full duplex- commands go to "Write"
            Assert.Equal(expectedMappedAddress, spiDeviceMock.DeviceMock.LastWriteBuffer[0]);
        }
Ejemplo n.º 4
0
        /// <summary>
        /// A general purpose parallel I/O expansion for I2C or SPI applications.
        /// </summary>
        /// <param name="bus">The bus the device is connected to.</param>
        /// <param name="reset">The output pin number that is connected to the hardware reset.</param>
        /// <param name="interruptA">The input pin number that is connected to the interrupt for Port A (INTA).</param>
        /// <param name="interruptB">The input pin number that is connected to the interrupt for Port B (INTB).</param>
        /// <param name="masterController">
        /// The controller for the reset and interrupt pins. If not specified, the default controller will be used.
        /// </param>
        /// <param name="bankStyle">
        /// The current bank style of the ports. This does not set the bank style- it tells us what the bank style is.
        /// It is *highly* recommended not to change the bank style from the default as there is no direct way to
        /// detect what style the chip is in and most apps will fail if the chip is not set to defaults. This setting
        /// has no impact on 8-bit expanders.
        /// </param>
        /// <param name="shouldDispose">True to dispose the Gpio Controller</param>
        protected Mcp23xxx(BusAdapter bus, int reset       = -1, int interruptA = -1, int interruptB = -1,
                           GpioController masterController = null, BankStyle bankStyle = BankStyle.Sequential, bool shouldDispose = true)
        {
            _bus           = bus;
            _bankStyle     = bankStyle;
            _shouldDispose = masterController == null ? true : shouldDispose;

            _reset      = reset;
            _interruptA = interruptA;
            _interruptB = interruptB;

            // Only need master controller if there are external pins provided.
            if (_reset != -1 || _interruptA != -1 || _interruptB != -1)
            {
                _masterGpioController = masterController ?? new GpioController();

                if (_interruptA != -1)
                {
                    _masterGpioController.OpenPin(_interruptA, PinMode.Input);
                }

                if (_interruptB != -1)
                {
                    _masterGpioController.OpenPin(_interruptB, PinMode.Input);
                }

                if (_reset != -1)
                {
                    _masterGpioController.OpenPin(_reset, PinMode.Output);
                    Disable();
                }
            }

            if (!_disabled)
            {
                // Set all of the pins to input, GPIO outputs to low, and set input polarity to match the input.
                // This is the normal power-on / reset state of the Mcp23xxx chips.
                if (PinCount == 8)
                {
                    InternalWriteByte(Register.IODIR, 0xFF, Port.PortA);
                    InternalWriteByte(Register.GPIO, 0x00, Port.PortA);
                    InternalWriteByte(Register.IPOL, 0x00, Port.PortA);
                }
                else
                {
                    InternalWriteUInt16(Register.IODIR, 0xFFFF);
                    InternalWriteUInt16(Register.GPIO, 0x0000);
                    InternalWriteUInt16(Register.IPOL, 0x0000);
                }
            }
        }
Ejemplo n.º 5
0
        /// <summary>
        /// Disables the device by setting the reset pin low.
        /// </summary>
        public void Disable()
        {
            if (_reset == -1)
            {
                throw new InvalidOperationException("No reset pin configured.");
            }

            _masterGpioController.Write(_reset, PinValue.Low);

            // Registers will all be reset when re-enabled
            _bankStyle  = BankStyle.Sequential;
            _increments = true;
            _disabled   = true;
        }
Ejemplo n.º 6
0
 public BankStyleMock(SpiDevice device, BankStyle bankStyle)
     : base(new SpiAdapter(device, 0x20), bankStyle: bankStyle)
 {
 }
Ejemplo n.º 7
0
 public McpMock(IBusDevice device, BankStyle bankStyle)
     : base(device, 0x20, bankStyle: bankStyle)
 {
 }