VS1063 encoding data from LINE1 input

Designing hardware that uses VLSI Solution's devices as slave codecs such as an external MP3 decoder chip for a host microcontroller.
Post Reply
EMBED_LU
User
Posts: 6
Joined: Mon 2021-03-15 12:31

VS1063 encoding data from LINE1 input

Post by EMBED_LU »

Hello
I am making an audio transmission and reception system between Master board and Slave board using VLSI's VS1063A codec chip. The hardware specifications for Master and Slave are all the same.
I will explain more about the system in detail.
The master encodes the audio signal that input to the LINE1 into the MP3 format and sends it to Slave via the USART of the MCU.(USART Maximum Baudrate 2.5 Mbps).
And then, Slave will decode the data received from Master and output it to the speaker.

Before designing the system, I will briefly explain my current progress.
I successed audio output, that is mp3 sample, beep sound, sine test, mp3 format data given by master sent through USART and decoded from Slave. (No LINE1 encoding)

However, when I transmit mp3 encoded format signal from audio which is input to LINE1, I faced the problem.
there is not audio output signal is from Slave side

I cannot solve this problem.
I'll attach the source code below, so please point out the wrong points.
For your information, I don't use SD card!

Code: Select all


static int32_t VS1063_DecodeMode_Init(void)
{
	uint8_t retry; 	

	VS1063_HW_Reset(); //VS1063 HW reset
	
	while(!DREQ); /* Wait DREQ HIGH */
	
	VS1063_SPI_ReadWriteByte(0xff); //dummy byte, SPI Test
	retry = 0;
	
	// VS1063_ApplyPlugin();
	
	/* SCI_MODE SETTING */
	while(VS1063_ReadReg(SCI_MODE) != 0x0800) // SM SDINEW | SM_RESET | SM_TEST
	{
		VS1063_WriteReg(SCI_MODE, 0x0804); //SM_RESET bit automatically clear
		HAL_Delay(2);
		if(retry++ > 100)
		{
#ifdef DEBUG_PRINT
			printf("SCI MODE Set Error\r\n");
#endif
			return MODE_ERROR;
		}
	}
		
	retry = 0;
	
	/* SCI_COCKF SETTING */
	while(VS1063_ReadReg(SCI_CLOCKF) != 0x9800) 
	{
		/* x3.0 Clock, 36MHz / 7, SPI Baudrate should be less than 5.14MHz */
		VS1063_WriteReg(SCI_CLOCKF, 0x9800);
		if(retry++ > 100)
		{ 
#ifdef DEBUG_PRINT
			printf("SCI_CLOCKF Set Error\r\n");
#endif
			return CLOCKF_ERROR;
		}
	}
	
	retry = 0;
	/* SCI_AUDATA SETTING */
	#if 0
	while(VS1063_ReadReg(SCI_AUDATA) != 0xAC46) 
	{
		/* 0xAC45 = 44.1KHz sample rate, stereo type */
		VS1063_WriteReg(SCI_AUDATA, 0xAC46);
		if(retry++ > 100)
		{ 
#ifdef DEBUG_PRINT
			printf("SCI_AUDATA Set Error\r\n");
#endif
			return AUDATA_ERROR;
		}   
	}
	#else
	while(VS1063_ReadReg(SCI_AUDATA) != 0xBB82) 
	{
		/* 0xBB82 = 48KHz sample rate, stereo type */
		VS1063_WriteReg(SCI_AUDATA, 0xBB82);
		if(retry++ > 100)
		{ 
#ifdef DEBUG_PRINT
			printf("SCI_AUDATA Set Error\r\n");
#endif
			return AUDATA_ERROR;
		}   
	}
	#endif

	VS1063_WriteReg(SCI_VOL, 0x0000); //volume init(maximum volume)
	VS1063_SetDecodeTime(0x0000);     //decode time init
	
	XDCS_LOW;
	
	VS1063_SPI_ReadWriteByte(0xFF);   //dummy byte
	VS1063_SPI_ReadWriteByte(0xFF);   //dummy byte
	VS1063_SPI_ReadWriteByte(0xFF);   //dummy byte
	VS1063_SPI_ReadWriteByte(0xFF);   //dummy byte
	 
	XDCS_HIGH;
	HAL_Delay(20);
	
	return 1;
} 

