Stream and Play music using UART of VS1010

Designing hardware and software for systems that use the VS1010 MP3 Audio DSP Microcontroller.
Post Reply
eswaran
User
Posts: 5
Joined: Tue 2017-09-26 16:04

Stream and Play music using UART of VS1010

Post by eswaran » Mon 2017-12-18 6:47

Hi,

We are having VS1010 evaluation board. We want to stream one music file (mp3 or any other format) through UART of VS1010 and want to play the same.

Please suggest me the possibility of doing the same in the evaluation board.

Please share me if any sample codes are available

thanks & regards,
Kotteeswaran.E

User avatar
Panu
VLSI Staff. Currently on holiday.
Posts: 2710
Joined: Tue 2010-06-22 13:43

Re: Stream and Play music using UART of VS1010

Post by Panu » Mon 2017-12-18 11:58

Hi!

Yeah... we've written some code for that, but I think it should be modified a little... Hmm, which VS1010 chip you have? VS1010B? VS1010C?

-Panu
Info: Line In and Line Out, VS1000 User interface, Overlay howto, Latest VSIDE, MCU Howto, Youtube
Panu-Kristian Poiksalo, VLSI Solution Oy

eswaran
User
Posts: 5
Joined: Tue 2017-09-26 16:04

Re: Stream and Play music using UART of VS1010

Post by eswaran » Tue 2017-12-19 6:35

Hi Sir,

VS1010C is used in our board.

thanks & regards,
Kotteeswaran.E

eswaran
User
Posts: 5
Joined: Tue 2017-09-26 16:04

Re: Stream and Play music using UART of VS1010

Post by eswaran » Wed 2017-12-20 6:32

Hi Banu,

Is it possible to get some updates today.

thanks & regards,
Kotteeswaran.E

eswaran
User
Posts: 5
Joined: Tue 2017-09-26 16:04

Re: Stream and Play music using UART of VS1010

Post by eswaran » Wed 2017-12-20 6:33

Even through SPI is also ok instead of UART.

thanks & regards,
Kotteeswaran.E

User avatar
Panu
VLSI Staff. Currently on holiday.
Posts: 2710
Joined: Tue 2010-06-22 13:43

Re: Stream and Play music using UART of VS1010

Post by Panu » Wed 2017-12-20 15:29

There is some UART stream receiver code hidden in the ROM but you need to first run some software on the chip to activate it.
Is it possible to get some updates today.
Please don't rush... I'll see what I can do.

-Panu
Info: Line In and Line Out, VS1000 User interface, Overlay howto, Latest VSIDE, MCU Howto, Youtube
Panu-Kristian Poiksalo, VLSI Solution Oy

User avatar
Panu
VLSI Staff. Currently on holiday.
Posts: 2710
Joined: Tue 2010-06-22 13:43

Re: Stream and Play music using UART of VS1010

Post by Panu » Fri 2017-12-22 18:04

Hi!

Sorry, the UART streaming requires some more work. I'll get back to you on early January.

-Panu
Info: Line In and Line Out, VS1000 User interface, Overlay howto, Latest VSIDE, MCU Howto, Youtube
Panu-Kristian Poiksalo, VLSI Solution Oy

eswaran
User
Posts: 5
Joined: Tue 2017-09-26 16:04

Re: Stream and Play music using UART of VS1010

Post by eswaran » Mon 2018-01-22 3:06

Hi Sir,

Any updates on this.

thanks & regards,
Kotteeswaran.E

User avatar
Panu
VLSI Staff. Currently on holiday.
Posts: 2710
Joined: Tue 2010-06-22 13:43

Re: Stream and Play music using UART of VS1010

Post by Panu » Mon 2018-01-22 12:20

Hi!

I'm working on it. Can you tell a little more about your application?

-Panu
Info: Line In and Line Out, VS1000 User interface, Overlay howto, Latest VSIDE, MCU Howto, Youtube
Panu-Kristian Poiksalo, VLSI Solution Oy

User avatar
Panu
VLSI Staff. Currently on holiday.
Posts: 2710
Joined: Tue 2010-06-22 13:43

Re: Stream and Play music using UART of VS1010

Post by Panu » Thu 2019-06-27 14:11

Dear Eswaran,
here is the source code of a Win32 application which streams an MP3 file to the VS1010 using the stream protocol. It's very prone to bit errors, but It usually works at least once after resetting the VS1010.

-Panu


Code for VS1010C:

Code: Select all

#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>

#define COM_PORT "COM7"
#define COM_SPEED 460800

static HANDLE port=0;
static COMMTIMEOUTS originalTimeouts;

	unsigned char outbuf[16384];
	unsigned char inbuf[16384];
	unsigned long bytesWritten;
	unsigned long bytesReceived;
	unsigned long transaction = 0;

