コード例 #1
0
ファイル: debug_lock.c プロジェクト: AndreMiras/EFM32-Library
/**********************************************************
 * Performs the Debug Unlock sequence to erase all
 * device contents and obtain debug access. 
 * In case the device is not locked, it will initiate
 * the AAP window extension sequence in order to 
 * access the AAP before trying to unlock. 
 **********************************************************/
void unlockTarget(void)
{  
  /* If target is unlocked we reset target and send the
   * AAP Window Expansion Sequence to have longer time
   * to access the AAP registers */
  if ( !targetLocked ) {
    printf("Target is not locked.\n" 
           "Performing AAP Window Expansion Sequence.\n");
    performAapExpansion();
  } 
  
  printf("Sending Unlock Sequence\n");
    
  /* Start a Device Erase (Debug Unlock) operation */
  writeAP(AAP_CMDKEY, AAP_UNLOCK_KEY);
  writeAP(AAP_CMD, AAP_CMD_DEVICEERASE);
  writeAP(AAP_CMDKEY, 0);
    
  /* Wait long enough for Device Erase to complete. 
   * This is typically around 50ms. We wait much longer
   * just to be sure. */
  delayMs(1000);
  
  /* Reset and verify that target is unlocked */
  hardResetTarget();
  delayMs(100);  

  /* Verify that target is unlocked. This function will raise
   * an exception if target is not unlocked. */
  verifyUnlockedStatus();
  
  /* If we get here, the target is unlocked */
  printf("Target successfully unlocked\n");
}
コード例 #2
0
/**********************************************************
 * Writes a value to a CPU register in the target.
 * 
 * @param reg
 *   The register number to write to
 * 
 * @param value
 *   The value to write to the register
 **********************************************************/
void writeCpuReg(int reg, uint32_t value)
{
  /* Wait until debug register is ready to accept new data */
  waitForRegReady();
  
  /* Write value to Data Register */
  writeAP(AP_TAR, (uint32_t)&(CoreDebug->DCRDR));
  writeAP(AP_DRW, value);
  
  /* Write register number ot Selector Register. 
   * This will update the CPU register */
  writeAP(AP_TAR, (uint32_t)&(CoreDebug->DCRSR));
  writeAP(AP_DRW, 0x10000 | reg); 
}
コード例 #3
0
/**********************************************************
 * Verifies the current firmware against the locally
 * stored original. This function assumes the firmware
 * has been written to target starting at address 0x00. 
 *
 * @param fwImage
 *    Pointer to locally stored copy of firmware image
 * 
 * @param size
 *    Size (in bytes) of firmware image
 * 
 * @returns 
 *    True if target firmware matches local copy. 
 *    False otherwise. 
 **********************************************************/
bool verifyFirmware(uint32_t *fwImage, uint32_t size)
{
  int i;
  int numWords = size / 4;
  bool ret = true;
  uint32_t value;
  uint32_t addr;
  uint32_t tarWrap =  getTarWrap();
  
  printf("Verifying firmware\n");
  
  /* Set autoincrement on TAR */
  writeAP(AP_CSW, AP_CSW_DEFAULT | AP_CSW_AUTO_INCREMENT);
  
  for ( i=0; i<numWords; i++ ) 
  {   
    /* Get current address */
    addr = i*4;
        
    /* TAR must be initialized at every TAR wrap boundary
     * because the autoincrement wraps around at these */
    if ( (addr & tarWrap) == 0 )
    {
      writeAP(AP_TAR, addr);
      
      /* Do one dummy read. Subsequent reads will return the 
       * correct result. */
      readAP(AP_DRW, &value);
    }
    
    /* Read the value from addr */
    readAP(AP_DRW, &value);
    
    /* Verify that the read value matches what is expected */
    if ( value != fwImage[i] ) 
    {
      printf("Verification failed at address 0x%.8x\n", addr);
      printf("Value is 0x%.8x, should have been 0x%.8x\n", value, fwImage[i]);
      ret = false;
      break;
    }
  }
  
  /* Disable autoincrement on TAR */
  writeAP(AP_CSW, AP_CSW_DEFAULT);
     
  return ret;
}
コード例 #4
0
/**********************************************************
 * Reads one word from internal memory
 * 
 * @param addr 
 *    The address to read from
 * 
 * @returns 
 *    The value at @param addr
 **********************************************************/
uint32_t readMem(uint32_t addr)
{
  uint32_t ret;
  writeAP(AP_TAR, addr);
  readAP(AP_DRW, &ret);
  readDP(DP_RDBUFF, &ret);
  return ret;
}
コード例 #5
0
/**********************************************************
 * Uploads and runs the flashloader on the target
 * The flashloader is written directly to the start
 * of RAM. Then the PC and SP are loaded from the
 * flashloader image. 
 **********************************************************/
void uploadFlashloader(uint32_t *flImage, uint32_t size)
{
  int w;
  uint32_t addr;
  uint32_t tarWrap;
  
  uint32_t numWords = size / 4;
  if ( numWords * 4 < size ) numWords++;
   
  resetAndHaltTarget();
  
  /* Get the TAR wrap-around period */
  tarWrap = getTarWrap();
  
  printf("Uploading flashloader\n");
  
  /* Enable autoincrement on TAR */
  writeAP(AP_CSW, AP_CSW_DEFAULT | AP_CSW_AUTO_INCREMENT);
  
  for ( w=0; w<numWords; w++ ) 
  {
    /* Get address of current word */
    addr = RAM_START + w * 4;
    
    /* At the TAR wrap boundary we need to reinitialize TAR
     * since the autoincrement wraps at these */
    if ( (addr & tarWrap) == 0 )
    {
      writeAP(AP_TAR, addr);
    }
    
    writeAP(AP_DRW, flImage[w]);
  }
  
  writeAP(AP_CSW, AP_CSW_DEFAULT);
  
  printf("Booting flashloader\n");
  
  /* Load SP (Reg 13) from flashloader image */
  writeCpuReg(13, flImage[0]);
  
  /* Load PC (Reg 15) from flashloader image */
  writeCpuReg(15, flImage[1]);
    
  runTarget();
}
コード例 #6
0
/**********************************************************
 * Halts the target CPU
 **********************************************************/