static int32_t VS1063_EncodeMode_Init(void)
{
  uint8_t retry; 	
  
	VS1063_HW_Reset(); //VS1063 HW reset(); 
	
	while(!DREQ);
	
	VS1063_SPI_ReadWriteByte(0xff); //dummy byte, SPI Test
	retry = 0;
		
	/* SCI_COCKF SETTING */
  while(VS1063_ReadReg(SCI_CLOCKF) != 0xB000) // XTALI x 4.0, more x 1.5 
  {
	  VS1063_WriteReg(SCI_CLOCKF, 0xB000);   
	  HAL_Delay(2);                        
	  if(retry++ > 100)
	  { 
#ifdef DEBUG_PRINT
			printf("SCI_CLOCKF Set Error\r\n");
#endif
			return CLOCKF_ERROR;
	  }
  }
	
	VS1063_ApplyPlugin();
	
	/* User must write the right values to SCI_AICTRL0, SCI_AICTRL3, and SCI_WRAMADDR.
		 These value are only read at encdoing startup
		 SCI_AICTRL1 and SCI_AICTRL2 can be altered anytime, but it is preferable to write good init values befor activation
	*/
	
	/* SCI_AICTRL0 SETTING */
	while(VS1063_ReadReg(SCI_AICTRL0) != 48000U) // sample rate 48 kHz(read at encoding startup)
  {
	  VS1063_WriteReg(SCI_AICTRL0, 48000U); 
	  HAL_Delay(2);               
	  if(retry++ > 100)
	  { 
#ifdef DEBUG_PRINT
			printf("SCI_AICTRL0 Set Error\r\n");
#endif
			return AICTRL0_ERROR; 
	  }
  }
	
	/* SCI_AICTRL1 SETTING */
	while(VS1063_ReadReg(SCI_AICTRL1) != 1024U) // encoding gain is SCI_AICTRL1/1024, (1024 is equal to gain 1.0)
  {
		/* gain = 1  */   
	  VS1063_WriteReg(SCI_AICTRL1, 1024U); 
	  HAL_Delay(2);               
	  if(retry++ > 100)
	  { 
#ifdef DEBUG_PRINT
			printf("SCI_AICTRL1 Set Error\r\n");
#endif
			return AICTRL1_ERROR;
	  }
  }	
	
	/* SCI_AICTRL3 SETTING */
	while(VS1063_ReadReg(SCI_AICTRL3) != 0x0060) // Stereo MP3
  {
		/* mp3 format, streo mode */   
	  VS1063_WriteReg(SCI_AICTRL3, 0x0060); 
	  HAL_Delay(2);               
	  if(retry++ > 100)
	  { 
#ifdef DEBUG_PRINT
			printf("SCI_AICTRL3 Set Error\r\n");
#endif
			return AICTRL3_ERROR;
	  }
  }		
	
	#if 1
	/* SCI_WRAMADDR SETTING */
	while(VS1063_ReadReg(SCI_WRAMADDR) != 0xE0C0) //Set bitrate to CBR 192 kbit/s
  {
	  VS1063_WriteReg(SCI_WRAMADDR, 0xE0C0); 
	  HAL_Delay(2);               
	  if(retry++ > 100)
	  { 
#ifdef DEBUG_PRINT
			printf("SCI_WRAMADDR Set Error\r\n");
#endif
			return WRAMADDR_ERROR;
	  }
  }
	#else
	while(VS1063_ReadReg(SCI_WRAMADDR) != 0x60A0) //Set bitrate to VBR 160 kbit/s
  {
	  VS1063_WriteReg(SCI_WRAMADDR, 0x60A0); 
	  HAL_Delay(2);               
	  if(retry++ > 100)
	  { 
#ifdef DEBUG_PRINT
			printf("SCI_WRAMADDR Set Error\r\n");
#endif
			return WRAMADDR_ERROR;
	  }
  }
	#endif
	
	/* SCI_MODE SETTING */
	while(VS1063_ReadReg(SCI_MODE) != 0x5000) // SM_RESET | SM_ENCODE | SM_LINE1(LINE1)
	{
		VS1063_WriteReg(SCI_MODE, 0x5004); 
		HAL_Delay(2);
		if(retry++ > 100)
		{
#ifdef DEBUG_PRINT
			printf("SPI MODE Set Error\r\n");
#endif
			return MODE_ERROR;
		}
	}
	VS1063_WriteReg(SCI_VOL, 0x0000); //volume init(maximum volume)
	/* SCI_AIADDR SETTING */
	VS1063_WriteReg(SCI_AIADDR, 0x0050);  // Activate Encoding.
	
	return 1;
}
void Audio_Send_Proc(void)
{
	static uint8_t recBuf[REC_BUFFER_SIZE] = {0, };
	// int volLevel = VS1063_ReadReg(SCI_VOL) & 0xff;
#ifdef DEBUG_PRINT
	// printf("\nvol %1.1fdB", -0.5*volLevel);
#endif
	playerStates = psPlayback;        // Set state to normal playback

	while(playerStates != psStopped)
	{
		int n;
		/* See if there is some data available */
		if((n = VS1063_ReadReg(SCI_HDAT1)) > 0) // Check VS1063A receive buffer size
		{
			uint8_t *pbuf = recBuf;
			int i;
			
			n = min(n, REC_BUFFER_SIZE/2); // REC_BUFFER_SIZE = 512
			
			/* Read encoding data */
			for(i=0; i<n; i++)
			{
				uint16_t w = VS1063_ReadReg(SCI_HDAT0);
				*pbuf++ = (uint8_t)(w>>8);
				*pbuf++ = (uint8_t)(w&0xFF);
			}

			playerStates = psStopped;
			
			/* Transmit USART 2.5MBps */
			UART2_Transmit(recBuf, n); 
			// HAL_Delay(50);
		}
		else
		{
#ifdef DEBUG_PRINT
			printf("Error!\r\n");
#endif
			return;
		}
	}
}
1) Is the Initialization setting correct, Decoding and Encoding ?
2) Is the encoding algorithm from me wrong? Please tell me wroing point.
3) Why n value is 256?
4) Is there any additional parameter information to be set when decoding?
User avatar
pasi
VLSI Staff
Posts: 2123
Joined: Thu 2010-07-15 16:04

