2
\$\begingroup\$

I am sending bytes from SPI master (FTDI FT2232H) over SPI to the SPI slave (FPGA). SPI master is actually a C program that implements libMPSSE directly from the FTDI.

C program looks like this:

// POSIX headers
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>

// Other headers
#include "libMPSSE_spi.h"
#include "WinTypes.h"

    
////////////////////////////////////////////////////////////////////////////////////////////////////
// This function prints an array and then exits. We will use it for error printing.
////////////////////////////////////////////////////////////////////////////////////////////////////
void print_and_quit(char array[]){
    printf("%s\n", array);
    getchar();
    exit(1);
}


////////////////////////////////////////////////////////////////////////////////////////////////////
// Entry point.
////////////////////////////////////////////////////////////////////////////////////////////////////
int main(int argc, char ** argv){

    // A:
    Init_libMPSSE();
    
    FT_STATUS status; // B:
    FT_DEVICE_LIST_INFO_NODE channel_info; // C:
    FT_HANDLE handle; // D:

    ChannelConfig channel_configuration;

    unsigned int channel = 0;
    unsigned int channel_count = 0;
    int i;

    // E:
    status = SPI_GetNumChannels(&channel_count);
    if (status != FT_OK){
        print_and_quit("MASTER: Error while checking number of available MPSSE channels.");
    }
    else if (channel_count < 1){
        print_and_quit("MASTER: There are no MPSSE channels available.");
    }
    else{
        printf("MASTER: There are %d MPSSE channels available.\n", channel_count);
    }

    // F:
    for (i = 0; i < channel_count; i++){
        
        status = SPI_GetChannelInfo(i, &channel_info);
        if (status != FT_OK){
            print_and_quit("MASTER: Error getting channel info.");
        }
        else{
            printf("MASTER: Channel number: %d\n", i);
            printf("MASTER: Channel description: %s\n", channel_info.Description);
            printf("MASTER: Channel serial number: %s\n", channel_info.SerialNumber);
        }
    }

    // G:
    printf("MASTER: Enter a channel number to use: ");
    scanf("%u", &channel);

    // H:
    status = SPI_OpenChannel(channel, &handle);
    if (status != FT_OK){
        print_and_quit("MASTER: Error openning desired MPSSE channel.");
    }

    // I:
    channel_configuration.ClockRate = 1000;
    channel_configuration.configOptions = SPI_CONFIG_OPTION_MODE0 | SPI_CONFIG_OPTION_CS_DBUS4 |
        SPI_CONFIG_OPTION_CS_ACTIVELOW;
    channel_configuration.LatencyTimer = 30;
    status = SPI_InitChannel(handle, &channel_configuration);
    if (status != FT_OK){
        print_and_quit("MASTER: Error configuring & initializing selected MPSSE channel.");
    }
        
    // J:
    uint8_t send_buffer[8] = {
        0x00,
        0x00,
        0x00,
        0x00,
        0x00,
        0x00,
        0x00,
        0x11
    };
    uint32_t transfer_count = 0;
    uint32_t transfer_options = SPI_TRANSFER_OPTIONS_SIZE_IN_BYTES |
        SPI_TRANSFER_OPTIONS_CHIPSELECT_ENABLE | SPI_TRANSFER_OPTIONS_CHIPSELECT_DISABLE;
    
    status = SPI_Write(handle, send_buffer, 8, &transfer_count, transfer_options);
    if (status != FT_OK){
        print_and_quit("MASTER: SPI communication error.");
    }
    status = SPI_CloseChannel(handle);
    if (status != FT_OK){
        print_and_quit("MASTER: SPI channel closed.");
    }
    Cleanup_libMPSSE();
    
    return 0;

}

For some reason, sometimes the communication looks like this (signals are MOSI & SCK):

enter image description here

But sometimes communication is different like this:

enter image description here

and whenever I get the second signal, FPGA goes into a state which is reset state or idle state. I am not sure about which one it is.

In both cases FTDI chip sends 8 bytes i.e. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11 but when this is done in 1st case, MOSI data falls just a little which is correct, and in second case MOSI data remains high and also some high frequency clock can be seen on the SCK!

Why could this happen?


ADD1:

After suggested I measured GND directly on the PCB and I get some 2.5 kHz noise. This is the same frequency that can be seen in a scenario when after the data transmission, PCB goes in an idle / reset state.

Here is the noise from afar:

enter image description here

And a closeup to take the measurement of the frequency (2.5 kHz):

enter image description here


ADD2:

After discovering 2.5 kHz "noise" on the GND I assume that probably my oscilloscope is not connected properly. GND wires of the probes are properly connected to the GND, but there is a GND plug on the front of the oscilloscope which is not connected currently.

enter image description here

Could this be my problem?


ADD3:

After dissconnecting my oscilloscope from my system and discovering that symptoms remain, I am sure that oscilloscope is not part of the problem of going in a reset/idle state. Therefore I am suspecting that the problem is the PCB design which I already linked to in my first paragraph. Because link that I posted has Kicad project file, I am posting a PDF of the schematics here as well, so that somebody might check the SPI signal lines - I am using MODE0 as can be seen from the C program. SPI clock is 1kHz. FPGA's SPI slave is driven by 12 MHz external oscillator.

