SPI Transfer error

I try to communicate with an MP3 Click module connected on Click #1 (but same thing for Click #2) on an endpoint.
Here is code:

using GHIElectronics.Endpoint.Core;
using static GHIElectronics.Endpoint.Core.EPM815;
using System.Device.Spi;
using System.Device.Gpio;
using System.Device.Gpio.Drivers;
using System.Numerics;

namespace testVs1053b
{
    internal class Program
    {
        static private byte[] cmdBuffer = new byte[4];
        static private byte[] readBuffer = new byte[4];

        static void Main(string[] args)
        {
            Console.WriteLine("Hello, World!");

            // Construct SPI bus cmdSetting
            EPM815.Spi.Initialize(EPM815.Spi.Spi4);
            var setting = new SpiConnectionSettings(EPM815.Spi.Spi4)
            {
                ClockFrequency = 2_000_000,
 //               Mode = SpiMode.Mode0,
                //ChipSelectLineActiveState = false,
                //DataFlow=DataFlow.MsbFirst,
                //DataBitLength=8,
                //BusId=EPM815.Spi.Spi4
            };
            var _spi = SpiDevice.Create(setting);

            // Construct pins
            // CS pin
            var pinNumberCS = EPM815.Gpio.Pin.PZ7;

            var portCS = pinNumberCS / 16;
            var pinCS = pinNumberCS % 16;
            var gpioDriverCS = new LibGpiodDriver(portCS);
            var gpioCS = new GpioController(PinNumberingScheme.Logical, gpioDriverCS);
            if (gpioCS == null) throw new NullReferenceException("GpioCS is null");
            gpioCS.OpenPin(pinCS);
            gpioCS.SetPinMode(pinCS, PinMode.Output);
            gpioCS.Write(pinCS, PinValue.High);

            // DCS pin
            var pinNumberDCS = EPM815.Gpio.Pin.PZ6;

            var portDCS = pinNumberDCS / 16;
            var pinDCS = pinNumberDCS % 16;
            var gpioDriverDCS = new LibGpiodDriver(portDCS);
            var gpioDCS = new GpioController(PinNumberingScheme.Logical, gpioDriverDCS);
            if (gpioDCS == null) throw new NullReferenceException("GpioDCS is null");
            gpioDCS.OpenPin(pinDCS);
            gpioDCS.SetPinMode(pinDCS, PinMode.Output);
            gpioDCS.Write(pinDCS, PinValue.High);

            // Reset pin
            var pinNumberReset = EPM815.Gpio.Pin.PA12;

            var portReset = pinNumberReset / 16;
            var pinReset = pinNumberReset % 16;
            var gpioDriverReset = new LibGpiodDriver(portReset);
            var gpioReset = new GpioController(PinNumberingScheme.Logical, gpioDriverReset);
            if (gpioReset == null) throw new NullReferenceException("GpioReset is null");
            gpioReset.OpenPin(pinReset);
            gpioReset.SetPinMode(pinReset, PinMode.Output);
            gpioReset.Write(pinReset, PinValue.High);

            // Dreq pin
            var pinNumberDreq = EPM815.Gpio.Pin.PC3;

            var portDreq = pinNumberDreq / 16;
            var pinDreq = pinNumberDreq % 16;
            var gpioDriverDreq = new LibGpiodDriver(portDreq);
            var gpioDreq = new GpioController(PinNumberingScheme.Logical, gpioDriverDreq);
            if (gpioDreq == null) throw new NullReferenceException("GpioDreq is null");
            gpioDreq.OpenPin(pinDreq);
            gpioDreq.SetPinMode(pinDreq, PinMode.InputPullUp);

            // Reset Module
            gpioReset.Write(pinReset, PinValue.Low);
            Thread.Sleep(1);
            gpioReset.Write(pinReset, PinValue.High);
            Thread.Sleep(1);

            // Get Status 
            cmdBuffer[0] = 0x03;
            cmdBuffer[1] = 0x01; // Get SCI_STATUS
            cmdBuffer[2] = 0;
            cmdBuffer[3] = 0;

            gpioCS.Write(pinCS, PinValue.Low);
            _spi.TransferFullDuplex(cmdBuffer, readBuffer);
            gpioCS.Write(pinCS, PinValue.High);


        }
    }
}

It throws an exception when I try transfer via SPI:

I’ve try to set mode (or not, it seems to be Mode0 by default), but I always obtain this error.

Add the line “GHI add” to your code. We will mention this is our doc if that fix the problem.

var setting = new SpiConnectionSettings(EPM815.Spi.Spi4)
{
    ClockFrequency = 2_000_000,

    ChipSelectLine = 0 // GHI added
};
1 Like

You are the error killer ! That is fixed !

3 Likes

Can someone please explain why we have System.Device.Spi as well as EPM815.Spi namespaces?

I think first one is implementation of communication (read, write, transfer …) whereas the second, is which pin on endpoint (link to STM32) is connected (MISO, MOSI, …).

System.Device.Spi from Microsoft.

EPM815.Spi from GHI as advanced, that allows you change pins or buffer size (next release).

So I figured I’ll add to this convo instead of starting a new one. I’m having similar troubles transferring data over SPI. “System.IO.IOException: Error 22 performing SPI data transfer.”
Mode = 3, Clock Frequency = 100000

EDIT: It was the clock frequency. Seems it needs to be 1Mhz? Weird.

This is the function that throws:

It’s pretty disappointing that all you see is “error 22” not some specific explanatory text. Here’s the control code it’s sending to the driver:

I will confess to not having tried your code snippet @Mr_John_Smith , but errno 22 (EINVAL) means that the underlying code didn’t like one of the provided arguments. Some combination of the values provided (or omitted) in _spiConnectionSettings is giving the underlying linux driver some indigestion. Are the expected values being pulled out of config into your locals?

Yes. the SpiMode = 3, and Clock Frequency = 100Khz. It didn’t like 100Khz, and I had to increase it to 1Mhz.

1 Like