VS1010 MEMS microphone capture

Designing hardware and software for systems that use the VS1010 MP3 Audio DSP Microcontroller.
Post Reply
User avatar
Panu
VSDSP Expert
Posts: 2821
Joined: Tue 2010-06-22 13:43

VS1010 MEMS microphone capture

Post by Panu »

Dear all,

Here is a small example that configures the MEMS microphone port on the developer board and loops audio from the microphone to the DAC. It uses interrupts to get the MEMS data and decimates the data in an overly simplistic fashion by just taking the average of 8 samples. The idea is that this demonstrates the usage of the MEMS interface hardware; it's not a very good example of signal processing.

Code: Select all

#include <vo_stdio.h>
#include <vs1010b.h>
#include <audiofs.h>
#include <vo_gpio.h>
#include <fifoy.h>
#include <protocol.h>

__y s_int16 memsDataBuffer[128];
__y struct FIFOY memsFifo;

#pragma interrupt y 0x26
void MemsMicInterruptHandler(void) {
	FIFOYPut(&memsFifo,PERIP(FAUDIO_L)); //Get audio from mems data port to FIFO
}

void fini(void) { //Disable the MEMS mic interrupt
	PERIP(INT_ENABLE0_HP) &= ~(1 << 6);
}

ioresult main (char *params) {
	int i;
	static s_int32 sampleRate = 24000;
	ioctl(stdaudioout, IOCTL_AUDIO_SET_ORATE, &sampleRate);
	ioctl(stdaudioout, IOCTL_AUDIO_SET_OCHANNELS, (IOCTL_ARGUMENT)2);

	gotoShell = 0;
	FIFOYInit(&memsFifo,memsDataBuffer,sizeof(memsDataBuffer));
	PERIP(INT_ENABLE0_HP) |= (1 << 6);

	printf("Looping, [Enter] to end..\n");	
	GpioSetAsPeripheral(0x09); //MD1
	GpioSetAsPeripheral(0x0a); //MC1
	
	PERIP(MEMSMIC_CF) = MEMSMIC_CF_SELIO | MEMSMIC_CF_ENA;// | MEMSMIC_CF_LEDGE | MEMSMIC_CF_REDGE;
	PERIP(PERIP_CF) |= (1 << 2); //Enable MC1 clock generation /// \todo vs1010b.h file has error!		
	PERIP(FAUDIO_SEL) = 2; //Route MEMS mic to fast audio read register

	while(!gotoShell) { // Loop until Enter is pressed
		static u_int16 abuf[2];
		if (FIFOYFill(&memsFifo) > 8) { //8 MEMS samples (192k) available, average them to get a crude 24kHz sample.
			s_int16 s = 0;
			for (i=0; i<8; i++) s += FIFOYGet(&memsFifo) / 4;

			abuf[0] = abuf[1] = s;
			stdaudioout->op->Write(stdaudioout, abuf, 0, 4);						
		}
	}
	
	return S_OK;
}
Attachments
arch-LoopMems-2017-08-01-16-59-Average24k.zip
Loops audio from MEMS microphone to output. Source code, VSIDE solution.
(12.8 KiB) Downloaded 245 times
User avatar
Panu
VSDSP Expert
Posts: 2821
Joined: Tue 2010-06-22 13:43

Re: VS1010 MEMS microphone capture

Post by Panu »

Hi again!

With help from other experts at VLSI, here's a mems microphone loopback code with a proper decimation filter. With this one the sound quality is actually pretty good and it is a good example of signal processing. :D

