I2S to USB microphone received data is periodically garbage (nRF Connect SDK v2.6.1)

Hi,

I'm trying to use an nRF52840 dev kit as an I2S-to-USB microphone, but I've been running into a problem where the recorded audio is periodically unusable.

To debug, I connected another nRF52840 dev kit to act as an I2S slave. It simply delivers a repeating sawtooth waveform.

I can receive this on my primary dev board and send it to the host PC over a USB audio interface. Here's what I record in Audacity:

As you can see, the sawtooth is clearly visible, but every 6000 samples or so, I see these strange spikes. I think the problem lies with the USB transfer, because I've done some quick checks to make sure the received I2S data is as expected.

To transmit data over USB, I use the following function:

bool write_to_usb(struct net_buf *buffer, size_t size){
	int ret;

	if (!buffer || !size) {
		LOG_ERR("BUFF NULL!");
		/* This should never happen */
		return 1;
	}

	/* Check if OUT device buffer can be used for IN device */
	if (size == usb_audio_get_in_frame_size(mic_dev)) {
		ret = usb_audio_send(mic_dev, buffer, size);
		if(ret){
			net_buf_unref(buffer);
			return 1;
		}
	} else {
		LOG_ERR("In frame not equal to size. Found %d, expected %d", usb_audio_get_in_frame_size(mic_dev), size);
		net_buf_unref(buffer);
		return 1;
	}

	return 0;
}

This function is called from my nrfx I2S handler:

struct net_buf *buf = net_buf_alloc(&netbuf_pool, K_NO_WAIT);
if(buf){
	int16_t* rx_aud = (int16_t*) p_released->p_rx_buffer;

	// Copy data from I2S to USB audio
	for(int i = 0; i < SAMPLES_PER_CHUNK; i++){
		net_buf_add_le16(buf, rx_aud[i]);
	}
	write_to_usb(buf, CHUNK_SIZE_BYTES);
}

The net buffer pool is initialized like so:

NET_BUF_POOL_DEFINE(netbuf_pool, 50, CHUNK_SIZE_BYTES, 0, NULL);

Am I using the net buffer incorrectly here?

I've attached the project files for both dev boards for reference.

i2s_out.zipi2s_in_usb_audio.zip

Related