static bool ComSetParams(HANDLE port,int baud) {
	DCB dcb;
	memset(&dcb,0,sizeof(dcb));
	dcb.DCBlength=sizeof(dcb);
	dcb.BaudRate=baud;
	dcb.fBinary=1;
	dcb.Parity=NOPARITY;
	dcb.StopBits=ONESTOPBIT;
	dcb.ByteSize=8;
	return SetCommState(port,&dcb)!=0;
}

static bool OpenComPort(char* p,int targetSpeed) {
	char portname[16];
	sprintf(portname,"\\\\.\\%s",p);
	port=CreateFile(portname,GENERIC_READ|GENERIC_WRITE,0,0,OPEN_EXISTING,0,0);
	if(!port) {
		printf("COM port is not valid: %s\n",portname);
		return false;
	}
	if(!GetCommTimeouts(port,&originalTimeouts)) {
		printf("Cannot get comm timeouts\n");
		return false;
	}
	COMMTIMEOUTS newTimeouts={200,10,100,10,100};
	SetCommTimeouts(port,&newTimeouts);
	if(!ComSetParams(port,targetSpeed)) {
		SetCommTimeouts(port,&originalTimeouts);
		CloseHandle(port);
		printf("Failed to set COM parameters\n");
		return false;
	}
	printf("Successfully set COM parameters\n");
	return true;
}


// Send a BREAK token by switching to a low bitrate for sending a long zero.
void SendBreak() {
	char outbuf[1];
	unsigned long bytesWritten;
	ComSetParams(port,9600);
	outbuf[0] = 0;
	WriteFile(port,outbuf,1,&bytesWritten,NULL);
	ComSetParams(port,COM_SPEED);
	PurgeComm(port, PURGE_RXABORT | PURGE_RXCLEAR);
	Sleep(10);
}



// Poke cs.cancel to VS1010 memory
void fSendCancel() {
	outbuf[0] = 0x30;
	outbuf[1] = '~';
	outbuf[2] = 0x30;
	outbuf[3] = 'b';
	outbuf[4] = 0x30;
	outbuf[5] = 'e';
	outbuf[6] = 0x30;
	outbuf[7] = 'x';
	outbuf[8] = 0x30;
	outbuf[9] = '1';
	outbuf[10] = 0x30;
	outbuf[11] = 'w';
	WriteFile(port,outbuf,12,&bytesWritten,NULL);
}


void SendUnCancel() {
	outbuf[0] = 0x30;
	outbuf[1] = '~';
	outbuf[2] = 0x30;
	outbuf[3] = 'b';
	outbuf[4] = 0x30;
	outbuf[5] = 'e';
	outbuf[6] = 0x30;
	outbuf[7] = 'x';
	outbuf[8] = 0x30;
	outbuf[9] = '0';
	outbuf[10] = 0x30;
	outbuf[11] = 'w';
	WriteFile(port,outbuf,12,&bytesWritten,NULL);
}

void SendUnCancel() {
	outbuf[0] = 0x30;
	outbuf[1] = '~';
	outbuf[2] = 0x30;
	outbuf[3] = 'b';
	outbuf[4] = 0x30;
	outbuf[5] = 'e';
	outbuf[6] = 0x30;
	outbuf[7] = 'x';
	outbuf[8] = 0x30;
	outbuf[9] = '0';
	outbuf[10] = 0x30;
	outbuf[11] = 'w';
	WriteFile(port,outbuf,12,&bytesWritten,NULL);
}




