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;
}