SEGGER with STM32: Failed to connect to target. No idcode detected

921 Views Asked by At

I've been attempting to set the PLL clock frequency on a STM32H7B3 board, and I was able to do so by setting the DIVN multiplier (RCC_PLL1DIVR_N1) in the code below. The last time I was able to do this successfully was with the multiplier set to 1. When I tried downloading the code with multiplier set to 0x18F (= 399), I got the above error message. I now realize that the max I should have tried was probably DIVN = 280 due to the sys_ck specs, but nonetheless, the error happened upon downloading the code, not running it. I tried using the reset button, but to no avail. I now can't connect to the board and I don't know what else to try.

  RCC -> CFGR &= 0; // Reset register
  int32_t cfgr = RCC -> CFGR;
  int32_t sws_pll1 = RCC_CFGR_SWS_PLL1;
  int32_t status = cfgr & sws_pll1;
  while (!status) {
   cfgr = RCC -> CFGR;
   sws_pll1 = RCC_CFGR_SWS_PLL1;
   status = cfgr & sws_pll1;
  } // System clock switch status: Wait until PLL1 is system clock; TODO: hangs*/
  // RCC source control register
  RCC->CR |= RCC_CR_HSION; // HSI clock enable
  while (!(RCC->CR & RCC_CR_HSIRDY)); // Wait until HSI clock is ready
  /* -------- PLL Config -------- */
  // RCC PLLs clock source selection register
  RCC -> PLLCKSELR |= RCC_PLLCKSELR_PLLSRC_HSI; // Select HSI as PLL clock source (hsi_ck)
  // Note: Must have PLL1ON = 0 for modifying prescaler
  RCC -> PLLCKSELR &= ~RCC_PLLCKSELR_DIVM1; // Reset prescaler for PLL1 to disabled
  RCC -> PLLCKSELR |= RCC_PLLCKSELR_DIVM1_5; // Set prescaler for PLL1 to divsion by 32
  // RCC PLL1 fractional divider register
  RCC -> PLL1FRACR = 0; // Set FRACN to 0
  // RCC PLLs configuration register
  RCC -> PLLCFGR |= RCC_PLLCFGR_PLL1FRACEN; // PLL1 franctional latch enable
  RCC -> PLLCFGR &= ~RCC_PLLCFGR_PLL1VCOSEL; // Select PLL1 output frequency range: wide VCO range from 128 to 560 MHz
  RCC -> PLLCFGR |= RCC_PLLCFGR_PLL1RGE_3; // Select PLL1 input reference frequency range: between 8 and 16 MHz
  // Note: Must have PLL1ON = 0 and PLL1RDY = 0 for enabling divider output
  RCC -> PLLCFGR |= RCC_PLLCFGR_DIVP1EN; // PLL1 DIVP divider output enable
  RCC -> PLLCFGR |= RCC_PLLCFGR_DIVQ1EN; // PLL1 DIVQ divider output enable
  RCC -> PLLCFGR |= RCC_PLLCFGR_DIVR1EN; // PLL1 DIVR divider output enable
  // RCC PLL1 dividers configuration register
  // Note: Must have PLL1ON = 0 and PLL1RDY = 0 for writing bits
  RCC -> PLL1DIVR &= 0; // Reset register
  RCC -> PLL1DIVR |= (0x1 << RCC_PLL1DIVR_N1_Pos) & RCC_PLL1DIVR_N1; // DIVN = 0x18F = 399
  RCC -> PLL1DIVR |= (0x1 << RCC_PLL1DIVR_P1_Pos) & RCC_PLL1DIVR_P1; // DIVP = 1
  RCC -> PLL1DIVR |= (0x1 << RCC_PLL1DIVR_Q1_Pos) & RCC_PLL1DIVR_Q1; // DIVQ = 1
  RCC -> PLL1DIVR |= (0x1 << RCC_PLL1DIVR_R1_Pos) & RCC_PLL1DIVR_R1; // DIVR = 1
  // RCC source control register
  RCC -> CR |= RCC_CR_PLL1ON; // PLL1 enable
  //while((RCC -> CR & RCC_CR_PLL1RDY) == 0); // Wait until PLL1 clock is ready; TODO: hangs

Update: I ran JLinkSTM32, but it printed the following:

Connecting to J-Link via USB...O.K.
Using SWD as target interface.
Target interface speed: 1000 kHz.
VTarget = 3.299V
Reset target...O.K.
Reset option bytes to factory settings...
Option bytes reset to factory settings.
Resetting option bytes failed.
Press any key to exit.
1

There are 1 best solutions below

17
On

Run the command line JLinkSTM32.exe utility (installed with the J-Flash tools), select option 9 (For STM32H7xxxx) and hope (takes a few nervous seconds).

enter image description here

If successful, it may have bulk-erased the flash and will have reset the option bytes for the whole chip. It has got me out of a number of inexplicable lock-out situations not recoverable via the J-Flash GUI tool.