Netduino home hardware projects downloads community

Jump to content


Photo

Spi prblems with vl1053 (mp3 decoder) - SOLVED


  • Please log in to reply
21 replies to this topic

#1 hanzibal

hanzibal

    Advanced Member

  • Members
  • PipPipPip
  • 1287 posts
  • LocationSweden

Posted 28 February 2011 - 02:48 PM

Hi all! Got me a vl1053 bob from sparkfun and hooked it up to my new netduino mini yesterday eve. Stayed up all night trying to get it to talk spi with the vl1053 board. Have tried all different kinds of params for spi.conguration and at best I managed to get reactions, though highly inconsistent semi junk replies when trying to read and write 1053 sci registers. Currently I run spi @ 1 MHz (have tried as low as 10 kHz) with manual xcs (active low chip select on the 1053) through gpio pin 8 of the mini, high idle clock and sample on falling edge. I have pulled up xreset and rx, pulled down gpio0 and gpio1 on the 1053. Im aware of the dreq/xtest bug found on some of these sparkfun bobs but my dreq seem to work and those boards passed sine tests whereas mine doesnt even come that far. The board is said to come out of reset in "new" spi mode, but I cant verify since the replies from reading the sci_mode register is unreliable, which seem to go for pretty much all registers except for sci_vol which on rare occasions behaves as expected. I've tried hw reset, soft reset (the latter produces a popping noise followed by irregular static in my earphones) but so far nothing seem to help. Even tried re-soldering the headers I installed. I clearly get the feeling that spi is misconfigured and line sampling out of clock sync (above config is probably wrong according to docs but thats the only config that produces any reactons or replies from the board at all). Spi is a fairly simple interface, but still. Any ideas anyone?

#2 Chris Walker

Chris Walker

    Secret Labs Staff

  • Moderators
  • 7165 posts
  • LocationNew York, NY

Posted 28 February 2011 - 03:30 PM

Hi hanzibal, Have you upgraded your Netduino Mini to the v4.1.0.6 RC2 or v4.1.1 a7 firmware? There are a number of SPI bugfixes there. Chris

#3 hanzibal

hanzibal

    Advanced Member

  • Members
  • PipPipPip
  • 1287 posts
  • LocationSweden

Posted 28 February 2011 - 03:41 PM

That was quick! Oh, no I haven't, but I sure will. I get back on the results, thanks!

#4 hanzibal

hanzibal

    Advanced Member

  • Members
  • PipPipPip
  • 1287 posts
  • LocationSweden

Posted 28 February 2011 - 09:33 PM

Hi hanzibal,

Have you upgraded your Netduino Mini to the v4.1.0.6 RC2 or v4.1.1 a7 firmware? There are a number of SPI bugfixes there.

Chris

Worked like a charm! :D

Infact, immediately after rebooting from reprogramming the device, an annoyingly loud sine wave came from my earphones. This was somewhat of a surprise since I (as suspected) had configured the spi port the wrong way around in terms of idle clock state and sampling edge.

Anyway, I changed the spi config (low idle clock and rising edge) and my vl1053b now passes the sine test. SPI now seems totally reliable.

Many thanks to you Chris!

Btw, I noticed that I was the first to download then TTL version of v4.1.0.6 RC2, could that really be true?

#5 Chris Walker

Chris Walker

    Secret Labs Staff

  • Moderators
  • 7165 posts
  • LocationNew York, NY

Posted 01 March 2011 - 02:08 AM

Btw, I noticed that I was the first to download then TTL version of v4.1.0.6 RC2, could that really be true?


Could be. :) RC2 is more or less identical to RC1 (just "updated" to match the Netduino firmware).

Chris

#6 hanzibal

hanzibal

    Advanced Member

  • Members
  • PipPipPip
  • 1287 posts
  • LocationSweden

Posted 01 March 2011 - 03:17 AM

Now my mini plays mp3, no sd yet so Im just looping a tiny 8 kHz file but it works. The vl1053 is a small wonder in it self. Almost pulled an all-nighter again, its too hard to stop when you're having this much fun :-)

#7 Chris Walker

Chris Walker

    Secret Labs Staff

  • Moderators
  • 7165 posts
  • LocationNew York, NY

Posted 01 March 2011 - 04:42 AM

Now my mini plays mp3, no sd yet so Im just looping a tiny 8 kHz file but it works. The vl1053 is a small wonder in it self. Almost pulled an all-nighter again, its too hard to stop when you're having this much fun :-)


:) That's awesome.

#8 hanzibal

hanzibal

    Advanced Member

  • Members
  • PipPipPip
  • 1287 posts
  • LocationSweden

Posted 09 March 2011 - 12:06 AM

:) That's awesome.

Thanks, I added an sd card reader today sharing the spi bus with the vs1053. After updating firmware, it kind of works, but sound is pretty chopped up, at least when playing 192 kbps mp3 files. Problems could be related to sharing the bus, bad programming on my behalf or simply insufficient speed causing buffer underflow.

When talking to the vs1053, I run the spi bus at about 10 MHz using manual cs control not involving pin 13.

What is the spi clock speed used when reading the sd card using the new built in sd card functions, i.e. after card detection?

#9 hanzibal

hanzibal

    Advanced Member

  • Members
  • PipPipPip
  • 1287 posts
  • LocationSweden

Posted 15 March 2011 - 12:41 AM

All problems solved, re-wrote chip select functions using built in instead of manual control. Now, music flows and life is good :) Thanks for all the help!

#10 netdruinofreak

netdruinofreak

    New Member

  • Members
  • Pip
  • 2 posts

Posted 19 September 2011 - 11:12 PM

All problems solved, re-wrote chip select functions using built in instead of manual control. Now, music flows and life is good :)

Thanks for all the help!


Hanzibal,
I got the MP3 shield with the SD card. I am trying get the audio to play with the VS1053. I cannot seem to get audio to output. What is you VS1053 setup (MODE, CLOCK, etc...)

I am able to open a file and stream the data via SPI but the audio is not coming out. I just ordered another MP3 shield (just in case I have a bad one).

Please help. Thank you.

Richard

#11 hanzibal

hanzibal

    Advanced Member

  • Members
  • PipPipPip
  • 1287 posts
  • LocationSweden

Posted 14 December 2011 - 01:29 PM

What is you VS1053 setup (MODE, CLOCK, etc...)

Sorry for taking so long to reply - are you still interested in the setup code?

#12 NicholasSTG

NicholasSTG

    Member

  • Members
  • PipPip
  • 16 posts

Posted 15 December 2011 - 04:08 AM

Sorry for taking so long to reply - are you still interested in the setup code?


I'd love to get this code if possible.

#13 hanzibal

hanzibal

    Advanced Member

  • Members
  • PipPipPip
  • 1287 posts
  • LocationSweden

Posted 15 December 2011 - 12:33 PM

I'd love to get this code if possible.

Below is a class that implements initialization of the vs1053b, good luck with it.

using System;
using System.Threading;
using Microsoft.SPOT;
using Microsoft.SPOT.Hardware;
using SecretLabs.NETMF.Hardware;
using SecretLabs.NETMF.Hardware.NetduinoMini;
using System.IO;

class vs1053b
{
    private SPI.Configuration spi_sci;
    private SPI.Configuration spi_sdi;
    private SPI spip;
    private InputPort dreq;
    private OutputPort reset;

    private byte[] wr_buff = { 0, 0, 0, 0 };
    private byte[] rd_buff = { 0, 0 };

