drivers: serial: stm32: rework code for max re-use in wide data support
Restructuring code for poll_in/poll_out/fifo_fill/fifo_read because for wide data support, all code is identical except the calls to LL_USART_{ReceiveData8/TransmitData8}. This allows both implementations, 8 and 9 bit data-width to call a visitor function, passing the either the 8 bit or 9 bit data-width function pointer. Signed-off-by: Jeroen van Dooren <jeroen.van.dooren@nobleo.nl>
This commit is contained in:
parent
250e1f93ca
commit
435d5d1a94
1 changed files with 88 additions and 22 deletions
|
@ -569,7 +569,11 @@ static int uart_stm32_config_get(const struct device *dev,
|
||||||
}
|
}
|
||||||
#endif /* CONFIG_UART_USE_RUNTIME_CONFIGURE */
|
#endif /* CONFIG_UART_USE_RUNTIME_CONFIGURE */
|
||||||
|
|
||||||
static int uart_stm32_poll_in(const struct device *dev, unsigned char *c)
|
typedef void (*poll_in_fn)(
|
||||||
|
const struct uart_stm32_config *config,
|
||||||
|
void *in);
|
||||||
|
|
||||||
|
static int uart_stm32_poll_in_visitor(const struct device *dev, void *in, poll_in_fn get_fn)
|
||||||
{
|
{
|
||||||
const struct uart_stm32_config *config = dev->config;
|
const struct uart_stm32_config *config = dev->config;
|
||||||
|
|
||||||
|
@ -586,13 +590,15 @@ static int uart_stm32_poll_in(const struct device *dev, unsigned char *c)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
*c = (unsigned char)LL_USART_ReceiveData8(config->usart);
|
get_fn(config, in);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void uart_stm32_poll_out(const struct device *dev,
|
typedef void (*poll_out_fn)(
|
||||||
unsigned char c)
|
const struct uart_stm32_config *config, void *out);
|
||||||
|
|
||||||
|
static void uart_stm32_poll_out_visitor(const struct device *dev, void *out, poll_out_fn set_fn)
|
||||||
{
|
{
|
||||||
const struct uart_stm32_config *config = dev->config;
|
const struct uart_stm32_config *config = dev->config;
|
||||||
#ifdef CONFIG_PM
|
#ifdef CONFIG_PM
|
||||||
|
@ -635,10 +641,30 @@ static void uart_stm32_poll_out(const struct device *dev,
|
||||||
}
|
}
|
||||||
#endif /* CONFIG_PM */
|
#endif /* CONFIG_PM */
|
||||||
|
|
||||||
LL_USART_TransmitData8(config->usart, (uint8_t)c);
|
set_fn(config, out);
|
||||||
irq_unlock(key);
|
irq_unlock(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void uart_stm32_poll_in_u8(const struct uart_stm32_config *config, void *in)
|
||||||
|
{
|
||||||
|
*((unsigned char *)in) = (unsigned char)LL_USART_ReceiveData8(config->usart);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void uart_stm32_poll_out_u8(const struct uart_stm32_config *config, void *out)
|
||||||
|
{
|
||||||
|
LL_USART_TransmitData8(config->usart, *((uint8_t *)out));
|
||||||
|
}
|
||||||
|
|
||||||
|
static int uart_stm32_poll_in(const struct device *dev, unsigned char *c)
|
||||||
|
{
|
||||||
|
return uart_stm32_poll_in_visitor(dev, (void *)c, uart_stm32_poll_in_u8);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void uart_stm32_poll_out(const struct device *dev, unsigned char c)
|
||||||
|
{
|
||||||
|
uart_stm32_poll_out_visitor(dev, (void *)&c, uart_stm32_poll_out_u8);
|
||||||
|
}
|
||||||
|
|
||||||
static int uart_stm32_err_check(const struct device *dev)
|
static int uart_stm32_err_check(const struct device *dev)
|
||||||
{
|
{
|
||||||
const struct uart_stm32_config *config = dev->config;
|
const struct uart_stm32_config *config = dev->config;
|
||||||
|
@ -708,9 +734,11 @@ static inline void __uart_stm32_get_clock(const struct device *dev)
|
||||||
|
|
||||||
#ifdef CONFIG_UART_INTERRUPT_DRIVEN
|
#ifdef CONFIG_UART_INTERRUPT_DRIVEN
|
||||||
|
|
||||||
static int uart_stm32_fifo_fill(const struct device *dev,
|
typedef void (*fifo_fill_fn)(const struct uart_stm32_config *config, const void *tx_data,
|
||||||
const uint8_t *tx_data,
|
const uint8_t offset);
|
||||||
int size)
|
|
||||||
|
static int uart_stm32_fifo_fill_visitor(const struct device *dev, const void *tx_data, int size,
|
||||||
|
fifo_fill_fn fill_fn)
|
||||||
{
|
{
|
||||||
const struct uart_stm32_config *config = dev->config;
|
const struct uart_stm32_config *config = dev->config;
|
||||||
uint8_t num_tx = 0U;
|
uint8_t num_tx = 0U;
|
||||||
|
@ -723,12 +751,12 @@ static int uart_stm32_fifo_fill(const struct device *dev,
|
||||||
/* Lock interrupts to prevent nested interrupts or thread switch */
|
/* Lock interrupts to prevent nested interrupts or thread switch */
|
||||||
key = irq_lock();
|
key = irq_lock();
|
||||||
|
|
||||||
while ((size - num_tx > 0) &&
|
while ((size - num_tx > 0) && LL_USART_IsActiveFlag_TXE(config->usart)) {
|
||||||
LL_USART_IsActiveFlag_TXE(config->usart)) {
|
|
||||||
/* TXE flag will be cleared with byte write to DR|RDR register */
|
/* TXE flag will be cleared with byte write to DR|RDR register */
|
||||||
|
|
||||||
/* Send a character (8bit , parity none) */
|
/* Send a character */
|
||||||
LL_USART_TransmitData8(config->usart, tx_data[num_tx++]);
|
fill_fn(config, tx_data, num_tx);
|
||||||
|
num_tx++;
|
||||||
}
|
}
|
||||||
|
|
||||||
irq_unlock(key);
|
irq_unlock(key);
|
||||||
|
@ -736,32 +764,70 @@ static int uart_stm32_fifo_fill(const struct device *dev,
|
||||||
return num_tx;
|
return num_tx;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int uart_stm32_fifo_read(const struct device *dev, uint8_t *rx_data,
|
static void fifo_fill_with_u8(const struct uart_stm32_config *config,
|
||||||
const int size)
|
const void *tx_data, const uint8_t offset)
|
||||||
|
{
|
||||||
|
const uint8_t *data = (const uint8_t *)tx_data;
|
||||||
|
/* Send a character (8bit) */
|
||||||
|
LL_USART_TransmitData8(config->usart, data[offset]);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int uart_stm32_fifo_fill(const struct device *dev, const uint8_t *tx_data, int size)
|
||||||
|
{
|
||||||
|
if (uart_stm32_ll2cfg_databits(uart_stm32_get_databits(dev), uart_stm32_get_parity(dev)) ==
|
||||||
|
UART_CFG_DATA_BITS_9) {
|
||||||
|
return -ENOTSUP;
|
||||||
|
}
|
||||||
|
return uart_stm32_fifo_fill_visitor(dev, (const void *)tx_data, size,
|
||||||
|
fifo_fill_with_u8);
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef void (*fifo_read_fn)(const struct uart_stm32_config *config, void *rx_data,
|
||||||
|
const uint8_t offset);
|
||||||
|
|
||||||
|
static int uart_stm32_fifo_read_visitor(const struct device *dev, void *rx_data, const int size,
|
||||||
|
fifo_read_fn read_fn)
|
||||||
{
|
{
|
||||||
const struct uart_stm32_config *config = dev->config;
|
const struct uart_stm32_config *config = dev->config;
|
||||||
uint8_t num_rx = 0U;
|
uint8_t num_rx = 0U;
|
||||||
|
|
||||||
while ((size - num_rx > 0) &&
|
while ((size - num_rx > 0) && LL_USART_IsActiveFlag_RXNE(config->usart)) {
|
||||||
LL_USART_IsActiveFlag_RXNE(config->usart)) {
|
|
||||||
/* RXNE flag will be cleared upon read from DR|RDR register */
|
/* RXNE flag will be cleared upon read from DR|RDR register */
|
||||||
|
|
||||||
/* Receive a character (8bit , parity none) */
|
read_fn(config, rx_data, num_rx);
|
||||||
rx_data[num_rx++] = LL_USART_ReceiveData8(config->usart);
|
num_rx++;
|
||||||
|
|
||||||
/* Clear overrun error flag */
|
/* Clear overrun error flag */
|
||||||
if (LL_USART_IsActiveFlag_ORE(config->usart)) {
|
if (LL_USART_IsActiveFlag_ORE(config->usart)) {
|
||||||
LL_USART_ClearFlag_ORE(config->usart);
|
LL_USART_ClearFlag_ORE(config->usart);
|
||||||
/*
|
/*
|
||||||
* On stm32 F4X, F1X, and F2X, the RXNE flag is affected (cleared) by
|
* On stm32 F4X, F1X, and F2X, the RXNE flag is affected (cleared) by
|
||||||
* the uart_err_check function call (on errors flags clearing)
|
* the uart_err_check function call (on errors flags clearing)
|
||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return num_rx;
|
return num_rx;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void fifo_read_with_u8(const struct uart_stm32_config *config, void *rx_data,
|
||||||
|
const uint8_t offset)
|
||||||
|
{
|
||||||
|
uint8_t *data = (uint8_t *)rx_data;
|
||||||
|
|
||||||
|
data[offset] = LL_USART_ReceiveData8(config->usart);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int uart_stm32_fifo_read(const struct device *dev, uint8_t *rx_data, const int size)
|
||||||
|
{
|
||||||
|
if (uart_stm32_ll2cfg_databits(uart_stm32_get_databits(dev), uart_stm32_get_parity(dev)) ==
|
||||||
|
UART_CFG_DATA_BITS_9) {
|
||||||
|
return -ENOTSUP;
|
||||||
|
}
|
||||||
|
return uart_stm32_fifo_read_visitor(dev, (void *)rx_data, size,
|
||||||
|
fifo_read_with_u8);
|
||||||
|
}
|
||||||
|
|
||||||
static void uart_stm32_irq_tx_enable(const struct device *dev)
|
static void uart_stm32_irq_tx_enable(const struct device *dev)
|
||||||
{
|
{
|
||||||
const struct uart_stm32_config *config = dev->config;
|
const struct uart_stm32_config *config = dev->config;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue