• Hardware
  • Booting from SD card by shorting GPIO

Hey,

I'd like to add a button to my cape/pcb that makes the Bela boot from the SD card.

Managing your SD card mentions either pressing boot button (S2) or shorting P8_45 and P8_46 to 3.3V and P8_44 to GND. If I look at the BBB schematics it seems shorting P8_43 (LCD_DATA2) to GND through a 100Ω resistor should work, as that is what the boot button does.

Why does Bela require shorting three pins? Does holding down the boot button not always works, perhaps when a Bela cape is attached?

edit: messed up the title, should be booting from SD

    Ward Why does Bela require shorting three pins? Does holding down the boot button not always works, perhaps when a Bela cape is attached?

    According to the BONEBLK_SRM,

    the default setting. On boot, the processor will look for the eMMC on the MMC1 port first, followed by the microSD slot on MMC0, USB0 and UART0. In the event there is no microSD card and the eMMC is empty, UART0 or USB0 could be used as the board source.
    If you have a microSD card from which you need to boot from, hold the boot button down. On boot, the processor will look for the SPI0 port first, then microSD on the MMC0 port, followed by USB0 and UART0. In the event there is no microSD card and the eMMC is empty, USB0 or UART0 could be used as the board source.

    Now, we observed that sometimes when pressing the button to force boot from SD card, the board wouldn't boot. As we do have some peripherals (analog ADC and DAC) connected to SPI0 our guess was that these would be somewhat interfering with the boot process. Perhaps the BBB though that there was a valid SPI flash on SPI0 and tried to download data from it. The issue was intermittent but still annoying and confusing, so we went for recommending the three pins as that changes the boot sequence so that it tries the microSD before SPI0, thus removing this issue.

    giuliomoro changed the title to Booting from SD card by shorting GPIO .

    So I looked at the boot pin configuration table in the and to summarize:

    sysboot pins        boot sequence
    0100 0000 0011 1100 MMC1  --> MMC0  --> UART0 --> USB0   (normal boot order)
    0100 0000 0011 1000 SPI0  --> MMC0  --> USB0  --> UART0  (boot button held)
    0100 0000 0011 0111 MMC0  --> SPI0  --> UART0 --> USB0   (with jumpers)
    
    MMC1 = EMMC
    MMC0 = SD card

    Yup, sound right. If on your board you don't have any SPI peripheral on P9_18 and P9_21, then just use the button and forget about the jumpers.

    I want the end-user to be able to boot from SD so they can flash a clean image to the EMMC, without opening the device and touching the BBB. I had the idea to put a right-angled tactile switch near the edge of the board, so the user can push that with a toothpick or paperclip.

    These switches only seem to come in SPST which is OK when I only have to short P8_43 to GND. However, as I have an OLED display and 12bit ADCs connected to SPI0 I probably have to implement the jumper solution with a single SPST switch.

    I don't really have a deep understanding of transistors but I think this should work...

      Ward These switches only seem to come in SPST which is OK when I only have to short P8_43 to GND. However, as I have an OLED display and 12bit ADCs connected to SPI0 I probably have to implement the jumper solution with a single SPST switch.

      If you do have something connected to the SPI bus, you could make sure that those are in reset mode when the board boots. If they have a reset pin, do not hardwire it as always on, but rather put a pullup/down on it to keep it in reset at boot and then connect it to a GPIO that gets toggled from the code before initialising the devices.

      Keep in mind that you have all the boot pins exposed on P8 and you don't have to use the same logic as pressing S2, that is to say that another alternative is to investigate if you can find two suitable boot sequences such that:

      • one boots from MMC1, the other one from MMC0 without passing via SPI
      • only require a single change to pass from one to the other

      Then, hardwire the "default" one via resistors on the board and wire the one pin you need to change to the button.

      I think I might not be able to keep all my SPI devices reset.

      • I have a SSD1322 oled driver with a reset pin wired to a gpio. I'll add a physical pulldown resistor to make sure it stays reset. Not a problem.
      • I also have 2x MCP3008 which do not have reset pins but use the CS both as chip select and as shutdown. As I have one of the CS pins connected to P9_17 (spi0_cs0) and this pin is used when initializing from SPI0. I can add pullup resistors so they stay shutdown. It still might be possible to create a similar situation as you described, where sometimes the SPI boot might 'succeed' and thus not proceed to SD card boot. I can probably verify if this happens without ordering new PCBs.

      As for an alternative boot order, I looked at the boot config table and I found one options that might work:

      0100 0000 0010 1000 EMAC --> MMC0 --> XIP (MUX2) --> NANDI2C

      If the EMAC / ethernet boot reliably fails this could be an option. I'm not sure if this is a good idea security wise and it seems to add 5 second to the boot time according to the EMAC boot initialization procedure.

      To get this boot order I'd have to pull down both P8_43 and P8_41 which I can do by connecting both pins through their own resistor to one side of the switch, and the other side to ground. If I find out later that I don't have the SPI boot issue I can just not populate the P8_41 resistor.

      I think I'm going to try if just shorting P8_43 to ground is enough before making further changes to the PCB.

        Ward If the EMAC / ethernet boot reliably fails this could be an option. I'm not sure if this is a good idea security wise and it seems to add 5 second to the boot time according to the EMAC boot initialization procedure.

        I'm not familiar with that one, sorry.

        Note that it's not only about whether you have an SPI peripheral there, but also whether that peripheral behaves in such a way that the bootloader may mistake it for flash or EEPROM. See section SPI boot 26.1.8.6.2 Initialization and detection of the TRM:

        The ROM Code initializes the SPI controller, pin muxing and clocks for communicating with the SPI
        device. The controller is initialized in Mode 3 and the clock is setup to operate at 12 MHz. There is no
        specific device identification routine that is executed by the ROM code to identify whether a boot device is
        preset or not. If no SPI device is present, the sector read will return only 0xFFFFFFFF and the SPI boot
        will be treated as failed.

        So for instance if your device always has the data out line high at boot, that should be enough. If it's left to high-z, then you may need some weak but not too weak pullups: they have to be small enough to counteract the effect of any (if there is any at all?) internal pulldowns but they should be large enough not to interfere with signal quality or current consumption at runtime. Try 10k maybe?

        • Ward replied to this.
          4 months later

          giuliomoro So for instance if your device always has the data out line high at boot, that should be enough. If it's left to high-z, then you may need some weak but not too weak pullups: they have to be small enough to counteract the effect of any (if there is any at all?) internal pulldowns but they should be large enough not to interfere with signal quality or current consumption at runtime. Try 10k maybe?

          I will put 10kΩ pullups on the reset and CS lines so all SPI devices stay disabled. The only ICs connected to the BBB spi data input line are 2x MP3208 which stay high-z when the CS is pulled high.

          In BB-SPIDEV0-00A0.dts I found that the data pin (P9_21) is defined as input pullup. However, the device tree overlays are loaded from Linux (right?), so that would be after the AM335x has already booted from MMC0 or MMC1.

          To be sure I will also be adding 10kΩ to P9_21 so when floating the data line will go to 3.3V and will read 0xFFFFFFFF.

            Ward In BB-SPIDEV0-00A0.dts I found that the data pin (P9_21) is defined as input pullup. However, the device tree overlays are loaded from Linux (right?), so that would be after the AM335x has already booted from MMC0 or MMC1.

            correct: you need to fix that in hardware!

            Ward To be sure I will also be adding 10kΩ to P9_21 so when floating the data line will go to 3.3V and will read 0xFFFFFFFF.

            that sounds wise. Otherwise the high-z lines could give any readings there.