    public vs1053b(bool allowTests)
    {
        reset = new OutputPort(Pins.GPIO_PIN_7, true);      // vs1053 reset pin

        dreq = new InputPort(Pins.GPIO_PIN_5, false, Port.ResistorMode.Disabled);   // vs1053 dreq pin

        // serial interface for commands
        spi_sci = new SPI.Configuration(Pins.GPIO_PIN_8,    // xcs on vs1053 (command chip select)
                            false,                          // cs active high/low
                            0,                              // CS Setup time
                            0,                              // CS Hold time
                            false,                          // Clock idle high/low
                            true,               			// Data is sampled on rising/falling edge of clock
                            1000,               			// Clock rate in kHz
                            SPI_Devices.SPI1);

        /// serial interface for music data (to decoder)
        spi_sdi = new SPI.Configuration(Pins.GPIO_PIN_6,    // xdcs (bsync) on vs1053 (data chip select)
                            false,                          // cs active high/low
                            0,                              // CS Setup time
                            0,                              // CS Hold time
                            false,                          // Clock idle high/low
                            true,               			// Data is sampled on rising/falling edge of clock
                            1000,               			// Clock rate in kHz
                            SPI_Devices.SPI1);

        // start with sci
        spip = new SPI(spi_sci);

        Reset();

        // mute
        WriteRegister(0x0B, 0xffff); // analogue drivers off (hw mute)
        Thread.Sleep(1);

        // write to SCI_MODE register @ 0x00 to set SM_SDINEW|SM_LAYER12
        WriteRegister(0x00, 0x0802);
        Thread.Sleep(1);

        // use the vs1053 PLL clock multiplier
        WriteRegister(3, 0x8800);   // 3.5 x XTALI (12,288 MHz) ~ 43 MHz and max 1 extra multiplier 
        Thread.Sleep(100);
        AwaitDREQ();

        // we can now increase sdi speed
        var c = spi_sdi;
        spi_sdi = new SPI.Configuration(c.ChipSelect_Port, c.BusyPin_ActiveState, c.ChipSelect_SetupTime, c.ChipSelect_HoldTime, c.Clock_IdleState, c.Clock_Edge, 5000, c.SPI_mod);

        // 2 bytes of zero as recommended by VLSI
        WriteData(0, 0);

        // turn off bass and treble enhancers
        WriteRegister(0x2, 0x0000);
    }

    private void SelectCommand()
    {
        if (spip.Config != spi_sci)
            spip.Config = spi_sci;
    }

    private void SelectData()
    {
        if (spip.Config != spi_sdi)
            spip.Config = spi_sdi;
    }

    // Write to an  SCI register
    private void WriteRegister(byte address, ushort data, bool waitForDREQ = true)
    {
        wr_buff[0] = 2;                    // write command
        wr_buff[1] = address;              // register
        wr_buff[2] = (byte)(data >> 8);    // high byte
        wr_buff[3] = (byte)(data & 0xff);  // low byte

        if (waitForDREQ) AwaitDREQ();      // wait for dreq to go high
        SelectCommand();       			// select SCI
        spip.Write(wr_buff);
    }

    // SCI read
    private ushort ReadRegister(byte address)
    {
        wr_buff[0] = 3; 		// read command
        wr_buff[1] = address;   // register

        AwaitDREQ();            // wait for dreq to go high
        SelectCommand();        // select SCI
        spip.WriteRead(wr_buff, rd_buff, 2);

        ushort r = rd_buff[0];
        r <<= 8;
        r |= rd_buff[1];

        return r;
    }

    private void AwaitDREQ()
    {
        if (dreq.Read()) return;
        while (!dreq.Read()) ;
    }

    // SDI write
    private void WriteData(params byte[] bytes)
    {
        AwaitDREQ();            // wait for dreq to go high
        SelectData();   		// select SDI
        spip.Write(bytes);
    }

    // hw reset
    private void HardwareReset()
    {
        // reset the 1053
        reset.Write(false);
        Thread.Sleep(1);
        reset.Write(true);
        Thread.Sleep(10);
    }

    // sw reset
    private void SoftReset()
    {
        WriteRegister(0, 0x0804); // SM_SDINEW|SM_RESET 
        Thread.Sleep(1);
        AwaitDREQ();
    }

