Pages: [1]   Go Down
Author Topic: Arduino+ VS1053 + SPI problems  (Read 8339 times)
0 Members and 1 Guest are viewing this topic.
0
Offline Offline
Newbie
*
Karma: 0
Posts: 4
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi

I ve been trying to get SPI to work for some time now with the VS1053B Data=http://www.vlsi.fi/fileadmin/datasheets/vlsi/vs1053.pdf vlsi mp3 chip BUT cant! I wonder if anyone can direct me as to where I am going wrong.

I am using an arduino mega + a sparkfun VS1053B breakout board  data=http://www.sparkfun.com/datasheets/BreakoutBoards/VS1053-v13.pdf
Pins
Arduino-->Breakout

50    --->SO
51    --->SI
52    --->SCLK
53    --->CS
5V   ---->VCC
GND ---> GND

Also LEFT -->Speaker
       GBUF --> Speaker

Wanted to see if I can do the sine test:
Code:
//Connection vs1053b to Arduino mega

#define DATAOUT 51//MOSI
#define DATAIN 50//MISO -
#define SPICLOCK  52//sck
#define SLAVESELECT 53//ss

byte clr;
char spi_transfer(volatile char data)
{
  SPDR = data;                    // Start the transmission
  while (!(SPSR & (1<<SPIF)))     // Wait the end of the transmission
  {
  };
  return SPDR;                    // return the received byte
}

void setup()
{
  pinMode(DATAOUT, OUTPUT);
  pinMode(DATAIN, INPUT);
  pinMode(SPICLOCK,OUTPUT);
  pinMode(SLAVESELECT,OUTPUT);
  digitalWrite(SLAVESELECT,HIGH); //disable device
  // SPCR = 01010000
  //interrupt disabled,spi enabled,msb 1st,master,clk low when idle,
  //sample on leading edge of clk,system clock/16 (fastest)
  //The VS1053 spec states that the max SPI clock frequency is 5MHz, the data order is MSB, and the data is valid on
  //the rising edge of the clock, so the default settings of the SPI Shortcut (500kHz, MSB, rising edge) are applicable.
  // SPR0 set to 1 means 16/16 =1 MHz
   SPCR = (1<<SPE)|(1<<MSTR) | (1<<SPR0) | (0<<CPOL) | (0<<CPHA) | (0<<DORD);
  clr=SPSR;
  clr=SPDR;
  delay(10);

digitalWrite(SLAVESELECT,LOW);
spi_transfer(0x02);
spi_transfer(0x00);
spi_transfer(0x0c); //bits 8-15    
spi_transfer(0x20);  // bits 0-7  00100000  //allow SDI TESTs
digitalWrite(SLAVESELECT,HIGH);
delay(10);

//Once in Test mode SS should remain HIGH
spi_transfer(0x53);
spi_transfer(0xEF);
spi_transfer(0x6E);
spi_transfer(0xAA);
spi_transfer(0x00);
spi_transfer(0x00);
spi_transfer(0x00);
spi_transfer(0x00);



}


void loop()
{
    
}


The expectation is that once this is run I should hear a sine wave in the speaker....but I cant. Can anyone see an obvious flaw?

Thanks in advance
Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 1
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hey jaybay,

I am similarly befuddled.  Did you manage to solve your problem?  Or, have you considered using Arduino's SPI Library: http://www.arduino.cc/playground/Code/Spi
« Last Edit: August 24, 2009, 07:56:12 pm by ladyobsolete » Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 4
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi uploading,

yes I tried a few SPI libraries with no luck! Still looking for a solution.

BW

Jaybay
Logged

Germany
Offline Offline
Full Member
***
Karma: 8
Posts: 117
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi,

How did you connect the other pins: Reset and DCS? You can also check the DREQ pin if it goes high after a reset.

Regards,
Andreas
Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 6
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

wish u good luck, I am also look forward to tackling the communication of vs1003 to SD module by Arduino Duemilanove
Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 2
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi,

any news on this? I am also thinking about a project based on the VS1053. Because I am an absolute beginner, I wanted Arduino to be the base for my first experiments, but I would prefer to know if it works at all before I buy an Arduino Board.

Thanks a lot in advance for any answer.
Joerg
Logged

0
Offline Offline
Jr. Member
**
Karma: 0
Posts: 50
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi Jaybay,

Just thinking, are you able to read back from the status registers? So you could verify whether the writing to codec is correct or not.


Cheers,

Joseph
Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 4
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I had the same problem. The SparkFun breakout board ties the XRESET pin to ground via a 100K resistor. You won't be able to do anything until you bring that pin high.

Hope this helps!
Logged

0
Offline Offline
Full Member
***
Karma: 0
Posts: 147
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
Pins
Arduino-->Breakout

50    --->SO
51    --->SI
52    --->SCLK
53    --->CS
5V   ---->VCC
GND ---> GND

Connect RESET to the RESET-pin on the Arduino too. And connect DREQ to a input pin on the Arduino. With the 1053 you need to check that DREQ is high before you write anything to it.

Quote
Also LEFT -->Speaker
      GBUF --> Speaker

What kind of speaker? The VS is not capable of driving a normal speaker element directly. Connect 30Ohm headphones instead, or connect it to an amplifier.

Also, make sure that the NEWMODE-bit is set in the mode-register. If this bit is cleared, the vs1053 enters vs1001-mode which is quite different.
Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 2
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

This is a modified code I tried, taking care of your hints and adding comments, but I also don´t get it to work with an Arduino Mega. However, because I am new to Arduino and microcontroller programming, this does not neccessarily have to mean anything...  smiley.

Code:
//Connection vs1053b to Arduino mega

#define DATAOUT 51//MOSI
#define DATAIN 50//MISO -
#define SPICLOCK  52//sck
#define SLAVESELECT 53//ss
#define DREQ 49 //DREQ
#define VSRESET 48

byte clr;
char spi_transfer(volatile char data)
{
  SPDR = data;                    // Start the transmission
  while (!(SPSR & (1<<SPIF)))     // Wait the end of the transmission
  {
  };
  return SPDR;                    // return the received byte
}

void setup()
{
  pinMode(VSRESET, OUTPUT);
  digitalWrite(VSRESET, HIGH);
  pinMode(DATAOUT, OUTPUT);
  pinMode(DATAIN, INPUT);
  pinMode(SPICLOCK,OUTPUT);
  pinMode(SLAVESELECT,OUTPUT);
  pinMode(DREQ, INPUT);
  digitalWrite(SLAVESELECT,HIGH); //disable device
  // SPCR = 01010000
  //interrupt disabled,spi enabled,msb 1st,master,clk low when idle,
  //sample on leading edge of clk,system clock/16 (fastest)
  //The VS1053 spec states that the max SPI clock frequency is 5MHz, the data order is MSB, and the data is valid on
  //the rising edge of the clock, so the default settings of the SPI Shortcut (500kHz, MSB, rising edge) are applicable.
  // SPR0 set to 1 means 16/16 =1 MHz
  SPCR = (1<<SPE)|(1<<MSTR) | (1<<SPR0) | (0<<CPOL) | (0<<CPHA) | (0<<DORD);
  clr=SPSR;
  clr=SPDR;
  delay(1000);

digitalWrite(SLAVESELECT,LOW);
spi_transfer(0x02); // instruction byte set to "write"
spi_transfer(0x00); // address byte = 0
spi_transfer(0x0c); // bits 08-15  00001100  // SM_SDISHARE, SM_SDINEW (share SPI chip select, VS1002 native SPI modes)
spi_transfer(0x20); // bits 00-07  00100000  // SM_TESTS (allow SDI tests)
digitalWrite(SLAVESELECT,HIGH);
delay(1000);

//Once in Test mode SS should remain HIGH
digitalWrite(SLAVESELECT,HIGH);
spi_transfer(0x53); // this and the following two bytes are the command for sine test (p. 63)
spi_transfer(0xEF); // ^
spi_transfer(0x6E); // ^
//spi_transfer(0xAA); // 10101010 = Samplerate index (10?) + sine skip speed (10)
spi_transfer(0x7E); // for a sine wave test @ 5168 hz
spi_transfer(0x00); // needs to be 0x00
spi_transfer(0x00); // ^
spi_transfer(0x00); // ^
spi_transfer(0x00); // ^
digitalWrite(SLAVESELECT,LOW);
delay(1000);
digitalWrite(SLAVESELECT,HIGH);
spi_transfer(0x45); // exit sine test (p. 63)
spi_transfer(0x78); // ^
spi_transfer(0x69); // ^
spi_transfer(0x74); // ^
spi_transfer(0x00); // ^
spi_transfer(0x00); // ^
spi_transfer(0x00); // ^
spi_transfer(0x00); // ^
digitalWrite(SLAVESELECT,LOW);
}


void loop()
{
    
}