Re: VS1063 encoding data from LINE1 input

Post by pasi »

while(VS1063_ReadReg(SCI_MODE) != 0x5000) // SM_RESET | SM_ENCODE | SM_LINE1(LINE1)
Are you intentionally removing the SM_NEWMODE bit from SCI_MODE?

3) "n" is often 256, because you take the minimum of the data available and the record buffer size, which is 512 bytes, i.e. 256 words.

What code does your UART2_Transmit() contain? You're passing in "n", which is words. Are you sending "n" words or "n" bytes (half of what you should send)?
Visit https://www.facebook.com/VLSISolution VLSI Solution on Facebook
EMBED_LU
User
Posts: 6
Joined: Mon 2021-03-15 12:31

Re: VS1063 encoding data from LINE1 input

Post by EMBED_LU »

Thank you for your answer.
Are you intentionally removing the SM_NEWMODE bit from SCI_MODE?
Are SM_NEWMODE and SM_SDINEW the same?
I didn't remove it intentionally., I will set SM_SDINEW bit.
3) "n" is often 256, because you take the minimum of the data available and the record buffer size, which is 512 bytes, i.e. 256 words.
What code does your UART2_Transmit() contain? You're passing in "n", which is words. Are you sending "n" words or "n" bytes (half of what you should send)?
n mean the length of transmitting data in USART2_Transmit()
I just understood. That it's stored two bytes at the same time.
EMBED_LU
User
Posts: 6
Joined: Mon 2021-03-15 12:31

Re: VS1063 encoding data from LINE1 input

Post by EMBED_LU »

I have a few more questions. I set it to CBR mode, but the n value is not fixed.
What's the reason? I want to get a fixed 512 bytes. I will wait for your reply
Thank you.
User avatar
pasi
VLSI Staff
Posts: 2123
Joined: Thu 2010-07-15 16:04

Re: VS1063 encoding data from LINE1 input

Post by pasi »

HDAT1 indicates how much data is in the FIFO to be read. When new mp3 audio frames are encoded, the data is added to the FIFO.

CBR (constant bitrate) means the encoding uses the same number of bytes per mp3 frame. However, for some bitrate/samplerate combination this is on average -- some frames are 1 byte longer than some others. Also, because data is stored in the output FIFO as words, it is not straightforward to read each mp3 frame separately.

But you should not really need to separate the frames. Just read data as soon as it becomes available and send it to the decoder. (Because the encoder and decoder run with different physical crystals, they will have a little frequency difference, so at some point you would like to add samplerate adjustment to the decoder.)

Currently your code reads data as soon as there is at least 1 word to be read. If you want to read larger blocks for the transmission efficiency, just require that there is more data available before you read the data.

Code: Select all

		if((n = VS1063_ReadReg(SCI_HDAT1)) >= 256) // Check VS1063A receive buffer size
Visit https://www.facebook.com/VLSISolution VLSI Solution on Facebook
EMBED_LU
User
Posts: 6
Joined: Mon 2021-03-15 12:31

Re: VS1063 encoding data from LINE1 input

Post by EMBED_LU »

Thank you so much!
Post Reply