    public void Reset()
    {
        HardwareReset();
        SoftReset();
    }
}


#14 Mario Vernari

Mario Vernari

    Advanced Member

  • Members
  • PipPipPip
  • 1722 posts
  • LocationVenezia, Italia

Posted 15 December 2011 - 12:50 PM

Hello Hanzibal.
Well, great job indeed...but I'd suggest to avoid to take advantage of the SPI-config "hole". It's a good practice, that may lead to bad results.
If you take a look at the SPI driver (C#, but native as well), there's no way to release correctly the resources (i.e. ports). IMHO, the "Config" property of the SPI class should be read-only.
Rather, I'd use the proper way to open the SPI port, by its constructor. To change config, just dispose the old SPI instance, and create a new one.

Also, implement the IDisposable pattern for correctly release any IDisposable resource (i.e. ports).
Thank you
Cheers
Biggest fault of Netduino? It runs by electricity.

#15 hanzibal

hanzibal

    Advanced Member

  • Members
  • PipPipPip
  • 1287 posts
  • LocationSweden

Posted 15 December 2011 - 02:47 PM

I wasn't aware there was a hole, thanks. However, I only use a single static instance of the class so for me it shouldn't cause any problems. This also applies for the suggested Dispose pattern.

#16 NicholasSTG

NicholasSTG

    Member

  • Members
  • PipPip
  • 16 posts

Posted 15 December 2011 - 10:15 PM

Thanks for the post. I'm at work, but I can't wait to get home and give this a whirl.

#17 hanzibal

hanzibal

    Advanced Member

  • Members
  • PipPipPip
  • 1287 posts
  • LocationSweden

Posted 16 December 2011 - 09:19 PM

You're welcome. The device is initially muted so remember to set an appropriate volume by writing a value of say 0x60 to register 0xB. Use the WriteData class function to send your data (mp3 or other) for the device to play. Good luck!

#18 NicholasSTG

NicholasSTG

    Member

  • Members
  • PipPip
  • 16 posts

Posted 16 December 2011 - 11:50 PM

You're welcome. The device is initially muted so remember to set an appropriate volume by writing a value of say 0x60 to register 0xB.

Use the WriteData class function to send your data (mp3 or other) for the device to play.

Good luck!


Ok, I'm beginning to think I'm not terribly bright. Than you so much for the code, but I cannot seem to make it work. I have the regular Netduino and the Sparkfun Shield with SD Card on board (http://www.sparkfun.com/products/10628). I've managed to read SD cards in a separate project.

Is the board I have the board you've gotten your card to work with? I've changed the pin definitions to match the shield as opposed to the Netduino Mini, and tried several other things I can think of, but it seems to think it's playing (and in a couple of cases I've gotten static, just no sound). The partial success is what lead me to pull the SD card bits out and just try to play an embedded resource, but that did not help (I've been trying the sample files posted on the sparkfun site just since it seemed most likely that those would work).

Would it be possible for you to post a working example of your code playing a file? I'm just going a little crazy after a couple days trying to make this work.

Thanks.

#19 hanzibal

hanzibal

    Advanced Member

  • Members
  • PipPipPip
  • 1287 posts
  • LocationSweden

Posted 17 December 2011 - 12:19 AM

Sorry, I don't know anything about the shield you're using. I'm using a simple vs1053 breakout board and a Netduino mini. Maybe someone else can help you?

#20 NicholasSTG

NicholasSTG

    Member

  • Members
  • PipPip
  • 16 posts

Posted 17 December 2011 - 12:49 AM

Sorry, I don't know anything about the shield you're using. I'm using a simple vs1053 breakout board and a Netduino mini.

Maybe someone else can help you?


Thanks for all your help. I had a feeling the more I stepped through it I was using different hardware.




0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users

home    hardware    projects    downloads    community    where to buy    contact Copyright © 2010-2014 Secret Labs LLC  |  Legal   |   CC BY-SA
This webpage is licensed under a Creative Commons Attribution-ShareAlike License.