diff --git a/Src/admin_vendor.c b/Src/admin_vendor.c index 043dc9e..2bf9714 100644 --- a/Src/admin_vendor.c +++ b/Src/admin_vendor.c @@ -56,6 +56,36 @@ int admin_vendor_version(const CAPDU *capdu, RAPDU *rapdu) { return 0; } +int admin_vendor_nfc_enable(const CAPDU *capdu, RAPDU *rapdu) { + if (P1 != 0x00 && P1 != 0x01) EXCEPT(SW_WRONG_P1P2); + if (P2 != 0x00) EXCEPT(SW_WRONG_P1P2); + if (LC != 0x00) EXCEPT(SW_WRONG_LENGTH); + + uint32_t magic = P1 * 0x50 + 0x100; + FLASH_OBProgramInitTypeDef cfg = { + .OptionType = OPTIONBYTE_PCROP, + .PCROPConfig = FLASH_BANK_1, + .PCROPStartAddr = FLASH_BASE + magic, // Reuse this option word as NFC switch + .PCROPEndAddr = FLASH_BASE + 0xF, // Fixed value + }; + DBG_MSG("Unlock OB\n"); + HAL_FLASH_Unlock(); + HAL_FLASH_OB_Unlock(); + int ret = HAL_FLASHEx_OBProgram(&cfg); + HAL_FLASH_OB_Lock(); + HAL_FLASH_Lock(); + HAL_FLASHEx_OBGetConfig(&cfg); + uint32_t *flash_loc = (uint32_t*) 0x1FFF7808U; + DBG_MSG("HAL_FLASHEx_OBGetConfig: %d %x %x %x\n", + ret, cfg.PCROPStartAddr, cfg.PCROPEndAddr, *flash_loc); + // DBG_MSG("value= %x %x\n", *(uint32_t*)FLASH_BASE, *(uint32_t*)cfg.PCROPStartAddr); + + if (ret != HAL_OK) return -1; + + return 0; +} + + extern uint32_t _stack_boundary; static int stack_test(const CAPDU *capdu, RAPDU *rapdu) { diff --git a/Src/main.c b/Src/main.c index 9579593..74483e5 100644 --- a/Src/main.c +++ b/Src/main.c @@ -274,6 +274,15 @@ static void config_usb_mode(void) { // enable the device_periodic_task, which controls LED and Touch sensing device_loop_enable = 1; } + +static int check_is_nfc_en(void) { + uint32_t *flash_loc = (uint32_t*) 0x1FFF7808U; + uint32_t val = *flash_loc; //FLASH->PCROP1SR; + DBG_MSG("%x\n", val); + return val == 0xFFFFFFFFU || // ST production default value + val == 0xFFFF802a; // magic written by admin_vendor_nfc_enable() +} + // Called by core library void USBD_LL_Init_Done(void) { @@ -316,7 +325,7 @@ int main(void) { MX_USART2_UART_Init(); SetupMPU(); // comment out this line during on-chip debugging /* USER CODE BEGIN 2 */ - in_nfc_mode = 1; // boot in NFC mode by default + in_nfc_mode = check_is_nfc_en(); // boot in NFC mode by default nfc_init(); set_nfc_state(in_nfc_mode); @@ -327,6 +336,10 @@ int main(void) { applets_install(); init_apdu_buffer(); + if (!in_nfc_mode) { + while (!detect_usb()); + config_usb_mode(); + } DBG_MSG("Main Loop\n"); /* USER CODE END 2 */