Exemple #1
0
 /// <summary>
 /// Read the given pins with the given pin numbers.
 /// </summary>
 /// <param name="pinValuePairs">The pin/value pairs to read.</param>
 public void Read(Span <PinValuePair> pinValuePairs)
 {
     for (int i = 0; i < pinValuePairs.Length; i++)
     {
         pinValuePairs[i] = new PinValuePair(pinValuePairs[i].PinNumber, Read(pinValuePairs[i].PinNumber));
     }
 }
Exemple #2
0
        /// <summary>
        /// Reads the value of a set of pins
        /// </summary>
        protected void Read(Span <PinValuePair> pinValuePairs)
        {
            (uint pins, _) = new PinVector32(pinValuePairs);
            if ((pins >> PinCount) > 0)
            {
                ThrowBadPin(nameof(pinValuePairs));
            }

            ushort result;

            if (pins < 0xFF + 1)
            {
                // Only need to get the first 8 pins (PortA)
                result = InternalReadByte(Register.GPIO, Port.PortA);
            }
            else if ((pins & 0xFF) == 0)
            {
                // Only need to get the second 8 pins (PortB)
                result = (ushort)(InternalReadByte(Register.GPIO, Port.PortB) << 8);
            }
            else
            {
                // Need to get both
                result = InternalReadUInt16(Register.GPIO);
            }

            for (int i = 0; i < pinValuePairs.Length; i++)
            {
                int pin = pinValuePairs[i].PinNumber;
                pinValuePairs[i] = new PinValuePair(pin, result & (1 << pin));
            }
        }
Exemple #3
0
        public void WriteSpan()
        {
            _mockedGpioDriver.Setup(x => x.OpenPinEx(1));
            _mockedGpioDriver.Setup(x => x.OpenPinEx(2));
            _mockedGpioDriver.Setup(x => x.IsPinModeSupportedEx(1, PinMode.Output)).Returns(true);
            _mockedGpioDriver.Setup(x => x.IsPinModeSupportedEx(2, PinMode.Output)).Returns(true);
            _mockedGpioDriver.Setup(x => x.GetPinModeEx(1)).Returns(PinMode.Output);
            _mockedGpioDriver.Setup(x => x.GetPinModeEx(2)).Returns(PinMode.Output);
            _mockedGpioDriver.Setup(x => x.WriteEx(1, PinValue.High));
            _mockedGpioDriver.Setup(x => x.WriteEx(2, PinValue.Low));
            _mockedGpioDriver.Setup(x => x.ClosePinEx(1));
            _mockedGpioDriver.Setup(x => x.ClosePinEx(2));
            var ctrl = new GpioController(PinNumberingScheme.Logical, _mockedGpioDriver.Object);

            Assert.NotNull(ctrl);
            ctrl.OpenPin(1, PinMode.Output);
            ctrl.OpenPin(2, PinMode.Output);
            Assert.True(ctrl.IsPinOpen(1));
            Span <PinValuePair> towrite = stackalloc PinValuePair[2];

            towrite[0] = new PinValuePair(1, PinValue.High);
            towrite[1] = new PinValuePair(2, PinValue.Low);
            ctrl.Write(towrite);
            ctrl.ClosePin(1);
            ctrl.ClosePin(2);
            Assert.False(ctrl.IsPinOpen(1));
        }
Exemple #4
0
 public void Read(Span <PinValuePair> pinValues)
 {
     for (int i = 0; i < pinValues.Length; i++)
     {
         int pin = pinValues[i].PinNumber;
         pinValues[i] = new PinValuePair(pin, Read(pin));
     }
 }
Exemple #5
0
 public void Read(Span <PinValuePair> pinValuePairs)
 {
     WriteLine($"{nameof(Read)}(pinValuePairs):");
     for (int i = 0; i < pinValuePairs.Length; i++)
     {
         var pair = pinValuePairs[i];
         pinValuePairs[i] = new PinValuePair(pair.PinNumber, Read(pair.PinNumber));
     }
 }
