G30 SPI - Changing SPI config from one with low edge latching to one with high edge latching causes error in first transaction


I am having an issue with a G30 module.

If I want to talk to two devices I set up SPI like this

SPI.Configuration config_Right = new SPI.Configuration(GHI.Pins.G30.Gpio.PC7, false, 0, 0, false, false, 500, GHI.Pins.G30.SpiBus.Spi2);
SPI.Configuration config_mcu = new SPI.Configuration(GHI.Pins.G30.Gpio.PB0, false, 3, 0, false, true, 500, GHI.Pins.G30.SpiBus.Spi2);
SPI_Bus = new SPI(config_mcu);

Now before initiating an SPI transaction I make sure to execute

SPI_Bus.Config = <the appropriate config>

I have seen this work in the past. The only difference being that I changed the clock_edge parameter of config_mcu to true.

Now the confusing part is that If I conduct a transaction using config_right, then my next transaction with config_mcu will not contain the correct data on MOSI. I have confirmed that MOSI behavior is incorrect even with no devices attached.

However if I continue to have transactions with config_mcu they will be correct until the next time I launch a transaction with the other device, then the first one with config_mcu will be wrong again.

Does anyone know what might be the source of my issue?

https://www.ghielectronics.com/docs/14/spi#80 has the multi-device section; it seems to match yours, so all I can suggest is either you have something in your code that you haven’t noticed, or you have identified a very specific bug.

In case of 1, can you create a completely minimal program that demonstrates this?
In case of 2, and to help support 1, can you identify the SDK and firmware versions (use FezConfig to show) ?


Thanks for reaching back out to me. So I made the simple program.

public class Program
    static SPI SPI_Bus;
    static byte[] tx_data, rx_data, m_tx_data, m_rx_data;

    public static void Main()
        SPI.Configuration config_A = new SPI.Configuration(GHI.Pins.G30.Gpio.PC7, false, 0, 0, false, false, 500, GHI.Pins.G30.SpiBus.Spi2);
        SPI.Configuration config_B = new SPI.Configuration(GHI.Pins.G30.Gpio.PB0, false, 3, 0, false, true, 500, GHI.Pins.G30.SpiBus.Spi2);

        SPI_Bus = new SPI(config_A);

        tx_data = new byte[3];
        rx_data = new byte[3];

        tx_data[0] = 0xA1;
        tx_data[1] = 0xA2;
        tx_data[2] = 0xA3;

        m_tx_data = new byte[3];
        m_rx_data = new byte[3];

        m_tx_data[0] = 0xB1;
        m_tx_data[1] = 0xB2;
        m_tx_data[2] = 0xB3;

        while (true)
            SPI_Bus.Config = config_A;
            SPI_Bus.WriteRead(tx_data, rx_data);

            SPI_Bus.Config = config_B;
            SPI_Bus.WriteRead(m_tx_data, m_rx_data); // this is where the problem is expected

            SPI_Bus.WriteRead(m_tx_data, m_rx_data); // the second transmission is expected to work

And this is what I see on my analyzer:

The program is straightforward. The pattern you see here repeats for forever. Interestingly, the “incorrect” transaction is always the same when the data is not changing between transactions. It looks to me like the G30 won’t pull the line low until a few clocks in. Further more my analyzer doesn’t even see three bytes here. I’m counting 24 clock pulses for the correct transaction and 22 for the incorrect.

Here you see MISO working but I have verified that this happens even without the devices attached so it can’t be logic level issues or signal integrity.

My program here demonstrates an obvious workaround. But I don’t rest easy knowing my receiving device receives something invalid at unknown times.

Can you reproduce the issue and see what causes the behavior?

SDK: Netmf 4.3 SDK (release notes match this firmware number)

It may be worth stating that if both configurations have Clock_polarity set to false then the issue does not occur. Of course this is not a viable fix because the G30 will not stabilize logic when Device B expects.

1 Like

great write up of the problem. That at least becomes actionable for GHI, if this is truly a bug

1 Like

@jwizard93 Does that same issue occur on SPI1?

To summarize: when you change the SPI config on the same bus to an identical config but with an inverted clock edge, the first transaction after the change is corrupt?

@Justin Yes the issue occurs on SPI1 as well. However, the incorrect bytes read 0x4B 0x2B instead of 0xFE 0xCA.

@John_Brochue In my application and in my simple program above I also have a chipSelect_setupTime of 3. I removed that to test for your question. The answer is yes even with otherwise identical parameters if one clock edge is different than the other then the issue arises.

Also I never could find this out, so while we are talking SPI, what are the units for the setup time and hold time parameters?

The unit is in microseconds. We were able to reproduce the issue, but don’t have a fix at this time.

1 Like

@John_Brochue I understand. I will push forward with the workaround for now. Would you please inform me when a solution is discovered? Thanks for the info.

We will update you when we have more information.

@John_Brochue If I updated to the latest (which I believe is what you call TinyCLR OS?) Would I still have this issue?

TinyCLR OS is indeed the latest that we have, but it isn’t quite production ready yet. If the issue does exist on TinyCLR, we will be able to get a fix out much quicker for it.

Oh okay. I go to market very soon. I was on the fence about the upgrade now I feel comfortable with holding off. Thank you for the support.