MSEL pins on FE310

The manual makes mention of MSEL pins to control boot mode, but can’t seem to find info on which pins they are, including the datasheet.

Mostly interested in use for HiFive1 boards if they happen to become bootlocked and/or to avoid needing a doubletap bootloader.

Any info on these?

Which exact manual are you looking at? The HiFive Unleashed/FU540 has MSEL pins, but I don’t think that the FE310 does.

If you have bootloader problems you can reflash the bootloader via jtag. I believe the doubletap bootloader on the original HiFive1 is for the Arduino environment, so that people can use that without needing to learn how to use jtag.

Specifically the FE310-G002, and it’s manual linked from the RevB page

Pg 23 (Chpt 5 – Boot Process) it describes the different boot modes and the MSEL[1:0] pins, which I think is distinct from the Unleased chips (I recall seeing maybe 6 bits for that boot mode?).

My guess is the register exists, but the pins are not exposed on the package itself? I do see the pin state is read from 0x1000, but if the reset vector starts right at 0x1004 and reads it right away, I’m not sure I could do anything fancy to change it. It’s not a terrible thing to miss, but was curious if I’d be able to use it :slight_smile:

This may be starting to get off-topic since it’s more HiFive1 specific, but I was able to resolve my bootloader problems via jtag, so I’m not looking for a solution per se but have since been toying with the startup and initial flash locations. (I may have been mistaken about doubletap here, but the RevB does have some kind of bootcode at the start of flash that at least powers off the radios in the ESP32).

Chapter 5 states the four values of MSEL[1:0] are
0 0 trap loop
0 1 j QSPI (0x2000 0000)
1 0 j OTP (0x0002 0000)
1 1 j ROM (0x0001 0000) (on -G000 it’s 0x00001000 or a typo?)

Since we observe normal start up from the qspi flash device, it must be the case that MSEL[0] is pulled high, and MSEL[1] is either pulled low or floats to low level.

Looking at the schematic of HiFive1 Rev B there is a pullup resistor R29 (100k) on physical pin 1. Pin 1 is GPIO-31, also SPI2-DQ3 (aka, QSPI-DQ3). It would make sense for the initial boot select pins to be grouped together with the external device that reads at boot, and placed sequentially at either the high end or the low end of physical pins and/or i/o lines.

If I had to fathom a guess, the two (and possibly all four) MSEL pins are
MSEL-0 GPIO-31 48QFN-pin-1
MSEL-1 GPIO-30 48QFN-pin-2
MSEL-2 GPIO-28 48QFN-pin-3
MSEL-3 GPIO-27 48QFN-pin-4

The Preliminary Datasheets, for both -G000 and -G002 parts, has a typo in Figure2.1; there are duplicate “QSPI-DQ-2’s” and two pin 2’s.

There is a slightly different description of the boot chapter in the Manual for the -G000 part. There, it makes reference to three signals psdmaskromen, psdotpen, and psdqspien, instead of the two MSEL inputs.




HiFive1 Rev B Schematic

Don’t think it’s a typo–judging from the memory map, it looks like the mode select rom at 0x1000 is new in g002, and they moved the mask rom down to 0x1_000 to make room.

Oh! That’s really interesting with the 1.0.1 rev mentioning the psd___en names instead. Maybe this was originally intended to be an AON controlled behavior? But, not sure since they removed the specific names in later versions. The behavior sounds the same despite g002 saying it’s the mode select rom that implements that behavior.

Hmmm, maybe they do reuse pins. Reading this again, it sounds like the pin state is stored in 0x1000, so maybe I can make an in-memory loop to print that value and try shorting different pins to see.

You are absolutely right, not a typo. Saw that Wesley made the change on 3/24/2017, making both the address and the size of bootrom go from 0x1000 to 0x10000; and corresponding change to the reset vector (hang point) from 0x1040 to 0x10040.

Your idea of testing our hypothesis by in-memory loop is a profound one. Might want to run from ram 0x80000000 so as not to engage any QSPI behavior. Note that QSPI is an IOF function (on IOF0 to be precise), so you might want to disable those IOF-EN bits for gpio27,28,30,31 beforehand.

It’s probably not trivial just how during the power-up or reset process the i/o pins make their way over to memory location 0x1000. This might be a one-time-per-reset hardware thing. Also curious is what are the reset values for IOF-EN. Do all i/o pins come up as gpio, or do some pins (like the QSPI pins) come up at reset as IOF0? If a scope is available, watching for level shifts might give a clue as to when a pin changes from input to output, for example.

Another very simple test might be to gently pull high the WP#/IO2 pin 3 of the flash chip – which is by our guess MSEL1 – and then power-up or reset the device. If you’re not able to run code from 0x20000000 anymore then it means we’ve successfully selected the ROM at 0x10000 (on the -G002 part). Pulling Low the HOLD#/IO3 line might inhibit the flash chip and thus interfere with our sleuthing. Quick sketch follows. Very interested to see your discoveries.

Some other items of interest follow. Curious how the jump goes to ram rather than [external] flash. Maybe this was an fpga debug thing, later changed to 0x20000000 just before tapeout? Might be there is no reading of any pins after all anymore? So curious!

I filed a SiFive internal documentation bug, asking about the MSEL pins, and pointing at this forum thread.
I also pointed out the QSPI_DQ_2 error.

1 Like

Thanks @jimw! Looking forward to hearing more about that.

Good news is I was able to very easily read the pin state at 0x1000 via JTAG, and confirmed the default state is 0x03 (jump to mask rom).

The bad news is no matter what I tried I could not get this to change. Pulling any of the SPI pins either high or low with a 100k resistor and resetting the board did not seem to change this. I also tried a few of the AON pins (such as wake/reset) and a few others I was suspicious of. None seemed to do the trick.

I had tried to hold the WP pin high and continue boot, but couldn’t get it to fail as expected, so I probably did something wrong here ;] but I think with the document bug in I may hold off on this for now.