Beispiel #1
0
/**
  * @brief  Reset the RCC clock configuration to the default reset state.
  * @note   The default reset state of the clock configuration is given below:
  *         - MSI  ON and used as system clock source
  *         - HSE, HSI, PLL and PLLSAIxSource OFF
  *         - AHB, APB1 and APB2 prescaler set to 1.
  *         - CSS, MCO OFF
  *         - All interrupts disabled
  * @note   This function doesn't modify the configuration of the
  *         - Peripheral clocks
  *         - LSI, LSE and RTC clocks
  * @retval An ErrorStatus enumeration value:
  *          - SUCCESS: RCC registers are de-initialized
  *          - ERROR: not applicable
  */
ErrorStatus LL_RCC_DeInit(void)
{
  uint32_t vl_mask = 0;

  /* Set MSION bit */
  LL_RCC_MSI_Enable();

  /* Insure MSIRDY bit is set before writing default MSIRANGE value */
  while (LL_RCC_MSI_IsReady() == 0)
  {
    __NOP();
  }

  /* Set MSIRANGE default value */
  LL_RCC_MSI_SetRange(LL_RCC_MSIRANGE_6);
  /* Set MSITRIM bits to the reset value*/
  LL_RCC_MSI_SetCalibTrimming(0);

  /* Set HSITRIM bits to the reset value*/
  LL_RCC_HSI_SetCalibTrimming(0x10);

  /* Reset CFGR register */
  LL_RCC_WriteReg(CFGR, 0x00000000);

  vl_mask = 0xFFFFFFFFU;

  /* Reset HSION, HSIKERON, HSIASFS, HSEON, PLLSYSON bits */
  CLEAR_BIT(vl_mask, (RCC_CR_HSION | RCC_CR_HSIASFS | RCC_CR_HSIKERON  | RCC_CR_HSEON |
  RCC_CR_PLLON));

  /* Reset PLLSAI1ON bit */
  CLEAR_BIT(vl_mask, RCC_CR_PLLSAI1ON);

#if defined(RCC_PLLSAI2_SUPPORT)
  /* Reset PLLSAI2ON bit */
  CLEAR_BIT(vl_mask, RCC_CR_PLLSAI2ON);
#endif /*RCC_PLLSAI2_SUPPORT*/

  /* Write new mask in CR register */
  LL_RCC_WriteReg(CR, vl_mask);

  /* Reset PLLCFGR register */
  LL_RCC_WriteReg(PLLCFGR, 16 << RCC_POSITION_PLLN);

  /* Reset PLLSAI1CFGR register */
  LL_RCC_WriteReg(PLLSAI1CFGR, 16 << RCC_POSITION_PLLSAI1N);

#if defined(RCC_PLLSAI2_SUPPORT)
  /* Reset PLLSAI2CFGR register */
  LL_RCC_WriteReg(PLLSAI2CFGR, 16 << RCC_POSITION_PLLSAI2N);
#endif /*RCC_PLLSAI2_SUPPORT*/

  /* Reset HSEBYP bit */
  LL_RCC_HSE_DisableBypass();

  /* Disable all interrupts */
  LL_RCC_WriteReg(CIER, 0x00000000);

  return SUCCESS;
}
Beispiel #2
0
/**
  * @brief  Reset the RCC clock configuration to the default reset state.
  * @note   The default reset state of the clock configuration is given below:
  *         - MSI  ON and used as system clock source
  *         - HSE, HSI and PLL OFF
  *         - AHB, APB1 and APB2 prescaler set to 1.
  *         - CSS, MCO OFF
  *         - All interrupts disabled
  * @note   This function doesn't modify the configuration of the
  *         - Peripheral clocks
  *         - LSI, LSE and RTC clocks
  * @retval An ErrorStatus enumeration value:
  *          - SUCCESS: RCC registers are de-initialized
  *          - ERROR: not applicable
  */
ErrorStatus LL_RCC_DeInit(void)
{
  uint32_t vl_mask = 0U;

  /* Set MSION bit */
  LL_RCC_MSI_Enable();

  /* Insure MSIRDY bit is set before writing default MSIRANGE value */
  while (LL_RCC_MSI_IsReady() == 0U)
  {
    __NOP();
  }

  /* Set MSIRANGE default value */
  LL_RCC_MSI_SetRange(LL_RCC_MSIRANGE_5);
  /* Set MSITRIM bits to the reset value*/
  LL_RCC_MSI_SetCalibTrimming(0U);

  /* Set HSITRIM bits to the reset value*/
  LL_RCC_HSI_SetCalibTrimming(0x10U);

  /* Reset SW, HPRE, PPRE and MCOSEL bits */
  vl_mask = 0xFFFFFFFFU;
  CLEAR_BIT(vl_mask, (RCC_CFGR_SW | RCC_CFGR_HPRE | RCC_CFGR_PPRE1 | RCC_CFGR_PPRE2 | RCC_CFGR_MCOSEL));
  LL_RCC_WriteReg(CFGR, vl_mask);

  /* Reset HSI, HSE, PLL */
  vl_mask = LL_RCC_ReadReg(CR);
#if defined(RCC_CR_HSIOUTEN)  	
  CLEAR_BIT(vl_mask, RCC_CR_HSION| RCC_CR_HSIKERON| RCC_CR_HSIDIVEN | RCC_CR_HSIOUTEN | \
                     RCC_CR_HSEON | RCC_CR_PLLON); 
#else
  CLEAR_BIT(vl_mask, RCC_CR_HSION| RCC_CR_HSIKERON| RCC_CR_HSIDIVEN | \
                     RCC_CR_HSEON | RCC_CR_PLLON); 
#endif					 
  LL_RCC_WriteReg(CR, vl_mask);
  /* Delay after an RCC peripheral clock */
  vl_mask = LL_RCC_ReadReg(CR);

  /* Reset HSEBYP bit */
  LL_RCC_HSE_DisableBypass();

  /* Set RCC_CR_RTCPRE to 0b00*/
  CLEAR_BIT(vl_mask, RCC_CR_RTCPRE); 
  LL_RCC_WriteReg(CR, vl_mask);

  /* Reset CFGR register */
  LL_RCC_WriteReg(CFGR, 0x00000000U);

#if defined(RCC_HSI48_SUPPORT)
  /* Reset CRRCR register */
  LL_RCC_WriteReg(CRRCR, 0x00000000U);

  /* Disable HSI48 */
  LL_RCC_HSI48_Disable();

#endif /*RCC_HSI48_SUPPORT*/

  /* Disable all interrupts */
  LL_RCC_WriteReg(CIER, 0x00000000U);

  return SUCCESS;
}
Beispiel #3
0
static int usb_dc_stm32_clock_enable(void)
{
	struct device *clk = device_get_binding(STM32_CLOCK_CONTROL_NAME);
	struct stm32_pclken pclken = {

#ifdef DT_USB_HS_BASE_ADDRESS
		.bus = STM32_CLOCK_BUS_AHB1,
		.enr = LL_AHB1_GRP1_PERIPH_OTGHS
#else /* DT_USB_HS_BASE_ADDRESS */

#ifdef USB
		.bus = STM32_CLOCK_BUS_APB1,
		.enr = LL_APB1_GRP1_PERIPH_USB,

#else /* USB_OTG_FS */

#ifdef CONFIG_SOC_SERIES_STM32F1X
		.bus = STM32_CLOCK_BUS_AHB1,
		.enr = LL_AHB1_GRP1_PERIPH_OTGFS,
#else
		.bus = STM32_CLOCK_BUS_AHB2,
		.enr = LL_AHB2_GRP1_PERIPH_OTGFS,
#endif /* CONFIG_SOC_SERIES_STM32F1X */

#endif /* USB */

#endif /* DT_USB_HS_BASE_ADDRESS */
	};

	/*
	 * Some SoCs in STM32F0/L0/L4 series disable USB clock by
	 * default.  We force USB clock source to MSI or PLL clock for this
	 * SoCs.  However, if these parts have an HSI48 clock, use
	 * that instead.  Example reference manual RM0360 for
	 * STM32F030x4/x6/x8/xC and STM32F070x6/xB.
	 */
#if defined(RCC_HSI48_SUPPORT)

	/*
	 * In STM32L0 series, HSI48 requires VREFINT and its buffer
	 * with 48 MHz RC to be enabled.
	 * See ENREF_HSI48 in referenc maual RM0367 section10.2.3:
	 * "Reference control and status register (SYSCFG_CFGR3)"
	 */
#ifdef CONFIG_SOC_SERIES_STM32L0X
	if (LL_APB2_GRP1_IsEnabledClock(LL_APB2_GRP1_PERIPH_SYSCFG)) {
		LL_SYSCFG_VREFINT_EnableHSI48();
	} else {
		LOG_ERR("System Configuration Controller clock is "
			"disabled. Unable to enable VREFINT which "
			"is required by HSI48.");
	}
#endif /* CONFIG_SOC_SERIES_STM32L0X */

	LL_RCC_HSI48_Enable();
	while (!LL_RCC_HSI48_IsReady()) {
		/* Wait for HSI48 to become ready */
	}

	LL_RCC_SetUSBClockSource(LL_RCC_USB_CLKSOURCE_HSI48);
#elif defined(LL_RCC_USB_CLKSOURCE_NONE)
	/* When MSI is configured in PLL mode with a 32.768 kHz clock source,
	 * the MSI frequency can be automatically trimmed by hardware to reach
	 * better than ±0.25% accuracy. In this mode the MSI can feed the USB
	 * device. For now, we only use MSI for USB if not already used as
	 * system clock source.
	 */
#if defined(CONFIG_CLOCK_STM32_MSI_PLL_MODE) && !defined(CONFIG_CLOCK_STM32_SYSCLK_SRC_MSI)
	LL_RCC_MSI_Enable();
	while (!LL_RCC_MSI_IsReady()) {
		/* Wait for MSI to become ready */
	}
	/* Force 48 MHz mode */
	LL_RCC_MSI_EnableRangeSelection();
	LL_RCC_MSI_SetRange(LL_RCC_MSIRANGE_11);
	LL_RCC_SetUSBClockSource(LL_RCC_USB_CLKSOURCE_MSI);
#else
	if (LL_RCC_PLL_IsReady()) {
		LL_RCC_SetUSBClockSource(LL_RCC_USB_CLKSOURCE_PLL);
	} else {
		LOG_ERR("Unable to set USB clock source to PLL.");
	}
#endif /* CONFIG_CLOCK_STM32_MSI_PLL_MODE && !CONFIG_CLOCK_STM32_SYSCLK_SRC_MSI */
#endif /* RCC_HSI48_SUPPORT / LL_RCC_USB_CLKSOURCE_NONE */

	if (clock_control_on(clk, (clock_control_subsys_t *)&pclken) != 0) {
		LOG_ERR("Unable to enable USB clock");
		return -EIO;
	}

#ifdef DT_USB_HS_BASE_ADDRESS


#ifdef DT_COMPAT_ST_STM32_USBPHYC
	LL_AHB1_GRP1_EnableClock(LL_AHB1_GRP1_PERIPH_OTGHSULPI);
	LL_APB2_GRP1_EnableClock(LL_APB2_GRP1_PERIPH_OTGPHYC);
#else
	/* Disable ULPI interface (for external high-speed PHY) clock */
	LL_AHB1_GRP1_DisableClock(LL_AHB1_GRP1_PERIPH_OTGHSULPI);
	LL_AHB1_GRP1_DisableClockLowPower(LL_AHB1_GRP1_PERIPH_OTGHSULPI);
#endif /* DT_COMPAT_ST_STM32_USBPHYC */

#endif /* DT_USB_HS_BASE_ADDRESS */

	return 0;
}

