drivers: serial: nrfx_uarte: Use ENDTX_STOPTX short if possible
Use short which is available on some devices. Signed-off-by: Krzysztof Chruściński <krzysztof.chruscinski@nordicsemi.no>
This commit is contained in:
parent
b7b25fe09c
commit
ffdf9a978d
2 changed files with 35 additions and 19 deletions
|
|
@ -20,7 +20,7 @@ config UART_$(nrfx_uart_num)_ASYNC
|
||||||
|
|
||||||
config UART_$(nrfx_uart_num)_ENHANCED_POLL_OUT
|
config UART_$(nrfx_uart_num)_ENHANCED_POLL_OUT
|
||||||
bool "Efficient poll out on port $(nrfx_uart_num)"
|
bool "Efficient poll out on port $(nrfx_uart_num)"
|
||||||
depends on !SOC_SERIES_NRF54LX
|
depends on !$(dt_nodelabel_has_prop,uart$(nrfx_uart_num),short-endtx-stoptx)
|
||||||
default y
|
default y
|
||||||
depends on HAS_HW_NRF_UARTE$(nrfx_uart_num)
|
depends on HAS_HW_NRF_UARTE$(nrfx_uart_num)
|
||||||
depends on HAS_HW_NRF_PPI || HAS_HW_NRF_DPPIC
|
depends on HAS_HW_NRF_PPI || HAS_HW_NRF_DPPIC
|
||||||
|
|
|
||||||
|
|
@ -39,9 +39,13 @@ LOG_MODULE_REGISTER(uart_nrfx_uarte, CONFIG_UART_LOG_LEVEL);
|
||||||
#error "No PPI or DPPI"
|
#error "No PPI or DPPI"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define UARTE(idx) DT_NODELABEL(uart##idx)
|
||||||
|
#define UARTE_HAS_PROP(idx, prop) DT_NODE_HAS_PROP(UARTE(idx), prop)
|
||||||
|
#define UARTE_PROP(idx, prop) DT_PROP(UARTE(idx), prop)
|
||||||
|
|
||||||
/* Execute macro f(x) for all instances. */
|
/* Execute macro f(x) for all instances. */
|
||||||
#define UARTE_FOR_EACH_INSTANCE(f, sep, off_code) \
|
#define UARTE_FOR_EACH_INSTANCE(f, sep, off_code, ...) \
|
||||||
NRFX_FOREACH_PRESENT(UARTE, f, sep, off_code, _)
|
NRFX_FOREACH_PRESENT(UARTE, f, sep, off_code, __VA_ARGS__)
|
||||||
|
|
||||||
/* Determine if any instance is using interrupt driven API. */
|
/* Determine if any instance is using interrupt driven API. */
|
||||||
#define IS_INT_DRIVEN(unused, prefix, i, _) \
|
#define IS_INT_DRIVEN(unused, prefix, i, _) \
|
||||||
|
|
@ -85,6 +89,15 @@ LOG_MODULE_REGISTER(uart_nrfx_uarte, CONFIG_UART_LOG_LEVEL);
|
||||||
#define UARTE_ENHANCED_POLL_OUT 1
|
#define UARTE_ENHANCED_POLL_OUT 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define INSTANCE_PROP(unused, prefix, i, prop) UARTE_PROP(prefix##i, prop)
|
||||||
|
#define INSTANCE_PRESENT(unused, prefix, i, prop) 1
|
||||||
|
|
||||||
|
/* Driver supports case when all or none instances support that HW feature. */
|
||||||
|
#if (UARTE_FOR_EACH_INSTANCE(INSTANCE_PROP, (+), (0), endtx_stoptx_supported)) == \
|
||||||
|
(UARTE_FOR_EACH_INSTANCE(INSTANCE_PRESENT, (+), (0), endtx_stoptx_supported))
|
||||||
|
#define UARTE_HAS_ENDTX_STOPTX_SHORT 1
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* RX timeout is divided into time slabs, this define tells how many divisions
|
* RX timeout is divided into time slabs, this define tells how many divisions
|
||||||
* should be made. More divisions - higher timeout accuracy and processor usage.
|
* should be made. More divisions - higher timeout accuracy and processor usage.
|
||||||
|
|
@ -269,7 +282,8 @@ static void uarte_nrfx_isr_int(const void *arg)
|
||||||
/* If interrupt driven and asynchronous APIs are disabled then UART
|
/* If interrupt driven and asynchronous APIs are disabled then UART
|
||||||
* interrupt is still called to stop TX. Unless it is done using PPI.
|
* interrupt is still called to stop TX. Unless it is done using PPI.
|
||||||
*/
|
*/
|
||||||
if (nrf_uarte_int_enable_check(uarte, NRF_UARTE_INT_ENDTX_MASK) &&
|
if (!IS_ENABLED(UARTE_HAS_ENDTX_STOPTX_SHORT) &&
|
||||||
|
nrf_uarte_int_enable_check(uarte, NRF_UARTE_INT_ENDTX_MASK) &&
|
||||||
nrf_uarte_event_check(uarte, NRF_UARTE_EVENT_ENDTX)) {
|
nrf_uarte_event_check(uarte, NRF_UARTE_EVENT_ENDTX)) {
|
||||||
endtx_isr(dev);
|
endtx_isr(dev);
|
||||||
}
|
}
|
||||||
|
|
@ -455,7 +469,8 @@ static bool is_tx_ready(const struct device *dev)
|
||||||
{
|
{
|
||||||
const struct uarte_nrfx_config *config = dev->config;
|
const struct uarte_nrfx_config *config = dev->config;
|
||||||
NRF_UARTE_Type *uarte = get_uarte_instance(dev);
|
NRF_UARTE_Type *uarte = get_uarte_instance(dev);
|
||||||
bool ppi_endtx = config->flags & UARTE_CFG_FLAG_PPI_ENDTX;
|
bool ppi_endtx = config->flags & UARTE_CFG_FLAG_PPI_ENDTX ||
|
||||||
|
IS_ENABLED(UARTE_HAS_ENDTX_STOPTX_SHORT);
|
||||||
|
|
||||||
return nrf_uarte_event_check(uarte, NRF_UARTE_EVENT_TXSTOPPED) ||
|
return nrf_uarte_event_check(uarte, NRF_UARTE_EVENT_TXSTOPPED) ||
|
||||||
(!ppi_endtx ?
|
(!ppi_endtx ?
|
||||||
|
|
@ -1450,14 +1465,14 @@ static void uarte_nrfx_isr_async(const void *arg)
|
||||||
rxto_isr(dev);
|
rxto_isr(dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nrf_uarte_event_check(uarte, NRF_UARTE_EVENT_ENDTX)
|
if (!IS_ENABLED(UARTE_HAS_ENDTX_STOPTX_SHORT) &&
|
||||||
&& nrf_uarte_int_enable_check(uarte, NRF_UARTE_INT_ENDTX_MASK)) {
|
(nrf_uarte_event_check(uarte, NRF_UARTE_EVENT_ENDTX) &&
|
||||||
|
nrf_uarte_int_enable_check(uarte, NRF_UARTE_INT_ENDTX_MASK))) {
|
||||||
endtx_isr(dev);
|
endtx_isr(dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nrf_uarte_event_check(uarte, NRF_UARTE_EVENT_TXSTOPPED)
|
if (nrf_uarte_event_check(uarte, NRF_UARTE_EVENT_TXSTOPPED) &&
|
||||||
&& nrf_uarte_int_enable_check(uarte,
|
nrf_uarte_int_enable_check(uarte, NRF_UARTE_INT_TXSTOPPED_MASK)) {
|
||||||
NRF_UARTE_INT_TXSTOPPED_MASK)) {
|
|
||||||
txstopped_isr(dev);
|
txstopped_isr(dev);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1739,6 +1754,7 @@ static const struct uart_driver_api uart_nrfx_uarte_driver_api = {
|
||||||
#endif /* UARTE_INTERRUPT_DRIVEN */
|
#endif /* UARTE_INTERRUPT_DRIVEN */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#ifdef UARTE_ENHANCED_POLL_OUT
|
||||||
static int endtx_stoptx_ppi_init(NRF_UARTE_Type *uarte,
|
static int endtx_stoptx_ppi_init(NRF_UARTE_Type *uarte,
|
||||||
struct uarte_nrfx_data *data)
|
struct uarte_nrfx_data *data)
|
||||||
{
|
{
|
||||||
|
|
@ -1757,6 +1773,7 @@ static int endtx_stoptx_ppi_init(NRF_UARTE_Type *uarte,
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
#endif /* UARTE_ENHANCED_POLL_OUT */
|
||||||
|
|
||||||
static int uarte_instance_init(const struct device *dev,
|
static int uarte_instance_init(const struct device *dev,
|
||||||
uint8_t interrupts_active)
|
uint8_t interrupts_active)
|
||||||
|
|
@ -1790,14 +1807,16 @@ static int uarte_instance_init(const struct device *dev,
|
||||||
nrf_uarte_configure(uarte, &cfg->hw_config);
|
nrf_uarte_configure(uarte, &cfg->hw_config);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (IS_ENABLED(UARTE_ENHANCED_POLL_OUT) &&
|
#ifdef UARTE_HAS_ENDTX_STOPTX_SHORT
|
||||||
cfg->flags & UARTE_CFG_FLAG_PPI_ENDTX) {
|
nrf_uarte_shorts_enable(uarte, NRF_UARTE_SHORT_ENDTX_STOPTX);
|
||||||
|
#elif defined(UARTE_ENHANCED_POLL_OUT)
|
||||||
|
if (cfg->flags & UARTE_CFG_FLAG_PPI_ENDTX) {
|
||||||
err = endtx_stoptx_ppi_init(uarte, data);
|
err = endtx_stoptx_ppi_init(uarte, data);
|
||||||
if (err < 0) {
|
if (err < 0) {
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef UARTE_ANY_ASYNC
|
#ifdef UARTE_ANY_ASYNC
|
||||||
if (data->async) {
|
if (data->async) {
|
||||||
|
|
@ -1819,7 +1838,7 @@ static int uarte_instance_init(const struct device *dev,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(cfg->flags & UARTE_CFG_FLAG_PPI_ENDTX)) {
|
if (!IS_ENABLED(UARTE_HAS_ENDTX_STOPTX_SHORT) && !(cfg->flags & UARTE_CFG_FLAG_PPI_ENDTX)) {
|
||||||
nrf_uarte_int_enable(uarte, NRF_UARTE_INT_ENDTX_MASK);
|
nrf_uarte_int_enable(uarte, NRF_UARTE_INT_ENDTX_MASK);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1850,7 +1869,8 @@ static int uarte_instance_init(const struct device *dev,
|
||||||
static void wait_for_tx_stopped(const struct device *dev)
|
static void wait_for_tx_stopped(const struct device *dev)
|
||||||
{
|
{
|
||||||
const struct uarte_nrfx_config *config = dev->config;
|
const struct uarte_nrfx_config *config = dev->config;
|
||||||
bool ppi_endtx = config->flags & UARTE_CFG_FLAG_PPI_ENDTX;
|
bool ppi_endtx = (config->flags & UARTE_CFG_FLAG_PPI_ENDTX) ||
|
||||||
|
IS_ENABLED(UARTE_HAS_ENDTX_STOPTX_SHORT);
|
||||||
NRF_UARTE_Type *uarte = get_uarte_instance(dev);
|
NRF_UARTE_Type *uarte = get_uarte_instance(dev);
|
||||||
bool res;
|
bool res;
|
||||||
|
|
||||||
|
|
@ -1982,10 +2002,6 @@ static int uarte_nrfx_pm_action(const struct device *dev,
|
||||||
}
|
}
|
||||||
#endif /* CONFIG_PM_DEVICE */
|
#endif /* CONFIG_PM_DEVICE */
|
||||||
|
|
||||||
#define UARTE(idx) DT_NODELABEL(uart##idx)
|
|
||||||
#define UARTE_HAS_PROP(idx, prop) DT_NODE_HAS_PROP(UARTE(idx), prop)
|
|
||||||
#define UARTE_PROP(idx, prop) DT_PROP(UARTE(idx), prop)
|
|
||||||
|
|
||||||
#define UARTE_IRQ_CONFIGURE(idx, isr_handler) \
|
#define UARTE_IRQ_CONFIGURE(idx, isr_handler) \
|
||||||
do { \
|
do { \
|
||||||
IRQ_CONNECT(DT_IRQN(UARTE(idx)), DT_IRQ(UARTE(idx), priority), \
|
IRQ_CONNECT(DT_IRQN(UARTE(idx)), DT_IRQ(UARTE(idx), priority), \
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue