/*************************************************************************//** * @brief * This function locks the debug interface by first enabling debug mode by * bit-banging a SWD init sequence on the SWD interface and then setting * the Debug lock bit in the flash. * @return * Returns true if the DLW has been sucessfully set, false otherwise. ****************************************************************************/ __ramfunc bool DEBUGLOCK_lock(void) { /* Start debug interface. */ DEBUGLOCK_startDebugInterface(); /* Set the debug lock word */ FLASH_writeWord(DEBUG_LOCK_WORD, 0x0); /* Verify sucessful write by checking the DLW. */ if (*((uint32_t *) DEBUG_LOCK_WORD) == 0x0) { return true; } return false; }
/**************************************************************************//** * @brief * The main command line loop. Placed in Ram so that it can still run after * a destructive write operation. * NOTE: __ramfunc is a IAR specific instruction to put code into RAM. * This allows the bootloader to survive a destructive upload. *****************************************************************************/ static void commandlineLoop( void ) { uint8_t c; /* The main command loop */ while (1) { /* Retrieve new character */ c = BOOTLDIO_rxByte(); /* Echo */ if (c != 0) { BOOTLDIO_txByte( c ); } switch (c) { /* Bootloader version command */ case 'i': /* Print version */ BOOTLDIO_printString("\r\n\r\n" BOOTLOADER_VERSION_STRING ); /* Print the chip ID */ BOOTLDIO_printHex(DEVINFO->UNIQUEH); BOOTLDIO_printHex(DEVINFO->UNIQUEL); BOOTLDIO_printString("\r\n"); break; /* Upload command */ case 'u': BOOTLDIO_printString( readyString ); XMODEM_download( BOOTLOADER_SIZE, flashSize ); break; /* Destructive upload command */ case 'd': BOOTLDIO_printString( readyString ); XMODEM_download( 0, flashSize ); break; /* Write to user page */ case 't': BOOTLDIO_printString( readyString ); XMODEM_download( USER_PAGE_START, USER_PAGE_END ); break; /* Write to lock bits */ case 'p': BOOTLDIO_printString( readyString ); XMODEM_download( LOCK_PAGE_START, LOCK_PAGE_END ); break; /* Boot into new program */ case 'b': Disconnect( 5000, 2000 ); BOOT_boot(); break; /* Debug lock */ case 'l': #if defined( BL_DEBUG ) /* We check if there is a debug session active in DHCSR. If there is we * abort the locking. This is because we wish to make sure that the debug * lock functionality works without a debugger attatched. */ if ((CoreDebug->DHCSR & CoreDebug_DHCSR_C_DEBUGEN_Msk) != 0x0) { USB_PUTS( "\r\n\r\n **** WARNING: DEBUG SESSION ACTIVE. NOT LOCKING! **** \r\n\r\n" ); BOOTLDIO_printString( "Debug active.\r\n" ); } else { USB_PUTS( "Starting debug lock sequence.\r\n" ); #endif FLASH_writeWord( DEBUG_LOCK_WORD, 0x0 ); if ( *(volatile uint32_t*)DEBUG_LOCK_WORD == 0x0 ) { BOOTLDIO_printString( okString ); } else { BOOTLDIO_printString( failString ); } #if defined( BL_DEBUG ) USB_PRINTF( "Debug lock word: 0x%x \r\n", *((uint32_t *) DEBUG_LOCK_WORD) ); } #endif break; /* Verify content by calculating CRC of entire flash */ case 'v': verify( 0, flashSize ); break; /* Verify content by calculating CRC of application area */ case 'c': verify( BOOTLOADER_SIZE, flashSize ); break; /* Verify content by calculating CRC of user page.*/ case 'n': verify( USER_PAGE_START, USER_PAGE_END ); break; /* Verify content by calculating CRC of lock page */ case 'm': verify( LOCK_PAGE_START, LOCK_PAGE_END ); break; /* Reset command */ case 'r': Disconnect( 5000, 2000 ); /* Write to the Application Interrupt/Reset Command Register to reset * the EFM32. See section 9.3.7 in the reference manual. */ SCB->AIRCR = 0x05FA0004; break; /* Unknown command */ case 0: /* Timeout waiting for RX - avoid printing the unknown string. */ break; default: BOOTLDIO_printString( unknownString ); } } }