Difference between booting with USB host connected and not?

Hello,

To keep things short, I have a problem with a FPGA sketch. Everything works as expected when i start the MKR 4000 board connected to a PC via a data USB cable, and if i disconnect it everything still works (the board is powered by 5V on the Vin pin).

If I start the board without connecting it to the PC things gets wierd. The FPGA design works more or less, but there is minor data corruption when I write data to the RAM, corruption which is not present when the board is booted with the data USB cable connected. I suspect that something isn't working quite right with the FPGA configuration when the USB cable is unplugged during startup.

I can of course go into more detail, but i think I'll keep it short for now.

Does anyone have an idea what might be happening? It seems like the only real difference between the cases is the presence of the USB DP and DM wires, so i guess something happens differently during startup depending on whether USB communication is up and running. I can't for the life of me figure out what that might be however.

Earlier tests:

I suspected the battery management IC capped the input current to 100 mA at first, which i thought might not be enough to configure the FPGA correctly, but it turns out that the board is capped at 100 mA even with the USB data cable attached. I tried changing the input current limit on the chip via I2C, but that made no difference neither.

I've tried a USB charge only cable hooked up to the PC, that didn't work so I'm fairly certain that having a USB host connected is the important part, instead of some magical ground problem.

Here is the sketch I'm using to configure the FPGA, I'm using the method provided by SmarkAleks back in the day

#include <arduino.h>
#include <SPI.h>
#include "jtag.h"

// For High level functions such as pinMode or digitalWrite, you have to use FPGA_xxx
// Low level functions (in jtag.c file) use other kind of #define (TDI,TDO,TCK,TMS) with different values
#define FPGA_TDI                            (26u)
#define FPGA_TDO                            (29u)
#define FPGA_TCK                            (27u)
#define FPGA_TMS                            (28u)

// Clock send by SAMD21 to the FPGA
#define FPGA_CLOCK                        (30u)

// SAMD21 to FPGA control signal (interrupt ?)
#define FPGA_MB_INT                       (31u)

// FPGA to SAMD21 control signal (interrupt ?)
#define FPGA_INT                          (33u) //B2 N2

// For MKR pinout assignments see : https://systemes-embarques.fr/wp/brochage-connecteur-mkr-vidor-4000/

extern void enableFpgaClock(void);

#define no_data    0xFF, 0xFF, 0xFF, 0xFF, \
          0xFF, 0xFF, 0xFF, 0xFF, \
          0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, \
          0xFF, 0xFF, 0xFF, 0xFF, \
          0x00, 0x00, 0x00, 0x00  \

#define NO_BOOTLOADER   no_data
#define NO_APP        no_data
#define NO_USER_DATA    no_data

__attribute__ ((used, section(".fpga_bitstream_signature")))
const unsigned char signatures[4096] = {
  //#include "signature.ttf"
  NO_BOOTLOADER,

  0x00, 0x00, 0x08, 0x00,
  0xA9, 0x6F, 0x1F, 0x00,   // Don't care.
  0x20, 0x77, 0x77, 0x77, 0x2e, 0x73, 0x79, 0x73, 0x74, 0x65, 0x6d, 0x65, 0x73, 0x2d, 0x65, 0x6d, 0x62, 0x61, 0x72, 0x71, 0x75, 0x65, 0x73, 0x2e, 0x66, 0x72, 0x20, 0x00, 0x00, 0xff, 0xf0, 0x0f,
  0x01, 0x00, 0x00, 0x00,   
  0x01, 0x00, 0x00, 0x00,   // Force

  NO_USER_DATA,
};
__attribute__ ((used, section(".fpga_bitstream")))
const unsigned char bitstream[] = {
  #include "app.h"
};


// the setup function runs once when you press reset or power the board
void setup() {

  int ret;
  uint32_t ptr[1];

  enableFpgaClock();

  //Init Jtag Port
  ret = jtagInit();
  mbPinSet();

  // Load FPGA user configuration
  ptr[0] = 0 | 3;
  mbEveSend(ptr, 1);

  // Give it delay
  delay(1000);

  // Configure onboard LED Pin as output
  pinMode(LED_BUILTIN, OUTPUT);

  // Disable all JTAG Pins (usefull for USB BLASTER connection)
  pinMode(FPGA_TDO, INPUT);
  pinMode(FPGA_TMS, INPUT);
  pinMode(FPGA_TDI, INPUT);
  pinMode(FPGA_TCK, INPUT);

  // Configure other share pins as input too
  pinMode(FPGA_INT, INPUT);

}


// the loop function runs over and over again forever
void loop() {

                     
}

I'm grateful for any help, cheers!

Why not post a schematic, I am not good on word problems.

One thing come to my mind is if Arduino bootloader use DFLL in USBCRM mode when usb is connected. In this case it can run USB without crystal and it will recover reference clock from usb frame. So without usb it will use internal oscillator and it is not that accurate.

I recommend to use 24 MHz crystal oscillator for FPGA side if there isn't usb connected.

Offtopic: I'm doing expansion board that have 50 MHz oscillator and MAX V CPLD. This is hobby project so it will take time.

Did you ever solve this? I am having a similar issue that came about after messing around with the Vidor the last couple of weeks. Any sketch I run on the 4000 works the first time after uploading, but on reset or power off/on nothing seems to run.

Unfortunately i didn't really solve it, i reverted some changes and then it magically started working again.

I suspect there might be some finer points of FPGA design that I'm messing up, i'm crossing clock domains left and right without any real training in hardware design. I often end up brute forcing it by making random minor changes and recompiling until it works. I never tried messing around any more with the USB trail, i just test stuff after unplugging the arduino from the computer now.

Luckely i'm almost done with the FPGA parts of the project now, it's more of a chore than fun by now.

I hope no potential empolyers ever reads this:D

Btw, did it ever work properly or did it always stop working after a reboot? What method are you using to flash the FPGA?

I'm just using the default VidorPeripherals library. My project was to get bluetooth working on the Vidor, which I managed to solve but it wasn't working on battery power alone. Today I noticed that when I plugged it back in to the PC it immediately started up without intervention. So, I looked again at the BatteryMonitor example sketch and noticed the culprit in setup()... while (!Serial). So, yeah. smh. Lol.

Haha been there done that, more or less. Congrats for solving it either way:)

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.