drivers: serial: nrf: Make pull-ups on UART pins configurable
This is a follow-up to commit 3656ba5ae9
.
Do not enforce pull-up resistors to be enabled on RXD and CTS pins
in nRF UART drivers, as in certain hardware designs this may be
undesirable or may even make certain hardware not working.
Instead, provide devicetree properties that allow enabling of those
resistors when it is actually needed.
Signed-off-by: Andrzej Głąbek <andrzej.glabek@nordicsemi.no>
This commit is contained in:
parent
fd73eb8b60
commit
3842babc79
3 changed files with 83 additions and 72 deletions
|
@ -996,7 +996,9 @@ static int uart_nrfx_init(const struct device *dev)
|
|||
nrf_gpio_cfg_output(TX_PIN);
|
||||
|
||||
if (RX_PIN_USED) {
|
||||
nrf_gpio_cfg_input(RX_PIN, NRF_GPIO_PIN_PULLUP);
|
||||
nrf_gpio_cfg_input(RX_PIN,
|
||||
PROP(rx_pull_up) ? NRF_GPIO_PIN_PULLUP
|
||||
: NRF_GPIO_PIN_NOPULL);
|
||||
}
|
||||
|
||||
nrf_uart_txrx_pins_set(uart0_addr, TX_PIN, RX_PIN);
|
||||
|
@ -1010,7 +1012,9 @@ static int uart_nrfx_init(const struct device *dev)
|
|||
}
|
||||
|
||||
if (HAS_PROP(cts_pin)) {
|
||||
nrf_gpio_cfg_input(CTS_PIN, NRF_GPIO_PIN_PULLUP);
|
||||
nrf_gpio_cfg_input(CTS_PIN,
|
||||
PROP(cts_pull_up) ? NRF_GPIO_PIN_PULLUP
|
||||
: NRF_GPIO_PIN_NOPULL);
|
||||
}
|
||||
|
||||
nrf_uart_hwfc_pins_set(uart0_addr, RTS_PIN, CTS_PIN);
|
||||
|
@ -1104,37 +1108,36 @@ static void uart_nrfx_pins_enable(const struct device *dev, bool enable)
|
|||
return;
|
||||
}
|
||||
|
||||
uint32_t tx_pin = nrf_uart_tx_pin_get(uart0_addr);
|
||||
uint32_t rx_pin = nrf_uart_rx_pin_get(uart0_addr);
|
||||
uint32_t cts_pin = nrf_uart_cts_pin_get(uart0_addr);
|
||||
uint32_t rts_pin = nrf_uart_rts_pin_get(uart0_addr);
|
||||
|
||||
if (enable) {
|
||||
nrf_gpio_pin_write(tx_pin, 1);
|
||||
nrf_gpio_cfg_output(tx_pin);
|
||||
nrf_gpio_pin_write(TX_PIN, 1);
|
||||
nrf_gpio_cfg_output(TX_PIN);
|
||||
if (RX_PIN_USED) {
|
||||
nrf_gpio_cfg_input(rx_pin, NRF_GPIO_PIN_PULLUP);
|
||||
nrf_gpio_cfg_input(RX_PIN,
|
||||
PROP(rx_pull_up) ? NRF_GPIO_PIN_PULLUP
|
||||
: NRF_GPIO_PIN_NOPULL);
|
||||
}
|
||||
|
||||
if (HAS_PROP(rts_pin)) {
|
||||
nrf_gpio_pin_write(rts_pin, 1);
|
||||
nrf_gpio_cfg_output(rts_pin);
|
||||
nrf_gpio_pin_write(RTS_PIN, 1);
|
||||
nrf_gpio_cfg_output(RTS_PIN);
|
||||
}
|
||||
if (HAS_PROP(cts_pin)) {
|
||||
nrf_gpio_cfg_input(cts_pin, NRF_GPIO_PIN_PULLUP);
|
||||
nrf_gpio_cfg_input(CTS_PIN,
|
||||
PROP(cts_pull_up) ? NRF_GPIO_PIN_PULLUP
|
||||
: NRF_GPIO_PIN_NOPULL);
|
||||
}
|
||||
} else {
|
||||
nrf_gpio_cfg_default(tx_pin);
|
||||
nrf_gpio_cfg_default(TX_PIN);
|
||||
if (RX_PIN_USED) {
|
||||
nrf_gpio_cfg_default(rx_pin);
|
||||
nrf_gpio_cfg_default(RX_PIN);
|
||||
}
|
||||
|
||||
if (HAS_PROP(rts_pin)) {
|
||||
nrf_gpio_cfg_default(rts_pin);
|
||||
nrf_gpio_cfg_default(RTS_PIN);
|
||||
}
|
||||
|
||||
if (HAS_PROP(cts_pin)) {
|
||||
nrf_gpio_cfg_default(cts_pin);
|
||||
nrf_gpio_cfg_default(CTS_PIN);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -161,18 +161,17 @@ struct uarte_nrfx_data {
|
|||
struct uarte_nrfx_config {
|
||||
NRF_UARTE_Type *uarte_regs; /* Instance address */
|
||||
uint32_t flags;
|
||||
uint32_t pseltxd; /* PSEL.TXD register value */
|
||||
uint32_t pselrxd; /* PSEL.RXD register value */
|
||||
uint32_t pselcts; /* PSEL.CTS register value */
|
||||
uint32_t pselrts; /* PSEL.RTS register value */
|
||||
nrf_gpio_pin_pull_t rxd_pull; /* RXD pin pull configuration */
|
||||
nrf_gpio_pin_pull_t cts_pull; /* CTS pin pull configuration */
|
||||
#ifdef CONFIG_UART_ASYNC_API
|
||||
nrfx_timer_t timer;
|
||||
#endif
|
||||
};
|
||||
|
||||
struct uarte_init_config {
|
||||
uint32_t pseltxd; /* PSEL.TXD register value */
|
||||
uint32_t pselrxd; /* PSEL.RXD register value */
|
||||
uint32_t pselcts; /* PSEL.CTS register value */
|
||||
uint32_t pselrts; /* PSEL.RTS register value */
|
||||
};
|
||||
|
||||
static inline struct uarte_nrfx_data *get_dev_data(const struct device *dev)
|
||||
{
|
||||
return dev->data;
|
||||
|
@ -1664,36 +1663,36 @@ static int endtx_stoptx_ppi_init(NRF_UARTE_Type *uarte,
|
|||
}
|
||||
|
||||
static int uarte_instance_init(const struct device *dev,
|
||||
const struct uarte_init_config *config,
|
||||
uint8_t interrupts_active)
|
||||
{
|
||||
int err;
|
||||
NRF_UARTE_Type *uarte = get_uarte_instance(dev);
|
||||
struct uarte_nrfx_data *data = get_dev_data(dev);
|
||||
const struct uarte_nrfx_config *cfg = get_dev_config(dev);
|
||||
|
||||
nrf_uarte_disable(uarte);
|
||||
|
||||
data->dev = dev;
|
||||
|
||||
nrf_gpio_pin_write(config->pseltxd, 1);
|
||||
nrf_gpio_cfg_output(config->pseltxd);
|
||||
nrf_gpio_pin_write(cfg->pseltxd, 1);
|
||||
nrf_gpio_cfg_output(cfg->pseltxd);
|
||||
|
||||
if (config->pselrxd != NRF_UARTE_PSEL_DISCONNECTED) {
|
||||
nrf_gpio_cfg_input(config->pselrxd, NRF_GPIO_PIN_PULLUP);
|
||||
if (cfg->pselrxd != NRF_UARTE_PSEL_DISCONNECTED) {
|
||||
nrf_gpio_cfg_input(cfg->pselrxd, cfg->rxd_pull);
|
||||
}
|
||||
|
||||
nrf_uarte_txrx_pins_set(uarte, config->pseltxd, config->pselrxd);
|
||||
nrf_uarte_txrx_pins_set(uarte, cfg->pseltxd, cfg->pselrxd);
|
||||
|
||||
if (config->pselcts != NRF_UARTE_PSEL_DISCONNECTED) {
|
||||
nrf_gpio_cfg_input(config->pselcts, NRF_GPIO_PIN_PULLUP);
|
||||
if (cfg->pselcts != NRF_UARTE_PSEL_DISCONNECTED) {
|
||||
nrf_gpio_cfg_input(cfg->pselcts, cfg->cts_pull);
|
||||
}
|
||||
|
||||
if (config->pselrts != NRF_UARTE_PSEL_DISCONNECTED) {
|
||||
nrf_gpio_pin_write(config->pselrts, 1);
|
||||
nrf_gpio_cfg_output(config->pselrts);
|
||||
if (cfg->pselrts != NRF_UARTE_PSEL_DISCONNECTED) {
|
||||
nrf_gpio_pin_write(cfg->pselrts, 1);
|
||||
nrf_gpio_cfg_output(cfg->pselrts);
|
||||
}
|
||||
|
||||
nrf_uarte_hwfc_pins_set(uarte, config->pselrts, config->pselcts);
|
||||
nrf_uarte_hwfc_pins_set(uarte, cfg->pselrts, cfg->pselcts);
|
||||
|
||||
err = uarte_nrfx_configure(dev, &get_dev_data(dev)->uart_config);
|
||||
if (err) {
|
||||
|
@ -1701,7 +1700,7 @@ static int uarte_instance_init(const struct device *dev,
|
|||
}
|
||||
|
||||
if (IS_ENABLED(CONFIG_UART_ENHANCED_POLL_OUT) &&
|
||||
get_dev_config(dev)->flags & UARTE_CFG_FLAG_PPI_ENDTX) {
|
||||
cfg->flags & UARTE_CFG_FLAG_PPI_ENDTX) {
|
||||
err = endtx_stoptx_ppi_init(uarte, data);
|
||||
if (err < 0) {
|
||||
return err;
|
||||
|
@ -1721,7 +1720,7 @@ static int uarte_instance_init(const struct device *dev,
|
|||
/* Enable receiver and transmitter */
|
||||
nrf_uarte_enable(uarte);
|
||||
|
||||
if (config->pselrxd != NRF_UARTE_PSEL_DISCONNECTED) {
|
||||
if (cfg->pselrxd != NRF_UARTE_PSEL_DISCONNECTED) {
|
||||
nrf_uarte_event_clear(uarte, NRF_UARTE_EVENT_ENDRX);
|
||||
|
||||
nrf_uarte_rx_buffer_set(uarte, &data->rx_data, 1);
|
||||
|
@ -1729,11 +1728,11 @@ static int uarte_instance_init(const struct device *dev,
|
|||
}
|
||||
}
|
||||
|
||||
if (!(get_dev_config(dev)->flags & UARTE_CFG_FLAG_PPI_ENDTX)) {
|
||||
if (!(cfg->flags & UARTE_CFG_FLAG_PPI_ENDTX)) {
|
||||
nrf_uarte_int_enable(uarte, NRF_UARTE_INT_ENDTX_MASK);
|
||||
}
|
||||
|
||||
if (get_dev_config(dev)->flags & UARTE_CFG_FLAG_LOW_POWER) {
|
||||
if (cfg->flags & UARTE_CFG_FLAG_LOW_POWER) {
|
||||
nrf_uarte_int_enable(uarte, NRF_UARTE_INT_TXSTOPPED_MASK);
|
||||
}
|
||||
|
||||
|
@ -1754,44 +1753,39 @@ static int uarte_instance_init(const struct device *dev,
|
|||
|
||||
static void uarte_nrfx_pins_enable(const struct device *dev, bool enable)
|
||||
{
|
||||
if (!(get_dev_config(dev)->flags & UARTE_CFG_FLAG_GPIO_MGMT)) {
|
||||
const struct uarte_nrfx_config *cfg = get_dev_config(dev);
|
||||
|
||||
if (!(cfg->flags & UARTE_CFG_FLAG_GPIO_MGMT)) {
|
||||
return;
|
||||
}
|
||||
|
||||
NRF_UARTE_Type *uarte = get_uarte_instance(dev);
|
||||
uint32_t tx_pin = nrf_uarte_tx_pin_get(uarte);
|
||||
uint32_t rx_pin = nrf_uarte_rx_pin_get(uarte);
|
||||
uint32_t cts_pin = nrf_uarte_cts_pin_get(uarte);
|
||||
uint32_t rts_pin = nrf_uarte_rts_pin_get(uarte);
|
||||
|
||||
if (enable) {
|
||||
nrf_gpio_pin_write(tx_pin, 1);
|
||||
nrf_gpio_cfg_output(tx_pin);
|
||||
if (rx_pin != NRF_UARTE_PSEL_DISCONNECTED) {
|
||||
nrf_gpio_cfg_input(rx_pin, NRF_GPIO_PIN_PULLUP);
|
||||
nrf_gpio_pin_write(cfg->pseltxd, 1);
|
||||
nrf_gpio_cfg_output(cfg->pseltxd);
|
||||
if (cfg->pselrxd != NRF_UARTE_PSEL_DISCONNECTED) {
|
||||
nrf_gpio_cfg_input(cfg->pselrxd, cfg->rxd_pull);
|
||||
}
|
||||
|
||||
if (IS_RTS_PIN_SET(get_dev_config(dev)->flags)) {
|
||||
nrf_gpio_pin_write(rts_pin, 1);
|
||||
nrf_gpio_cfg_output(rts_pin);
|
||||
if (IS_RTS_PIN_SET(cfg->flags)) {
|
||||
nrf_gpio_pin_write(cfg->pselrts, 1);
|
||||
nrf_gpio_cfg_output(cfg->pselrts);
|
||||
}
|
||||
|
||||
if (IS_CTS_PIN_SET(get_dev_config(dev)->flags)) {
|
||||
nrf_gpio_cfg_input(cts_pin,
|
||||
NRF_GPIO_PIN_PULLUP);
|
||||
if (IS_CTS_PIN_SET(cfg->flags)) {
|
||||
nrf_gpio_cfg_input(cfg->pselcts, cfg->cts_pull);
|
||||
}
|
||||
} else {
|
||||
nrf_gpio_cfg_default(tx_pin);
|
||||
if (rx_pin != NRF_UARTE_PSEL_DISCONNECTED) {
|
||||
nrf_gpio_cfg_default(rx_pin);
|
||||
nrf_gpio_cfg_default(cfg->pseltxd);
|
||||
if (cfg->pselrxd != NRF_UARTE_PSEL_DISCONNECTED) {
|
||||
nrf_gpio_cfg_default(cfg->pselrxd);
|
||||
}
|
||||
|
||||
if (IS_RTS_PIN_SET(get_dev_config(dev)->flags)) {
|
||||
nrf_gpio_cfg_default(rts_pin);
|
||||
if (IS_RTS_PIN_SET(cfg->flags)) {
|
||||
nrf_gpio_cfg_default(cfg->pselrts);
|
||||
}
|
||||
|
||||
if (IS_CTS_PIN_SET(get_dev_config(dev)->flags)) {
|
||||
nrf_gpio_cfg_default(cts_pin);
|
||||
if (IS_CTS_PIN_SET(cfg->flags)) {
|
||||
nrf_gpio_cfg_default(cfg->pselcts);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1924,6 +1918,11 @@ static int uarte_nrfx_pm_control(const struct device *dev,
|
|||
(UARTE_PROP(idx, pin_prop)), \
|
||||
(NRF_UARTE_PSEL_DISCONNECTED))
|
||||
|
||||
#define UARTE_PULL(idx, pull_up_prop) \
|
||||
COND_CODE_1(UARTE_PROP(idx, pull_up_prop), \
|
||||
(NRF_GPIO_PIN_PULLUP), \
|
||||
(NRF_GPIO_PIN_NOPULL))
|
||||
|
||||
#define HWFC_AVAILABLE(idx) \
|
||||
(UARTE_HAS_PROP(idx, rts_pin) || UARTE_HAS_PROP(idx, cts_pin))
|
||||
|
||||
|
@ -1972,25 +1971,24 @@ static int uarte_nrfx_pm_control(const struct device *dev,
|
|||
UARTE_CFG_FLAG_GPIO_MGMT : 0) | \
|
||||
(IS_ENABLED(CONFIG_UART_##idx##_ENHANCED_POLL_OUT) ? \
|
||||
UARTE_CFG_FLAG_PPI_ENDTX : 0) | \
|
||||
USE_LOW_POWER(idx), \
|
||||
USE_LOW_POWER(idx), \
|
||||
.pseltxd = UARTE_PROP(idx, tx_pin), /* must be set */ \
|
||||
.pselrxd = UARTE_PSEL(idx, rx_pin), /* optional */ \
|
||||
.pselcts = UARTE_PSEL(idx, cts_pin), /* optional */ \
|
||||
.pselrts = UARTE_PSEL(idx, rts_pin), /* optional */ \
|
||||
.rxd_pull = UARTE_PULL(idx, rx_pull_up), \
|
||||
.cts_pull = UARTE_PULL(idx, cts_pull_up), \
|
||||
IF_ENABLED(CONFIG_UART_##idx##_NRF_HW_ASYNC, \
|
||||
(.timer = NRFX_TIMER_INSTANCE( \
|
||||
CONFIG_UART_##idx##_NRF_HW_ASYNC_TIMER),)) \
|
||||
}; \
|
||||
static int uarte_##idx##_init(const struct device *dev) \
|
||||
{ \
|
||||
const struct uarte_init_config init_config = { \
|
||||
.pseltxd = UARTE_PROP(idx, tx_pin), /* must be set */ \
|
||||
.pselrxd = UARTE_PSEL(idx, rx_pin), /* optional */ \
|
||||
.pselcts = UARTE_PSEL(idx, cts_pin), /* optional */ \
|
||||
.pselrts = UARTE_PSEL(idx, rts_pin), /* optional */ \
|
||||
}; \
|
||||
COND_CODE_1(CONFIG_UART_##idx##_ASYNC, \
|
||||
(UARTE_IRQ_CONFIGURE(idx, uarte_nrfx_isr_async);), \
|
||||
(UARTE_IRQ_CONFIGURE(idx, uarte_nrfx_isr_int);)) \
|
||||
return uarte_instance_init( \
|
||||
dev, \
|
||||
&init_config, \
|
||||
IS_ENABLED(CONFIG_UART_##idx##_INTERRUPT_DRIVEN)); \
|
||||
} \
|
||||
DEVICE_DT_DEFINE(UARTE(idx), \
|
||||
|
|
|
@ -67,3 +67,13 @@ properties:
|
|||
- 460800
|
||||
- 921600
|
||||
- 1000000
|
||||
|
||||
rx-pull-up:
|
||||
type: boolean
|
||||
required: false
|
||||
description: Enable pull-up resistor on the RX pin.
|
||||
|
||||
cts-pull-up:
|
||||
type: boolean
|
||||
required: false
|
||||
description: Enable pull-up resistor on the CTS pin.
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue