Saturday, September 25, 2010

Ethernet Shield SPI mod

Some people have been working on a modification to allow them to use the official arduino ethernet shield with the provided yet unsupported SD card reader (there seems to be major updates to the shield: as I write these lines the NYC maker faire is on and the arduino team is announcing some major changes to the arduino family including, I hear, a new ethernet shield...).

I will modify my ethernet shield to allow me to use it stacked with the VS1053 chip mp3 decoder shield and not have them both fight for SPI communications (this would happen because the Wiznet chip that comes on the ethernet shield, does not implement a proper version of SPI and it is recommended to disable SPI on the chip altogether when not in use - basically it disabling the SS line doesn't actually stop the chip from sending information to the SPI bus, confusing all the other SPI devices that happen to be connected to the bus).

So the steps I will follow are:

1. add a wire between the SEN pin of the wiznet chip and one of the ATmega ports on the arduino (I choose D8).
2. modify the ethernet library to change the state of the extra pin every time we finish a SPI read/ write cycle.

I will keep posting as I go...

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(){


}

Tuesday, September 21, 2010

Arduino and SparkFun MP3 shield test code

For the speakers project I'm currently working in, I got an mp3 shield for the arduino from sparkfun. I'm currently exploring the VS1053D decoder chip. To that goal, I wrote the attached testing code that will put the chip to test mode and output a sine wave sound with adjustable pitch. I noticed that there's not much info available on the internet to make this shield work, so I'll make make code available as I go (check also the google code pages for this project.

#include SPI.h ---> put brackets here and delete this comment
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 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)
  
  for (;;){}
}
void chip_write (unsigned int address, word data){
    byte aux;
    digitalWrite(CS_pin, LOW);
    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 (!DREQ_pin){};
    digitalWrite(CS_pin, HIGH);
}
void chip_sineTest(int pitch){
   digitalWrite(CS_pin, HIGH);
   SPI.transfer(0x53);
   SPI.transfer(0xEF);
   SPI.transfer(0x6E);
   SPI.transfer(pitch);
   SPI.transfer(0);
   SPI.transfer(0);
   SPI.transfer(0);
   SPI.transfer(0);    
}
void initialize(){
   
}