I'm having a bit of trouble detecting a software reset (according to the documentation). I'm on a BF548 0.2 silicon
References are from: ADSP-BF54x Blackfin Processor Hardware Reference, Revision 0.4, August 2008
Section 17 “System Reset and Booting,” under the heading “Reset and Booting Registers” (starting on page 17-107) informs us that we can interrogate the SWRST and/or the SYSCR registers to help us determine which form of software reset occurred. According to the register diagrams (Figures 17-39 and 17-40) and described in the accompanying text, bits 15 and 14 in either register should tell us our two possible software reset methods (bit 15 set if the reset was initiated by software, and both bits set if the reset was initiated by the watchdog).
Section 17 “System Reset and Booting,” under the headings “Programming Examples” -> “System Reset” (page 17-154) show the ROM function call to initiate a software reset. The text says, “To perform a system and core reset, use the code shown in Listing 17-2 or Listing 17-3,” and lists this code in Listing 17-2:
bfrom_SysControl(SYSCTRL_SYSRESET, 0, NULL);
Section 18 “Dynamic Power Management,” under the headings “Programming Examples” -> “Perform a System Reset or Soft-Reset” (page 18-44) shows example code which uses terminology that conflicts with the previous usage. The text says, “Listing 18-7 and Listing 18-8 provide code for executing a system reset or a soft-reset (= system reset + core reset), in Blackfin assembly and C code, respectively.” This code suggests the example code from section 17 only resets the system. From section 18:
bfrom_SysControl( SYSCTRL_SYSRESET, NULL, NULL );
bfrom_SysControl( SYSCTRL_SOFTRESET, NULL, NULL );
The flag documentation also supports this interpretation (page 18-32): “SYSCTRL_SYSRESET performs a system reset, and SYSCTRL_SOFTRESET combines a core and a system reset.”
I initially tried to implement code that followed the more intuitive documentation in section 18. I need the whole processor to reset as if it is coming up from power-on or a watchdog event. Thus, I used the “SYSCTRL_SOFTRESET” flag in my call to bfrom_SysControl(). As expected, this immediately transferred control back to the start of my first boot stream. However, the SWRST and SYSCR registers do not report a software reset state (bit 15 is clear in both registers, and I'm aware of the clear-on-read behavior of the SWRST register).
So, I tried to find out what the “SYSCTRL_SYSRESET” flag accomplishes, and it seems to reset the processor, but the boot ROM never starts to execute the first boot stream. The processor seems to “hang” as if the board has received power with the processor in BMODE 0000 (no boot).
Even though the documentation seems to indicate we shouldn’t attempt to manually manipulate the SWRST register, I tried to simply set the reset bits (*pSWRST |= 0x0007), and observed the exact same behavior as using the “SYSCTRL_SYSRESET” flag (reset with no boot).
So, I have either 1) a method to reset execution to the first stream, but a failure to detect if the reset originated in software, or 2) a failure to re-enter program execution across a reset.
Through trial and error, I discovered that setting a single bit in SWRST [2:0] does not trigger a no-boot reset. And, that bit can be read across a “SYSCTRL_SOFTRESET” cycle. Therefore, if I adjust my reboot procedure to always include:
*pSWRST |= 0x0001
bfrom_SysControl(SYSCTRL_SOFTRESET, NULL, NULL)
, I can tell if the reset came from software, the watchdog, or a hardware event.
With this feedback in place, all of my requirements for boot functionality are met, and tests show proper functionality on the target (booting from SPI flash on the EZ-Kit eval board).
Here are my questions:
Does this solution violate any intended behavior of the processor?
Does issuing a “SYSCTRL_SOFTRESET” type of reset really reset the processor at all? Or, is it more like a “jump” back to the initial boot stream?
What is the proper way to issue a “SYSCTRL_SYSRESET” type of reset? It doesn’t seem very productive to include a built-in ROM function that just hangs the processor. Every code example seems to indicate just calling the function should reset the processor. If I need to provide additional infrastructure to achieve the documented functionality, that’s totally fine.
Thank you, in advance, for any insights you can share.