Thông báo

Collapse
No announcement yet.

[Helps] LPC1769 và VS1011 audio decoder.

Collapse
X
 
  • Lọc
  • Giờ
  • Show
Clear All
new posts

  • [Helps] LPC1769 và VS1011 audio decoder.

    Chào mấy anh/em,
    Mình đang làm cái project nhỏ vể máy mp3, mới viết tới driver cho VS1011 audio decoder thì bị đứng hình không biết sai chổ nào, mò 2-3 bữa nay rồi. Mong mọi người giúp mình với.
    Mục tiêu: driver cho VS1011 và test âm thanh.
    Phần cứng:
    VS1011 -> LPV1769
    SI -> P0.18
    SO -> P0.17
    SCLK ->P0.15
    DREQ ->P0.21
    xDCS ->P0.19
    xCS ->P0.16
    xRST ->P0.20
    Firmware: (mình dùng IAR)
    Driver:
    Code:
    /**********************************************************************
    * $Id$		vs1011.c					2012-07-02
    *
    * @file		vs1011.c
    * @brief	VS1011 audio decoder driver
    * @MCU		NXP ARM Cortex-M3 LPC1769
    * @version	1.0
    * @date		02. July. 2012
    * @Company  
    * @Website    
    * @author	Sang Mai 
    *
    * @References: THORSTEN PAULY 2007,Luca Pascarella 2009 - www.lucasproject.it	
    *
    * All rights reserved.
    *
    ***********************************************************************/
    #include "lpc17xx_spi.h"
    #include "lpc17xx_libcfg.h"
    #include "lpc17xx_pinsel.h"
    #include "lpc17xx_gpio.h"
    #include "vs1011.h"
    
    /*************************************************
    * SPI Define
    *
    **************************************************/
    #define SPI_Function    PINSEL_FUNC_3
    #define SPI_Port        PINSEL_PORT_0
    #define SPI_SCK         PINSEL_PIN_15
    #define SPI_MISO        PINSEL_PIN_17
    #define SPI_MOSI        PINSEL_PIN_18
    /*************************************************
    * VS1011 Define
    *
    **************************************************/
    #define VS1011_Port     PINSEL_PORT_0
    #define VS1011_Function PINSEL_FUNC_0
    #define VS1011_xCS      PINSEL_PIN_16
    #define VS1011_xDCS     PINSEL_PIN_19
    #define VS1011_xRST     PINSEL_PIN_20
    #define VS1011_DREQ     PINSEL_PIN_21
    /*************************************************
    *
    *General Define
    *
    **************************************************/
    #define Output 1
    #define Input 0
    /*************************************************
    *
    * Local Variable
    *
    **************************************************/
    static unsigned long DREQ_Port;
    // SPI Configuration structure variable
    SPI_CFG_Type SPI_ConfigStruct;
    // SPI Data Setup structure variable
    SPI_DATA_SETUP_Type xferConfig;
    
    /************************************************************************
     * @brief 		SPI and VS1011 Configuration
     * @param[in]	None
     * @return		None
     ***********************************************************************/
    void SPI_Config(void)
    {
        PINSEL_CFG_Type PinCfg;
        //Pin config
        
        /*
    	 * Initialize SPI pin connect
    	 * P0.15 - SCK;
    	 * P0.16 - CS/xCS - used as GPIO
    	 * P0.17 - MISO
    	 * P0.18 - MOSI
         * P0.19 - xDCS/BSYNC -GPIO
         * P0.20 - RESET/xRST - GPIO
         * P0.21 - DREQ - GPIO
        */
        //SPI 
        PinCfg.Funcnum = SPI_Function;
    	PinCfg.OpenDrain = PINSEL_PINMODE_NORMAL;
    	PinCfg.Pinmode = PINSEL_PINMODE_PULLUP;
    	PinCfg.Portnum = SPI_Port;
    	PinCfg.Pinnum = SPI_SCK;
        PINSEL_ConfigPin(&PinCfg);
        PinCfg.Pinnum = SPI_MISO;
        PINSEL_ConfigPin(&PinCfg);
        PinCfg.Pinnum = SPI_MOSI;
        PINSEL_ConfigPin(&PinCfg);
        
        // initialize SPI configuration structure to default
    	SPI_ConfigStruct.CPHA = SPI_CPHA_FIRST;
    	SPI_ConfigStruct.CPOL = SPI_CPOL_LO;
    	SPI_ConfigStruct.ClockRate = 1000000;
    	SPI_ConfigStruct.DataOrder = SPI_DATA_MSB_FIRST;
    	SPI_ConfigStruct.Databit = SPI_DATABIT_8;
    	SPI_ConfigStruct.Mode = SPI_MASTER_MODE;
    
    	// Initialize SPI peripheral with parameter given in structure above
    	SPI_Init(LPC_SPI, &SPI_ConfigStruct);
        
        //GPIO 
        
    	PinCfg.Funcnum = VS1011_Function; //GPIO
        PinCfg.Pinnum = (VS1011_xCS);
    	PINSEL_ConfigPin(&PinCfg);
        PinCfg.Pinnum = (VS1011_xDCS);
    	PINSEL_ConfigPin(&PinCfg);
        PinCfg.Pinnum = (VS1011_xRST);
    	PINSEL_ConfigPin(&PinCfg);
        PinCfg.Pinnum = (VS1011_DREQ);
    	PINSEL_ConfigPin(&PinCfg);
        
        //GPIO Direction
        GPIO_SetDir(VS1011_Port, (1<<VS1011_xCS), Output);//output
        GPIO_SetDir(VS1011_Port, (1<<VS1011_xDCS), Output);//output
        GPIO_SetDir(VS1011_Port, (1<<VS1011_xRST), Output);//output
        GPIO_SetDir(VS1011_Port, (1<<VS1011_DREQ), Input);//input
        
        //SPI config
        
       
        
    }
    /************************************************************************
     * @brief 		Initialize VS1011 - 
     * @param[in]	None
     * @return		None
     ***********************************************************************/
    void VS1011_Init(void)
    {
        xCS_DeSelect();
        xDCS_DeSelect();
        xRST_Enable();
        //delay
        delay();
        xRST_Disable();
        
        
        // enable sinewave test
        VS1011_WriteReg(VS1011_MODE,SineTestEnable); 
        delay();
        while (!ReadDREQ());
        // set clock for VS1011
        VS1011_WriteReg(VS1011_CLOCKF, 0x9800);
        delay();
        while (!ReadDREQ());
        
    }
    
    /************************************************************************
     * @brief 		Drive xCS output.
     * @param[in]	None
     * @return		None
     ***********************************************************************/
    void xCS_DeSelect(void)
    {
       GPIO_SetValue(VS1011_Port, (1<<VS1011_xCS)); 
    }
    
    void xCS_Select(void)
    {
       GPIO_ClearValue(VS1011_Port, (1<<VS1011_xCS)); 
    }
    /************************************************************************
     * @brief 		Drive xDCS output.
     * @param[in]	None
     * @return		None
     ***********************************************************************/
    void xDCS_DeSelect(void)
    {
       GPIO_SetValue(VS1011_Port, (1<<VS1011_xDCS)); 
    }
    
    void xDCS_Select(void)
    {
       GPIO_ClearValue(VS1011_Port, (1<<VS1011_xDCS)); 
    }
    /************************************************************************
     * @brief 		Drive xRESET output.
     * @param[in]	None
     * @return		None
     ***********************************************************************/
    void xRST_Disable(void)
    {
       GPIO_SetValue(VS1011_Port, (1<<VS1011_xRST)); 
    }
    
    void xRST_Enable(void)
    {
       GPIO_ClearValue(VS1011_Port, (1<<VS1011_xRST)); 
    }
    
    /************************************************************************
     * @brief 		Read DREQ Value from VS1011
     * @param[in]	None
     * @return		1 or 0
     ***********************************************************************/
    uint8_t ReadDREQ()
    {
        DREQ_Port = GPIO_ReadValue(VS1011_Port);
        if (( DREQ_Port & VS1011_DREQ) == 0) return 0;
        if (( DREQ_Port & VS1011_DREQ) == 1) return 1;
    }
    /************************************************************************
     * @brief 		Reading data info in SCI data register 
     * @param[in]	Address
     * @return		the value that input address
     ***********************************************************************/
    uint16_t VS1011_ReadReg( uint8_t vAddress)
    {
        uint16_t wValue;
        
        xCS_Select(); //Control register is selected
        SPI_SendData(LPC_SPI, VS1011_SCIRead_Command);
        SPI_SendData(LPC_SPI,vAddress);
        wValue = SPI_ReceiveData(LPC_SPI);
        //((uint8_t*)&wValue)[0] = SPI_ReceiveData(LPC_SPI);
        xCS_DeSelect();
     
        return wValue; //test
    }
    /************************************************************************
     * @brief 		Writing data info in SCI data register 
     * @param[in]	Address, writing value
     * @return		None
     ***********************************************************************/
    void VS1011_WriteReg( uint8_t vAddress, uint16_t wValue)
    {
         unsigned char Data_Buf[4];
        xCS_Select();
        delay();
        SPI_SendData(LPC_SPI, VS1011_SCIWrite_Command);
        SPI_SendData(LPC_SPI,vAddress);
        //SPI_SendData(LPC_SPI, wValue);
        SPI_SendData(LPC_SPI, ((uint8_t*)&wValue)[1]);
        SPI_SendData(LPC_SPI, ((uint8_t*)&wValue)[0]);
        delay();
        
        /*
        Data_Buf[0] = VS1011_SCIWrite_Command;
    	Data_Buf[1] = vAddress;
    	Data_Buf[2] = ((uint8_t*)&wValue)[1];
    	Data_Buf[3] = ((uint8_t*)&wValue)[0];
        xferConfig.tx_data = Data_Buf;
    	xferConfig.rx_data = 0;
    	xferConfig.length = 4;
    	SPI_ReadWrite(LPC_SPI, &xferConfig, SPI_TRANSFER_POLLING);
        */
        xCS_DeSelect();
        
    }
    /************************************************************************
     * @brief 		Enable VS1011 Sine wave test
     * @param[in]	None
     * @return		None
     ***********************************************************************/
    void VS1011_EnableSineTest()
    {
        unsigned char Data_Buf[8];
    
    	Data_Buf[0] = 0x53;
    	Data_Buf[1] = 0xEF;
    	Data_Buf[2] = 0x6E;
    	Data_Buf[3] = 126; //5168 Hz
    	Data_Buf[4] = 0x00;
    	Data_Buf[5] = 0x00;
    	Data_Buf[6] = 0x00;
    	Data_Buf[7] = 0x00;
        
        VS1011_WriteData(Data_Buf, 8);
        
        
        
    }
    
    /************************************************************************
     * @brief 		Disable VS1011 Sine wave test
     * @param[in]	None
     * @return		None
     ***********************************************************************/
    void VS1011_DisableSineTest()
    {
        unsigned char Data_Buf[8];
    
    	Data_Buf[0] = 0x45;
    	Data_Buf[1] = 0x78;
    	Data_Buf[2] = 0x69;
    	Data_Buf[3] = 0x74; //5168 Hz
    	Data_Buf[4] = 0x00;
    	Data_Buf[5] = 0x00;
    	Data_Buf[6] = 0x00;
    	Data_Buf[7] = 0x00;
        
        VS1011_WriteData(Data_Buf, 8);
        
        VS1011_WriteReg(VS1011_MODE,SineTestDisable); //enable sine test condition
        
        
        
    }
    
    /************************************************************************
     * @brief 		VS1011 Soft reset
     * @param[in]	None
     * @return		None
     ***********************************************************************/
    void VS1011_SoftReset()
    {
        VS1011_WriteReg(VS1011_MODE, 0x0806);
        //delay
        delay();
        VS1011_WriteReg(VS1011_CLOCKF, 0x9800);
        
        while (ReadDREQ() == 0);
        
    }
    /************************************************************************
     * @brief 		Writing data to VS1011 data buffer in order to decode it 
     * @param[in]	
     * @return		
     ***********************************************************************/
    void VS1011_WriteData(uint8_t *Data, int len)
    {
        int i;
        //uint8_t temp, ret;
        
        xDCS_Select();
        //delay
        delay();
        for( i= 0; i < len ; i++)
        {
            SPI_SendData(LPC_SPI,Data[i]);
        }
        delay();
        xDCS_DeSelect();
    }
    /************************************************************************
     * @brief 		Delay Function 
     * @param[in]	
     * @return		
     ***********************************************************************/
    void delay(void)
    {
    	
        unsigned int count;
    	
        for(count = 0; count < 10000; count++)
        {
        }
    
    }
    Main:

    Code:
    /**********************************************************************
    * $Id$		main.c					2012-07-02
    *//**
    * @file		main.c
    * @brief	The purpose of this project is to test the interface btw MCU 
    *           and VS1011
    * @MCU		NXP ARM Cortex-M3 LPC1769
    * @version	1.0
    * @date		02. July. 2012
    * @Company   
    * @Website    
    * @author	 Sang Mai
    *
    * @References:
    *
    * All rights reserved.
    *
    ***********************************************************************/
    #include "lpc17xx_spi.h"
    #include "lpc17xx_libcfg.h"
    #include "lpc17xx_pinsel.h"
    #include "lpc17xx_gpio.h"
    
    #include "vs1011.h"
    
    void main(void)
    {
        SPI_Config();
        /*
         * LED Config
         */
        GPIO_SetDir(0, (1<<PINSEL_PIN_22), 1);
        //GPIO_SetValue(0, (1<<PINSEL_PIN_22));
        GPIO_ClearValue(0, (1<<PINSEL_PIN_22));
        
        
        VS1011_Init();
            
        VS1011_EnableSineTest(); 
        
        //xCS_DeSelect();
        //xDCS_DeSelect();
        //xRST_Disable();
        while (1)
        {
           
         
        }
    }
    Mình không tài nào nghe dc âm thanh sinewave khi chay đoạn code này! không biết giao thức SPI mình config và giải thuật có đúng ko.
    Cảm ơn anh/em rất nhìu.
    Last edited by sang84119; 07-07-2012, 11:43.
    Nick: maiphuocsang
    Mail:
    Yêu Điện Tử, Nhưng Không Giỏi Điện Tử...Anh Em Chỉ Giáo!!!

  • #2
    1* driver cho VS1011 sai, thiếu rất nhiều.
    2* SPI LPC1769, sai/thiếu.

    Đây là code tham khảo về driver cho VS1011.
    *.c file
    Code:
    #include "app_config.h"
    
    //SCI Registers
    #define VS_SCI_MODE		0x00	//RW	Mode control
    #define VS_SCI_STATUS	0x01	//RW	Status
    #define VS_SCI_BASS		0x02	//RW	Built-in bass enhancer
    #define VS_SCI_CLOCKF	0x03	//RW	Clock freq+doubler
    #define VS_SCI_DEC_TIME	0x04	//R		Decode time in seconds 
    #define VS_SCI_AUDATA	0x05	//RW	Misc. audio data
    #define VS_SCI_WRAM		0x06	//RW	RAM write
    #define VS_SCI_WRAMADDR	0x07	//RW	Base address for RAM write
    #define VS_SCI_HDAT0	0x08	//R		Stream header data 0
    #define VS_SCI_HDAT1	0x09	//R		Stream header data 1
    #define VS_SCI_AIADDR	0x0A	//RW	Start address of application
    #define VS_SCI_VOL		0x0B	//RW	Volume control
    #define VS_SCI_AICTRL0	0x0C	//RW	Application control register 0
    #define VS_SCI_AICTR11	0x0D	//RW	Application control register 1
    #define VS_SCI_AICTRL2	0x0E	//RW	Application control register 2
    #define VS_SCI_AICTRL3	0x0F	//RW	Application control register 3
    
    #define VS_INS_WRITE	0x02
    #define VS_INS_READ		0x03
    
    #define VS_SPI_WIDTH	8
    
    #ifndef VS_SPI_CLK_DIV
    #define VS_SPI_CLK_DIV	8
    #endif
    
    #define VSSPIInit()		SPIMasterEnable(VS_SPI,SPI_RIS_FIRST,SPI_SAM_FIRST,VS_SPI_CLK_DIV,0,0,VS_SPI_WIDTH - 1); 
    
    typedef enum
    {
    	MP3_FLAG_NULL = 0,
    	MP3_FLAG_START,
    	MP3_FLAG_NORMAL,
    	MP3_FLAG_STOP,
    	MP3_FLAG_JUMP,
    	MP3_FLAG_PAUSE,
    	MP3_FLAG_MUTE,
    	MP3_FLAG_NEXT
    } mp3_flag_t;
    
    mp3_flag_t mp3_flag = MP3_FLAG_NULL;
    
    extern void delay_1ms(unsigned int n);
    
    void VSSCITransfer(unsigned int len, unsigned char *spi_buf);
    void VSSCIWrite(unsigned char ad, unsigned short data);
    unsigned short VSSCIRead(unsigned char ad);
    
    char mp3_file_name[128];
    unsigned char mp3_buf[MP3_LOAD_SIZE];
    unsigned int mp3_buf_p;
    File mp3_file;
    DirList mp3_list;
    char mp3_dir[128];
    
    extern EmbeddedFileSystem efs;
    extern DirList list;
    extern char current_dir[128];
    
    unsigned char file_end = 0;
    unsigned char vol_l = 80;
    unsigned char vol_r = 80;
    
    unsigned long audio_buf_address = 0;
    unsigned char playing_flag = 0;
    unsigned char play_all = 0;
    unsigned char jump_percent = 0;
    
    //void VSSDITransfer(unsigned int len, unsigned char *spi_buf);
    
    void VSReset(void)
    {
    	Clrb(VS_RST_PRTC,VS_RST_PIN);
    	delay_1ms(500);
    	Setb(VS_RST_PRTS,VS_RST_PIN);
    	delay_1ms(100);
    }
    
    void VSInit(void)
    {
    	unsigned char spi_buf[4];
    	spi_buf[0] = 0;
    	spi_buf[1] = 0;
    	spi_buf[2] = 0;
    	spi_buf[3] = 0;
    
    	Orb(VS_CS_DPRT,VS_CS_PIN);
    	Setb(VS_CS_PRTS,VS_CS_PIN);
    	Orb(VS_RST_DPRT,VS_RST_PIN);
    	Clrb(VS_RST_PRTC,VS_RST_PIN);
    	Orb(VS_DCS_DPRT,VS_DCS_PIN);
    	Setb(VS_DCS_PRTS,VS_DCS_PIN);
    
    	VSReset();
    
    	VSSCIWrite(VS_SCI_MODE,0x0804); //soft reset, set to new mode and disable layer 1-2
    	delay_1ms(1);
    	while (!Rdb(VS_DREQ_PINP,VS_DREQ_PIN));
    	//VSSCIWrite(VS_SCI_CLOCKF,); //set if the clock is other than 24.576MHz
    	//delay_1ms(1);
    	//while (!Rdb(VS_DREQ_PINP,VS_DREQ_PIN));
    	VSAudioSetVolume(vol_l,vol_r);
    
    	if ((VSSCIRead(VS_SCI_STATUS) >> 4) == 2)
    	{
    		saystr("\r\nVS1011E found\r\n");
    	}
    	else
    	{
    		saystr("\r\nVS1011E not found\r\n");
    	}
    
    	VSSDITransfer(4,spi_buf);
    
    }
    
    void VSSCITransfer(unsigned int len, unsigned char *spi_buf)
    {
    	VSSPIInit();
    	
    	Clrb(VS_CS_PRTC,VS_CS_PIN);
    	
    	SPIMasterTransfer2(VS_SPI,len,spi_buf);
    	
    	Setb(VS_CS_PRTS,VS_CS_PIN);
    	
    	SPIMasterDisable(VS_SPI);
    }
    
    void VSSCIWrite(unsigned char ad, unsigned short data)
    {
    	unsigned char spi_buf[4];
    	spi_buf[0] = VS_INS_WRITE;
    	spi_buf[1] = ad;
    	spi_buf[2] = data >> 8;
    	spi_buf[3] = data;
    
    	VSSCITransfer(4,spi_buf);
    }
    
    unsigned short VSSCIRead(unsigned char ad)
    {
    	unsigned char spi_buf[4];
    	unsigned short data = 0x00;
    
    	spi_buf[0] = VS_INS_READ;
    	spi_buf[1] = ad;
    
    	VSSCITransfer(4,spi_buf);
    
    	data = spi_buf[2] << 8;
    	data |= spi_buf[3];
    
    	return (data);
    }
    
    void VSSDITransfer(unsigned int len, unsigned char *spi_buf)
    {
    	VSSPIInit();
    	
    	Clrb(VS_DCS_PRTC,VS_DCS_PIN);
    	
    	SPIMasterTransfer2(VS_SPI,len,spi_buf);
    	
    	Setb(VS_DCS_PRTS,VS_DCS_PIN);
    	
    	SPIMasterDisable(VS_SPI);
    }
    
    void VSSineTest(void)
    {
    	unsigned char spi_buf[8];
    
    	spi_buf[0] = 0x53;
    	spi_buf[1] = 0xEF;
    	spi_buf[2] = 0x6E;
    	spi_buf[3] = 126; //5168 Hz
    	spi_buf[4] = 0x00;
    	spi_buf[5] = 0x00;
    	spi_buf[6] = 0x00;
    	spi_buf[7] = 0x00;
    
    	VSSCIWrite(VS_SCI_MODE,0x0820); //enable SDI tests
    	delay_1ms(1);
    	while (!Rdb(VS_DREQ_PINP,VS_DREQ_PIN));
    
    	VSSDITransfer(8, spi_buf);
    
    	delay_1ms(500);
    
    	spi_buf[0] = 0x45;
    	spi_buf[1] = 0x78;
    	spi_buf[2] = 0x69;
    	spi_buf[3] = 0x74;
    	spi_buf[4] = 0x00;
    	spi_buf[5] = 0x00;
    	spi_buf[6] = 0x00;
    	spi_buf[7] = 0x00;
    
    	VSSDITransfer(8, spi_buf);
    
    	VSSCIWrite(VS_SCI_MODE,0x0800); //disable SDI tests
    }
    
    void VSAudioPlayAll(char *dir_name)
    {
    	unsigned char i = 0;
    
    	while (dir_name[i])
    	{
    		mp3_dir[i] = dir_name[i];
    		i++;
    	}
    	mp3_dir[i] = 0;
    
    	if (ls_openDir(&mp3_list, &(efs.myFs) , mp3_dir) != 0)
    	{
    		return;
    	}
    
    	mp3_flag = MP3_FLAG_NEXT;
    	playing_flag = 1;
    	play_all = 1;
    }
    
    void VSAudioPlay(char *file_name, char *dir_name)
    {
    	unsigned char i = 0;
    	unsigned char j = 0;
    
    	while (dir_name[i]) //search for \0
    	{
    		mp3_file_name[i] = dir_name[i];
    		mp3_dir[i] = dir_name[i];
    		i++;
    	}
    	mp3_dir[i] = 0;
    
    	if (i > 1) //file in root don't need '/'
    	{
    		mp3_file_name[i] = '/';
    		i++;
    	}
    	else
    	{
    		i = 0;
    	}
    
    	while (file_name[j])
    	{
    		mp3_file_name[i] = file_name[j];
    		i++;
    		j++;
    	}
    	mp3_file_name[i] = 0;
    
    	mp3_flag = MP3_FLAG_START;
    	playing_flag = 1;
    }
    
    void VSAudioSend(void)
    {
    	unsigned int res;
    	while (Rdb(VS_DREQ_PINP,VS_DREQ_PIN) && (mp3_buf_p < MP3_LOAD_SIZE))
    	{
    		VSSDITransfer(16,mp3_buf+mp3_buf_p);
    		mp3_buf_p += 16;
    	}
    	if (mp3_buf_p >= MP3_LOAD_SIZE)
    	{
    		mp3_buf_p = 0;
    		if (!file_end)
    		{
    			SDSPIInit();
    			res = file_read(&mp3_file,MP3_LOAD_SIZE,mp3_buf);
    			if (res != MP3_LOAD_SIZE)
    			{
    				file_end = 1;	
    			}
    		}
    		else
    		{
    			mp3_flag = MP3_FLAG_STOP;
    		}
    	}
    	while (Rdb(VS_DREQ_PINP,VS_DREQ_PIN) && (mp3_buf_p < MP3_LOAD_SIZE))
    	{
    		VSSDITransfer(16,mp3_buf+mp3_buf_p);
    		mp3_buf_p += 16;
    	}
    }
    
    void VSAudioTask(void)
    {
    	char next_file_name[LIST_MAXLENFILENAME];
    	unsigned char i;
    	unsigned int res;
    	unsigned long buf;
    	if (playing_flag)
    	{
    		switch (mp3_flag)
    		{
    			case MP3_FLAG_START :
    				AppSDInit();
    				res = file_fopen(&mp3_file, &efs.myFs, mp3_file_name, 'r');
    				if (res != 0)
    				{
    					mp3_flag = MP3_FLAG_STOP;
    				}
    				else
    				{
    					mp3_buf_p = 0;
    					mp3_flag = MP3_FLAG_NULL;
    					file_end = 0;
    					res = file_read(&mp3_file,MP3_LOAD_SIZE,mp3_buf);
    					VSAudioSend();
    				}
    				break;
    			case MP3_FLAG_STOP :
    				file_fclose(&mp3_file);
    				if (play_all)
    				{
    					mp3_flag = MP3_FLAG_NEXT;
    				}
    				else
    				{
    					fs_umount(&efs.myFs);
    					playing_flag = 0;
    					mp3_flag = MP3_FLAG_NULL;
    				}
    				break;
    			case MP3_FLAG_JUMP :
    				SDSPIInit();
    				file_fclose(&mp3_file);
    				res = file_fopen(&mp3_file, &efs.myFs, mp3_file_name, 'r');
    				if (res != 0)
    				{
    					mp3_flag = MP3_FLAG_STOP;
    				}
    				else
    				{
    					buf = (mp3_file.FileSize*jump_percent)/100; //get jump size
    					mp3_file.FilePtr = buf;
    					mp3_buf_p = 0;
    					mp3_flag = MP3_FLAG_NULL;
    					file_end = 0;
    					res = file_read(&mp3_file,MP3_LOAD_SIZE,mp3_buf);
    					VSAudioSend();
    				}
    				break;
    			case MP3_FLAG_PAUSE :
    				break;
    			case MP3_FLAG_MUTE :
    				VSAudioSend();
    				break;
    			case MP3_FLAG_NEXT :
    				SDSPIInit();
    				file_fclose(&mp3_file);
    				res = ls_getNext(&mp3_list);
    				if (res == 0)
    				{
    					mp3_list.currentEntry.FileName[LIST_MAXLENFILENAME-1] = '\0';
    					if (((mp3_list.currentEntry.FileName[LIST_MAXLENFILENAME-4]) == 'M') &&
    						((mp3_list.currentEntry.FileName[LIST_MAXLENFILENAME-3]) == 'P') &&
    						((mp3_list.currentEntry.FileName[LIST_MAXLENFILENAME-2]) == '3'))
    					{
    						i = 0;
    						while (mp3_list.currentEntry.FileName[i] != ' ')
    						{
    							next_file_name[i] = mp3_list.currentEntry.FileName[i];
    							i++;
    						}
    						next_file_name[i] = '.';
    						i++;
    						next_file_name[i] = 'M';
    						i++;
    						next_file_name[i] = 'P';
    						i++;
    						next_file_name[i] = '3';
    						i++;
    						next_file_name[i] = 0;
    
    						VSAudioPlay(next_file_name,mp3_dir);
    						//saystr(mp3_list.currentEntry.FileName);
    						//mp3_flag = MP3_FLAG_STOP;
    					}
    
    				}				
    				else
    				{
    					if (ls_openDir(&mp3_list, &(efs.myFs) , mp3_dir) != 0)
    					{
    						mp3_flag = MP3_FLAG_STOP;
    					}
    				}
    				break;
    			default :
    				VSAudioSend();
    				break;
    		}
    	}
    }
    
    void VSAudioCmd(char cmd, unsigned char para)
    {
    	if (!playing_flag)
    	{
    		saystr("\r\nNo playing file\r\n");
    		return;
    	}
    	switch (cmd)
    	{
    		case 'N' : //Next
    			mp3_flag = MP3_FLAG_NEXT;
    			break;
    		case 'S' : //Stop
    			mp3_flag = MP3_FLAG_STOP;
    			play_all = 0;
    			break;
    		case 'J' : //Jump
    			mp3_flag = MP3_FLAG_JUMP;
    			jump_percent = para;
    			if (jump_percent > 99)
    				jump_percent = 99;
    			break;
    		case 'P' : //Pause
    			mp3_flag = MP3_FLAG_PAUSE;
    			break;
    		case 'C' : //Continue
    			mp3_flag = MP3_FLAG_NULL;
    			break;
    		case 'M' : //Mute
    			VSSCIWrite(VS_SCI_VOL,0xFEFE);
    			delay_1ms(1);
    			while (!Rdb(VS_DREQ_PINP,VS_DREQ_PIN));
    			break;
    		case 'L' : //sound enable
    			VSAudioSetVolume(vol_l,vol_r);
    			break;
    		case 'U' : //volume Up
    			VSAudioSetVolume(vol_l+5,vol_r+5);
    			break;
    		case 'D' : //volume Down
    			VSAudioSetVolume(vol_l-5,vol_r-5);
    			break;
    		case 'V' : //set Volume
    			if (para > 99)
    				para = 99;
    			VSAudioSetVolume(para,para);
    			break;
    	}
    }
    
    void VSAudioSetVolume(unsigned char new_vol_l, unsigned char new_vol_r)
    {
    	unsigned short buf;
    	vol_l = new_vol_l;
    	vol_r = new_vol_r;
    
    	buf = 0xFE - (vol_l << 8)/100;
    	buf = buf << 8;
    	buf |= 0xFE - (vol_r << 8)/100;
    		
    	VSSCIWrite(VS_SCI_VOL,buf); //decrese 32 dB for both left and right
    	delay_1ms(1);
    	while (!Rdb(VS_DREQ_PINP,VS_DREQ_PIN));
    }
    
    void VSTest(void)
    {
    	VSSineTest();
    }
    
    unsigned char VSIsPlaying(void)
    {
    	return (playing_flag);
    }
    
    unsigned char VSGetTrackPosition(void)
    {
    	unsigned long current_ptr,file_size;
    
    	file_size = mp3_file.FileSize >> 10; //divide with 1KB
    	current_ptr = mp3_file.FilePtr >> 10; //divide with 1KB
    
    	return (current_ptr*100/file_size);
    }
    *.h file
    Code:
    #ifndef _VS1011B_
    #define _VS1011B_
    
    #ifndef MP3_LOAD_SIZE
    #define MP3_LOAD_SIZE		4096
    #endif
    
    void VSReset(void);
    void VSInit(void);
    void VSSineTest(void);
    void VSTest(void);
    void VSSDITransfer(unsigned int len, unsigned char *spi_buf);
    
    void VSAudioCmd(char cmd, unsigned char para);
    void VSAudioPlay(char *file_name, char *dir_name);
    void VSAudioPlayAll(char *dir_name);
    void VSAudioTask(void);
    void VSAudioSetVolume(unsigned char new_vol_l, unsigned char new_vol_r);
    unsigned char VSIsPlaying(void);
    unsigned char VSGetTrackPosition(void);
    
    #endif
    ***** code của em hình như được xào nấu lại từ code của PIC hặc AVR thì phải code trên của ITX là code chung chung chỉ để tham khảo về cách thiết lập VS1011. ITX như mọi người sẽ chẳng bao giờ có ý định viết driver cho VS1011 trên LPC1700 series đâu bởi vì :
    Việc gì phải xài con chip VS1011 cho phí tiền ? trong khi LPC1769 có thể giải mã trực tiếp được mp3 ?
    Code tham khảo ok tại đây AN11178: MP3 player solution on NXP LPC1700 series | www.LPCware.com
    Từ chối trách nhiệm:
    Mọi thông tin từ ITX cung cấp với hi vọng nó có ích và không đi kèm với bất kì sự bảo đảm nào.
    Blog: http://mritx.blogspot.com

    Comment


    • #3
      Chào a itx,
      A nhận định rất đúng, e xào lại từ mấy cái code e tìm dc trên mạng, chủ yếu là AVR và PIC ^^ và trong đó e cũng có tham khảo code a đưa phía trên.

      Vì mới tiếp xúc với ARM gần được một tháng, nên e chọn đường dể để đi trc, khi làm xong cái này e sẽ làm thử theo cách của a là dùng bộ giải mã trực tiếp của LPC17xx^^.
      A cho e hỏi SPI e sai chổ nào vậy? vì e tham khảo config SPI trong example mẩu của NXP, e xem đi xem lại nhìu lần lắm
      Cảm ơn a rất nhiều, để e sửa lại code e rồi cho a biết kết quả nhé
      Last edited by sang84119; 09-07-2012, 15:33.
      Nick: maiphuocsang
      Mail:
      Yêu Điện Tử, Nhưng Không Giỏi Điện Tử...Anh Em Chỉ Giáo!!!

      Comment

      Về tác giả

      Collapse

      sang84119 Tìm hiểu thêm về sang84119

      Bài viết mới nhất

      Collapse

      Đang tải...
      X