in CMake-armcc/Drivers/STM32L4xx_HAL_Driver/Src/stm32l4xx_hal_uart.c [3128:3376]
HAL_StatusTypeDef UART_SetConfig(UART_HandleTypeDef *huart)
{
uint32_t tmpreg;
uint16_t brrtemp;
UART_ClockSourceTypeDef clocksource;
uint32_t usartdiv;
HAL_StatusTypeDef ret = HAL_OK;
#if defined(USART_PRESC_PRESCALER)
uint32_t lpuart_ker_ck_pres;
#endif /* USART_PRESC_PRESCALER */
uint32_t pclk;
/* Check the parameters */
assert_param(IS_UART_BAUDRATE(huart->Init.BaudRate));
assert_param(IS_UART_WORD_LENGTH(huart->Init.WordLength));
if (UART_INSTANCE_LOWPOWER(huart))
{
assert_param(IS_LPUART_STOPBITS(huart->Init.StopBits));
}
else
{
assert_param(IS_UART_STOPBITS(huart->Init.StopBits));
assert_param(IS_UART_ONE_BIT_SAMPLE(huart->Init.OneBitSampling));
}
assert_param(IS_UART_PARITY(huart->Init.Parity));
assert_param(IS_UART_MODE(huart->Init.Mode));
assert_param(IS_UART_HARDWARE_FLOW_CONTROL(huart->Init.HwFlowCtl));
assert_param(IS_UART_OVERSAMPLING(huart->Init.OverSampling));
#if defined(USART_PRESC_PRESCALER)
assert_param(IS_UART_PRESCALER(huart->Init.ClockPrescaler));
#endif /* USART_PRESC_PRESCALER */
/*-------------------------- USART CR1 Configuration -----------------------*/
/* Clear M, PCE, PS, TE, RE and OVER8 bits and configure
* the UART Word Length, Parity, Mode and oversampling:
* set the M bits according to huart->Init.WordLength value
* set PCE and PS bits according to huart->Init.Parity value
* set TE and RE bits according to huart->Init.Mode value
* set OVER8 bit according to huart->Init.OverSampling value */
tmpreg = (uint32_t)huart->Init.WordLength | huart->Init.Parity | huart->Init.Mode | huart->Init.OverSampling ;
MODIFY_REG(huart->Instance->CR1, USART_CR1_FIELDS, tmpreg);
/*-------------------------- USART CR2 Configuration -----------------------*/
/* Configure the UART Stop Bits: Set STOP[13:12] bits according
* to huart->Init.StopBits value */
MODIFY_REG(huart->Instance->CR2, USART_CR2_STOP, huart->Init.StopBits);
/*-------------------------- USART CR3 Configuration -----------------------*/
/* Configure
* - UART HardWare Flow Control: set CTSE and RTSE bits according
* to huart->Init.HwFlowCtl value
* - one-bit sampling method versus three samples' majority rule according
* to huart->Init.OneBitSampling (not applicable to LPUART) */
tmpreg = (uint32_t)huart->Init.HwFlowCtl;
if (!(UART_INSTANCE_LOWPOWER(huart)))
{
tmpreg |= huart->Init.OneBitSampling;
}
MODIFY_REG(huart->Instance->CR3, USART_CR3_FIELDS, tmpreg);
#if defined(USART_PRESC_PRESCALER)
/*-------------------------- USART PRESC Configuration -----------------------*/
/* Configure
* - UART Clock Prescaler : set PRESCALER according to huart->Init.ClockPrescaler value */
MODIFY_REG(huart->Instance->PRESC, USART_PRESC_PRESCALER, huart->Init.ClockPrescaler);
#endif /* USART_PRESC_PRESCALER */
/*-------------------------- USART BRR Configuration -----------------------*/
UART_GETCLOCKSOURCE(huart, clocksource);
/* Check LPUART instance */
if (UART_INSTANCE_LOWPOWER(huart))
{
/* Retrieve frequency clock */
switch (clocksource)
{
case UART_CLOCKSOURCE_PCLK1:
pclk = HAL_RCC_GetPCLK1Freq();
break;
case UART_CLOCKSOURCE_HSI:
pclk = (uint32_t) HSI_VALUE;
break;
case UART_CLOCKSOURCE_SYSCLK:
pclk = HAL_RCC_GetSysClockFreq();
break;
case UART_CLOCKSOURCE_LSE:
pclk = (uint32_t) LSE_VALUE;
break;
default:
pclk = 0U;
ret = HAL_ERROR;
break;
}
/* If proper clock source reported */
if (pclk != 0U)
{
#if defined(USART_PRESC_PRESCALER)
/* Compute clock after Prescaler */
lpuart_ker_ck_pres = (pclk / UARTPrescTable[huart->Init.ClockPrescaler]);
/* Ensure that Frequency clock is in the range [3 * baudrate, 4096 * baudrate] */
if ((lpuart_ker_ck_pres < (3U * huart->Init.BaudRate)) ||
(lpuart_ker_ck_pres > (4096U * huart->Init.BaudRate)))
{
ret = HAL_ERROR;
}
else
{
/* Check computed UsartDiv value is in allocated range
(it is forbidden to write values lower than 0x300 in the LPUART_BRR register) */
usartdiv = (uint32_t)(UART_DIV_LPUART(pclk, huart->Init.BaudRate, huart->Init.ClockPrescaler));
if ((usartdiv >= LPUART_BRR_MIN) && (usartdiv <= LPUART_BRR_MAX))
{
huart->Instance->BRR = usartdiv;
}
else
{
ret = HAL_ERROR;
}
} /* if ( (lpuart_ker_ck_pres < (3 * huart->Init.BaudRate) ) ||
(lpuart_ker_ck_pres > (4096 * huart->Init.BaudRate) )) */
#else
/* No Prescaler applicable */
/* Ensure that Frequency clock is in the range [3 * baudrate, 4096 * baudrate] */
if ((pclk < (3U * huart->Init.BaudRate)) ||
(pclk > (4096U * huart->Init.BaudRate)))
{
ret = HAL_ERROR;
}
else
{
usartdiv = (uint32_t)(UART_DIV_LPUART(pclk, huart->Init.BaudRate));
if ((usartdiv >= LPUART_BRR_MIN) && (usartdiv <= LPUART_BRR_MAX))
{
huart->Instance->BRR = usartdiv;
}
else
{
ret = HAL_ERROR;
}
} /* if ( (pclk < (3 * huart->Init.BaudRate) ) || (pclk > (4096 * huart->Init.BaudRate) )) */
#endif /* USART_PRESC_PRESCALER */
} /* if (pclk != 0) */
}
/* Check UART Over Sampling to set Baud Rate Register */
else if (huart->Init.OverSampling == UART_OVERSAMPLING_8)
{
switch (clocksource)
{
case UART_CLOCKSOURCE_PCLK1:
pclk = HAL_RCC_GetPCLK1Freq();
break;
case UART_CLOCKSOURCE_PCLK2:
pclk = HAL_RCC_GetPCLK2Freq();
break;
case UART_CLOCKSOURCE_HSI:
pclk = (uint32_t) HSI_VALUE;
break;
case UART_CLOCKSOURCE_SYSCLK:
pclk = HAL_RCC_GetSysClockFreq();
break;
case UART_CLOCKSOURCE_LSE:
pclk = (uint32_t) LSE_VALUE;
break;
default:
pclk = 0U;
ret = HAL_ERROR;
break;
}
/* USARTDIV must be greater than or equal to 0d16 */
if (pclk != 0U)
{
#if defined(USART_PRESC_PRESCALER)
usartdiv = (uint16_t)(UART_DIV_SAMPLING8(pclk, huart->Init.BaudRate, huart->Init.ClockPrescaler));
#else
usartdiv = (uint16_t)(UART_DIV_SAMPLING8(pclk, huart->Init.BaudRate));
#endif /* USART_PRESC_PRESCALER */
if ((usartdiv >= UART_BRR_MIN) && (usartdiv <= UART_BRR_MAX))
{
brrtemp = (uint16_t)(usartdiv & 0xFFF0U);
brrtemp |= (uint16_t)((usartdiv & (uint16_t)0x000FU) >> 1U);
huart->Instance->BRR = brrtemp;
}
else
{
ret = HAL_ERROR;
}
}
}
else
{
switch (clocksource)
{
case UART_CLOCKSOURCE_PCLK1:
pclk = HAL_RCC_GetPCLK1Freq();
break;
case UART_CLOCKSOURCE_PCLK2:
pclk = HAL_RCC_GetPCLK2Freq();
break;
case UART_CLOCKSOURCE_HSI:
pclk = (uint32_t) HSI_VALUE;
break;
case UART_CLOCKSOURCE_SYSCLK:
pclk = HAL_RCC_GetSysClockFreq();
break;
case UART_CLOCKSOURCE_LSE:
pclk = (uint32_t) LSE_VALUE;
break;
default:
pclk = 0U;
ret = HAL_ERROR;
break;
}
if (pclk != 0U)
{
/* USARTDIV must be greater than or equal to 0d16 */
#if defined(USART_PRESC_PRESCALER)
usartdiv = (uint16_t)(UART_DIV_SAMPLING16(pclk, huart->Init.BaudRate, huart->Init.ClockPrescaler));
#else
usartdiv = (uint16_t)(UART_DIV_SAMPLING16(pclk, huart->Init.BaudRate));
#endif /* USART_PRESC_PRESCALER */
if ((usartdiv >= UART_BRR_MIN) && (usartdiv <= UART_BRR_MAX))
{
huart->Instance->BRR = usartdiv;
}
else
{
ret = HAL_ERROR;
}
}
}
#if defined(USART_CR1_FIFOEN)
/* Initialize the number of data to process during RX/TX ISR execution */
huart->NbTxDataToProcess = 1;
huart->NbRxDataToProcess = 1;
#endif /* USART_CR1_FIFOEN */
/* Clear ISR function pointers */
huart->RxISR = NULL;
huart->TxISR = NULL;
return ret;
}