void haltTarget(void)
{
  int timeout = DEBUG_EVENT_TIMEOUT;
  writeAP(AP_TAR, (uint32_t)&(CoreDebug->DHCSR));
  writeAP(AP_DRW, STOP_CMD);
  
  uint32_t dhcrState;
  do {
    writeAP(AP_TAR, (uint32_t)&(CoreDebug->DHCSR));
    readAP(AP_DRW, &dhcrState);
    readDP(DP_RDBUFF, &dhcrState);
    timeout--;
  } while ( !(dhcrState & CoreDebug_DHCSR_S_HALT_Msk) && timeout > 0 ); 
  
  if ( !(dhcrState & CoreDebug_DHCSR_S_HALT_Msk) ) {
    RAISE(SWD_ERROR_TIMEOUT_HALT);
  }
}
コード例 #7
0
/**********************************************************
 * Resets the target CPU by using the AIRCR register. 
 * The target will be halted immediately when coming
 * out of reset. Does not reset the debug interface.
 **********************************************************/
void resetAndHaltTarget(void)
{
  uint32_t dhcsr;
  int timeout = DEBUG_EVENT_TIMEOUT;
  
  /* Halt target first. This is necessary before setting
   * the VECTRESET bit */
  haltTarget();
  
  /* Set halt-on-reset bit */
  writeMem((uint32_t)&(CoreDebug->DEMCR), CoreDebug_DEMCR_VC_CORERESET_Msk);
  
  /* Clear exception state and reset target */
  writeAP(AP_TAR, (uint32_t)&(SCB->AIRCR));
  writeAP(AP_DRW, (0x05FA << SCB_AIRCR_VECTKEY_Pos) |
                  SCB_AIRCR_VECTCLRACTIVE_Msk |
                  SCB_AIRCR_VECTRESET_Msk);
    
  /* Wait for target to reset */
  do { 
    delayUs(10);
    timeout--;
    dhcsr = readMem((uint32_t)&(CoreDebug->DHCSR));
  } while ( dhcsr & CoreDebug_DHCSR_S_RESET_ST_Msk );
  
  
  /* Check if we timed out */
  dhcsr = readMem((uint32_t)&(CoreDebug->DHCSR));
  if ( dhcsr & CoreDebug_DHCSR_S_RESET_ST_Msk ) 
  {
    RAISE(SWD_ERROR_TIMEOUT_WAITING_RESET);
  }
  
  /* Verify that target is halted */
  if ( !(dhcsr & CoreDebug_DHCSR_S_HALT_Msk) ) 
  {
    RAISE(SWD_ERROR_TARGET_NOT_HALTED);
  }
}
コード例 #8
0
/**********************************************************
 * Writes a chunk of data to a buffer in the flashloader.
 * This function does not make any checks or assumptions.
 * It simply copies a number of words from the 
 * local to the remote buffer.
 * 
 * @param remoteAddr
 *    Address of the flashloader buffer at the target
 * 
 * @param localBuffer
 *    The local buffer to write from
 * 
 * @param numWords
 *    Number of words to write to buffer
 **********************************************************/
void writeToFlashloaderBuffer(uint32_t remoteAddr, uint32_t *localBuffer, int numWords)
{
    uint32_t bufferPointer = (uint32_t)remoteAddr;
    int curWord = 0;
    uint32_t tarWrap;

    /* Get the TAR wrap-around period */
    tarWrap = getTarWrap();
    
    /* Set auto increment on TAR to allow faster writes */
    writeAP(AP_CSW, AP_CSW_DEFAULT | AP_CSW_AUTO_INCREMENT);
    
    /* Initialize TAR with the start of buffer */
    writeAP(AP_TAR, bufferPointer);
    
    /* Send up to one full buffer of data */    
    while ( curWord < numWords )
    {
      /* At TAR wrap boundary we need to reinitialize TAR
       * since the autoincrement wraps at these */
      if ( (bufferPointer & tarWrap) == 0 )
      {
        writeAP(AP_TAR, bufferPointer);
      }
      
      /* Write one word */
      writeAP(AP_DRW, localBuffer[curWord]);
      
      /* Increment local and remote pointers */
      bufferPointer += 4;
      curWord += 1;
    }
            
    /* Disable auto increment on TAR */
    writeAP(AP_CSW, AP_CSW_DEFAULT);
}
コード例 #9
0
/**********************************************************
 * Lets the target CPU run freely (stops halting)
 **********************************************************/
void runTarget(void)
{
  writeAP(AP_TAR, (uint32_t)&(CoreDebug->DHCSR));
  writeAP(AP_DRW, RUN_CMD);
}
コード例 #10
0
/**********************************************************
 * Writes one word to internal memory
 * 
 * @param addr 
 *    The address to write to 
 *
 * @param data
 *    The value to write
 * 
 * @returns 
 *    The value at @param addr
 **********************************************************/
void writeMem(uint32_t addr, uint32_t data)
{
  writeAP(AP_TAR, addr);
  writeAP(AP_DRW, data);
}
コード例 #11
0
/**********************************************************
 * Single steps the target
 **********************************************************/
void stepTarget(void)
{
  writeAP(AP_TAR, (uint32_t)&(CoreDebug->DHCSR));
  writeAP(AP_DRW, STEP_CMD);
}