Saturday, September 25, 2010

new sine test wave for VS1053 shield on an arduino board

UPDATE 06.05.2011: if the code below, doesn't work for you, try SPI_MODE1 instead of SPI_MODE0 (thanks Anonymous).

This new code for the arduino + mp3 shield sine wave tester works much better than the one I posted on my last post. Basically I removed the infinite for loop on the main loop() function and added a 1ms delay after setting the CS line LOW or HIGH. I got this last tip here.

This code works on the 0019 arduino IDE and uses the new SPI library that comes with the IDE.

code:
 #include [SPI.h] //replace [] by greater than and smaller than symbols - had to do this because of
//the blog stripping the symbols because it thinks it's html
int CS_pin = 9;
int DREQ_pin = 3;
void setup() {
  pinMode(CS_pin, OUTPUT);
  pinMode(DREQ_pin, INPUT);
  SPI.begin();
  SPI.setBitOrder(MSBFIRST);
  //CPOL = 0, CPHA = 1
  //see http://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);
  initialize();
}
void loop(){
  digitalWrite(CS_pin, HIGH);
  chip_write(0x00, 0x0c20); // sets sci_mode register, SM_SDINEW, SM_SDISHARE
                          // SM_TESTS.  pg 25, 26
  chip_sineTest(0xAA);   // test tone frequency (pg 35)
}
void chip_write (unsigned int address, word data){
    byte aux;
    digitalWrite(CS_pin, LOW);
    delay(1);
    SPI.transfer(0x02);  //write command
    SPI.transfer(address); //SDI_MODE register
    //extract and send higher byte of data
    aux = data >> 8;
    SPI.transfer(aux);
    //extract and send lower byte of data
    aux = data & 0b11111111;
    SPI.transfer(aux);
    //wait for the chip to finish executing command
    //while (!digitalRead(DREQ_pin)){};
    digitalWrite(CS_pin, HIGH);
    delay(1);
}
void chip_sineTest(int pitch){
   digitalWrite(CS_pin, HIGH);
   delay(1);
   SPI.transfer(0x53);
   SPI.transfer(0xEF);
   SPI.transfer(0x6E);
   SPI.transfer(pitch);
   SPI.transfer(0);
   SPI.transfer(0);
   SPI.transfer(0);
   SPI.transfer(0);
   digitalWrite(CS_pin, LOW);
   delay(1);  
}
void initialize(){


}

3 comments:

zodiak aka Rui said...

NOTE that you have to remove pins D0 and D1 (TX and RX) from the shield. I just bent them away from the header.

Anonymous said...

It seems that you used the wrong configuration for the SPI.setDatamode() function. SPI_MODE1 didn't work for me while SPI_MODE0 worked.

Still, nice code example.
thx

zodiak aka Rui said...

yeah, I may have posted an older version of the many versions that I tried before this worked ;-)

Glad it worked for you!

Cheers,
Rui