void main(int argc, char **argv) {
	int i;

	int vs1010dataBufferFree = 0; //If no other guess, send this many bytes (may happen during startup..)
	FILE *f;

	printf ("ArgC: %d. ArgV[1]:%d\n",argc,argv[1]);
	if(!OpenComPort(COM_PORT,COM_SPEED)) {

		Sleep(500);
		return;
	}	

	int zeros = 2000;

	f = fopen(argv[1],"rb");
	if (!f) {
		printf("no mp3 file");
		Sleep(1000);
		exit(2);
	}

	ReadFile(port,inbuf,10,&bytesReceived,NULL); printf("#1 %d bytes:%02x %02x %02x \n",bytesReceived,inbuf[0],inbuf[1],inbuf[2]);


	outbuf[0] = 0x53; //Send PREPARE opcode - VS1010 will start listening to stream
	WriteFile(port,outbuf,1,&bytesWritten,NULL);
	Sleep(10);

	ReadFile(port,inbuf,10,&bytesReceived,NULL); printf("#2 %d bytes:%02x %02x %02x \n",bytesReceived,inbuf[0],inbuf[1],inbuf[2]);
	



#if 1


	SendBreak();
	Sleep(1000);
	vs1010dataBufferFree = 0;

	ReadFile(port,inbuf,100,&bytesReceived,NULL);
	printf("Received %d bytes:%02x ",bytesReceived,inbuf[0]);


	restart:

	outbuf[0] = 0x51; //Send PREPARE opcode - VS1010 will start listening to stream
	WriteFile(port,outbuf,1,&bytesWritten,NULL);
	Sleep(100);
	SendUnCancel();

	//outbuf[0] = 0x40; //Send RESET opcode
	//WriteFile(port,outbuf,1,&bytesWritten,NULL);
	
	i=1;

	while (i++) {
	    Sleep(1);	
		ReadFile(port,inbuf,1,&bytesReceived,NULL);
		printf("Received %d bytes:%02x ",bytesReceived,inbuf[0]);
		if ((bytesReceived == 1) && (inbuf[0]>0xf0) && (inbuf[0]<0xfc)) {
			i=0;
		}
		outbuf[0] = 0x51; // Query for stream buffer available
		WriteFile(port,outbuf,1,&bytesWritten,NULL);

	}

	vs1010dataBufferFree = 0;

	while(1) {

		printf("\n Transaction %d: ",++transaction);
		if (vs1010dataBufferFree==0) {
			bytesReceived = 10;
			while (bytesReceived == 10) {
				ReadFile(port,inbuf,10,&bytesReceived,NULL);
				printf("%d:%02x%02x%02x ",bytesReceived,inbuf[0],inbuf[1],inbuf[2]);
			}

			outbuf[0] = 0x10;
			WriteFile(port,outbuf,1,&bytesWritten,NULL);
			printf("vFree:");
			inbuf[0] = 0;
			Sleep(1);
			ReadFile(port,inbuf,10,&bytesReceived,NULL);
			printf("%d:%02x%02x%02x ",bytesReceived,inbuf[0],inbuf[1],inbuf[2]);

			if (bytesReceived) {
				vs1010dataBufferFree = inbuf[bytesReceived-1];
				if (vs1010dataBufferFree > 0x11) {
					printf("NotFreeReply(0x%02x)!",vs1010dataBufferFree);
					SendUnCancel();
					Sleep(100);
					vs1010dataBufferFree = 0;
				}
				vs1010dataBufferFree *= 32; //Convert to bytes
				printf("fr1:%d ",vs1010dataBufferFree);
			}
		}
		SendUnCancel();
		printf("fr2:%d ",vs1010dataBufferFree);
		if (vs1010dataBufferFree) {
			int fr = 0;
			if (fr=fread(&outbuf[3],1,vs1010dataBufferFree,f)) {
				unsigned char tmpbuf[3];
				outbuf[0]=0x20;
				outbuf[1]=fr>>8;
				outbuf[2]=fr&0xff;

				printf("free=%d read=%d ",vs1010dataBufferFree,fr);

				WriteFile(port,outbuf,1,&bytesWritten,NULL);
				ReadFile(port,inbuf,1,&bytesReceived,NULL);
				printf("'%d:%02x=fc ",bytesReceived,inbuf[0]);
				if (inbuf[0]==0xf0) {	
					printf("\nVS1010 says reset\n");
					goto restart;
				}
				SendUnCancel();
				WriteFile(port,&outbuf[1],fr+2,&bytesWritten,NULL);
				printf("wrot %4d bytes ",bytesWritten-3); //-3 for the protocol overhead
				ReadFile(port,inbuf,1,&bytesReceived,NULL);
				printf("Final %d:%02x ",bytesReceived,inbuf[0]);
				if (!bytesReceived) {
					printf("ERROR: No reply to packet\n");
					Sleep(10000);
					break;
				}
				SendUnCancel();
				if (inbuf[0] <= 0x11) {
					vs1010dataBufferFree = (inbuf[0]) * 32; //Convert to bytes
				} else {
					vs1010dataBufferFree = 0;
				}

			} else {
				vs1010dataBufferFree=0;
				break;
			}
		}
	} 	


#endif

	printf("End of File.\n");
	Sleep(2000);

}



Code for VS1010B:

Code: Select all

#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>

#define COM_PORT "COM7"
#define COM_SPEED 460800

static HANDLE port=0;
static COMMTIMEOUTS originalTimeouts;

	unsigned char outbuf[16384];
	unsigned char inbuf[16384];
	unsigned long bytesWritten;
	unsigned long bytesReceived;
	unsigned long transaction = 0;

