Search code examples
c#uwpwindows-10-iot-core

Windows IoT | Problems with SPI transaction


Faced with the fact that SPI stops working, I can’t understand why, since there is no exception. I'm using a non-standard way for the transfer event. This is due to the fact that the Raspberry Pi cannot be a slave. My master is STM32F103C8T6. To solve this problem, GPIO was raised on the Raspberry Pi.

 private void InitGPIO()
    {
        gpioController = GpioController.GetDefault();
        gpioPinSTM = gpioController.OpenPin(GPIO_PIN25);
        gpioPinSTM.IsDriveModeSupported(GpioPinDriveMode.InputPullDown);
        gpioPinSTM.SetDriveMode(GpioPinDriveMode.Input);
        gpioPinSTM.ValueChanged += Gpio_ValueChanged;
    }

STM changes the state of the GPIO, and the Gpio_ValueChanged method is triggered by any change.

    private void Gpio_ValueChanged(GpioPin sender, GpioPinValueChangedEventArgs args)
    {
        if (args.Edge == GpioPinEdge.RisingEdge)
        {
           STM32F103C6T6.TransferFullDuplex(arrToSTM, arrFromSTM);
           getFromSTM();
        }
    }

Wrote separately diagnostics at transaction. Where do I get data from STM. The first element of the array comes with iteration. As you can see then I start to get 0.

enter image description here

I decided that spi should run on a separate thread. By executing a transaction in a timer.

void TimerSPI(object sender, object e)
    {
        if (gpioPinSTM.Read() == GpioPinValue.High)
        {
            if (checkGPIOStatus == 1)
            {
                STM32F103C6T6.TransferFullDuplex(arrToSTM, arrFromSTM);
                getFromSTM();
                checkGPIOStatus = 0;
            }
        }
        else if (gpioPinSTM.Read() == GpioPinValue.Low)
        {
            checkGPIOStatus = 1;
        }
    }

Used two types of timers and got different results First option:

private DispatcherTimer timer = new DispatcherTimer();
....
timer = new DispatcherTimer() { Interval = TimeSpan.FromMilliseconds(3) };
timer.Tick += TimerSPI;
timer.Start();

Second option:

private static System.Timers.Timer timer;
....
timer = new System.Timers.Timer(3);
timer.Elapsed += TimerSPI;
timer.AutoReset = true;
timer.Enabled = true;

In the first case, it works fine, but slowly. In the second case, it works quickly, but the same situation occurs as described above. Maybe someone knows how such a transaction can be implemented? And maybe my approach is completely wrong, I don't know...


Solution

  • I found this solution, I don’t know how true it is, but it helped me.

    private void TimerSPI(object sender, object e)
        {
            timer.Stop();
            if (gpioPinSTM.Read() == GpioPinValue.High)
            {
                //System.Diagnostics.Debug.WriteLine($"HIGH");
                if (checkGPIOStatus == 1)
                {
                    checkGPIOStatus = 0;
                    //System.Diagnostics.Debug.WriteLine($"SendWhen 1: {arraySTM.cellInt1} || {arraySTM1.cellInt1} || {arraySTM2.cellInt1}");
                    STM32F103C6T6.TransferFullDuplex(arrToSTM, arrFromSTM);
                    getFromSTM();
                    operationStatus((STATUS)arrayFromSTM2.cellInt1);
                    //System.Diagnostics.Debug.WriteLine($"##############################################################################");
                }
            }
            else if (gpioPinSTM.Read() == GpioPinValue.Low)
            {
                //System.Diagnostics.Debug.WriteLine($"LOW");
                if (checkGPIOStatus == 0)
                {
                    checkGPIOStatus = 1;
                    //System.Diagnostics.Debug.WriteLine($"SendWhen 0: {arraySTM.cellInt1} || {arraySTM1.cellInt1} || {arraySTM2.cellInt1}");
                    STM32F103C6T6.TransferFullDuplex(arrToSTM, arrFromSTM);
                    getFromSTM();
                    operationStatus((STATUS)arrayFromSTM2.cellInt1);
                    //System.Diagnostics.Debug.WriteLine($"##############################################################################");
                }
            }
            timer.Start();
        }
    

    STM operates in standby mode at 0 and 1.