Usb read/ write without uart

Hi,

I am trying to setup usb on a custom board which does not have uart. I am able to enable usb using the zephyr usb device api and can see the correct status whenever I connect or disconnect my usb.

I have based my project on usb cdc acm example from zephyr, and tried to do a simple write and read using zephyr usb api. The issue I am facing is that when I try to write or read data over usb I do not see any message on my serial monitor (I am using hercules as serial monitor). I am also doing logs/ prints on RTT of the data but the readback from host/ serial monitor is always zero. So I am very confused as in where the problem lies.
I also tried to use usb_transfer instead of using usb_write/ read function but in this case I saw that the callback does not get triggered. And my transfer never gets done or throws any error. To simplify it further I am testing this on nrf5340dk by disabling uart configs and got the same issue.


Below I have attached my configs usb file and screenshot of my RTT logs. Could you please have a look and let me know what I am doing wrong?

P.S: I can see that I get a warning (usb device: failed to write endpoint buffer 0x80)and write error (usb write error:  -11) if I do not open my com port so I am guessing that com port settings are ok.

#include <zephyr/device.h>
#include <zephyr/drivers/uart.h>
#include <zephyr/kernel.h>
#include <zephyr/usb/class/usb_cdc.h>
#include <zephyr/usb/usb_device.h>

#define IN_ENDPOINT_ADDR  0x80
#define OUT_ENDPOINT_ADDR 0x00

// void usb_cb(uint8_t ep, enum usb_dc_ep_cb_status_code status) {
//     switch (status) {
//         case USB_DC_EP_SETUP:
//             printk("Setup\n");
//             break;
//         case USB_DC_EP_DATA_OUT:
//             printk("Rcv\n");
//             break;
//         case USB_DC_EP_DATA_IN:
//             printk("Send \n");
//             // int ret = usb_write(IN_ENDPOINT_ADDR, testdata, sizeof(testdata), NULL);
//             // if (ret != 0) {
//             //     printk("Failed to write USB: %d\n", ret);
//             // }
//             // printk("write data: %d %d %d %d %d\n", testdata[0], testdata[1], testdata[2], testdata[3], testdata[4]);
//             break;
//         default:
//             printk("Unknown\n");
//             break;
//     }
// }

uint8_t testdata[5] = {1, 2, 3, 4, 5};
uint8_t readdata[5];

void usb_transfer_cb(uint8_t ep, int tsize, void *priv) {
    printk("\n ep:%d", ep);
    printk("transfer complete\n");
    printk("tsize: %d\n", tsize);
}

void usb_enable_cb(enum usb_dc_status_code status, const uint8_t *param) {
    switch (status) {
        case USB_DC_CONFIGURED:
            printk("USB device configured\n");
            break;
        case USB_DC_CONNECTED:
            printk("USB device halted\n");
            break;
        case USB_DC_DISCONNECTED:
            printk("USB device disconnected\n");
            break;
        case USB_DC_ERROR:
            printk("USB error\n");
            break;
        case USB_DC_SET_HALT:
            printk("USB set halt\n");
            break;
        case USB_DC_CLEAR_HALT:
            printk("USB clear halt\n");
            break;
        default:
            break;
    }
}

int usb_init(void) {
    const struct device *usb_dev = DEVICE_DT_GET(DT_NODELABEL(cdc_acm_uart));
    if (!usb_dev) {
        printk("CDC ACM device not found\n");
        return -1;
    }

    int ret = usb_enable(usb_enable_cb);
    if (ret != 0) {
        printk("Failed to enable USB\n");
    }

    k_msleep(5000);
    while (1) {
        int ret = usb_write(IN_ENDPOINT_ADDR, testdata, sizeof(testdata), NULL);
        if (ret != 0) {
            printk("Failed to write USB: %d\n", ret);
        }
        printk("write data: %d %d %d %d %d\n", testdata[0], testdata[1], testdata[2], testdata[3], testdata[4]);

        k_msleep(1000);
        int read = usb_read(OUT_ENDPOINT_ADDR, readdata, sizeof(readdata), NULL);
        if (read != 0) {
            printk("Failed to read USB: %d\n", read);
        }
        k_msleep(1000);
        printk("read data: %d %d %d %d %d\n", readdata[0], readdata[1], readdata[2], readdata[3], readdata[4]);
    }

    /*Trying with usb_transfer instead of usb write/read*/
    // int ret_trans = usb_transfer(IN_ENDPOINT_ADDR, testdata, sizeof(testdata), USB_TRANS_WRITE, usb_transfer_cb, NULL);
    // if (ret_trans != 0) {
    //     printk("Failed to write USB: %d\n", ret_trans);
    // }

    return 0;
}

5344.nrf5340dk_nrf5340_cpuapp.dts

 0576.prj.conf

Parents Reply
  •  Yes I did try it on a nrf5340 DK but as you can see from the screenshot above I am always reading 0 and not the data I write using usb write function. 
    My intention is to setup usb so  that I do not have to use uart calls and  implementation is as shown in usb.c file . I am guessing I need to configure endpoints before I can use usb drivers but not sure how to do that.  If you can guide me how to set up usb correctly that would help me alot or any sample code that uses zephyr usb api would be much appreciated,

    Regards

Children
Related