So I'm working on a project that contains a Blackfin processor, specifically the BF592 datasheet

One thing that confuses me is how exactly the boot up process will work. During development, I plan on loading programs through the JTAG interface. This will also allow me to debug.

However when I want to actually deploy a program such that it can start up from scratch, I will need to place the program (loader file) on some type of external flash. Looking at it the BF592 datasheet, I can have the processor boot up external SPI flash.

One of the boot modes is described as follows:

SPI1 master boot from flash (BMODE = 0x2) — In this mode, SPI1 is configured to operate in master mode and to connect to 8-, 16-, 24-, or 32-bit addressable devices. The processor uses the PG11/SPI1_SSEL5 to select a single SPI EEPROM/flash device, submits a read command and successive address bytes (0×00) until a valid 8-, 16-, 24-, or 32- bit addressable device is detected, and begins clocking data into the processor. Pull-up resistors are required on the SSEL and MISO pins. By default, a value of 0×85 is written to the SPI_BAUD register.

I'm confused. How exactly would this work? How would the SPI master know what opcode to submit to the external flash such that memory is retrieved? For example, I've been looking at this external flash IC. It requires an op code of 0x0B to be sent followed by the desired 3 byte address. How exactly would the SPI master on the Blackfin know to issue this?

I've been digging deep into the Blackfin manuals and this part just seems to be hand waved. What exactly am I missing? Is there some configuration registers in the Blackfin where this would be configured? Do I need to purchase some compatible flash IC? Is there some standard for SPI flash where the opcode 0x0B is always used when pulling data?


Update: I was finally able to find the dedicated hardware manual which explicitly explains the 'boot from SPI' sequence. See page 690. This says that it issues a 0x03 or/and 0x0B opcode.

  • \$\begingroup\$ There is indeed a fair amount of standardization in basic read commands - 0x03 possibly even more so than 0x0b which appears to be a high speed variant. Often you load the first part of your bootloader using the fixed method, and then have that take over and perform a more custom load of the rest or the main system image. An interesting problem has come up lately though, as SPI flash sizes start crossing the boundary where 4 address bytes are needed - this can get tricky as if software switches the flash to a mode incompatible with the boot expectation, warm reset may lead to boot failure. \$\endgroup\$ – Chris Stratton Mar 18 '17 at 17:56

Yes, the Blackfin "just knows" that it needs to issue a read command followed by an address (all zeros) in order load software from external SPI flash. Devices from different manufacturers (mostly) use the same set of commands.

The code that does this is stored in a small ROM inside the Blackfin chip itself. You have to dig for it, but Analog Devices usually has the source code for that ROM hidden away somewhere in the library files that come with the software development tools, in case you want to look at it.

I have had occasionally needed to work around bugs in the ROM bootloader with respect to specific SPI flash devices by creating an extra stage of bootloading for my project. I use the ROM bootloader to load a second-stage bootloader from the SPI flash, which then loads the application code. The second-stage loader is mostly a copy of the ROM bootloader, but it is constructed to live within the limitations of the ROM code, while also fixing the bug related to getting the application code loaded.

If you're interested in the gory details, I wrote a Circuit Cellar article about it. The article itself is not available online, but the associated archive contains the source code for my replacement bootloader, and the comments there explain exactly what the problem was.

  • \$\begingroup\$ Looking around at other chips, it does appear that many of them use the 0x0B opcode for read operation. I would have never assumed this. And that's an interesting concept, using the bootloader to load an 'improved' boot loader. Since you appear to be familiar with Blackfins, one further 'bonus question' if you wish: are you aware of any capability of loading the loader files to external flash via the JTAG interface (i.e. ICE->blackfin->external SPI flash)? \$\endgroup\$ – Izzo Mar 18 '17 at 15:42
  • 1
    \$\begingroup\$ Absolutely yes. The Analog Devices tools have that functionality built in. Essentially, they use the JTAG interface to load a special program into the on-chip program RAM, and this program then runs under the control of a script in the debugger. This script transfers data a block at a time into a buffer in the DSP's data RAM, and then triggers the program to write that block of data to the external SPI flash. This repeats until the entire file has been written. It generally works pretty well, but I've also had to occasionally fix bugs in this area as well. \$\endgroup\$ – Dave Tweed Mar 18 '17 at 15:53
  • \$\begingroup\$ I should tell you that all of my experience was acquired under the older "VisualDSP++" tools. I am not at all familiar with the new "CrossCore Embedded Studio" tools, which may or may not be completely different. \$\endgroup\$ – Dave Tweed Mar 18 '17 at 16:00
  • \$\begingroup\$ Great information, thank you. I would like to believe the conversion to CCES was just from a IDE maintainability stance and that these existing tools weren't removed. This at least gives me some confidence on the tool offering. \$\endgroup\$ – Izzo Mar 18 '17 at 16:03
  • 1
    \$\begingroup\$ CCES definitely has the ability to program external flash chips via the emulator using JTAG. \$\endgroup\$ – B Pete Mar 19 '17 at 1:48

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.