static bool ComSetParams(HANDLE port,int baud) {
	DCB dcb;
	memset(&dcb,0,sizeof(dcb));
	dcb.DCBlength=sizeof(dcb);
	dcb.BaudRate=baud;
	dcb.fBinary=1;
	dcb.Parity=NOPARITY;
	dcb.StopBits=ONESTOPBIT;
	dcb.ByteSize=8;
	return SetCommState(port,&dcb)!=0;
}

static bool OpenComPort(char* p,int targetSpeed) {
	char portname[16];
	sprintf(portname,"\\\\.\\%s",p);
	port=CreateFile(portname,GENERIC_READ|GENERIC_WRITE,0,0,OPEN_EXISTING,0,0);
	if(!port) {
		printf("COM port is not valid: %s\n",p);
		return false;
	}
	if(!GetCommTimeouts(port,&originalTimeouts)) {
		printf("Cannot get comm timeouts\n");
		return false;
	}
	COMMTIMEOUTS newTimeouts={200,10,100,10,100};
	SetCommTimeouts(port,&newTimeouts);
	if(!ComSetParams(port,targetSpeed)) {
		SetCommTimeouts(port,&originalTimeouts);
		CloseHandle(port);
		printf("Failed to set COM parameters\n");
		return false;
	}
	printf("grande success\n");
	return true;
}

void SendBreak() {
	char outbuf[1];
	unsigned long bytesWritten;
	ComSetParams(port,9600);
	outbuf[0] = 0;
	WriteFile(port,outbuf,1,&bytesWritten,NULL);
	ComSetParams(port,COM_SPEED);
	PurgeComm(port, PURGE_RXABORT | PURGE_RXCLEAR);
	Sleep(10);
}

void SendCancel() {
	outbuf[0] = 0x30;
	outbuf[1] = '~';
	outbuf[2] = 0x30;
	outbuf[3] = 'b';
	outbuf[4] = 0x30;
	outbuf[5] = 'e';
	outbuf[6] = 0x30;
	outbuf[7] = 'x';
	outbuf[8] = 0x30;
	outbuf[9] = '1';
	outbuf[10] = 0x30;
	outbuf[11] = 'w';
	WriteFile(port,outbuf,12,&bytesWritten,NULL);
}


void main(int argc, char **argv) {

	int dreq = 0; //If no other guess, send this many bytes (may happen during startup..)
	FILE *f;
	if(!OpenComPort(COM_PORT,COM_SPEED)) {
		Sleep(500);
		return;
	}

	int zeros = 2000;
	f = fopen(argv[1],"rb");
	if (!f) {
		printf("no mp3 file");
		Sleep(1000);
		exit(2);
	}

	SendBreak();
	Sleep(100);

	Sleep(1000);

	dreq = 0;
	Sleep(100);

	while(1) {

		if ((transaction == 100) && ftell(f)<3000) { //100 transactions and file not proceeding, cancel...
			SendCancel();
		}

		printf("\n Transaction %d: ",++transaction);
		if (dreq==0) {
			outbuf[0] = 0x10;
			WriteFile(port,outbuf,1,&bytesWritten,NULL);
			printf("DREQ:");
			ReadFile(port,inbuf,1,&bytesReceived,NULL);
			printf("%d:%02x ",bytesReceived,inbuf[0]);

			if (bytesReceived) {
				dreq = inbuf[bytesReceived-1]*32;
			}
		}
		if (dreq) {
			int fr = 0;
			if (fr=fread(&outbuf[3],1,dreq,f)) {
				unsigned char tmpbuf[3];
				dreq=0;
				outbuf[0]=0x20;
				outbuf[1]=fr>>8;
				outbuf[2]=fr&0xff;
				WriteFile(port,outbuf,fr+3,&bytesWritten,NULL);
				printf("wrote %4d bytes ",bytesWritten-3); //-3 for the protocol overhead
				ReadFile(port,inbuf,1,&bytesReceived,NULL);
				printf("Finally %d:%02x ",bytesReceived,inbuf[0]);
				if (!bytesReceived) {
					printf("ERROR: No reply to packet\n");
					Sleep(10000);
					break;
				}
				if ((inbuf[0]&0x80) == 0) {
					printf("ERROR: Reply to packet does not have bit 7 set\n");
					Sleep(10000);
					break;
				}
				dreq = (inbuf[0] & 0x7f) * 16;
			} else {
				dreq=0;
				break;
			}
		}
	} 
	printf("EOF");
	Sleep(5000);
}
Info: Line In and Line Out, VS1000 User interface, Overlay howto, Latest VSIDE, MCU Howto, Youtube
Panu-Kristian Poiksalo, VLSI Solution Oy

Post Reply