int i2c_stm32_runtime_configure(struct device *dev, u32_t config) { const struct i2c_stm32_config *cfg = DEV_CFG(dev); struct i2c_stm32_data *data = DEV_DATA(dev); I2C_TypeDef *i2c = cfg->i2c; u32_t clock = 0U; int ret; #if defined(CONFIG_SOC_SERIES_STM32F3X) || defined(CONFIG_SOC_SERIES_STM32F0X) LL_RCC_ClocksTypeDef rcc_clocks; /* * STM32F0/3 I2C's independent clock source supports only * HSI and SYSCLK, not APB1. We force clock variable to * SYSCLK frequency. */ LL_RCC_GetSystemClocksFreq(&rcc_clocks); clock = rcc_clocks.SYSCLK_Frequency; #else clock_control_get_rate(device_get_binding(STM32_CLOCK_CONTROL_NAME), (clock_control_subsys_t *) &cfg->pclken, &clock); #endif /* CONFIG_SOC_SERIES_STM32F3X) || CONFIG_SOC_SERIES_STM32F0X */ data->dev_config = config; k_sem_take(&data->bus_mutex, K_FOREVER); LL_I2C_Disable(i2c); LL_I2C_SetMode(i2c, LL_I2C_MODE_I2C); ret = stm32_i2c_configure_timing(dev, clock); k_sem_give(&data->bus_mutex); return ret; }
/** * @brief Initialize the I2C registers according to the specified parameters in I2C_InitStruct. * @param I2Cx I2C Instance. * @param I2C_InitStruct pointer to a @ref LL_I2C_InitTypeDef structure. * @retval An ErrorStatus enumeration value: * - SUCCESS: I2C registers are initialized * - ERROR: Not applicable */ uint32_t LL_I2C_Init(I2C_TypeDef *I2Cx, LL_I2C_InitTypeDef *I2C_InitStruct) { LL_RCC_ClocksTypeDef rcc_clocks; /* Check the I2C Instance I2Cx */ assert_param(IS_I2C_ALL_INSTANCE(I2Cx)); /* Check the I2C parameters from I2C_InitStruct */ assert_param(IS_LL_I2C_PERIPHERAL_MODE(I2C_InitStruct->PeripheralMode)); assert_param(IS_LL_I2C_CLOCK_SPEED(I2C_InitStruct->ClockSpeed)); assert_param(IS_LL_I2C_DUTY_CYCLE(I2C_InitStruct->DutyCycle)); assert_param(IS_LL_I2C_OWN_ADDRESS1(I2C_InitStruct->OwnAddress1)); assert_param(IS_LL_I2C_TYPE_ACKNOWLEDGE(I2C_InitStruct->TypeAcknowledge)); assert_param(IS_LL_I2C_OWN_ADDRSIZE(I2C_InitStruct->OwnAddrSize)); /* Disable the selected I2Cx Peripheral */ LL_I2C_Disable(I2Cx); /* Retrieve Clock frequencies */ LL_RCC_GetSystemClocksFreq(&rcc_clocks); /*---------------------------- I2Cx SCL Clock Speed Configuration ------------ * Configure the SCL speed : * - ClockSpeed: I2C_CR2_FREQ[5:0], I2C_TRISE_TRISE[5:0], I2C_CCR_FS, * and I2C_CCR_CCR[11:0] bits * - DutyCycle: I2C_CCR_DUTY[7:0] bits */ LL_I2C_ConfigSpeed(I2Cx, rcc_clocks.PCLK1_Frequency, I2C_InitStruct->ClockSpeed, I2C_InitStruct->DutyCycle); /*---------------------------- I2Cx OAR1 Configuration ----------------------- * Disable, Configure and Enable I2Cx device own address 1 with parameters : * - OwnAddress1: I2C_OAR1_ADD[9:8], I2C_OAR1_ADD[7:1] and I2C_OAR1_ADD0 bits * - OwnAddrSize: I2C_OAR1_ADDMODE bit */ LL_I2C_SetOwnAddress1(I2Cx, I2C_InitStruct->OwnAddress1, I2C_InitStruct->OwnAddrSize); /*---------------------------- I2Cx MODE Configuration ----------------------- * Configure I2Cx peripheral mode with parameter : * - PeripheralMode: I2C_CR1_SMBUS, I2C_CR1_SMBTYPE and I2C_CR1_ENARP bits */ LL_I2C_SetMode(I2Cx, I2C_InitStruct->PeripheralMode); /* Enable the selected I2Cx Peripheral */ LL_I2C_Enable(I2Cx); /*---------------------------- I2Cx CR2 Configuration ------------------------ * Configure the ACKnowledge or Non ACKnowledge condition * after the address receive match code or next received byte with parameter : * - TypeAcknowledge: I2C_CR2_NACK bit */ LL_I2C_AcknowledgeNextData(I2Cx, I2C_InitStruct->TypeAcknowledge); return SUCCESS; }
/** * @brief Initialize USART registers according to the specified * parameters in USART_InitStruct. * @note As some bits in USART configuration registers can only be written when the USART is disabled (USART_CR1_UE bit =0), * USART IP should be in disabled state prior calling this function. Otherwise, ERROR result will be returned. * @note Baud rate value stored in USART_InitStruct BaudRate field, should be valid (different from 0). * @param USARTx USART Instance * @param USART_InitStruct: pointer to a LL_USART_InitTypeDef structure * that contains the configuration information for the specified USART peripheral. * @retval An ErrorStatus enumeration value: * - SUCCESS: USART registers are initialized according to USART_InitStruct content * - ERROR: Problem occurred during USART Registers initialization */ ErrorStatus LL_USART_Init(USART_TypeDef *USARTx, LL_USART_InitTypeDef *USART_InitStruct) { ErrorStatus status = ERROR; uint32_t periphclk = LL_RCC_PERIPH_FREQUENCY_NO; #if (defined(USART4) || defined(USART5)) LL_RCC_ClocksTypeDef RCC_Clocks; #endif /* Check the parameters */ assert_param(IS_UART_INSTANCE(USARTx)); assert_param(IS_LL_USART_BAUDRATE(USART_InitStruct->BaudRate)); assert_param(IS_LL_USART_DATAWIDTH(USART_InitStruct->DataWidth)); assert_param(IS_LL_USART_STOPBITS(USART_InitStruct->StopBits)); assert_param(IS_LL_USART_PARITY(USART_InitStruct->Parity)); assert_param(IS_LL_USART_DIRECTION(USART_InitStruct->TransferDirection)); assert_param(IS_LL_USART_HWCONTROL(USART_InitStruct->HardwareFlowControl)); assert_param(IS_LL_USART_OVERSAMPLING(USART_InitStruct->OverSampling)); /* USART needs to be in disabled state, in order to be able to configure some bits in CRx registers */ if (LL_USART_IsEnabled(USARTx) == 0U) { /*---------------------------- USART CR1 Configuration ----------------------- * Configure USARTx CR1 (USART Word Length, Parity, Mode and Oversampling bits) with parameters: * - DataWidth: USART_CR1_M bits according to USART_InitStruct->DataWidth value * - Parity: USART_CR1_PCE, USART_CR1_PS bits according to USART_InitStruct->Parity value * - TransferDirection: USART_CR1_TE, USART_CR1_RE bits according to USART_InitStruct->TransferDirection value * - Oversampling: USART_CR1_OVER8 bit according to USART_InitStruct->OverSampling value. */ MODIFY_REG(USARTx->CR1, (USART_CR1_M | USART_CR1_PCE | USART_CR1_PS | USART_CR1_TE | USART_CR1_RE | USART_CR1_OVER8), (USART_InitStruct->DataWidth | USART_InitStruct->Parity | USART_InitStruct->TransferDirection | USART_InitStruct->OverSampling)); /*---------------------------- USART CR2 Configuration ----------------------- * Configure USARTx CR2 (Stop bits) with parameters: * - Stop Bits: USART_CR2_STOP bits according to USART_InitStruct->StopBits value. * - CLKEN, CPOL, CPHA and LBCL bits are to be configured using LL_USART_ClockInit(). */ LL_USART_SetStopBitsLength(USARTx, USART_InitStruct->StopBits); /*---------------------------- USART CR3 Configuration ----------------------- * Configure USARTx CR3 (Hardware Flow Control) with parameters: * - HardwareFlowControl: USART_CR3_RTSE, USART_CR3_CTSE bits according to USART_InitStruct->HardwareFlowControl value. */ LL_USART_SetHWFlowCtrl(USARTx, USART_InitStruct->HardwareFlowControl); /*---------------------------- USART BRR Configuration ----------------------- * Retrieve Clock frequency used for USART Peripheral */ #if defined(USART1) if (USARTx == USART1) { periphclk = LL_RCC_GetUSARTClockFreq(LL_RCC_USART1_CLKSOURCE); } #endif /* USART1 */ #if defined(USART1) else if (USARTx == USART2) #else if (USARTx == USART2) #endif { periphclk = LL_RCC_GetUSARTClockFreq(LL_RCC_USART2_CLKSOURCE); } #if defined(USART4) else if (USARTx == USART4) { /* USART4 clock is PCLK1 */ LL_RCC_GetSystemClocksFreq(&RCC_Clocks); periphclk = RCC_Clocks.PCLK1_Frequency; } #endif /* USART4 */ #if defined(USART5) else if (USARTx == USART5) { /* USART5 clock is PCLK1 */ LL_RCC_GetSystemClocksFreq(&RCC_Clocks); periphclk = RCC_Clocks.PCLK1_Frequency; } #endif /* USART5 */ else { /* Nothing to do, as error code is already assigned to ERROR value */ } /* Configure the USART Baud Rate : - valid baud rate value (different from 0) is required - Peripheral clock as returned by RCC service, should be valid (different from 0). */ if ((periphclk != LL_RCC_PERIPH_FREQUENCY_NO) && (USART_InitStruct->BaudRate != 0U)) { status = SUCCESS; LL_USART_SetBaudRate(USARTx, periphclk, USART_InitStruct->OverSampling, USART_InitStruct->BaudRate); } } /* Endif (=> USART not in Disabled state => return ERROR) */ return (status); }
/** * @brief Disable the LPTIM instance * @rmtoll CR ENABLE LL_LPTIM_Disable * @param LPTIMx Low-Power Timer instance * @note The following sequence is required to solve LPTIM disable HW limitation. * Please check Errata Sheet ES0335 for more details under "MCU may remain * stuck in LPTIM interrupt when entering Stop mode" section. * @retval None */ void LL_LPTIM_Disable(LPTIM_TypeDef *LPTIMx) { LL_RCC_ClocksTypeDef rcc_clock; uint32_t tmpclksource = 0; uint32_t tmpIER; uint32_t tmpCFGR; uint32_t tmpCMP; uint32_t tmpARR; uint32_t tmpCFGR2; /* Check the parameters */ assert_param(IS_LPTIM_INSTANCE(LPTIMx)); __disable_irq(); /********** Save LPTIM Config *********/ /* Save LPTIM source clock */ switch ((uint32_t)LPTIMx) { case LPTIM1_BASE: tmpclksource = LL_RCC_GetLPTIMClockSource(LL_RCC_LPTIM1_CLKSOURCE); break; case LPTIM2_BASE: tmpclksource = LL_RCC_GetLPTIMClockSource(LL_RCC_LPTIM2_CLKSOURCE); break; case LPTIM3_BASE: case LPTIM4_BASE: case LPTIM5_BASE: tmpclksource = LL_RCC_GetLPTIMClockSource(LL_RCC_LPTIM345_CLKSOURCE); break; default: break; } /* Save LPTIM configuration registers */ tmpIER = LPTIMx->IER; tmpCFGR = LPTIMx->CFGR; tmpCMP = LPTIMx->CMP; tmpARR = LPTIMx->ARR; tmpCFGR2 = LPTIMx->CFGR2; /************* Reset LPTIM ************/ (void)LL_LPTIM_DeInit(LPTIMx); /********* Restore LPTIM Config *******/ LL_RCC_GetSystemClocksFreq(&rcc_clock); if ((tmpCMP != 0UL) || (tmpARR != 0UL)) { /* Force LPTIM source kernel clock from APB */ switch ((uint32_t)LPTIMx) { case LPTIM1_BASE: LL_RCC_SetLPTIMClockSource(LL_RCC_LPTIM1_CLKSOURCE_PCLK1); break; case LPTIM2_BASE: LL_RCC_SetLPTIMClockSource(LL_RCC_LPTIM2_CLKSOURCE_PCLK4); break; case LPTIM3_BASE: case LPTIM4_BASE: case LPTIM5_BASE: LL_RCC_SetLPTIMClockSource(LL_RCC_LPTIM345_CLKSOURCE_PCLK4); break; default: break; } if (tmpCMP != 0UL) { /* Restore CMP and ARR registers (LPTIM should be enabled first) */ LPTIMx->CR |= LPTIM_CR_ENABLE; LPTIMx->CMP = tmpCMP; /* Polling on CMP write ok status after above restore operation */ do { rcc_clock.SYSCLK_Frequency--; /* Used for timeout */ } while (((LL_LPTIM_IsActiveFlag_CMPOK(LPTIMx) != 1UL)) && ((rcc_clock.SYSCLK_Frequency) > 0UL)); LL_LPTIM_ClearFlag_CMPOK(LPTIMx); } if (tmpARR != 0UL) { LPTIMx->CR |= LPTIM_CR_ENABLE; LPTIMx->ARR = tmpARR; LL_RCC_GetSystemClocksFreq(&rcc_clock); /* Polling on ARR write ok status after above restore operation */ do { rcc_clock.SYSCLK_Frequency--; /* Used for timeout */ } while (((LL_LPTIM_IsActiveFlag_ARROK(LPTIMx) != 1UL)) && ((rcc_clock.SYSCLK_Frequency) > 0UL)); LL_LPTIM_ClearFlag_ARROK(LPTIMx); } /* Restore LPTIM source kernel clock */ LL_RCC_SetLPTIMClockSource(tmpclksource); } /* Restore configuration registers (LPTIM should be disabled first) */ LPTIMx->CR &= ~(LPTIM_CR_ENABLE); LPTIMx->IER = tmpIER; LPTIMx->CFGR = tmpCFGR; LPTIMx->CFGR2 = tmpCFGR2; __enable_irq(); }