I'm running into a strange issue with RF7A2A1AB where several peripheral registers do not read back the documented reset value after powering up the board from 'cold' state (no power applied for at least 10 seconds). This is causing the flash programming peripheral (R_FACI_LP) to have problems, as described below.
The steps I took to reproduce this are as follows:
At this point I can inspect some peripheral memory with GDB. For example, read MSTPCRB (0x40047000)
(gdb) p/x *0x40047000$1 = 0xffbff7ff
(gdb) p/x *0x40047000
$1 = 0xffbff7ff
This register is supposed to read 0xFFFFFFFF on reset. I'm sure there are several other registers which are incorrect as well.
I stumbled upon this while running a bootloader which runs entirely in RAM. After a warm reboot (power off less than a few seconds), the code would run fine. However, after a cold reboot, R_FACI_LP->FSTATR2 would show ILGLERR after the first write to R_FACI_LP->FCR (with the same exact code!). Resetting with R_FACI_LP->FRESETR did not clear the error. Only a power cycle would clear the error.
As a final note, my SVD file includes an (undocumented?) register R_FACI_LP->PFBER (0x407EFFC8). As I understand, RA2A1, does not actually have this register. However, after a 'cold boot', this register reads 0x80. After a 'warm boot', it reads 0x00. Maybe this will give some clue to the flash issue
I appreciate any insight or guesses! I've been stumped with this issue all day!
The execution of user code in boot mode is not a defined use case (the use case of boot mode is on entering boot mode, the device executes the built in boot mode firmware, and communicate over SCI9 or…
What is the level on the MD pin, is the device going into boot mode?
Hi Jeremy, I think you got it! On my board this pin is used as IO and floats around 1V by default. If the board is powered down for less than a few seconds, a capacitor keep enough voltage on the pin for it to boot up in 'single-chip' mode next time. I tried tying MD to 3.3V and could no longer reproduce the problem.
Now the question is how can I detect this and exit the boot mode?
Is there a better way to detect that the chip is in boot mode other than looking at MSTPCRB?
Is there a command to exit boot mode, or do I need to perform a software reset?
How can I perform a software reset to jump back into RAM? I tried setting SCB->VTOR to 0x20000000, where I have a vector table with the correct stack pointer and reset vector address, however after performing a SYSRESETREQ, VTOR changes back to 0 and execution begins from flash. What am I missing here?
Thanks for your help,
The RA2A1 only goes into boot mode when the MD pin is low and the device is reset with the reset pin, other reset sources do not put the device into boot mode.
The RA boot firmware documentation is here :-
There is no command to exit boot mode, the device would have to be reset to exit boot mode.
All reset sources will reset the CPU. The reset value of the VTOR register is 0x00000000
Thanks, that confirms what I was thinking. Since I don't have control of the hardware and there is no way to programmatically exit boot mode, I should structure my program to work in boot mode as well.
In boot mode, I encountered an error when writing to flash. R_FACI_LP->FSTATR2 will show ILGLERR after any command and it is not recoverable by FRESETR. Is this expected when in boot mode?
The execution of user code in boot mode is not a defined use case (the use case of boot mode is on entering boot mode, the device executes the built in boot mode firmware, and communicate over SCI9 or USBFS with the host and responds to the commands sent over the serial interface, and programs and/or erases the flash in response to the commands sent over the serial interface).
The built in boot code will have started to execute upon entering boot mode, and will probably have initialised SCI9 and the USBFS (these are the transport interfaces of boot mode), and probably also initialised the flash controller, the CPG and some GPIO (it may also have initialised other peripherals in the device), at the point where you have stopped execution of the boot firmware, and started executing user code.
The state of the peripherals at the point where you started executing user code, with the device in boot mode, is not known, so the behaviour ofthe peripherals cannot be predicted.
I see. Your explanation makes perfect sense. I had noticed that VTOR was pointing to a non-zero address in boot mode. Presumable this is where the boot code ran from before my code took over.
In this case, the only solution is to inform users of my bootloader that the MD pin must be pulled high for correct operation.
Thanks again for all your help, Jeremy!
I wasn't totally satisfied relying an the state of a hardware pin for my software to work. As Jeremy mentioned, reset sources other than the reset pin do not put the hardware in boot mode.
Therefore we can issue a software reset over SWD via AIRCR.SYSRESETREQ. If MD is low, VTOR will still point to the internal bootloader at this point, so the trick it to halt the core immediately after reset, so it doesn't have a chance to run the bootloader. This is accomplished with DEMCR.VC_CORERESET.
With this combination, I'm able to load and run my code successfully even if MD is held low during a hardware reset!