ghi-electronics / TinyCLR-Libraries

Official Libraries supporting TinyCLR OS
https://www.ghielectronics.com/tinyclr/
17 stars 16 forks source link

Wake-up on PA2 only works once (SC13048Q) #1341

Closed dcyonce closed 5 months ago

dcyonce commented 5 months ago

If CPU is woke-up from PA2, shutdown no longer works. Once SC13408Q is woken up using PA2, device will no longer go into shutdown until after a RESET or power-cycle.

Example code showing the issue:

`using GHIElectronics.TinyCLR.Devices.Gpio; using GHIElectronics.TinyCLR.Devices.Rtc; using GHIElectronics.TinyCLR.Native; using GHIElectronics.TinyCLR.Pins; using System; using System.Runtime.InteropServices; using System.Threading;

namespace Pico_Shutdown_Tests { internal class Program { static GpioPin _Blue_LED; static GpioPin _Wakeup_0; static GpioPin _Wakeup_2; static RtcController rtc;

    static void Main()
    {

        rtc = RtcController.GetDefault();
        rtc.Now = new DateTime(2023, 4, 12);
        SystemTime.SetTime(rtc.Now);

        // Status LED
        _Blue_LED = GpioController.GetDefault().OpenPin(SC13048.GpioPin.PA8);
        _Blue_LED.SetDriveMode(GpioPinDriveMode.Output);

        // Wakeup - PA0
        _Wakeup_0 = GpioController.GetDefault().OpenPin(SC13048.GpioPin.PA0);
        _Wakeup_0.SetDriveMode(GpioPinDriveMode.Input);
        _Wakeup_0.ValueChanged += _Wakeup_0_ValueChanged;

        // Wakeup - PA2
        _Wakeup_2 = GpioController.GetDefault().OpenPin(SC13048.GpioPin.PA2);
        _Wakeup_2.SetDriveMode(GpioPinDriveMode.Input);
        _Wakeup_2.ValueChanged += _Wakeup_2_ValueChanged;

        // Slow blink the Blue LED 5 times to show the CPU has woken up
        for (int x = 0; x < 5; x++)
        {
            Thread.Sleep(500);
            _Blue_LED.Write(GpioPinValue.High);
            Thread.Sleep(500);
            _Blue_LED.Write(GpioPinValue.Low);
        }

        var wakeupPinAddress = (IntPtr)8; // 8 is special marshal address for wakeup pin
        var wakeupPins = 0x08000000; // special value to detect multi pins
        // PA0: bit 0
        // PA2: bit 1
        wakeupPins |= 0x08000000 | (1 << 0) | (1 << 1); // PA0, PA2
        Marshal.WriteInt32(wakeupPinAddress, wakeupPins);

        // ALWAYS fails with System.NotSupportedException when wkupPin=true
        // UNLESS you specify the Power.WakeupEdge = WakeupEdge.Rising;
        Power.WakeupEdge = WakeupEdge.Rising;
        Power.Shutdown(true, rtc.Now + TimeSpan.FromSeconds(30));
    }

    // Detect Wake-Up from PA0
    private static void _Wakeup_0_ValueChanged(GpioPin sender, GpioPinValueChangedEventArgs e)
    {
        // Blink the Blue LED 3 times very fast to show that the 
        // _Wakeup_0_ValueChanged() was caught
        for (int x = 0; x < 3; x++)
        {
            Thread.Sleep(50);
            _Blue_LED.Write(GpioPinValue.High);
            Thread.Sleep(100);
            _Blue_LED.Write(GpioPinValue.Low);
        }
    }

    // Detect Wake-Up from PA2
    private static void _Wakeup_2_ValueChanged(GpioPin sender, GpioPinValueChangedEventArgs e)
    {
        // Blink the Blue LED 10 times very fast to show that the 
        // _Wakeup_2_ValueChanged() was caught
        for (int x = 0; x < 10; x++)
        {
            Thread.Sleep(50);
            _Blue_LED.Write(GpioPinValue.High);
            Thread.Sleep(100);
            _Blue_LED.Write(GpioPinValue.Low);
        }
    }
}

}`

Wakeup-Test -Circuit