Zephyr and NRFX USB support

Hello,

I'm using Zephyr 2.6.1 and nRF5340.

Tried to include in my project the NRFX driver for USB and I'm currently not able to find an enabling option for that.

In the prj.conf seems that is not recognized (available) any entry for that (i.e. following the naming rule CONFIG_NRFX_USBD and looking into Kconfig file in C:\ncs\v2.6.1\zephyr\modules\hal_nordic\nrfx), and obviously the code in the nrfx_usbd.c is not enabled causing errors:

How can I enable the nRFX driver?

Thank you

Parents
  • Hello,

    You mention that the nrfx_usbd.c is not enabled causing errors. Can you please specify what errors? Is it just the highlighting of the text that is off, or do you get any build errors?

    And are you trying to use one of the samples? Or did you write your own application? 

    And finally, are you intending to use the zephyr USB drivers, or nrfx drivers directly?

    Best regards,

    Edvin

Reply
  • Hello,

    You mention that the nrfx_usbd.c is not enabled causing errors. Can you please specify what errors? Is it just the highlighting of the text that is off, or do you get any build errors?

    And are you trying to use one of the samples? Or did you write your own application? 

    And finally, are you intending to use the zephyr USB drivers, or nrfx drivers directly?

    Best regards,

    Edvin

Children
  • Hello Edvin,

    I'm writing my own application using NRFX drivers directly.

    Anyway I tried the Zephyr USB implementation (included example) to exclude any other issue and I got VCOM working, but this is not my goal.

    The errors I get are from the linker:

    undefined reference to `nrfx_usbd_init'

    undefined reference to `nrfx_usbdr_enable'

    undefined reference to `nrfx_usbd_ep_transfer'

    ...

    and so on.

    To me, seems that the USB file from nrfx is not compiled at all; this is what I put in the prj.conf:

    CONFIG_USB_NRFX=y
    CONFIG_USB_DEVICE_STACK=y
    CONFIG_USB_CDC_ACM=y

    thank you

  • Hello,

    You need to pick one. So if you want to use the nrfx driver, remove "CONFIG_USB_DEVICE_STACK=y" and "CONFIG_USB_CDC_ACM=y".

    Can you please share the entire build log? And perhaps also the application that you are trying to build. Perhaps I can have a look at it.

    Best regards,

    Edvin

  • Hello,

    Can't upload a .zip file, so here are the instruction to setup your project in 1minute:

    1. Create anew application from sample

    2. this is the main.c content, replace the one created in the example

    /*
     * Copyright (c) 2020 Nordic Semiconductor ASA
     *
     * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
     */
    
    #include <zephyr/kernel.h>
    #include <zephyr/drivers/gpio.h>
    #include <zephyr/init.h>
    #include <nrf.h>
    #include <nrfx.h>
    
    
    /*START************************************************** */
    /******************************************************** */
    
    #include <stdint.h>
    #include <stddef.h>
    #include <nrfx_usbd.h>
    #include <zephyr/logging/log.h>
    LOG_MODULE_REGISTER(USB);
    
    
    
    typedef enum {
        USB_SUCCESS = 0,
        USB_ERROR_INIT_FAILED,
        USB_ERROR_WRITE_FAILED,
        USB_ERROR_READ_FAILED
    } USB_Error_t;
    
    typedef void (*usb_event_handler_t)(nrfx_usbd_evt_t const * p_event);
    
    void USB_Init(usb_event_handler_t event_handler);
    void USB_Transfer(uint8_t ep, const void *p_data, size_t size);
    
    
    #define USB_EP_IN   0x81  // Endpoint IN (da dispositivo a host)
    #define USB_EP_OUT  0x01  // Endpoint OUT (da host a dispositivo)
    #define DATA_SIZE   64    // Dimensione dei dati da trasferire
    
    static uint8_t tx_data[DATA_SIZE] = "Hello from nRF5340!";
    static uint8_t rx_data[DATA_SIZE];
    
    void usb_event_handler2(nrfx_usbd_evt_t const * p_event) {
    	if (p_event->type == NRFX_USBD_EVT_EPTRANSFER) {
    		LOG_INF("Data transfer on endpoint %d completed", p_event->data.eptransfer.ep);
    	}
    }
    
    
    
    
    int main(void)
    {
        LOG_INF("USB CDC example started");
    
        USB_Init(usb_event_handler2);
    
        USB_Transfer(USB_EP_IN, tx_data, sizeof(tx_data));
    }
    
    
    
    void USB_Init(usb_event_handler_t event_handler) {
        nrfx_err_t res = nrfx_usbd_init(event_handler);
        if (res != NRFX_SUCCESS) {
            LOG_ERR("Failed to initialize USB: %d", res);
        }
    
        nrfx_usbd_enable();
        nrfx_usbd_start(1);
    }
    
    void USB_Transfer(uint8_t ep, const void *p_data, size_t size) {
        nrfx_usbd_transfer_t transfer = {
            .p_data = p_data,
            .size = size
        };
        nrfx_err_t res = nrfx_usbd_ep_transfer(ep, &transfer);
        if (res != NRFX_SUCCESS) {
            LOG_ERR("USB transfer failed: %d", res);
        }
    }
    
    
    
    
    
    
    
    
    
    /** @brief Allow access to specific GPIOs for the network core.
     *
     * Function is executed very early during system initialization to make sure
     * that the network core is not started yet. More pins can be added if the
     * network core needs them.
     */
    static int network_gpio_allow(void)
    {
    
    	/* When the use of the low frequency crystal oscillator (LFXO) is
    	 * enabled, do not modify the configuration of the pins P0.00 (XL1)
    	 * and P0.01 (XL2), as they need to stay configured with the value
    	 * Peripheral.
    	 */
    	uint32_t start_pin = (IS_ENABLED(CONFIG_SOC_ENABLE_LFXO) ? 2 : 0);
    
    	/* Allow the network core to use all GPIOs. */
    	for (uint32_t i = start_pin; i < P0_PIN_NUM; i++) {
    		NRF_P0_S->PIN_CNF[i] = (GPIO_PIN_CNF_MCUSEL_NetworkMCU <<
    					GPIO_PIN_CNF_MCUSEL_Pos);
    	}
    
    	for (uint32_t i = 0; i < P1_PIN_NUM; i++) {
    		NRF_P1_S->PIN_CNF[i] = (GPIO_PIN_CNF_MCUSEL_NetworkMCU <<
    					GPIO_PIN_CNF_MCUSEL_Pos);
    	}
    
    
    	return 0;
    }
    
    SYS_INIT(network_gpio_allow, PRE_KERNEL_1, CONFIG_KERNEL_INIT_PRIORITY_OBJECTS);
    

    3. This is the prj.conf, replace the one created by the example

    #
    # Copyright (c) 2020 Nordic Semiconductor ASA
    #
    # SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
    #
    CONFIG_MULTITHREADING=y
    CONFIG_KERNEL_MEM_POOL=y
    CONFIG_NUM_PREEMPT_PRIORITIES=0
    CONFIG_SYS_CLOCK_EXISTS=y
    CONFIG_ARM_MPU=y
    CONFIG_SIZE_OPTIMIZATIONS=y
    CONFIG_I2C=n
    CONFIG_WATCHDOG=n
    CONFIG_GPIO=n
    CONFIG_SPI=n
    CONFIG_SERIAL=n
    CONFIG_FLASH=n
    CONFIG_DYNAMIC_INTERRUPTS=n
    CONFIG_IRQ_OFFLOAD=n
    CONFIG_THREAD_STACK_INFO=n
    CONFIG_THREAD_CUSTOM_DATA=n
    CONFIG_BOOT_BANNER=n
    CONFIG_BOOT_DELAY=0
    CONFIG_CONSOLE=n
    CONFIG_UART_CONSOLE=n
    CONFIG_STDOUT_CONSOLE=n
    CONFIG_PRINTK=n
    CONFIG_EARLY_CONSOLE=n
    CONFIG_BOARD_ENABLE_CPUNET=y
    
    
    
    #enable the NRFX USB
    CONFIG_USB_DEVICE_DRIVER=y
    CONFIG_USB_NRFX=y
    #CONFIG_USB_DEVICE_STACK=y
    #CONFIG_USB_CDC_ACM=y

    4. create a build configuration

    then build and get the linker error

  • That USB code looks like it was ripped from the old NRF SDK and should not be needed for any NRF connect stuff.

    Zephyr (which NRF connect is based upon)  ships with an USB CDC implementation already, try using this. There are samples that show you how to.

  • I tried using the Zephyr implementation and it works fine but this is not my goal since the Zephyr USB implementation is not compatible with Zephyr UART Asynch (API with DMA) that I'm currently using.

Related