net: openthread: Init NCP after USB communication is established

The device has sent RESET_POWER_UP message before the communication
with the host hadn't been established. It could be observed with
pyspinel which displayed `Framing error`.

This commit fixes the bug by initializing NCP after the host stated
is ready to communicate.

This commit reverts initialization the USB stack into function
otPlatUartEnable to be consistent with others OpenThread platforms.
OpenThread co-processor samples are not affected by #27071 as they use
USB for SPINEL communication with host and not for UART console.

Note:
When co-processor communicates by USB CDC ACM and it is hard reset
(what is happening in current Zephyr OpenThread platform)
the connection needs to be properly handled by the host.

For posix platform used together with RCP it was implemented in:
https://github.com/openthread/openthread/pull/6454

and for NCP:
https://github.com/openthread/wpantund/pull/492 .

Signed-off-by: Lukasz Maciejonczyk <lukasz.maciejonczyk@nordicsemi.no>
This commit is contained in:
Lukasz Maciejonczyk 2021-04-23 11:20:55 +02:00 committed by Maureen Helm
commit 4500862af1
2 changed files with 33 additions and 33 deletions

View file

@ -9,42 +9,9 @@
#include <logging/log.h>
LOG_MODULE_REGISTER(ot_br, LOG_LEVEL_DBG);
#include <zephyr.h>
#include <usb/usb_device.h>
#include <drivers/uart.h>
#define APP_BANNER "***** OpenThread NCP on Zephyr %s *****"
void main(void)
{
#if defined(CONFIG_OPENTHREAD_COPROCESSOR_SPINEL_ON_UART_ACM)
const struct device *dev;
uint32_t baudrate = 0U;
int ret;
dev = device_get_binding(
CONFIG_OPENTHREAD_COPROCESSOR_SPINEL_ON_UART_DEV_NAME);
if (!dev) {
LOG_ERR("UART device not found");
return;
}
ret = usb_enable(NULL);
if (ret != 0) {
LOG_ERR("Failed to enable USB");
return;
}
LOG_INF("Wait for host to settle");
k_sleep(K_SECONDS(1));
ret = uart_line_ctrl_get(dev, UART_LINE_CTRL_BAUD_RATE, &baudrate);
if (ret) {
LOG_WRN("Failed to get baudrate, ret code %d", ret);
} else {
LOG_INF("Baudrate detected: %d", baudrate);
}
#endif /* CONFIG_OPENTHREAD_COPROCESSOR_SPINEL_ON_UART_ACM */
LOG_INF(APP_BANNER, CONFIG_NET_SAMPLE_APPLICATION_VERSION);
}

View file

@ -170,6 +170,39 @@ otError otPlatUartEnable(void)
uart_irq_callback_user_data_set(ot_uart.dev,
uart_callback,
(void *)&ot_uart);
#ifdef CONFIG_OPENTHREAD_COPROCESSOR_SPINEL_ON_UART_ACM
{
int ret;
uint32_t dtr = 0U;
ret = usb_enable(NULL);
if (ret != 0) {
LOG_ERR("Failed to enable USB");
return OT_ERROR_FAILED;
}
LOG_INF("Waiting for host to be ready to communicate");
/* Data Terminal Ready - check if host is ready to communicate */
while (!dtr) {
ret = uart_line_ctrl_get(ot_uart.dev,
UART_LINE_CTRL_DTR, &dtr);
if (ret) {
LOG_ERR("Failed to get Data Terminal Ready line state: %d",
ret);
continue;
}
k_msleep(100);
}
/* Data Carrier Detect Modem - mark connection as established */
(void)uart_line_ctrl_set(ot_uart.dev, UART_LINE_CTRL_DCD, 1);
/* Data Set Ready - the NCP SoC is ready to communicate */
(void)uart_line_ctrl_set(ot_uart.dev, UART_LINE_CTRL_DSR, 1);
}
#endif /* CONFIG_OPENTHREAD_COPROCESSOR_SPINEL_ON_UART_ACM */
uart_irq_rx_enable(ot_uart.dev);
return OT_ERROR_NONE;