enter image description here


ADD4:

Measuring the output of 1.2 V and 3.3 V voltage regulators revelas that on power-on 1.2 V power supply comes online approximately 3ms after the 3.3 V power supply.

enter image description here

This is an excerpt from the Lattice Ultra Plus UP5k datasheet that I already linked to:

4.5. Power-up Supply Sequence

It is recommended to bring up the power supplies in the following order. Note that there is no specified timing delay between the power supplies, however, there is a requirement for each supply to reach a level of 0.5 V, or higher, before any subsequent power supplies in the sequence are applied.

  1. VCC and VCCPLL should be the first two supplies to be applied. Note that these two supplies can be tied together subject to the recommendation to include a RC-based noise filter on the VCCPLL. Refer to iCE40 Hardware Checklist (FPGA-TN-02006).
  2. SPI_VCCIO1 should be the next supply, and can be applied any time after the previous supplies (VCC and VCCPLL) have reached as level of 0.5 V or higher.
  3. VPP_2V5 should be the next supply, and can be applied any time after previous supplies (VCC, VCCPLL and SPI_VCCIO1) have reached a level of 0.5 V or higher.
  4. Other Supplies (VCCIO0 and VCCIO2) do not affect device power-up functionality, and they can be applied any time after the initial power supplies (VCC and VCCPLL) have reached a level of 0.5 V or greater. There is no power down sequence required. However, when partial power supplies are powered down, it is required the above sequence to be followed when these supplies are re-powered up again.

ADD5:

Investigating further reveals that in the scenario when board goes in a reset/idle state chip select (CS) line has some sort of a glitch soon after data is transfered and CS returns high (this glitch is always present when board goes in a reset/idle state):

enter image description here

This however is not present when sending data suceeds and board does not go in a reset/idle state:

enter image description here


ADD6:

Regarding ADD5... Signals are much nicer if I put external pullup resistors on CS, MOSI, MISO and SCK lines (there are no more any weird voltages between 0V and 3.3V).

But when the glitch, mentioned in ADD5 happens, board still goes in reset/idle state. It looks like this:

enter image description here

And without a glitch when PCB continues to work normally after the data transfer:

enter image description here

So that glitch is probably source of my problems.

\$\endgroup\$
3
  • \$\begingroup\$ All - The long comment chain has now exceeded what is reasonable for comments. Therefore it has been moved to chat and should be continued there (link below). --- As this bulk moving of comments to chat can only be done once per question, any further comments posted here might be deleted without notice. Keep it in chat, please! Any updates to the question via an edit, or any new answers, can still be written as usual. Thanks. \$\endgroup\$
    – SamGibson
    Sep 28, 2021 at 13:19
  • \$\begingroup\$ Comments are not for extended discussion; this conversation has been moved to chat. \$\endgroup\$
    – SamGibson
    Sep 28, 2021 at 13:19
  • \$\begingroup\$ @ChristianB. - Hi, FYI I have copied your comment into the chatroom linked above, so that it is in the same place as all the previous comments, and deleted your comment from here. I cannot show it as properly owned by you in the chatroom, so I have linked your profile there. \$\endgroup\$
    – SamGibson
    Sep 28, 2021 at 17:12

1 Answer 1

1
\$\begingroup\$

I would connect CS to GND to check if program works.

I am not good enough to analyse such code, but I don't see where you select chip (set CS to low). I only see that you set which pin is CS out and CS active as low.

Sometimes Chip Select circuit is independent from microcontroller. Every device gets same signal and only selected reacts to that signal.

P.S. I'd comment it but I can't.

\$\endgroup\$
8
  • \$\begingroup\$ So a simple pull-down resistor on the CS you mean? Everything is already on the PCB, but I could do this one! \$\endgroup\$
    – 71GA
    Sep 23, 2021 at 19:45
  • \$\begingroup\$ Symptoms are the same when pull-down is connected to CS. \$\endgroup\$
    – 71GA
    Sep 23, 2021 at 19:48
  • 2
    \$\begingroup\$ I meant that you disconnect CS from your master and connect slave's CS to GND. Because if its connected and pull-down then masters signal overrides CS (or no?). I have CS connected to GND in my DS1804 and it works. Tonight I need to run SPI with MCP41100, so Im going to check If I need pull down or short circuit to gnd is enough. \$\endgroup\$
    – Jomonger
    Sep 23, 2021 at 19:58
  • 1
    \$\begingroup\$ FTDI pin 19 SPI_CS should be an output and send 0 to FPGA pin 16 iCE_SS_B. FTDI pin 21 iCE_SS_B should always be set as an output when FTDI is master. Pins from pdf. \$\endgroup\$
    – Jomonger
    Sep 23, 2021 at 20:47
  • 3
    \$\begingroup\$ In the pic it rather seems like MOSI isn't held at a defined level when /CS goes high. Not necessarily an error I guess, but it looks odd. \$\endgroup\$
    – Lundin
    Sep 27, 2021 at 8:13

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.