Code: Select all

	while(!gotoShell) { // Loop until Enter is pressed
		#define BLOCKSIZE 64 // Decimate 64 samples at 192kHz to 16 samples at 48kHz.
		static u_int16 fullRate[BLOCKSIZE];
		if (FIFOYFill(&memsFifo) > BLOCKSIZE) { 
		
			static s_int16 dec4delay[17*2];
			static s_int16 *dec4delayPtr = dec4delay+16;
			static const __mem_y s_int16 dec4coeff[17] = {
				-711,   -224,   153,    885,   1919,   3099,   4199,   4980,   5264, 4980,   4199,   3099,   1919,    885,   153,   -224,   -711
			};
			s_int16 *p = fullRate;
			for (i=0; i<BLOCKSIZE; i++) {
				*p++ = FIFOYGet(&memsFifo);
			}
			
			FirGeneralStrideAsm(fullRate, 1, BLOCKSIZE, dec4coeff, &dec4delayPtr, 17, 1);
			memcpystride(fullRate, sizeof(s_int16), fullRate, 4*sizeof(s_int16), BLOCKSIZE/4); //Re-pack decimate by 4.	
			stdaudioout->op->Write(stdaudioout, fullRate, 0, (BLOCKSIZE/4)*2);
		}
	}
With this code, the DAC runs at 48 kHz and the filter code outputs 16 samples at each iteration in mono mode, so it's pretty efficient too.

-Panu
Attachments
LoopMems.dlx
MEMS mic loopback program for VS1010B. VS1010 VSOS executable.
(1.2 KiB) Downloaded 235 times
arch-LoopMems-2017-08-01-18-24-DecimationFilter.zip
MEMS mic loopback using a FIR decimation filter. Source code, VSIDE solution.
(14.17 KiB) Downloaded 245 times
User avatar
Panu
VSDSP Expert
Posts: 2821
Joined: Tue 2010-06-22 13:43

Re: VS1010 MEMS microphone capture

Post by Panu »

Here's another improvement of the MEMS microphone loopback code. This one processes samples aperiodically, which gives better sound in some situations.
Attachments
arch-LoopMemV-2017-08-03-14-30-Aperiodic.zip
Souce code, VSIDE Solution
(16.15 KiB) Downloaded 218 times
LoopMemV.dlx
VS1010 VSOS Executable
(1.3 KiB) Downloaded 218 times
krdarrah
User
Posts: 4
Joined: Tue 2021-01-19 19:39

Re: VS1010 MEMS microphone capture

Post by krdarrah »

How to configure on LQFP-48?

I have this, but not sure?

Code: Select all

	GpioSetAsPeripheral(0x01); //MD0
	GpioSetAsPeripheral(0x1E); //MC0
	PERIP(PERIP_CF) |= (1 << 3); //Enable PERIP_CF_I2S48PIN
	PERIP(MEMSMIC_CF) = MEMSMIC_CF_ENA;//| MEMSMIC_CF_REDGE;
	PERIP(PERIP_CF) |= (1 << 1); //Enable MC0 clock generation
	PERIP(PERIP_CF) |= (1 << 3); //Enable PERIP_CF_I2S48PIN
	PERIP(FAUDIO_SEL) = 2; //Route MEMS mic to fast audio read register
Hannu
Senior User
Posts: 264
Joined: Mon 2016-05-30 11:54

Re: VS1010 MEMS microphone capture

Post by Hannu »

I don't have LQFP card on hand right now to test but I think you have the I2S overriding the GPIO0_1 and GPIO1_14 function.

I would try something like:

Code: Select all

	GpioSetAsPeripheral(0x01); //MD0
	GpioSetAsPeripheral(0x1E); //MC0
	PERIP(MEMSMIC_CF) = MEMSMIC_CF_ENA;//| MEMSMIC_CF_REDGE;/* MEMSMIC_SELIO should stay 0 */
	PERIP(PERIP_CF) |= (1 << 1); //Enable MC0 clock generation
	PERIP(FAUDIO_SEL) = 2; //Route MEMS mic to fast audio read register
krdarrah wrote: Fri 2021-02-26 17:54 How to configure on LQFP-48?

I have this, but not sure?

