vs1053b Realtime midi over SDI with Arduino [SOLVED]

Writing software that inputs and/or outputs audio and performs DSP algorithms such as filters, new codecs or audio effects.
Post Reply
Paul
User
Posts: 1
Joined: Fri 2013-01-25 13:38

vs1053b Realtime midi over SDI with Arduino [SOLVED]

Post by Paul » Fri 2013-01-25 13:50

Hi Folks,
I solved it myself (man, that feels good! :) ), here's a complete setup for midi, using seeedstudio's Music Shield.
Should work with any Arduino.
Please note the fact that you have to put 3v3 on GPIO1, to put it into realtime midi mode
Enjoy!

Paul Driessen

Code: Select all

/*
 ==================================================
 Arduino + Music Shield  ( seeedstudio ) via SPI
 ==================================================
 created 26 januari 2013
 by Paul Driessen
 www.pauldriessen.nl
 ================================================== 

 This code works with Arduino Leonardo + Music Shield from Seeedstudio
 I can't gurantee anything, but it should work with any Arduino I guess..
 
 http://www.seeedstudio.com/depot/music-shield-p-642.html?cPath=132_134
 
 !!!!!!ATTENTION PLEASE !!!!! VERY IMPORTANT !!!!!
 To boot the Music Shield into realtime midi mode the GPIO1 has to be connected to 3v3!!
 I located C20 on the board, this is the source of 3v3 on the board 
 and connected a thin wire from the + of this one to the GPIO, the hole named "1" is GPIO1
 **Please ask someone good in soldering to do this if uncertain yourself!!**
  
 Once GPIO1 is properly pulled up, this code will work.
  
*/


// inslude the SPI library:
#include <SPI.h>


// Music Shields XDCS is to be taken LOW on every transfer, and is connected to Arduino's A2.
// that is the "chips select pin" that is extra needed for getting SPI communication going
// the SDI communication mentioned by VLSI in their VS1053b documentation is a subset of SPI
// It just means that that is no command layer, just data: Serial Data Interface
const int XDCS = A2;

// where gonna get feedback over the DREQ line, connected to A1
const int DREQ = A1;

// where gonna give a hard reset ourselves, to be sure to have a nice booted chip..
const int XRESET = A0;

void setup() {
  digitalWrite(XDCS, HIGH);   //trick!!
  pinMode (XRESET, OUTPUT);   // XRESET  = LOW active
  
  // set the slaveSelectPin as an output:
  digitalWrite(XDCS, HIGH); //trick!!
  pinMode (XDCS, OUTPUT);   //this order prevents XDCS becomgin LOW! is LOW active!

  pinMode (DREQ, INPUT);

  // initialize SPI:
  SPI.begin(); 
  SPI.setBitOrder(MSBFIRST);    
  SPI.setDataMode(SPI_MODE0) ;          //capture on first risign edge
  SPI.setClockDivider(SPI_CLOCK_DIV16); //1 mhzfunction, mycrystal=16mhz
  
  //Serial.println("Reset & waiting for VS1053b to wake up..");
  digitalWrite(XRESET, LOW);    // push reset button
  delay(100);                   // keep depressed for 100ms
  digitalWrite(XRESET, HIGH);   // and release..
  //Serial.println("Wakie Wakie!!");  
  while(digitalRead(DREQ)==LOW)  
  {  
                                //wait for chip to wake up, DREQ becomes high after 22000 of his clockcycles..
                                //so xtal scan could be implemented here, not needed here because crystal is known
  };
  //Serial.println("Yohooo! The VS1053b has woken up!");
 
}

void loop() {
  //testProgram: Build your own interface/music here!
  //Have fun! Be creative!
  //greetings, 
  //Paul Driessen
  SendResetCC(1);   //reset all controllers on channel 1
  SendProgram(1,1); //prest select..
  SendCC(1,7,127); // channelvolume up..
  for(int p=1;p<=127;p++)
  {
      SendProgram(1,p); //prest select..
      for(int n=32;n<=64;n++)
      {
         SendNoteOn(1,n,127);
         digitalWrite(13, LOW);
         delay(50);   
         digitalWrite(13, HIGH);
         SendNoteOn(1,n,0);  //note off..
         delay(25);  
       };   
  };
}

void SendResetCC(unsigned char channel)
{
  SPIByte(0xB0 + channel ); //channel 0;
  SPIByte(0x79 ); //reset controller;
}  


void SendProgram(unsigned char channel, unsigned char preset)
{
  SPIByte(0xC0 + channel ); //channel 0;
  SPIByte(preset ); //controller;
}  
void SendCC(unsigned char channel, unsigned char cc,unsigned char value)
{
  SPIByte(0xB0 + channel ); //channel 0;
  SPIByte(cc ); //controller;
  SPIByte(value); //velo;
}  
void SendNoteOn(unsigned char channel, unsigned char note,unsigned char velocity )
{
  SPIByte(0x90 + channel ); //channel 0;
  SPIByte(note ); //note;
  SPIByte(velocity ); //velo;

}
void SPIByte(unsigned char val)
{
  while(digitalRead(DREQ)==LOW)
  {
     //wait for room in the buffer
  }  
  digitalWrite(XDCS,LOW); //start transmission
    SPI.transfer(0 );     //MSB
    SPI.transfer(val );   //LSB;
  digitalWrite(XDCS,HIGH);//end transmission  
}  

Post Reply