#if defined(USB_OTG_FS) || defined(USB_OTG_HS)
static u32_t usb_dc_stm32_get_maximum_speed(void)
{
	/*
	 * If max-speed is not passed via DT, set it to USB controller's
	 * maximum hardware capability.
	 */
#if defined(DT_COMPAT_ST_STM32_USBPHYC) && defined(DT_USB_HS_BASE_ADDRESS)
	u32_t speed = USB_OTG_SPEED_HIGH;
#else
	u32_t speed = USB_OTG_SPEED_FULL;
#endif /* DT_COMPAT_ST_STM32_USBPHYC && DT_USB_HS_BASE_ADDRESS */

#ifdef DT_USB_MAXIMUM_SPEED

	if (!strncmp(DT_USB_MAXIMUM_SPEED, "high-speed", 10)) {
		speed = USB_OTG_SPEED_HIGH;
	} else if (!strncmp(DT_USB_MAXIMUM_SPEED, "full-speed", 10)) {
#if defined(DT_COMPAT_ST_STM32_USBPHYC) && defined(DT_USB_HS_BASE_ADDRESS)
		speed = USB_OTG_SPEED_HIGH_IN_FULL;
#else
		speed = USB_OTG_SPEED_FULL;
#endif /* DT_COMPAT_ST_STM32_USBPHYC && DT_USB_HS_BASE_ADDRESS */
	} else if (!strncmp(DT_USB_MAXIMUM_SPEED, "low-speed", 9)) {
		speed = USB_OTG_SPEED_LOW;
	} else {
		LOG_DBG("Unsupported maximum speed defined in device tree. "
			"USB controller will default to its maximum HW "
			"capability");
	}
#endif /* DT_USB_MAXIMUM_SPEED */

	return speed;
}