/********************************************************** * Performs AAP Window Expansion. This function will reset * target, send the AAP expansion sequence, initialize the * debug interface and verify that AAP can be accessed. * It will try several delays between reset is released * and reading the AAP in case the reset line has a slow * ramp-up. * * After this function completes the AAP registers are * available. If it fails to access the AAP, it will * throw an exception. * **********************************************************/ void performAapExpansion(void) { uint32_t dpId, apId; int i,j; bool success = false; for ( i=0; i<AAP_EXPANSION_RETRY_COUNT; i++ ) { /* Pull reset pin low */ GPIO_PinOutClear((GPIO_Port_TypeDef)RESET_PORT, RESET_PIN); SWCLK_CLR(); delayMs(50); /* Send the AAP Window expansion sequence */ aapExtensionSequence(); /* Release reset */ delayUs(10); GPIO_PinOutSet((GPIO_Port_TypeDef)RESET_PORT, RESET_PIN); /* Try different delays in case of slow reset ramp */ for ( j=0; j<i; j++ ) { delayUs(10); } /* Connect to SW-DP */ TRY dpId = initDp(); apId = readApId(); if ( verifyDpId(dpId) && apId == EFM32_AAP_ID ) { /* Success! AAP registers can now be accessed. * We cannot return in the middle of a TRY block. * Set flag here and return after ENDTRY */ success = true; } CATCH /* Do nothing in case of error. We retry. */ ENDTRY /* Return if we found the AAP registers*/ if ( success ) { printf("AAP registers found\n"); return; } } /* Failed to get access to AAP registers. Raise an error. */ RAISE(SWD_ERROR_AAP_EXTENSION_FAILED); }
/********************************************************** * Performs the initialization sequence on the SW-DP. * After this completes the debug interface can be used. * Raises an exception on any error during connection. **********************************************************/ void connectToTarget(void) { uint32_t dpId,apId; delayUs(500); printf("Connecting to target...\n"); dpId = initDp(); /* Verify that the DP returns the correct ID */ if ( !verifyDpId(dpId) ) { printf("Read IDCODE = 0x%.8x\n", dpId); RAISE(SWD_ERROR_INVALID_IDCODE); } /* Verify that the AP returns the correct ID */ int retry = AHB_IDR_RETRY_COUNT; while ( retry > 0 ) { apId = readApId(); if ( verifyAhbApId(apId) ) { /* Success. AHB-AP registers found */ break; } retry--; } /* In case we did NOT find the AHB-AP registers check * if the chip is locked or if some other error ocurred. */ if ( !verifyAhbApId(apId) ) { /* If the ID is from AAP, the MCU is locked. * Debug access is not available. */ if ( apId == EFM32_AAP_ID ) { RAISE(SWD_ERROR_MCU_LOCKED); } else { /* The AP ID was not from AAP nor AHB-AP. This is an error. */ printf("Read IDR = 0x%.8x\n", apId); RAISE(SWD_ERROR_INVALID_IDR); } } /* Set up parameters for AHB-AP. This must be done before accessing * internal memory. */ initAhbAp(); /* * On Zero Gecko it is possible that the device is locked * even though we reach this point. We have to see if * we can access the AAP registers which are memory mapped * on these devices. The function will raise an exception * if the device is a Zero Gecko and is currently locked. */ if ( apId == EFM32_AHBAP_ID_2 ) { checkIfZeroGeckoIsLocked(); } haltTarget(); /* Get device name */ char deviceName[30]; getDeviceName(deviceName); printf("Target is %s\n", deviceName); /* Read the unique ID of the MCU */ uint64_t uniqueId = readUniqueId(); printf("Unique ID = 0x%.16llx\n", uniqueId); }