Any more hints what could be wrong? I also had connected the reset pin of the VS1053 board to the reset pin of Arduino, but still no success using iPod headphones.

This is a part of the example code available at  http://www.sparkfun.com/datasheets/PCB/vs1002_Sine_Test_Tone.c:
Code:
int      main (void) {

    // configure SPI0 pins,   master mode
      PINSEL0      = 0x1500;                        // SPI pin connections
        S0SPCCR = 32;                          // SCK = 1 MHz, counter > 8 and even
        S0SPCR  = 0x20;                      // Master, no interrupt enable
      
      IODIR0 |= 0x00000080;

 
       IOSET0 |= 0x80000080;   // cs high to start

       vs1002_SCI_write(0x00, 0x0c20);             // sets sci_mode register, SM_SDINEW, SM_SDISHARE
                                                                   // SM_TESTS.  pg 25, 26

       vs1002_sineTest(170);   // test tone frequency (pg 35)
       
      for (;;)
      {

      }
}   //main

void vs1002_SCI_write(unsigned char address, unsigned short int data)
{            
      IOCLR0 |= 0x00000080;                  // cs low
      
      S0SPDR  = 0x02;                      // read command
         while (!(S0SPSR & 0x80)) ;           // wait for transfer completed            
         
      S0SPDR  = address;                  // address here
         while (!(S0SPSR & 0x80)) ;           // wait for transfer completed      

      S0SPDR  = data >> 8;                
         while (!(S0SPSR & 0x80)) ;          // wait for transfer completed

      S0SPDR  = data;                
         while (!(S0SPSR & 0x80)) ;          // wait for transfer completed      

         IOSET0 |= 0x00000080;
            
}

// This is SDI write so cs is reversed (internally inverted), pg 21
// for a sine wave test @ 5168 hz, send sequence: 0x53, 0xEF, 0x6E, 126, 0, 0, 0, 0
void vs1002_sineTest(unsigned char pitch)
{
      IOSET0 |= 0x00000080;                  // cs HIGH
      
      S0SPDR  = 0x53;                
         while (!(S0SPSR & 0x80)) ;           // wait for transfer completed            
         
      S0SPDR  = 0xEF;            
         while (!(S0SPSR & 0x80)) ;           // wait for transfer completed      

      S0SPDR  = 0x6E;                
         while (!(S0SPSR & 0x80)) ;          // wait for transfer completed

      S0SPDR  = pitch;                
         while (!(S0SPSR & 0x80)) ;          // wait for transfer completed      
         
       S0SPDR  = 0;                
         while (!(S0SPSR & 0x80)) ;           // wait for transfer completed            
         
      S0SPDR  = 0;            
         while (!(S0SPSR & 0x80)) ;           // wait for transfer completed      

      S0SPDR  = 0;                
         while (!(S0SPSR & 0x80)) ;          // wait for transfer completed

      S0SPDR  = 0;                
         while (!(S0SPSR & 0x80)) ;          // wait for transfer completed      

         IOCLR0 |= 0x00000080;                  // cs LOW
}
Logged

Singapore
Offline Offline
Newbie
*
Karma: 0
Posts: 2
dan the man
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Hello,

I've also tried to interface with one of the SPF MP3 breakout boards, although mine is built around a VS1002 and my Arduino is a duemilanove. And I also can not get it to work  :-/

I tried to upload your updated sketch, only changed the pins to:

Code:
#define DATAOUT 11//MOSI
#define DATAIN 13//MISO -
#define SPICLOCK  12//sck
#define SLAVESELECT 9//ss
#define DREQ 8 //DREQ
#define VSRESET 7

My connections are (AVR -> vs1002):

v3.3 -> +vin
GND -> GND
DigitalPin7 -> RST (converted to lower voltage with 1.8k and 3.0k resistor)
DigitalPin8 -> DREQ
DigitalPin9 -> CS (converted to lower voltage with 1.8k and 3.0k resistor)
DigitalPin11 -> SI (converted to lower voltage with 1.8k and 3.0k resistor)
DigitalPin12 -> CLK (converted to lower voltage with 1.8k and 3.0k resistor)
DigitalPin13 -> SO

I realize that my voltage conversion is a little bit off, and the resulting output is closer to 3.17v when I check it. Is this the problem? If I understand things correctly I shouldn't have to convert the (AVR side) input pins, since the 3.3v output from the vs1002 should be higher than needed to detect a high signal, right?

BTW, as far as I can tell when it come to this simple test vs1002 and vs1053b should be fairly similar, but I could be wrong.