Code: Select all

	GpioSetAsPeripheral(0x01); //MD0
	GpioSetAsPeripheral(0x1E); //MC0
	PERIP(PERIP_CF) |= (1 << 3); //Enable PERIP_CF_I2S48PIN
	PERIP(MEMSMIC_CF) = MEMSMIC_CF_ENA;//| MEMSMIC_CF_REDGE;
	PERIP(PERIP_CF) |= (1 << 1); //Enable MC0 clock generation
	PERIP(PERIP_CF) |= (1 << 3); //Enable PERIP_CF_I2S48PIN
	PERIP(FAUDIO_SEL) = 2; //Route MEMS mic to fast audio read register
User avatar
Panu
VSDSP Expert
Posts: 2821
Joined: Tue 2010-06-22 13:43

Re: VS1010 MEMS microphone capture

Post by Panu »

krdarrah wrote: Fri 2021-02-26 17:54 How to configure on LQFP-48?
Hi!

We've been looking into this. As it turns out, the peripherals need to be used a little bit differently for it to work. Hold on, we're cleaning up and optimizing the source code and making it work as similarly as possible to the old code.

-Panu
User avatar
Panu
VSDSP Expert
Posts: 2821
Joined: Tue 2010-06-22 13:43

Re: VS1010 MEMS microphone capture

Post by Panu »

Dear VS1010 LQFP package users,

Here's a version of the digital mems microphone capture that works with the LQFP-48 package. It's been tested on the VS1010D LQFP Simple Board. The inner workings of the mic capture have been completely rewritten, but the usage is very simple:

Code: Select all

	InitMemsFilter(sampleRate); //12000 or 24000 
	
	while (lastReceivedCharUart0 != 27) { //Loopback from mems to dac
		s_int16 *s = Get16MicrophoneSamples();
		if (s) {
			stdaudioout->op->Write(stdaudioout, s, 0, 16 * 2); //16*2 bytes
		}
	}
This code loops back audio from the microphone to the main (dac) audio path. InitMemsFilter() sets up the microphone and Get16MicrophoneSamples() gets sound data. If there's not sufficient data in the buffer, the function returns NULL so it's safe to call from realtime systems.

This code can get data in two sample rates; either 24 kHz or 12 kHz. If you need some other sample rates, please let us know!

If you give the parameter 12, the demo uses 12 kHz sample rate, otherwise it uses 24 kHz sample rate.
VS1010>memslqfp
Mems loopback (lqfp), sample rate 24000. [Esc] to end

VS1010>memslqfp 12
Mems loopback (lqfp), sample rate 12000. [Esc] to end

VS1010>
vs1010_lqfp_board.jpg
vs1010_lqfp_board.jpg (111.01 KiB) Viewed 1434 times
To work in the LQFP package with all VS1010 versions, the code needs to use the I2S hardware to pump the bits from the microphone and then does high quality software decimation for the best sound quality. Please contact VLSI for details and how this might affect your system.

Sincerely,
Panu
Attachments
memslqfp.dlx
MEMS microphone capture demo program for VS1010D in LQFP package. VS1010/VSOS DLX executable.
(7.83 KiB) Downloaded 70 times
arch-memslqfp-2021-03-04-18-53-RC1.zip
Source code, VSIDE Solution
(37.9 KiB) Downloaded 80 times
User avatar
Henrik
VLSI Staff
Posts: 1239
Joined: Tue 2010-06-22 14:10

Re: VS1010 MEMS microphone capture

Post by Henrik »

Hello!

Here is a slighlty improved version of the VS1010 MEMS microphone capture program. The only difference here is that I have added a clean-up function FiniMemsFilter() which should be called before exiting. Otherwise there will be interrupts to erased code, which will probably cause a crash when the next program is loaded.

Kind regards,
- Henrik
Attachments
memslqfp.zip
(39.48 KiB) Downloaded 77 times
memslqfp.dlx
(8 KiB) Downloaded 66 times
Good signatures never die. They just fade away.
Post Reply