Entering Boot Mode

A physical pin state is not the only way to make the device enter the bootloader; often it is necessary for the application to trigger a bootloader update. The example below shows a function that checks for a value in User Row or EEPROM to trigger an update:

static bool is_boot_requested(void)
{
	/* Check for boot request from firmware */
	if (USERROW.USERROW31 == 0xEB) {
		/* Clear boot request*/
		USERROW.USERROW31 = 0xff;
		_PROTECTED_WRITE_SPM(NVMCTRL.CTRLA, NVMCTRL_CMD_PAGEERASEWRITE_gc);
		while(NVMCTRL.STATUS & NVMCTRL_EEBUSY_bm);
	}
	/* Check if SW1 (PC5) is low */
	else if(VPORTC.IN & PIN5_bm) {
		return false;
	}
	
	return true;
}

To enter Boot mode without pulling the pin low, byte 31 in User Row will need to be programmed either by the application or a programmer. The example below shows how to write the needed value and reset the device:

void enter_bootloader(void)
{
	/* Write boot request */
	USERROW.USERROW31 = 0xEB;
	_PROTECTED_WRITE_SPM(NVMCTRL.CTRLA, NVMCTRL_CMD_PAGEERASEWRITE_gc);
	while(NVMCTRL.STATUS & NVMCTRL_EEBUSY_bm);

	/* Issue system reset */
	_PROTECTED_WRITE(RSTCTRL.SWRR, RSTCTRL_SWRE_bm);
}

Together these two functions make it possible to enter Bootloader mode without needing power cycling and a physical pin.