This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

How to use nrf5340 as a USB Microphone device?

I want to use nrf5340 as a USB Audio Microphone.

I am taking the help of zephyr/samples/subsys/usb/audio/headphones_microphone sample app, which contains USB Headphone + USB Microphone.

To disable USB Headphone, I am commenting hp_dev related code from main.c and I am modifying the nrf5340dk_nrf5340_cpuapp.overlay as follows:

&usbd {
mic_0 {
label = "MICROPHONE";
compatible = "usb-audio-mic";
feature-mute;
channel-l;
channel-r;
};
};

I have a static 192 byte PCM buffer that I want to continuously send over USB, for which I am using the following code in loop:

struct usb_audio_dev_data *audio_dev_data = mic_dev->data;
struct net_buf *buffer = net_buf_alloc(audio_dev_data->pool, K_NO_WAIT);
memcpy(buffer->data, pcm_buffer, buffer_len);
ret = usb_audio_send(dev, buffer, buffer_len);

But it does not work and the code crashes. 

Please advise.

Parents
  • Hi

    You mean you run the code in a loop as fast as possible?

    Then you will eventually run out of net_buffers, or fill up the USB buffers. 

    Are you checking the return codes from net_buf_alloc(..) and usb_audio_send(..) to see if they return any errors?

    I would recommend registering the data_written_cb callback in the hp_ops setup, so that you get a callback whenever an audio packet is successfully sent over the USB interface. Then you can use this to schedule the next update.

    Best regards
    Torbjørn

  • Hi, t

    Thanks, I handled the buffers so that they don't fill up, and also wrote the data_written_cb. Within this callback, I am sending 192 bytes of audio data by calling usb_audio_send() again so that data is sent continuously after each successfully data_written_cb call. I can now see the Zephyr USB audio sample listed in the Audio Input devices of the host device. But I can not hear any sound on my host device. I tried sending a 400Hz sine wave, 600Hz sine wave, and also a 1 sec sample of a song (192k sized buffer), but I cannot hear any of those on the host default speaker. I captured the incoming USB data on the host device using wireshark, and it looks like the buffer that I am sending is getting received at the host side. But I am also seeing this error on wireshark :
    USB isodesc 0 [Protocol error (-EPROTO)] (192 bytes)
    Status: Protocol error (-EPROTO) (-71)

    One USB packet as captured on wireshark is as follows:


    00 de e9 93 00 88 ff ff 43 00 88 78 02 00 2d 00 .Þé...ÿÿC..x..-.
    c6 be 2b 61 00 00 00 00 8d c3 01 00 00 00 00 00 ƾ+a.....Ã......
    c0 00 00 00 d0 00 00 00 00 00 00 00 01 00 00 00 À...Ð...........
    01 00 00 00 82 01 00 00 04 02 00 00 01 00 00 00 ................
    b9 ff ff ff 00 00 00 00 c0 00 00 00 00 00 00 00 ¹ÿÿÿ....À.......
    00 08 00 00 3c aa e3 59 b3 52 bf e7 36 fe aa 62 ....<ªãY³R¿ç6þªb
    29 be 72 55 fc 11 e4 55 ec 66 62 66 b4 0f 29 cc )¾rUü.äUìfbf´.)Ì
    e5 de ea a0 26 b9 8a 00 2b ff 61 43 06 d1 ed 00 åÞê &¹..+ÿaC.Ñí.
    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
    00 00 00 01 00 00 a8 04 2e 03 20 00 00 c0 00 04 ......¨... ..À..
    2e 03 20 10 e2 07 8d b6 09 a5 f8 7b 56 8e f6 e0 .. .â..¶.¥ø{V.öà

    What could be wrong?
    Let me know if you want the entire wireshark capture, or want to look at the code.

  • Hi 

    How are you receiving the sound on the host side? 

    Unless you have some program trying to get sound from the microphone device, you won't be able to send anything from the nRF device. 

    In my case I am using the Audacity audio editing application in order to record audio, as this program makes it very easy to select the input source:

    I decided to test this myself based on your input, and realized that using the data_written_cb callback was not the easiest way to use the microphone class. 

    Instead I configured the data_request_cb callback, which will be triggered every time the host opens the microphone port for input. Then I could prepare a packet for sending here and send it over the USB interface. 

    Best regards
    Torbjørn

  • Are you able to post your code?  This seems like a reasonable approach but so far I haven't been able to get it to work without errors.

Reply Children
No Data
Related