/** * @brief Initialize UART channel * * This routine is called to reset the chip in a quiescent state. * It is assumed that this function is called only once per UART. * * @param dev UART device struct * * @return 0 */ static int uart_stm32_init(struct device *dev) { const struct uart_stm32_config *config = DEV_CFG(dev); struct uart_stm32_data *data = DEV_DATA(dev); UART_HandleTypeDef *UartHandle = &data->huart; __uart_stm32_get_clock(dev); /* enable clock */ #if defined(CONFIG_SOC_SERIES_STM32F1X) || defined(CONFIG_SOC_SERIES_STM32L4X) clock_control_on(data->clock, config->clock_subsys); #elif defined(CONFIG_SOC_SERIES_STM32F4X) clock_control_on(data->clock, (clock_control_subsys_t *)&config->pclken); #endif UartHandle->Instance = UART_STRUCT(dev); UartHandle->Init.WordLength = UART_WORDLENGTH_8B; UartHandle->Init.StopBits = UART_STOPBITS_1; UartHandle->Init.Parity = UART_PARITY_NONE; UartHandle->Init.HwFlowCtl = UART_HWCONTROL_NONE; UartHandle->Init.Mode = UART_MODE_TX_RX; UartHandle->Init.OverSampling = UART_OVERSAMPLING_16; HAL_UART_Init(UartHandle); #ifdef CONFIG_UART_INTERRUPT_DRIVEN config->uconf.irq_config_func(dev); #endif return 0; }
/** * @brief Initialize UART channel * * This routine is called to reset the chip in a quiescent state. * It is assumed that this function is called only once per UART. * * @param dev UART device struct * * @return 0 */ static int uart_cmsdk_apb_init(struct device *dev) { volatile struct uart_cmsdk_apb *uart = UART_STRUCT(dev); #ifdef CONFIG_UART_INTERRUPT_DRIVEN const struct uart_device_config * const dev_cfg = DEV_CFG(dev); #endif #ifdef CONFIG_CLOCK_CONTROL /* Enable clock for subsystem */ struct device *clk = device_get_binding(CONFIG_ARM_CLOCK_CONTROL_DEV_NAME); struct uart_cmsdk_apb_dev_data * const data = DEV_DATA(dev); #ifdef CONFIG_SOC_SERIES_BEETLE clock_control_on(clk, (clock_control_subsys_t *) &data->uart_cc_as); clock_control_on(clk, (clock_control_subsys_t *) &data->uart_cc_ss); clock_control_on(clk, (clock_control_subsys_t *) &data->uart_cc_dss); #endif /* CONFIG_SOC_SERIES_BEETLE */ #endif /* CONFIG_CLOCK_CONTROL */ /* Set baud rate */ baudrate_set(dev); /* Enable receiver and transmitter */ uart->ctrl = UART_RX_EN | UART_TX_EN; #ifdef CONFIG_UART_INTERRUPT_DRIVEN dev_cfg->irq_config_func(dev); #endif return 0; }
static inline void _gpio_dw_clock_on(struct device *port) { struct gpio_dw_config *config = port->config->config_info; struct gpio_dw_runtime *context = port->driver_data; clock_control_on(context->clock, config->clock_data); }
static int init_rtc(struct device *dev, const nrfx_rtc_config_t *config, nrfx_rtc_handler_t handler) { struct device *clock; const struct counter_nrfx_config *nrfx_config = get_nrfx_config(dev); const nrfx_rtc_t *rtc = &nrfx_config->rtc; clock = device_get_binding(DT_NORDIC_NRF_CLOCK_0_LABEL "_32K"); if (!clock) { return -ENODEV; } clock_control_on(clock, (void *)CLOCK_CONTROL_NRF_K32SRC); nrfx_err_t result = nrfx_rtc_init(rtc, config, handler); if (result != NRFX_SUCCESS) { LOG_INST_ERR(nrfx_config->log, "Failed to initialize device."); return -EBUSY; } get_dev_data(dev)->top = COUNTER_MAX_TOP_VALUE; LOG_INST_DBG(nrfx_config->log, "Initialized"); return 0; }
static int nrf5_init(struct device *dev) { const struct nrf5_802154_config *nrf5_radio_cfg = NRF5_802154_CFG(dev); struct nrf5_802154_data *nrf5_radio = NRF5_802154_DATA(dev); struct device *clk_m16; k_sem_init(&nrf5_radio->rx_wait, 0, 1); k_sem_init(&nrf5_radio->tx_wait, 0, 1); k_sem_init(&nrf5_radio->cca_wait, 0, 1); clk_m16 = device_get_binding(CONFIG_CLOCK_CONTROL_NRF5_M16SRC_DRV_NAME); if (!clk_m16) { return -ENODEV; } clock_control_on(clk_m16, NULL); nrf_drv_radio802154_init(); nrf5_radio_cfg->irq_config_func(dev); k_thread_create(&nrf5_radio->rx_thread, nrf5_radio->rx_stack, CONFIG_IEEE802154_NRF5_RX_STACK_SIZE, nrf5_rx_thread, dev, NULL, NULL, K_PRIO_COOP(2), 0, 0); SYS_LOG_INF("nRF5 802154 radio initialized"); return 0; }
int stm32_gpio_enable_int(int port, int pin) { struct stm32l4x_syscfg *syscfg = (struct stm32l4x_syscfg *)SYSCFG_BASE; struct device *clk = device_get_binding(STM32_CLOCK_CONTROL_NAME); uint32_t *reg; clock_control_on(clk, (clock_control_subsys_t *) STM32L4X_CLOCK_SUBSYS_SYSCFG); if (pin <= STM32L4X_PIN3) { reg = &syscfg->exticr1; } else if (pin <= STM32L4X_PIN7) { reg = &syscfg->exticr2; } else if (pin <= STM32L4X_PIN11) { reg = &syscfg->exticr3; } else if (pin <= STM32L4X_PIN15) { reg = &syscfg->exticr4; } else { return -EINVAL; } *reg &= STM32L4X_SYSCFG_EXTICR_PIN_MASK << ((pin % 4) * 4); *reg |= port << ((pin % 4) * 4); return 0; /* Nothing to do here for STM32L4s */ }
int z_clock_driver_init(struct device *device) { struct device *clock; ARG_UNUSED(device); clock = device_get_binding(CONFIG_CLOCK_CONTROL_NRF_K32SRC_DRV_NAME); if (!clock) { return -1; } clock_control_on(clock, (void *)CLOCK_CONTROL_NRF_K32SRC); /* TODO: replace with counter driver to access RTC */ nrf_rtc_prescaler_set(RTC, 0); nrf_rtc_cc_set(RTC, 0, CYC_PER_TICK); nrf_rtc_event_enable(RTC, RTC_EVTENSET_COMPARE0_Msk); nrf_rtc_int_enable(RTC, RTC_INTENSET_COMPARE0_Msk); /* Clear the event flag and possible pending interrupt */ nrf_rtc_event_clear(RTC, NRF_RTC_EVENT_COMPARE_0); NVIC_ClearPendingIRQ(RTC1_IRQn); IRQ_CONNECT(RTC1_IRQn, 1, rtc1_nrf_isr, 0, 0); irq_enable(RTC1_IRQn); nrf_rtc_task_trigger(RTC, NRF_RTC_TASK_CLEAR); nrf_rtc_task_trigger(RTC, NRF_RTC_TASK_START); if (!IS_ENABLED(TICKLESS_KERNEL)) { set_comparator(counter() + CYC_PER_TICK); } return 0; }
static int rtc_stm32_init(struct device *dev) { struct device *clk = device_get_binding(STM32_CLOCK_CONTROL_NAME); const struct rtc_stm32_config *cfg = DEV_CFG(dev); __ASSERT_NO_MSG(clk); k_sem_init(DEV_SEM(dev), 1, UINT_MAX); DEV_DATA(dev)->cb_fn = NULL; clock_control_on(clk, (clock_control_subsys_t *) &cfg->pclken); LL_PWR_EnableBkUpAccess(); LL_RCC_ForceBackupDomainReset(); LL_RCC_ReleaseBackupDomainReset(); #if defined(CONFIG_RTC_STM32_CLOCK_LSI) LL_RCC_LSI_Enable(); while (LL_RCC_LSI_IsReady() != 1) ; LL_RCC_SetRTCClockSource(LL_RCC_RTC_CLKSOURCE_LSI); #else /* CONFIG_RTC_STM32_CLOCK_LSE */ LL_RCC_LSE_SetDriveCapability(CONFIG_RTC_STM32_LSE_DRIVE_STRENGTH); LL_RCC_LSE_Enable(); /* Wait untill LSE is ready */ while (LL_RCC_LSE_IsReady() != 1) ; LL_RCC_SetRTCClockSource(LL_RCC_RTC_CLKSOURCE_LSE); #endif /* CONFIG_RTC_STM32_CLOCK_SRC */ LL_RCC_EnableRTC(); if (LL_RTC_DeInit(RTC) != SUCCESS) { return -EIO; } if (LL_RTC_Init(RTC, ((LL_RTC_InitTypeDef *) &cfg->ll_rtc_config)) != SUCCESS) { return -EIO; } LL_RTC_EnableShadowRegBypass(RTC); LL_EXTI_EnableIT_0_31(EXTI_LINE); LL_EXTI_EnableRisingTrig_0_31(EXTI_LINE); rtc_stm32_irq_config(dev); return 0; }
static int dtmr_cmsdk_apb_init(struct device *dev) { const struct dtmr_cmsdk_apb_cfg * const cfg = dev->config->config_info; #ifdef CONFIG_CLOCK_CONTROL /* Enable clock for subsystem */ struct device *clk = device_get_binding(CONFIG_ARM_CLOCK_CONTROL_DEV_NAME); #ifdef CONFIG_SOC_SERIES_BEETLE clock_control_on(clk, (clock_control_subsys_t *) &cfg->dtimer_cc_as); clock_control_on(clk, (clock_control_subsys_t *) &cfg->dtimer_cc_ss); clock_control_on(clk, (clock_control_subsys_t *) &cfg->dtimer_cc_dss); #endif /* CONFIG_SOC_SERIES_BEETLE */ #endif /* CONFIG_CLOCK_CONTROL */ cfg->dtimer_config_func(dev); return 0; }
static int pwm_stm32_init(struct device *dev) { const struct pwm_stm32_config *config = DEV_CFG(dev); struct pwm_stm32_data *data = DEV_DATA(dev); __pwm_stm32_get_clock(dev); /* enable clock */ clock_control_on(data->clock, (clock_control_subsys_t *)&config->pclken); return 0; }
/** * @brief enable IO port clock * * @param port I/O port ID * @param clk optional clock device * * @return 0 on success, error otherwise */ static int enable_port(u32_t port, struct device *clk) { /* enable port clock */ if (!clk) { clk = device_get_binding(STM32_CLOCK_CONTROL_NAME); } /* TODO: Merge this and move the port clock to the soc file */ #if defined(CONFIG_CLOCK_CONTROL_STM32_CUBE) struct stm32_pclken pclken; pclken.bus = STM32_CLOCK_BUS_GPIO; pclken.enr = ports_enable[port]; return clock_control_on(clk, (clock_control_subsys_t *) &pclken); #else /* TODO: Clean once F1 series moved to LL Clock control */ clock_control_subsys_t subsys = stm32_get_port_clock(port); return clock_control_on(clk, subsys); #endif /* CONFIG_CLOCK_CONTROL_STM32_CUBE */ }
/** * @brief Initialize UART channel * * This routine is called to reset the chip in a quiescent state. * It is assumed that this function is called only once per UART. * * @param dev UART device struct * * @return 0 */ static int uart_stm32_init(struct device *dev) { const struct uart_stm32_config *config = DEV_CFG(dev); struct uart_stm32_data *data = DEV_DATA(dev); USART_TypeDef *UartInstance = UART_STRUCT(dev); __uart_stm32_get_clock(dev); /* enable clock */ if (clock_control_on(data->clock, (clock_control_subsys_t *)&config->pclken) != 0) { return -EIO; } LL_USART_Disable(UartInstance); /* TX/RX direction */ LL_USART_SetTransferDirection(UartInstance, LL_USART_DIRECTION_TX_RX); /* 8 data bit, 1 start bit, 1 stop bit, no parity */ LL_USART_ConfigCharacter(UartInstance, LL_USART_DATAWIDTH_8B, LL_USART_PARITY_NONE, LL_USART_STOPBITS_1); if (config->hw_flow_control) { uart_stm32_set_hwctrl(dev, LL_USART_HWCONTROL_RTS_CTS); } /* Set the default baudrate */ uart_stm32_set_baudrate(dev, data->baud_rate); LL_USART_Enable(UartInstance); #ifdef USART_ISR_TEACK /* Wait until TEACK flag is set */ while (!(LL_USART_IsActiveFlag_TEACK(UartInstance))) ; #endif /* !USART_ISR_TEACK */ #ifdef USART_ISR_REACK /* Wait until REACK flag is set */ while (!(LL_USART_IsActiveFlag_REACK(UartInstance))) ; #endif /* !USART_ISR_REACK */ #ifdef CONFIG_UART_INTERRUPT_DRIVEN config->uconf.irq_config_func(dev); #endif return 0; }
static int stm32_flash_init(struct device *dev) { struct flash_stm32_priv *p = dev->driver_data; #if defined(CONFIG_SOC_SERIES_STM32L4X) struct device *clk = device_get_binding(STM32_CLOCK_CONTROL_NAME); /* enable clock */ clock_control_on(clk, (clock_control_subsys_t *)&p->pclken); #endif k_sem_init(&p->sem, 1, 1); return flash_stm32_write_protection(dev, false); }
static int i2s_stm32_enable_clock(struct device *dev) { const struct i2s_stm32_cfg *cfg = DEV_CFG(dev); struct device *clk; int ret; clk = device_get_binding(STM32_CLOCK_CONTROL_NAME); __ASSERT_NO_MSG(clk); ret = clock_control_on(clk, (clock_control_subsys_t *) &cfg->pclken); if (ret != 0) { LOG_ERR("Could not enable I2S clock"); return -EIO; } return 0; }
/** * @brief enable IO port clock * * @param port I/O port ID * @param clk optional clock device * * @return 0 on success, error otherwise */ static int enable_port(u32_t port, struct device *clk) { /* enable port clock */ if (!clk) { clk = device_get_binding(STM32_CLOCK_CONTROL_NAME); } struct stm32_pclken pclken; pclken.bus = STM32_CLOCK_BUS_GPIO; pclken.enr = ports_enable[port]; if (pclken.enr == STM32_PORT_NOT_AVAILABLE) { return -EIO; } return clock_control_on(clk, (clock_control_subsys_t *) &pclken); }
int stm32_gpio_enable_int(int port, int pin) { volatile struct stm32f3x_syscfg *syscfg = (struct stm32f3x_syscfg *)SYSCFG_BASE; volatile union syscfg__exticr *exticr; /* Enable System Configuration Controller clock. */ struct device *clk = device_get_binding(STM32_CLOCK_CONTROL_NAME); struct stm32_pclken pclken = { .bus = STM32_CLOCK_BUS_APB2, .enr = LL_APB2_GRP1_PERIPH_SYSCFG }; clock_control_on(clk, (clock_control_subsys_t *) &pclken); int shift = 0; if (pin <= 3) { exticr = &syscfg->exticr1; } else if (pin <= 7) { exticr = &syscfg->exticr2; } else if (pin <= 11) { exticr = &syscfg->exticr3; } else if (pin <= 15) { exticr = &syscfg->exticr4; } else { return -EINVAL; } shift = 4 * (pin % 4); exticr->val &= ~(0xf << shift); exticr->val |= port << shift; return 0; }
static int dma_stm32_init(struct device *dev) { struct dma_stm32_device *ddata = dev->driver_data; const struct dma_stm32_config *cdata = dev->config->config_info; int i; for (i = 0; i < DMA_STM32_MAX_STREAMS; i++) { ddata->stream[i].dev = dev; ddata->stream[i].busy = false; } /* Enable DMA clock */ ddata->clk = device_get_binding(STM32_CLOCK_CONTROL_NAME); __ASSERT_NO_MSG(ddata->clk); clock_control_on(ddata->clk, (clock_control_subsys_t *) &cdata->pclken); /* Set controller specific configuration */ cdata->config(ddata); return 0; }
int _sys_clock_driver_init(struct device *device) { struct device *clock; ARG_UNUSED(device); clock = device_get_binding(CONFIG_CLOCK_CONTROL_NRF5_K32SRC_DRV_NAME); if (!clock) { return -1; } clock_control_on(clock, (void *)CLOCK_CONTROL_NRF5_K32SRC); rtc_past = 0; #ifdef CONFIG_TICKLESS_IDLE expected_sys_ticks = 1; #endif /* CONFIG_TICKLESS_IDLE */ /* TODO: replace with counter driver to access RTC */ SYS_CLOCK_RTC->PRESCALER = 0; nrf_rtc_cc_set(SYS_CLOCK_RTC, RTC_CC_IDX, sys_clock_hw_cycles_per_tick); nrf_rtc_event_enable(SYS_CLOCK_RTC, RTC_EVTENSET_COMPARE0_Msk); nrf_rtc_int_enable(SYS_CLOCK_RTC, RTC_INTENSET_COMPARE0_Msk); /* Clear the event flag and possible pending interrupt */ RTC_CC_EVENT = 0; NVIC_ClearPendingIRQ(NRF5_IRQ_RTC1_IRQn); IRQ_CONNECT(NRF5_IRQ_RTC1_IRQn, 1, rtc1_nrf5_isr, 0, 0); irq_enable(NRF5_IRQ_RTC1_IRQn); nrf_rtc_task_trigger(SYS_CLOCK_RTC, NRF_RTC_TASK_CLEAR); nrf_rtc_task_trigger(SYS_CLOCK_RTC, NRF_RTC_TASK_START); return 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; }
static int i2c_stm32_init(struct device *dev) { struct device *clock = device_get_binding(STM32_CLOCK_CONTROL_NAME); const struct i2c_stm32_config *cfg = DEV_CFG(dev); u32_t bitrate_cfg; int ret; struct i2c_stm32_data *data = DEV_DATA(dev); #ifdef CONFIG_I2C_STM32_INTERRUPT k_sem_init(&data->device_sync_sem, 0, UINT_MAX); cfg->irq_config_func(dev); #endif /* * initialize mutex used when multiple transfers * are taking place to guarantee that each one is * atomic and has exclusive access to the I2C bus. */ k_sem_init(&data->bus_mutex, 1, 1); __ASSERT_NO_MSG(clock); if (clock_control_on(clock, (clock_control_subsys_t *) &cfg->pclken) != 0) { LOG_ERR("i2c: failure enabling clock"); return -EIO; } #if defined(CONFIG_SOC_SERIES_STM32F3X) || defined(CONFIG_SOC_SERIES_STM32F0X) /* * STM32F0/3 I2C's independent clock source supports only * HSI and SYSCLK, not APB1. We force I2C clock source to SYSCLK. * I2C2 on STM32F0 uses APB1 clock as I2C clock source */ switch ((u32_t)cfg->i2c) { #ifdef CONFIG_I2C_1 case DT_I2C_1_BASE_ADDRESS: LL_RCC_SetI2CClockSource(LL_RCC_I2C1_CLKSOURCE_SYSCLK); break; #endif /* CONFIG_I2C_1 */ #if defined(CONFIG_SOC_SERIES_STM32F3X) && defined(CONFIG_I2C_2) case DT_I2C_2_BASE_ADDRESS: LL_RCC_SetI2CClockSource(LL_RCC_I2C2_CLKSOURCE_SYSCLK); break; #endif /* CONFIG_SOC_SERIES_STM32F3X && CONFIG_I2C_2 */ #ifdef CONFIG_I2C_3 case DT_I2C_3_BASE_ADDRESS: LL_RCC_SetI2CClockSource(LL_RCC_I2C3_CLKSOURCE_SYSCLK); break; #endif /* CONFIG_I2C_3 */ } #endif /* CONFIG_SOC_SERIES_STM32F3X) || CONFIG_SOC_SERIES_STM32F0X */ bitrate_cfg = _i2c_map_dt_bitrate(cfg->bitrate); ret = i2c_stm32_runtime_configure(dev, I2C_MODE_MASTER | bitrate_cfg); if (ret < 0) { LOG_ERR("i2c: failure initializing"); return ret; } return 0; }
static int adc_stm32_init(struct device *dev) { struct adc_stm32_data *data = dev->driver_data; const struct adc_stm32_cfg *config = dev->config->config_info; struct device *clk = device_get_binding(STM32_CLOCK_CONTROL_NAME); ADC_TypeDef *adc = (ADC_TypeDef *)config->base; LOG_DBG("Initializing...."); data->dev = dev; #if defined(CONFIG_SOC_SERIES_STM32F0X) || defined(CONFIG_SOC_SERIES_STM32L0X) /* * All conversion time for all channels on one ADC instance for F0 and * L0 series chips has to be the same. This additional variable is for * checking if the conversion time selection of all channels on one ADC * instance is the same. */ data->acq_time_index = -1; #endif if (clock_control_on(clk, (clock_control_subsys_t *) &config->pclken) != 0) { return -EIO; } #if defined(CONFIG_SOC_SERIES_STM32L4X) /* * L4 series STM32 needs to be awaken from deep sleep mode, and restore * its calibration parameters if there are some previously stored * calibration parameters. */ LL_ADC_DisableDeepPowerDown(adc); #endif /* * F3 and L4 ADC modules need some time to be stabilized before * performing any enable or calibration actions. */ #if defined(CONFIG_SOC_SERIES_STM32F3X) || \ defined(CONFIG_SOC_SERIES_STM32L4X) LL_ADC_EnableInternalRegulator(adc); k_busy_wait(LL_ADC_DELAY_INTERNAL_REGUL_STAB_US); #endif #if defined(CONFIG_SOC_SERIES_STM32F0X) || \ defined(CONFIG_SOC_SERIES_STM32L0X) LL_ADC_SetClock(adc, LL_ADC_CLOCK_SYNC_PCLK_DIV4); #elif defined(CONFIG_SOC_SERIES_STM32F3X) || \ defined(CONFIG_SOC_SERIES_STM32L4X) LL_ADC_SetCommonClock(__LL_ADC_COMMON_INSTANCE(), LL_ADC_CLOCK_SYNC_PCLK_DIV4); #endif #if !defined(CONFIG_SOC_SERIES_STM32F2X) && \ !defined(CONFIG_SOC_SERIES_STM32F4X) && \ !defined(CONFIG_SOC_SERIES_STM32F7X) && \ !defined(CONFIG_SOC_SERIES_STM32F1X) /* * Calibration of F1 series has to be started after ADC Module is * enabled. */ adc_stm32_calib(dev); #endif #if defined(CONFIG_SOC_SERIES_STM32F0X) || \ defined(CONFIG_SOC_SERIES_STM32L0X) if (LL_ADC_IsActiveFlag_ADRDY(adc)) { LL_ADC_ClearFlag_ADRDY(adc); } /* * These two series STM32 has one internal voltage reference source * to be enabled. */ LL_ADC_SetCommonPathInternalCh(ADC, LL_ADC_PATH_INTERNAL_VREFINT); #endif #if defined(CONFIG_SOC_SERIES_STM32F0X) || \ defined(CONFIG_SOC_SERIES_STM32F3X) || \ defined(CONFIG_SOC_SERIES_STM32L0X) || \ defined(CONFIG_SOC_SERIES_STM32L4X) /* * ADC modules on these series have to wait for some cycles to be * enabled. */ u32_t adc_rate, wait_cycles; if (clock_control_get_rate(clk, (clock_control_subsys_t *) &config->pclken, &adc_rate) < 0) { LOG_ERR("ADC clock rate get error."); } wait_cycles = CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC / adc_rate * LL_ADC_DELAY_CALIB_ENABLE_ADC_CYCLES; for (int i = wait_cycles; i >= 0; i--) ; #endif LL_ADC_Enable(adc); #ifdef CONFIG_SOC_SERIES_STM32L4X /* * Enabling ADC modules in L4 series may fail if they are still not * stabilized, this will wait for a short time to ensure ADC modules * are properly enabled. */ u32_t countTimeout = 0; while (LL_ADC_IsActiveFlag_ADRDY(adc) == 0) { if (LL_ADC_IsEnabled(adc) == 0UL) { LL_ADC_Enable(adc); countTimeout++; if (countTimeout == 10) { return -ETIMEDOUT; } } } #endif config->irq_cfg_func(); #ifdef CONFIG_SOC_SERIES_STM32F1X /* Calibration of F1 must starts after two cycles after ADON is set. */ LL_ADC_StartCalibration(adc); LL_ADC_REG_SetTriggerSource(adc, LL_ADC_REG_TRIG_SOFTWARE); #endif adc_context_unlock_unconditionally(&data->ctx); return 0; }