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

  • Thanks for your input. I was using another audio recorder for capturing the incoming audio. With your suggestion, I added data_request_cb and used it to send the audio buffer to the host. With this, I was successfully able tos send 192k static PCM buffers of 400hz and 600hz sine wave and record it at the host side. Now I would like to send dynamic audio values to the host. My input is coming from an I2S interface which I want to relay to the USB host. The I2S gives me 1920 bytes of data every 10ms, which I am memcopying into a buffer, and sending over USB inside data_request_cb. From wireshark, I can see that the data is being transmitted to the host successfully, but now again I am not able to hear it after recording on the host side. Any suggestions that I can try?

  • Hi 

    Could it be that your host is trying to play back audio to your nRF device as well, over USB?

    Could you try to change the playback device on the host side to ensure that you play sound to the standard sound driver, and not the USB driver set up by the nRF device?

    Best regards
    Torbjørn

Reply Children
  • No, that is not the case. I have enabled only the microphone device in my code, I am not enabling the headphone device. My dts also has only the microphone. The dts is as follows:
    &usbd {
    mic_0 {
    label = "MICROPHONE";
    compatible = "usb-audio-mic";
    feature-mute;
    channel-l;
    channel-r;
    };
    };

    So on the host side, for output I only see one option: the standard system speaker. Whereas for input I see two options: standard mic input and zephyr mic, from which I select the zephyr mic to send audio from the nrf to the host.

  • Hi

    Did this problem occur once you changed from sending a sine wave to sending I2S data?

    Have you done some debugging on the nRF side to verify that the I2S data looks OK when you get it from the I2S driver?

    Best regards
    Torbjørn

Related