2017-09-22 27 views
1

私はSPI経由で簡単な接続を設定しようとしていますが、SpiDeviceを取得しようとするとSpiDevice.FromIdAsyncメソッドは終了しません。これはほとんど例外なく、ほとんど例外なく見えます。非同期メソッドSpiDevice.FromIdAsyncが終了しません

spi = await SpiDevice.FromIdAsync(dis[0].Id, settings); 

接続の設定に使用するコードは、https://docs.microsoft.com/en-us/windows/iot-core/learn-about-hardware/pinmappings/pinmappingsrpi#spi-busです。

この例では、シフトレジスタとして動作するLEDドライバに1バイトを出力します。ターゲットデバイスとしてRaspberry Pi 3を使用し、IDEとしてVisual Studio Community 2017を使用します。

MainPage.xaml.cs

using System; 
using Windows.UI.Xaml; 
using Windows.UI.Xaml.Controls; 
using Windows.Devices.Gpio; 
using Windows.Devices.Spi; 
using Windows.Devices.Enumeration; 
using System.Threading.Tasks; 

namespace SPI_Test 
{ 
    public sealed partial class MainPage : Page 
    { 
     public MainPage() 
     { 
      this.InitializeComponent(); 

      try 
      { 
       InitGPIO(); 
       InitSpi().Wait(); 

       timer = new DispatcherTimer(); 
       timer.Interval = TimeSpan.FromMilliseconds(500); 
       timer.Tick += Timer_Tick; 
      } 
      catch (Exception) 
      { 

      } 
     } 

     GpioPin enablePin; 
     SpiDevice spi; 

     private void InitGPIO() 
     { 
      var gpio = GpioController.GetDefault(); 

      //create pin to control the output of the LED driver 
      //the outputs are active when the pin is low 
      enablePin = gpio.OpenPin(12); 
      enablePin.Write(GpioPinValue.High); //disable outputs at first 
      enablePin.SetDriveMode(GpioPinDriveMode.Output); 
     } 

     private async Task InitSpi() 
     { 
      try 
      { 
       // Use chip select line CS0 
       var settings = new SpiConnectionSettings(0); 
       // Set clock to 10MHz 
       settings.ClockFrequency = 10000000; 

       // Get a selector string that will return our wanted SPI controller 
       string aqs = SpiDevice.GetDeviceSelector("SPI0"); 

       // Find the SPI bus controller devices with our selector string 
       var dis = await DeviceInformation.FindAllAsync(aqs); 

       spi = await SpiDevice.FromIdAsync(dis[0].Id, settings); /* Create an SpiDevice with our bus controller and SPI settings */ 

      } 
      /* If initialization fails, display the exception and stop running */ 
      catch (Exception ex) 
      { 
       throw new Exception("SPI Initialization Failed", ex); 
      } 
     } 

     private DispatcherTimer timer; 
     private byte value = 0; 
     private void Timer_Tick(object sender, object e) 
     { 
      enablePin.Write(GpioPinValue.High); //disable outputs 
      spi.Write(new byte[] { value++ }); //send the current value to the LEDs and increase by 1 
      enablePin.Write(GpioPinValue.Low); //re-enable outputs 
     } 

     private void Button_Click(object sender, RoutedEventArgs e) 
     { 
      timer.Start(); 
     } 
    } 
} 

MainPage.xamlを

<Page 
    x:Class="SPI_Test.MainPage" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:local="using:SPI_Test" 
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
    mc:Ignorable="d"> 

    <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"> 
     <StackPanel HorizontalAlignment="Center" VerticalAlignment="Center"> 
      <Button Click="Button_Click" Content="Start" Margin="15" /> 
     </StackPanel> 
    </Grid> 
</Page> 

答えて

1

あなたがあるため、ブロッキング呼び出し.Wait()と非同期呼び出しの混合のデッドロックが発生しています。そのロジックをイベントハンドラに移動することをお勧めします。 Like Loaded

public MainPage() { 
    this.InitializeComponent(); 
    this.Loaded += async (sender, e) => { 
     try { 
      InitGPIO(); 
      await InitSpi(); 

      timer = new DispatcherTimer(); 
      timer.Interval = TimeSpan.FromMilliseconds(500); 
      timer.Tick += Timer_Tick; 
     } catch (Exception) { 

     } 
    }; 
} 
+0

あなたの答えはありがとう。今すぐ動作します。デッドロックについて聞いたことはありません。私はこの記事http://blog.stephencleary.com/2012/07/dont-block-on-async-code.htmlを見つけたので、問題を理解するのに役立ちました。 – branbu28

関連する問題