Exemple #6
0
        /// <summary>
        /// Reads multiple pins from the device
        /// </summary>
        /// <param name="pinValues">Pins and values to be read</param>
        public void Read(Span <PinValuePair> pinValues)
        {
            (uint pins, _) = new PinVector32(pinValues);
            if (pins >> PinCount > 0)
            {
                ThrowInvalidPin(nameof(pinValues));
            }

            if ((pins & _pinModes) != 0)
            {
                // One of the specified pins was set to output (1)
                throw new InvalidOperationException("Cannot read from output pins.");
            }

            ushort data = PinCount == 8 ? ReadByte() : InternalReadUInt16();

            for (int i = 0; i < pinValues.Length; i++)
            {
                int pin = pinValues[i].PinNumber;
                pinValues[i] = new PinValuePair(pin, (data >> pin) & 1);
            }
        }
Exemple #7
0
        public void ReadSpan()
        {
            _mockedGpioDriver.Setup(x => x.OpenPinEx(1));
            _mockedGpioDriver.Setup(x => x.OpenPinEx(2));
            _mockedGpioDriver.Setup(x => x.IsPinModeSupportedEx(1, PinMode.Input)).Returns(true);
            _mockedGpioDriver.Setup(x => x.IsPinModeSupportedEx(2, PinMode.Input)).Returns(true);
            _mockedGpioDriver.Setup(x => x.ReadEx(1)).Returns(PinValue.Low);
            _mockedGpioDriver.Setup(x => x.ReadEx(2)).Returns(PinValue.High);
            _mockedGpioDriver.Setup(x => x.ClosePinEx(1));
            _mockedGpioDriver.Setup(x => x.ClosePinEx(2));
            var ctrl = new GpioController(PinNumberingScheme.Logical, _mockedGpioDriver.Object);

            Assert.NotNull(ctrl);
            ctrl.OpenPin(1, PinMode.Input);
            ctrl.OpenPin(2, PinMode.Input);
            Assert.True(ctrl.IsPinOpen(1));

            // Invalid usage (we need to prefill the array)
            // Was this the intended use case?
            Assert.Throws <InvalidOperationException>(() =>
            {
                Span <PinValuePair> wrongArg = stackalloc PinValuePair[2];
                ctrl.Read(wrongArg);
            });

            Span <PinValuePair> toread = stackalloc PinValuePair[2];

            toread[0] = new PinValuePair(1, PinValue.Low);
            toread[1] = new PinValuePair(2, PinValue.Low);
            ctrl.Read(toread);
            Assert.Equal(1, toread[0].PinNumber);
            Assert.Equal(2, toread[1].PinNumber);
            Assert.Equal(PinValue.Low, toread[0].PinValue);
            Assert.Equal(PinValue.High, toread[1].PinValue);
            ctrl.ClosePin(1);
            ctrl.ClosePin(2);
            Assert.False(ctrl.IsPinOpen(1));
        }
            private void WriteBits(byte bits, int count)
            {
                int changedCount = 0;

                for (int i = 0; i < count; i++)
                {
                    int newBit = (bits >> i) & 1;
                    if (!_useLastByte)
                    {
                        _pinBuffer[changedCount++] = new PinValuePair(_dataPins[i], newBit);
                    }
                    else
                    {
                        // Each bit change takes ~23μs, so only change what we have to
                        // This is particularly impactful when using all 8 data lines.
                        int oldBit = (_lastByte >> i) & 1;
                        if (oldBit != newBit)
                        {
                            _pinBuffer[changedCount++] = new PinValuePair(_dataPins[i], newBit);
                        }
                    }
                }

                if (changedCount > 0)
                {
                    _controller.Write(new ReadOnlySpan <PinValuePair>(_pinBuffer, 0, changedCount));
                }

                _useLastByte = true;
                _lastByte    = bits;

                // Enable pin needs to be high for at least 450ns when running on 3V
                // and 230ns on 5V. (PWeh on page 49/52 and Figure 25 on page 58)

                _controller.Write(_enablePin, PinValue.High);
                DelayHelper.DelayMicroseconds(1, allowThreadYield: false);
                _controller.Write(_enablePin, PinValue.Low);
            }