For the release of Silicon Labs' EFM8 product line, a factory bootloader was created. However, this bootloader only works natively on devices that are 'bootloader enabled'. These 'bootloader enabled' devices are:
The AN945 bootloader will also be compatible on any future EFM8 devices (including newer revisions of the above devices).
Bootloader enabled devices have the ability to check to see if they should jump to the bootloader or the application after a reset, before code starts running. Other Silicon Labs 8-bit devices, or older EFM8 devices, don't have this capability. However, you can change this by mimicking this function in the bootloader and application firmware.
Firstly, the bootloader image should contain a jump to the bootloader at the reset vector 0x0000. You can do this by adding the following code to the boot_startup.asm file in the bootloader project:
?BL_JUMP SEGMENT CODE AT 0 RSEG ?BL_JUMP LJMP boot_start
So, if there is no application, this will jump automatically to the bootloader.
Now, you need to modify your application code to mimic the bootloader capable parts' additional functionality. I've done this in the SILABS_STARTUP.A51 file of an application, since this is where you can insert code that effectively runs before your application. In here, we'll simply need to check to see if the bootloader exists. If it does, we'll jump there first and it will perform the other checks to see if we should go to the application.
However, in this case, we'll also need to determine whether we just came from the bootloader, since we technically are the application. Without this, we would get stuck in a loop - jumping from the application to the bootloader, back to the application, back to the bootloader, etc. I used R7 to store a particular value to say that we've just come from the bootloader. Here is the modified SILAB_STARTUP.A51 file:
CSEG AT 0 ?C_STARTUP: LJMP BootloaderCheck RSEG ?C_C51STARTUP #include "efm8_device.h" #define BL_SIGNATURE 0xA5 BootloaderCheck: ; Read and test R7 to see if we've already entered the bootloader ; since the last reset. If so, we should skip to the application mov A, #BL_SIGNATURE xrl A, R7 jz GotoApplication ; Read and test the boot vector enable byte (byte before Lock Byte) ; The signature is present if A is 0 (leave result in A) mov DPTR, #(BL_FLASH0_LIMIT - 2) movc A, @A+DPTR xrl A, #BL_SIGNATURE ; Restore the DPTR mov DPTR, #0000h ; If the signature is present, jump to the boot vector jz GotoBootVector GotoApplication: clr A ; Restore A mov R7, #0x00 ; Restore R7 jmp STARTUP1 ; Jump to reset vector (use this to save a byte) GotoBootVector: ; A = 0, no need to restore mov R7, #BL_SIGNATURE ; Write 0xA5 to R7 to indicate we've bootloaded ljmp BL_START_ADDRESS ; Jump to boot vector
The full SILABS_STARTUP.A51 file is zipped and attached to this forum post.