hci_lpuart with async uart api

What should I change to run the hci_lpuart sample with UART asynchronous API instead of the using the interrupt driven one? I have already changed the source file on the sample to use the ones in hci_uart_async sample. And have set CONFIG_NRF_SW_LPUART_INT_DRIVEN=n. However, the sample I'm running on the host is not triggering the bt_ready callback. Am I missing something?

nrf9160dk_nrf5240.conf:

# Override prj.conf defaults

CONFIG_GPIO=y
CONFIG_MAIN_STACK_SIZE=1024
CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=512
CONFIG_BT_MAX_CONN=16
CONFIG_BT_TINYCRYPT_ECC=n
CONFIG_BT_CTLR_DTM_HCI=y
# CONFIG_BT_CTLR_ASSERT_HANDLER=y

CONFIG_UART_1_ASYNC=y
CONFIG_UART_1_INTERRUPT_DRIVEN=n
CONFIG_UART_1_NRF_HW_ASYNC=y
CONFIG_UART_1_NRF_HW_ASYNC_TIMER=2
CONFIG_NRF_SW_LPUART=y
CONFIG_NRF_SW_LPUART_INT_DRIVEN=n

CMakeLists.txt:

cmake_minimum_required(VERSION 3.20.0)

add_compile_options(-Wall -Werror -Wno-unused-parameter)

find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
project(app LANGUAGES C)

target_sources(app PRIVATE ${ZEPHYR_BASE}/samples/bluetooth/hci_uart_async/src/hci_uart_async.c)
target_sources(app PRIVATE ${ZEPHYR_BASE}/samples/bluetooth/hci_uart_async/src/main.c)

  • Hi, 

    I see you've tagged the question with 'nRF9160,' so I assume you are pairing the controller with a 9160 host. I'm unsure if there is much benefit to using the Async API when the HCI host driver is using the interrupt API anyway. Either way, I can try to reproduce this problem with the 9160 DK next week.

    Best regards,

    Vidar

  • Hi Vidar,

    Yes, you're right. Sorry for not being more explicit about that.

    One question: shouldn't the use of async API decrease our power consumption (vs active interruption)?

    More details:

    Using gdb was able to see that it stops on bt_hci_transport_setup() because at uart_fifo_read(), I'm guessing something is setting CONFIG_UART_INTERRUPT_DRIVEN on. Even tough I added

    CONFIG_NRF_SW_LPUART=y
    CONFIG_NRF_SW_LPUART_INT_DRIVEN=n
    
    CONFIG_UART_2_ASYNC=y
    CONFIG_UART_2_INTERRUPT_DRIVEN=n
    CONFIG_UART_2_NRF_HW_ASYNC=y
    CONFIG_UART_2_NRF_HW_ASYNC_TIMER=2

    to the sample overlay running on the host.

    EDIT: I guess it comes from the fact that single peripheral definitions are Nordic specific Kconfigs, and uart_fifo_read does not recognize that and assumes we are using the interrupt driven driver.

  • The HCI host driver uses the interrupt-driven API and does not support the async API. Both the async and interrupt-driven APIs use DMA and are interrupt-driven, but the async API allows you to work with larger receive buffers, thus reducing the number of interrupts during reception.

    I don't think the additional CPU overhead from using the interrupt-driven API will have a noticeable effect on the current consumption, but the async API may allow you to send more data faster to the controller.

    The important thing for reducing current consumption is to ensure that the UARTE peripheral is disabled during idle periods. The LP UART driver does this regardless of the API used. 

    https://docs.nordicsemi.com/bundle/ncs-2.6.1/page/zephyr/hardware/peripherals/uart.html 

  • Thank you for the clarification. I think I was a little bit mislead about the existence of a hci_uart_async sample. Maybe it's meant to be used with other host devices than ones running zephyr.

Related