This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

VS1053 and NRF52832

Hello. I have SMARTMP3 Board and NRF52832. The vs1053 works fine on the arduino. But it doesn't work on the nrf52832.

I use these connections:

#define SCK_PIN     3
#define MOSI_PIN    4
#define MISO_PIN    28
#define CS_PIN        24

#define MP3_RESET 27
#define MP3_DREQ 23
#define MP3_XCS 24
#define MP3_XDCS 25 //Data Chip Select / BSYNC Pin

VCC to 3.3V (VDD)
GND to GND



For arduino I use this example https://github.com/ARISGames/arduino/blob/master/MP3_Player_Example/MP3_Player_Example.pde , I have also ported this code to the NRF52832, so they are the same. STATUS register should send me 0x48 value, but I receive only 0, that means it doesn't work. The SD Card (this board also has slot for sd card) works fine.

  • Hi Anar, 

    please verify that your connections are correct and that the correct VSxxxx mode is set on the vs1053

    Are you able to perform a logic trace of the SPI pins so that we can verify that the correct commands are sent to the vs1053?

    Lastly, please post the nRF52 code where you intialize the SPI driver and send data to the VS1053.

    Best regards

    Bjørn 

  • Hi Bjorn,

    the connections are okay, because the SD card on the same board works fine.

    I should receive 0x48 (what I receive on the arduino with the same code), but I receive only 0.

    Here is my code :

    /**
     * Copyright (c) 2016 - 2018, Nordic Semiconductor ASA
     * 
     * All rights reserved.
     * 
     * Redistribution and use in source and binary forms, with or without modification,
     * are permitted provided that the following conditions are met:
     * 
     * 1. Redistributions of source code must retain the above copyright notice, this
     *    list of conditions and the following disclaimer.
     * 
     * 2. Redistributions in binary form, except as embedded into a Nordic
     *    Semiconductor ASA integrated circuit in a product or a software update for
     *    such product, must reproduce the above copyright notice, this list of
     *    conditions and the following disclaimer in the documentation and/or other
     *    materials provided with the distribution.
     * 
     * 3. Neither the name of Nordic Semiconductor ASA nor the names of its
     *    contributors may be used to endorse or promote products derived from this
     *    software without specific prior written permission.
     * 
     * 4. This software, with or without modification, must only be used with a
     *    Nordic Semiconductor ASA integrated circuit.
     * 
     * 5. Any software provided in binary form under this license must not be reverse
     *    engineered, decompiled, modified and/or disassembled.
     * 
     * THIS SOFTWARE IS PROVIDED BY NORDIC SEMICONDUCTOR ASA "AS IS" AND ANY EXPRESS
     * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     * OF MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
     * DISCLAIMED. IN NO EVENT SHALL NORDIC SEMICONDUCTOR ASA OR CONTRIBUTORS BE
     * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
     * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
     * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     * 
     */
    /** @file
     * @defgroup fatfs_example_main main.c
     * @{
     * @ingroup fatfs_example
     * @brief FATFS Example Application main file.
     *
     * This file contains the source code for a sample application using FAT filesystem and SD card library.
     *
     */
    
    
    #include "nrf.h"
    #include "bsp.h"
    #include "ff.h"
    #include "diskio_blkdev.h"
    #include "nrf_block_dev_sdc.h"
    #include "nrf_delay.h"
    #include "SEGGER_RTT.h"
    
    
    #include "nrf_log.h"
    #include "nrf_log_ctrl.h"
    #include "nrf_log_default_backends.h"
    #include "nrf_drv_spi.h"
    
    #define FILE_NAME   "NORDIC.TXT"
    #define TEST_STRING "SD card example."
    
    #define SPI_INSTANCE 1
    
    #define SDC_SCK_PIN     3  ///< SDC serial clock (SCK) pin. 25   14
    #define SDC_MOSI_PIN    4 ///< SDC serial data in (DI) pin. 23  13
    #define SDC_MISO_PIN    28  ///< SDC serial data out (DO) pin. 24 12
    #define SDC_CS_PIN      24   ///< SDC chip select (CS) pin. 22    11
    
    #define MP3_RESET 27
    #define MP3_DREQ 23
    #define MP3_XCS 24
    #define MP3_XDCS 25 //Data Chip Select / BSYNC Pin
    
    //VS10xx SCI Registers
    #define SCI_MODE 0x00
    #define SCI_STATUS 0x01
    #define SCI_BASS 0x02
    #define SCI_CLOCKF 0x03
    #define SCI_DECODE_TIME 0x04
    #define SCI_AUDATA 0x05
    #define SCI_WRAM 0x06
    #define SCI_WRAMADDR 0x07
    #define SCI_HDAT0 0x08
    #define SCI_HDAT1 0x09
    #define SCI_AIADDR 0x0A
    #define SCI_VOL 0x0B
    #define SCI_AICTRL0 0x0C
    #define SCI_AICTRL1 0x0D
    #define SCI_AICTRL2 0x0E
    #define SCI_AICTRL3 0x0F
    
    static const nrf_drv_spi_t m_spi1 = NRF_DRV_SPI_INSTANCE(SPI_INSTANCE);
    
    static uint8_t rx_buffer[] = {0, 0};
    static FIL file;
    
    typedef struct {
        uint16_t length;
        uint8_t data[32];
    } fatfs_read_buffer_t;
    
    static fatfs_read_buffer_t fatfs_read_buffer = {.length = 0, .data = {0x00}};
    
    /**
     * @brief  SDC block device definition
     * */
    NRF_BLOCK_DEV_SDC_DEFINE(
            m_block_dev_sdc,
            NRF_BLOCK_DEV_SDC_CONFIG(
                    SDC_SECTOR_SIZE,
                    APP_SDCARD_CONFIG(SDC_MOSI_PIN, SDC_MISO_PIN, SDC_SCK_PIN, SDC_CS_PIN)
             ),
             NFR_BLOCK_DEV_INFO_CONFIG("Nordic", "SDC", "1.00")
    );
    
    /**
     * @brief Function for demonstrating FAFTS usage.
     */
    static void fatfs_example()
    {
        static FATFS fs;
        static DIR dir;
        static FILINFO fno;
    
        FRESULT ff_result;
        DSTATUS disk_state = STA_NOINIT;
    
        // Initialize FATFS disk I/O interface by providing the block device.
        static diskio_blkdev_t drives[] =
        {
                DISKIO_BLOCKDEV_CONFIG(NRF_BLOCKDEV_BASE_ADDR(m_block_dev_sdc, block_dev), NULL)
        };
    
        diskio_blockdev_register(drives, ARRAY_SIZE(drives));
    
        NRF_LOG_INFO("Initializing disk 0 (SDC)...");
        for (uint32_t retries = 10; retries && disk_state; --retries)
        {
            disk_state = disk_initialize(0);
        }
        if (disk_state)
        {
            NRF_LOG_INFO("Disk initialization failed.");
            return;
        }
    
        uint32_t blocks_per_mb = (1024uL * 1024uL) / m_block_dev_sdc.block_dev.p_ops->geometry(&m_block_dev_sdc.block_dev)->blk_size;
        uint32_t capacity = m_block_dev_sdc.block_dev.p_ops->geometry(&m_block_dev_sdc.block_dev)->blk_count / blocks_per_mb;
        NRF_LOG_INFO("Capacity: %d MB", capacity);
    
        NRF_LOG_INFO("Mounting volume...");
        ff_result = f_mount(&fs, "", 1);
        if (ff_result)
        {
            NRF_LOG_INFO("Mount failed.");
            return;
        }
    
        NRF_LOG_INFO("\r\n Listing directory: /");
        ff_result = f_opendir(&dir, "/");
        if (ff_result)
        {
            NRF_LOG_INFO("Directory listing failed!");
            return;
        }
    
        do
        {
            ff_result = f_readdir(&dir, &fno);
            if (ff_result != FR_OK)
            {
                NRF_LOG_INFO("Directory read failed.");
                return;
            }
    
            if (fno.fname[0])
            {
                if (fno.fattrib & AM_DIR)
                {
                    NRF_LOG_RAW_INFO("   <DIR>   %s",(uint32_t)fno.fname);
                }
                else
                {
                    NRF_LOG_RAW_INFO("%9lu  %s", fno.fsize, (uint32_t)fno.fname);
                }
            }
        }
        while (fno.fname[0]);
        NRF_LOG_RAW_INFO("");
    		
    		NRF_LOG_RAW_INFO("\n");
    /*
        NRF_LOG_INFO("Writing to file " FILE_NAME "...");
        ff_result = f_open(&file, FILE_NAME, FA_READ | FA_WRITE | FA_OPEN_APPEND);
        if (ff_result != FR_OK)
        {
            NRF_LOG_INFO("Unable to open or create file: " FILE_NAME ".");
            return;
        }
    
        ff_result = f_write(&file, TEST_STRING, sizeof(TEST_STRING) - 1, (UINT *) &bytes_written);
        if (ff_result != FR_OK)
        {
            NRF_LOG_INFO("Write failed\r\n.");
        }
        else
        {
            NRF_LOG_INFO("%d bytes written.", bytes_written);
        }
              
        (void) f_close(&file);*/
        return;
    }
    
    
    void playMP3(char* fileName)
    {
      int need_data = 1; 
    	FRESULT ff_result;
    	uint32_t bytes_read;
    	fatfs_example();
    
      while(1) {	        
                ff_result = f_open(&file, fileName, FA_READ);
    					
                if (ff_result != FR_OK)
                {
    							NRF_LOG_INFO("Unable to open file \n");
    							return;
                }
    		
        //while(!nrf_gpio_pin_read(MP3_DREQ)) 
    						nrf_delay_ms(10);
    			{ 
    
          //If the MP3 IC is happy, but we need to read new data from the SD, now is a great time to do so
          if(need_data == 1) {
    				if((ff_result = f_read(&file, fatfs_read_buffer.data, fatfs_read_buffer.length, &bytes_read)) != FR_OK)
    				break;
            //Data reading ----------------------------
            //if no data break-------------------------
            need_data = 0;
          }
    
          nrf_delay_ms(100); //Do NOTHING - sounds fine
        }
    
    
        if(need_data == 1){ //This is here in case we haven't had any free time to load new data
    			if((ff_result = f_read(&file, fatfs_read_buffer.data, fatfs_read_buffer.length, &bytes_read)) != FR_OK)
    				break;
          //Data read-----------------------------
          //if no data break----------------------
          need_data = 0;
        }
    
        //Once DREQ is released (high) we now feed 32 bytes of data to the VS1053 from our SD read buffer
        nrf_gpio_pin_clear(MP3_XDCS); //Select Data
        //for(int y = 0 ; y < sizeof(fatfs_read_buffer.data) ; y++)
    		{
          // Send SPI byte
    			nrf_drv_spi_transfer(&m_spi1, fatfs_read_buffer.data, sizeof(fatfs_read_buffer.data), rx_buffer, sizeof(rx_buffer));
        }
    
        nrf_gpio_pin_set(MP3_XDCS); //Deselect Data
        need_data = 1; //We've just dumped 32 bytes into VS1053 so our SD read buffer is empty. Set flag so we go get more data
      }
    
     // while(!nrf_gpio_pin_read(MP3_DREQ)) ; //Wait for DREQ to go high indicating transfer is complete
    	nrf_delay_ms(10);
      nrf_gpio_pin_set(MP3_XDCS); //Deselect Data
      
      //Close out this track
    	
    	NRF_LOG_INFO("end of the song");
    	
    	f_close(&file);
    }
    
    
    uint8_t Mp3ReadRegister (uint8_t addressbyte){
      while(!nrf_gpio_pin_read(MP3_DREQ)){}; //Wait for DREQ to go high indicating IC is available
      // nrf_gpio_pin_clear(MP3_XCS); //here
    		nrf_delay_ms(10);
      //SCI consists of instruction byte, address byte, and 16-bit data word.
      nrf_drv_spi_transfer(&m_spi1, (uint8_t*)0x03, sizeof(uint8_t), NULL, sizeof(uint8_t));
      nrf_drv_spi_transfer(&m_spi1, &addressbyte, sizeof(uint8_t), NULL, sizeof(uint8_t));
    	
      nrf_drv_spi_transfer(&m_spi1, (uint8_t*)0xFF, sizeof(uint8_t), &rx_buffer[0], sizeof(uint8_t));
    	while(nrf_gpio_pin_read(MP3_DREQ)){}; //Wait for DREQ to go high indicating IC is available
      nrf_drv_spi_transfer(&m_spi1, (uint8_t*)0xFF, sizeof(uint8_t), &rx_buffer[1], sizeof(uint8_t));
    	while(nrf_gpio_pin_read(MP3_DREQ)){}; //Wait for DREQ to go high indicating IC is available
    	
      int resultvalue = rx_buffer[0] << 8;
      resultvalue |= rx_buffer[1];
    	
    	//nrf_gpio_pin_set(MP3_XCS); //here
    	
      return resultvalue;
    }
    
    
    
    
    //Set VS10xx Volume Register
    void Mp3SetVolume(uint8_t leftchannel, uint8_t rightchannel){
      Mp3WriteRegister(SCI_VOL, leftchannel, rightchannel);
    }
    
    
    /**
     * @brief Function for main application entry.
     */
    int main(void)
    {
        bsp_board_init(BSP_INIT_LEDS);
    
        APP_ERROR_CHECK(NRF_LOG_INIT(NULL));
        NRF_LOG_DEFAULT_BACKENDS_INIT();
    
        SEGGER_RTT_Init ();
        SEGGER_RTT_SetTerminal(0);
    
        //NRF_LOG_INFO("\n\n\n\nFATFS example started. new8");  
        SEGGER_RTT_TerminalOut(0, "\nInitialization\n");
    
        //fatfs_example();	  
    	
              nrf_gpio_cfg_output(MP3_RESET);
    	  nrf_gpio_cfg_output(MP3_XDCS);
    	//  nrf_gpio_cfg_output(MP3_XCS);
    	  nrf_gpio_cfg_input(MP3_DREQ, NRF_GPIO_PIN_PULLDOWN);
    	
    	  nrf_drv_spi_config_t spi_config = NRF_DRV_SPI_DEFAULT_CONFIG;
        spi_config.ss_pin   = MP3_XCS;
        spi_config.miso_pin = SDC_MISO_PIN;
        spi_config.mosi_pin = SDC_MOSI_PIN;
        spi_config.sck_pin  = SDC_SCK_PIN;
    	  spi_config.frequency = SPI_FREQUENCY_FREQUENCY_M1;
        APP_ERROR_CHECK(nrf_drv_spi_init(&m_spi1, &spi_config, NULL, NULL));
    		
    		nrf_gpio_pin_clear(MP3_RESET);
    		nrf_gpio_pin_set(MP3_XDCS);
    		//nrf_gpio_pin_set(MP3_XCS);
    		
    		nrf_delay_ms(10);   
    	
    	  nrf_gpio_pin_set(MP3_RESET); //Bring up VS1053
    		
    		while(!nrf_gpio_pin_read(MP3_DREQ)){};
    		
    		nrf_drv_spi_transfer(&m_spi1, (uint8_t*)0xFF, sizeof(uint8_t), NULL, sizeof(uint8_t));
    		
    		nrf_delay_ms(10);
    		
    		//NRF_SPI0->FREQUENCY = SPI_FREQUENCY_FREQUENCY_M4;
    		
    		//Mp3WriteRegister(SCI_CLOCKF, 0x60, 0x00); //Set multiplier to 3.0x
    		
    		int k = Mp3ReadRegister(SCI_STATUS);
    		
    		//NRF_LOG_INFO("status = %d\n status2 = %d", ((k >> 4) & 0x0F), k);
                    char str[255];
    
                    sprintf(str, "\nstatus = %d\n", k);
    
                    SEGGER_RTT_TerminalOut(0, str);
    			
    			
    		
    		//Mp3SetVolume(20, 20); //Set initial volume (20 = -10dB) LOUD
    		
    	//	fatfs_example();	
    		
    /*
      Mp3SetVolume(20, 20); //Set initial volume (20 = -10dB) LOUD
    	
    	int MP3Mode = Mp3ReadRegister(SCI_MODE);
      int MP3Status = Mp3ReadRegister(SCI_STATUS);
      int MP3Clock = Mp3ReadRegister(SCI_CLOCKF);
    	
    	Mp3WriteRegister(SCI_CLOCKF, 0x60, 0x00); //Set multiplier to 3.0x
    	
    	MP3Clock = Mp3ReadRegister(SCI_CLOCKF);
    */
     //playMP3("track.mp3");
    
        while (true)
        {
            __WFE();
        }
    }
    
    /** @} */
    

  • OK, are you able to do a logic trace of the SPI lines? 

    Also you should add APP_ERROR_CHECKs to your nrf_drv_spi_transfer() calls in Mp3ReadRegister(), i.e. 

    APP_ERROR_CHECK(nrf_drv_spi_transfer(&m_spi1, (uint8_t*)0xFF, sizeof(uint8_t), &rx_buffer[0], sizeof(uint8_t)));

    that way the code will assert if any of the transfers return an error code. 

  • Done.

    It gives me an error on the first transfer in Mp3ReadRegister();

    APP_ERROR_CHECK(nrf_drv_spi_transfer(&m_spi1, (uint8_t *)0x03, sizeof(uint8_t), NULL, sizeof(uint8_t))); //here

Related