|
This won't help your board that already has firmware burned to flash. But, it could help prevent this issue on subsequent boards. Apologies in advance, this gets a little convoluted, so you might have to read it a couple times for everything to make sense.
The 1.2.1 SDK includes bootloader code, under firmware/boot_fw, that supports the commands used by Control Center to download firmware via USB. The boot firmware has its own, much simpler SDK API (no ThreadX, etc.).
For Control Center to recognize a device, it has to have one of the signatures in the drive .INF file (for USB download it looks like this is VID 0x04B4 / PID 0x00F3). So the issue becomes, how to get a device running 'real' firmware with your customized VID/PID to renumerate with the ones required by Control Center - and have the ability to replace itself with code downloaded over USB?
What you can do is redesign the .img that you program to flash so that it consists of two subprograms - your 'real' firmware, and a copy of the boot_fw. The SDKs have the ability to transfer control from one subprogram to the other (see CyFx3BootJumpToProgramEntry() in the boot SDK and CyU3PUsbJumpBackToBooter() in the "normal" SDK). You'll want to modify linker scripts so that the subprograms start at fixed memory addresses (i.e. 0x40030000 for the 'real' firmware and 0x40070000 for the boot_fw).
You can modify the descriptors in the boot_fw project so that the PID is 0x00F3. Compile the project with USB boot support enabled and SPI boot support disabled, then run arm-none-eabi-objcopy to convert the .elf into a binary file:
arm-none-eabi-objcopy --input-target=elf32-littlearm --output-target=binary --strip-all ${ProjName} boot_fw.bin
In the 'real' firmware, you can then use a simple .S file to pull in the boot_fw as a blob:
.section .text.boot
.code 32
.global boot_fw
boot_fw:
.incbin "boot_fw.bin"
The linker script for the 'real' firmware needs to place the blob at the same location it was compiled to (in the boot_fw project) and to make the boot_fw the start address of the (merged) program.
Now for the switching. The boot_fw can be augmented to have a variable that keeps track of whether this is the first boot following powerup, or not.
On first boot, the code should call CyFx3BootUsbStart(CyTrue, ...) as that appears to be a requirement for switching from the 'real' firmware back to the boot_fw. (CyU3PUsbJumpBackToBooter() throws an error if you don't do this). The boot_fw must load the USB descriptors of the 'real' firmware (since we tell CyFx3BootUsbStart that we do not want to renumerate). This is a sticky part of the subprogram approach - the boot_fw subprogram needs access to the descriptors of the 'real' subprogram - so you need to build the subprograms accordingly. Once the descriptors are loaded the boot_fw calls CyFx3BootJumpToProgramEntry() with the address of the 'real' subprogram.
To reflash, you need the ability to signal the 'real' firmware that it is time to jump back to the boot_fw. How you do this is application-specific; one way would be on receipt of a vendor-specific SETUP request. When the 'real' firmware receives this signal from the host it shuts down all the FX3 peripherals and calls CyU3PUsbJumpBackToBooter(boot_fw).
Now the boot_fw has control again. It checks the "first boot" flag and sees that this is a reboot. This time it calls CyFx3BootUsbStart(CyFalse) and loads the boot_fw USB descriptors (the ones that now identify it in a way compatible with Control Center). Then, it goes into USB boot mode, acting on commands from Control Center.
One modification you'll need to make to the USB boot code in the boot_fw is to ignore attempts to download into the boot_fw memory range (since that would destroy the firmware performing the download). Since Control Center seems to read back what was written as a verification, this means you can't download a merged .img to RAM when one (i.e. that was programmed to SPI flash) is already running. But "normal" images such as the CyBootProgrammer don't overlap boot_fw memory and *can* be downloaded. This is what allows you to rewrite the flash from Control Center.
What would be really nice is if Cypress eliminated the need for all of this by providing some way to jump back into the ROM bootloader in a way that only supports USB boot (i.e., as if the PMODE straps had been set for USB boot only).
Hope this helps,
Steve
|