Esempio n. 1
0
        public override void SetupComponent()
        {
            if (_pin == Cpu.Pin.GPIO_NONE || _pin < 0)
            {
                throw new Exception("The GpioPort has an invalid pin.");
            }

            if ((_modesExpected & _modesAllowed) != _modesExpected)
            {
                throw new InvalidOperationException("All modes expected have to be allowed: expected = " +
                                                    _modesExpected.ToString() + "; allowed = " + _modesAllowed.ToString());
            }

            _isReserved       = false;
            _mode             = GpioPortMode.None;
            _state            = false;
            _stateInitialized = false;

            _interruptMode = GpioInterruptMode.None;
            _resistorMode  = GpioResistorMode.Disabled;
            _debounceMode  = DebounceMode.None;
        }
Esempio n. 2
0
        internal void DeviceEnableAsInputPort(bool glitchFilter, GpioResistorMode resistorMode, GpioInterruptMode interruptMode, IntPtr isr, IntPtr isrParam)
        {
            if ((_modesExpected & GpioPortMode.InputPort) == 0)
            {
                if ((this is GpioPortNull) == false) // We put an warning about accessing a non-existing port in DeviceGet already
                {
                    Trace.WriteLine("Attempt to initialize GPIO Port " + Pin + " as an input port when it's expecting " + _modesExpected.ToString());
                }
                return;
            }

            if (_mode != GpioPortMode.None)
            {
                // return the port to a Disabled state first if it wasn't previously disabled.
                DeviceDisablePort();
            }

            _interruptMode = interruptMode;
            _isr           = isr;
            _isrParam      = isrParam;
            _resistorMode  = resistorMode;

            if (glitchFilter)
            {
                _debounceMode = (this.Emulator.GpioPorts.HardwareDebounceSupported) ? DebounceMode.HardwareDebounce : DebounceMode.SoftwareDebounce;
            }
            else
            {
                _debounceMode = DebounceMode.None;
            }

            _mode = GpioPortMode.InputPort;

            if (_stateInitialized == false)
            {
                // Since the pullup/pulldown are meant for as a way to avoid floating values, we shouldn't count the state as initialized.
                // We just simply set the state appropriately.
                if (_resistorMode == GpioResistorMode.PullUp)
                {
                    _state = true;
                }
                else if (_resistorMode == GpioResistorMode.PullDown)
                {
                    _state = false;
                }
            }

            if (_interruptMode != GpioInterruptMode.None)
            {
                if (isr.Equals(IntPtr.Zero))
                {
                    Debug.Assert(false, "Invalid ISR.");
                    Trace.WriteLine("Error: Interrupt port " + _pin + " has an invalid ISR.");
                    return;
                }

                if ((interruptMode == GpioInterruptMode.LevelHigh && _state == true) ||
                    (interruptMode == GpioInterruptMode.LevelLow && _state == false))
                {
                    HandleDebounce(true);

                    // Note that HandleDebounce will make this function re-entrant if it's a level interrupt.
                    return;
                }
            }
            else
            {
                _isr      = IntPtr.Zero;
                _isrParam = IntPtr.Zero;
            }
        }
Esempio n. 3
0
        public Action <T1> Debounce <T1>(Action <DebounceMode, T1> function, TimeSpan wait, DebounceMode mode = DebounceMode.Trailing)
        {
            var cancellationTokenSource     = new CancellationTokenSource();
            var leadCancellationTokenSource = new CancellationTokenSource();
            var leadCancelled = false;

            var lockObject     = new object();
            var leadLockObject = new object();

            return((t1) =>
            {
                lock (lockObject)
                {
                    cancellationTokenSource.Cancel();
                    cancellationTokenSource = new CancellationTokenSource();
                }

                Task.Delay(wait, cancellationTokenSource.Token)
                .ContinueWith(task =>
                {
                    if (mode > DebounceMode.Leading && !task.IsCanceled)
                    {
                        leadCancelled = false;
                        function(DebounceMode.Trailing, t1);
                    }
                });

                if (mode < DebounceMode.Trailing && !leadCancelled)
                {
                    leadCancelled = true;

                    Task.Delay(wait, leadCancellationTokenSource.Token)
                    .ContinueWith(task =>
                    {
                        if (!task.IsCanceled)
                        {
                            lock (leadLockObject)
                            {
                                leadCancellationTokenSource.Cancel();
                                leadCancellationTokenSource = new CancellationTokenSource();
                            }
                        }
                    });

                    function(DebounceMode.Leading, t1);
                }
            });
        }