I've also looked at superjazz tutorial (not allowed to post link yet) but also to no avail.

Anybody here that can shed any light on this, or can point to some other person successfully interfacing with any Arduino to one of these MP3 breakouts?

Huge thanks
Logged

Singapore
Offline Offline
Newbie
*
Karma: 0
Posts: 2
dan the man
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

I managed to solve my problems. Don't know if anybody still has problems with their VS1xxx breakout boards connecting to an Arduino but if so I wrote a little guide on how to set it up.

Please check it out at http://www.dannyboy.se/blog/?p=244.

In short, what threw me off was the fact that I didn't wait any time between setting the CS signal so my VS1002 wasn't ready when sending data.
Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 1
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

FYI: I'm a newbie - be gentle. :-)

I am doing something very similar. I am trying to turn on the sine wave test then turn it off, repeating the process. The following code does turn the sine on/off but also acts erratically (clicks, pops, different pitches and changes in delay times). If someone could tell me what is missing or just fix my code, I would greatly appreciate it. My goal is to create the most simplified and straightforward code approach so I can learn more about the logic being employed and how the SPI bus works. I'm just interested in a very basic walk-through of turning the sine test on then off. I want to make it work properly but I don't want anything fancy. Thank you in advance for your help.

This code based on: supertechman.blogspot.com/2010/09/arduino-and-sparkfun-mp3-shield-test.html

Arduino UNO w/ Sparkfun vs1053b shield

Arduino IDE Code:

#include <SPI.h>

int CS_pin = 9;
int DREQ_pin = 3;
byte received;

void setup()
{
  pinMode(CS_pin, OUTPUT);
  pinMode(DREQ_pin, INPUT);
  
  SPI.begin();
  SPI.setBitOrder(MSBFIRST);
  //CPOL = 0, CPHA = 1
  //see en.wikipedia.org/wiki/Serial_Peripheral_Interface_Bus#Mode_Numbers
  //and decoder chip datasheet
  SPI.setDataMode(SPI_MODE1);
  //max SDI clock freq = CLKI/7 and (datasheet) CLKI = 36.864, hence max clock = 5MHz
  //SPI clock arduino = 16MHz. 16/ 4 = 4MHz -- ok!
  SPI.setClockDivider(SPI_CLOCK_DIV4);
 
}

void loop()
{
  digitalWrite(CS_pin, HIGH);
  delay(5);

  // CHIP Write
  // sets sci_mode register, SM_SDINEW, SM_SDISHARE, SM_TESTS.  pg 25, 26
  byte aux;
  digitalWrite(CS_pin, LOW);
  delay(1);
  SPI.transfer(0x02);  //write command
  SPI.transfer(0x00); //SDI_MODE register
  //extract and send higher byte of data
  aux = 0x0c20 >> 8;
  SPI.transfer(aux);
  //extract and send lower byte of data
  aux = 0x0c20 & 0b11111111;
  SPI.transfer(aux);
  //wait for the chip to finish executing command
  while (!DREQ_pin){};
  digitalWrite(CS_pin, HIGH);
  delay(1);

  // Start SINE test
  digitalWrite(CS_pin, HIGH);
  delay(1);
  SPI.transfer(0x53);
  SPI.transfer(0xEF);
  SPI.transfer(0x6E);
  SPI.transfer(0xAA); // 44100 Hz test tone frequency (pg 35)
  SPI.transfer(0);
  SPI.transfer(0);
  SPI.transfer(0);
  SPI.transfer(0);
 
  delay(200);

  // EXIT SINE test
  digitalWrite(CS_pin, HIGH);
  delay(1);
  SPI.transfer(0x45);
  SPI.transfer(0x78);
  SPI.transfer(0x69);
  SPI.transfer(0x74);
  SPI.transfer(0);
  SPI.transfer(0);
  SPI.transfer(0);
  SPI.transfer(0);

  delay(200);
}
Logged

Italy
Offline Offline
Full Member
***
Karma: 3
Posts: 142
jayduino rox
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

The program looks fine, but the board you are using is buggy!

Pin 32 of the VLSI chip (XTEST, near the GPIO0 pin) on the breakout board is floating :o and is NOT connected to IOVDD as the datasheet of the the VS1053 recommends >smiley-sad
You might solder that, but it is tricky to do.

It is a serious flaw in the sparkfun VS1053b BOB.
Logged

Juergen

Pages: [1]   Go Up
Jump to: