This is an automated email from the ASF dual-hosted git repository.
wes3 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/mynewt-core.git
The following commit(s) were added to refs/heads/master by this push:
new 494da43 DA1469x UART rx pullup (#2035)
494da43 is described below
commit 494da43ae4919c4606538f69677302a43b54bba3
Author: wes3 <[email protected]>
AuthorDate: Fri Oct 11 09:24:04 2019 -0700
DA1469x UART rx pullup (#2035)
hw/mcu/dialog: Enabling internal pullup on UART rx pin
This commit allows the enabling of an internal pullup on the
UART rx pin. The reason behind this change is that the UART
LCR register cannot be written if the RX line is low as the
UART will be considered busy. If there is no external pullup
on the line, this could cause the initialization to fail.
The current code uses a fixed loop counter to timeout the
polling of the busy state as using a timer is a bit
heavyweight. A future change could be to either make
this configurable and/or read the clock speed to determine
a suitable loop counter.
---
hw/mcu/dialog/da1469x/include/mcu/da1469x_hal.h | 1 +
hw/mcu/dialog/da1469x/src/da1469x_periph.c | 3 ++
hw/mcu/dialog/da1469x/src/hal_uart.c | 48 +++++++++++++++++++++++++
hw/mcu/dialog/da1469x/syscfg.yml | 9 +++++
4 files changed, 61 insertions(+)
diff --git a/hw/mcu/dialog/da1469x/include/mcu/da1469x_hal.h
b/hw/mcu/dialog/da1469x/include/mcu/da1469x_hal.h
index 9c99f8e..b8e2ea6 100755
--- a/hw/mcu/dialog/da1469x/include/mcu/da1469x_hal.h
+++ b/hw/mcu/dialog/da1469x/include/mcu/da1469x_hal.h
@@ -54,6 +54,7 @@ struct da1469x_uart_cfg {
int8_t pin_rx;
int8_t pin_rts;
int8_t pin_cts;
+ uint8_t rx_pullup;
};
struct da1469x_hal_i2c_cfg {
diff --git a/hw/mcu/dialog/da1469x/src/da1469x_periph.c
b/hw/mcu/dialog/da1469x/src/da1469x_periph.c
index 6860670..7685322 100644
--- a/hw/mcu/dialog/da1469x/src/da1469x_periph.c
+++ b/hw/mcu/dialog/da1469x/src/da1469x_periph.c
@@ -86,6 +86,7 @@ static const struct da1469x_uart_cfg os_bsp_uart0_cfg = {
.pin_rx = MYNEWT_VAL(UART_0_PIN_RX),
.pin_rts = -1,
.pin_cts = -1,
+ .rx_pullup = MYNEWT_VAL(UART_0_RX_ENABLE_PULLUP)
};
#endif
#if MYNEWT_VAL(UART_1)
@@ -95,6 +96,7 @@ static const struct da1469x_uart_cfg os_bsp_uart1_cfg = {
.pin_rx = MYNEWT_VAL(UART_1_PIN_RX),
.pin_rts = MYNEWT_VAL(UART_1_PIN_RTS),
.pin_cts = MYNEWT_VAL(UART_1_PIN_CTS),
+ .rx_pullup = MYNEWT_VAL(UART_1_RX_ENABLE_PULLUP)
};
#endif
#if MYNEWT_VAL(UART_2)
@@ -104,6 +106,7 @@ static const struct da1469x_uart_cfg os_bsp_uart2_cfg = {
.pin_rx = MYNEWT_VAL(UART_2_PIN_RX),
.pin_rts = MYNEWT_VAL(UART_2_PIN_RTS),
.pin_cts = MYNEWT_VAL(UART_2_PIN_CTS),
+ .rx_pullup = MYNEWT_VAL(UART_2_RX_ENABLE_PULLUP)
};
#endif
diff --git a/hw/mcu/dialog/da1469x/src/hal_uart.c
b/hw/mcu/dialog/da1469x/src/hal_uart.c
index c0cad6b..a89595a 100644
--- a/hw/mcu/dialog/da1469x/src/hal_uart.c
+++ b/hw/mcu/dialog/da1469x/src/hal_uart.c
@@ -40,6 +40,13 @@ struct da1469x_uart {
volatile uint8_t tx_started : 1;
volatile uint8_t rx_data;
+ /*
+ * Stores rx pin func and pointer to cfg. Needed to enable/disable pullup
+ * when the uart is opened/closed
+ */
+ mcu_gpio_func rx_pin_func;
+ struct da1469x_uart_cfg *cfg;
+
hal_uart_rx_char rx_func;
hal_uart_tx_char tx_func;
hal_uart_tx_done tx_done;
@@ -214,6 +221,8 @@ da1469x_uart_common_isr(struct da1469x_uart *uart)
case 0x06: /* receiver line status */
break;
case 0x07: /* busy detect */
+ /* Clear the flag so if assert not defined no infinite loop here */
+ (void)regs->UART2_USR_REG;
assert(0);
break;
case 0x0c: /* character timeout */
@@ -403,6 +412,10 @@ hal_uart_init(int port, void *arg)
uart->regs = regs;
uart->irqn = irqn;
+ /* These are for uart open/close to enable a pullup on the rx line */
+ uart->rx_pin_func = gpiofunc[1];
+ uart->cfg = cfg;
+
mcu_gpio_set_pin_function(cfg->pin_tx, MCU_GPIO_MODE_OUTPUT, gpiofunc[0]);
mcu_gpio_set_pin_function(cfg->pin_rx, MCU_GPIO_MODE_INPUT, gpiofunc[1]);
if (cfg->pin_rts >= 0) {
@@ -429,6 +442,7 @@ hal_uart_config(int port, int32_t baudrate, uint8_t
databits, uint8_t stopbits,
UART2_Type *regs;
uint32_t reg;
uint32_t baudrate_cfg;
+ uint32_t loop_count;
uart = da1469x_uart_resolve(port);
if (!uart) {
@@ -463,6 +477,34 @@ hal_uart_config(int port, int32_t baudrate, uint8_t
databits, uint8_t stopbits,
if (!baudrate_cfg) {
return SYS_ENOTSUP;
}
+
+ /* Enable pullup if configured */
+ if (uart->cfg->rx_pullup) {
+ mcu_gpio_set_pin_function(uart->cfg->pin_rx,
MCU_GPIO_MODE_INPUT_PULLUP,
+ uart->rx_pin_func);
+ }
+
+ /*
+ * If the UART is busy we are not allowed to write to the LCR register.
+ * Doing so results in the "busy detect" error. Only reason UART should
+ * be busy here is if something is driving RX low.
+ *
+ * XXX: the loop counter here is ugly for sure. Did not want to assume
+ * an OS for the hal and instantiating a timer for this seemed pretty
+ * heavyweight. There are 4 instructions and I realize this time will be
+ * quite variable based on CPU clock and cache, etc.
+ *
+ * Did not want to simply poll and not break out as holding RX low would
+ * cause an infinite loop here.
+ */
+ loop_count = 0;
+ while (regs->UART2_USR_REG & UART2_UART2_USR_REG_UART_BUSY_Msk) {
+ ++loop_count;
+ if (loop_count > 10000) {
+ return SYS_EBUSY;
+ }
+ }
+
regs->UART2_LCR_REG |= UART2_UART2_LCR_REG_UART_DLAB_Msk;
regs->UART2_IER_DLH_REG = (baudrate_cfg >> 16) & 0xff;
regs->UART2_RBR_THR_DLL_REG = (baudrate_cfg >> 8) & 0xff;
@@ -545,5 +587,11 @@ hal_uart_close(int port)
break;
}
+ /* Set back to input with no pullup if pullup enabled */
+ if (uart->cfg->rx_pullup) {
+ mcu_gpio_set_pin_function(uart->cfg->pin_rx, MCU_GPIO_MODE_INPUT,
+ uart->rx_pin_func);
+ }
+
return 0;
}
diff --git a/hw/mcu/dialog/da1469x/syscfg.yml b/hw/mcu/dialog/da1469x/syscfg.yml
index d9fed26..c1c71f1 100644
--- a/hw/mcu/dialog/da1469x/syscfg.yml
+++ b/hw/mcu/dialog/da1469x/syscfg.yml
@@ -252,6 +252,9 @@ syscfg.defs:
UART_0_PIN_RX:
description: 'RX pin for UART0'
value: ''
+ UART_0_RX_ENABLE_PULLUP:
+ description: 'Enable internal pullup on RX pin. 0:none 1:enable pullup'
+ value: 0
UART_1:
description: Enable DA1469x UART 1 (UART2 peripheral)
@@ -268,6 +271,9 @@ syscfg.defs:
UART_1_PIN_CTS:
description: 'CTS pin for UART1'
value: -1
+ UART_1_RX_ENABLE_PULLUP:
+ description: 'Enable internal pullup on RX pin. 0:none 1:enable pullup'
+ value: 0
UART_2:
description: Enable DA1469x UART 2 (UART3 peripheral)
@@ -284,6 +290,9 @@ syscfg.defs:
UART_2_PIN_CTS:
description: 'CTS pin for UART2'
value: -1
+ UART_2_RX_ENABLE_PULLUP:
+ description: 'Enable internal pullup on RX pin. 0:none 1:enable pullup'
+ value: 0
TIMER_0:
description: Enable DA1469x timer 0 (Timer peripheral)