MidiVOX diagnostic sketch: MidiTest.ino


//
// MidiVox: Diagnostic tests (MIDI, LEDs, reset button, DAC)
//

// Author:  P.J. Drongowski
// Date:    28 April 2015
// Copyright (c) 2015 Paul J. Drongowski

#include "SPI.h"

//
// Pin definitions
//
// SPI pins: 
//     D13: SCK    Slave Clock
//     D12: MISO   Master In, Slave Out
//     D11: MOSI   Master Out, Slave In
//     D9:  SS     Slave Select
int ResetButton = 6 ;
int DataLED = 7 ;
int SlaveSelect = 9 ;

//
// Blink the data LED on the MidiVox board
//
void blinkDataLED() {
  digitalWrite(DataLED, HIGH) ;
  delay(500) ;
  digitalWrite(DataLED, LOW) ;
  delay(500) ;
}

void setup() {
  int i ;
  // Set up pin modes
  pinMode(ResetButton, INPUT_PULLUP) ;
  pinMode(DataLED, OUTPUT) ;
  pinMode(SlaveSelect, OUTPUT) ;

  // Turn the data LED off
  digitalWrite(DataLED, LOW) ;

  // Initialize the SPI interface
  SPI.begin() ;
  SPI.setBitOrder(MSBFIRST) ;

  // Initialize the MIDI interface
  Serial.begin(31250) ;

  // Blink data LED on and off four times at start-up
  for (i = 4 ; i > 0 ; i--) {
    blinkDataLED() ;
  }
}

//
// Use this loop to test the MidiVox data LED. The data LED 
// will flash rapidly until a new sketch is loaded.
//
void ledloop() {
  digitalWrite(DataLED, LOW) ;
  delay(100) ;
  digitalWrite(DataLED, HIGH) ;
  delay(100) ;
}

//
// Use this loop to test the reset button.
//
void buttonloop() {
  int button ;
  button = digitalRead(ResetButton) ;
  if (button == LOW) {
    digitalWrite(DataLED, HIGH) ;
  } if (button == HIGH) {
    digitalWrite(DataLED, LOW) ;
  }
}

//
// Write a 16-bit value to the MCP 4921 DAC.
//
void writeDac(word dacValue) {
  byte data ;
  digitalWrite(SlaveSelect, LOW) ;
  data = highByte(dacValue) ;
  data = 0x0F & data ;
  data = 0x30 | data ;
  SPI.transfer(data) ;
  data = lowByte(dacValue) ;
  SPI.transfer(data) ;
  digitalWrite(SlaveSelect, HIGH) ;
}

//
// Play one cycle of a sawtooth tone. The step size determines
// frequency.
//
void playCycle(int stepSize) {
  int i ;
  for (i = 2048 ; i > 0 ; i = i - stepSize) {
    writeDac(i) ;
    delay(0) ;
  }
}

//
// Play a short-duration tone through the DAC.
//
void playTone(int stepSize, int duration) {
  int i ;
  for (i = duration ; i > 0 ; i--) {
    playCycle(stepSize) ;
  }
}

//
// Use this loop to test the DAC audio output. Connect the
// audio output to an amplifier and speaker. You should hear
// a continuous tone (a sawtooth wave). Make sure that you
// have turned up the on-board volume control (trimpot).
//
void toneloop() {
  playCycle(32) ;
}

#define MIDI_NOTE_ON  0x90
#define MIDI_NOTE_OFF 0x80

//
// Use this loop to test MIDI input. Read a short (3 byte)
// MIDI note ON/OFF message. Play a tone for note ON. Zero
// out the DAC for note OFF.
//
void loop() {
  byte cmdByte, note, velocity ;
  if (Serial.available() > 0) {
    cmdByte = Serial.read() ;
    if ((cmdByte & 0xF0) == MIDI_NOTE_ON) {
      // Read the rest of the note ON message
      note = Serial.read() ;
      velocity = Serial.read() ;
      if (velocity == 0) {
        writeDac(0) ;
      } else {
        playTone(8, 256) ;
      }
    } else if ((cmdByte & 0xF0) == MIDI_NOTE_OFF) {
      // Read the rest of the note OFF message
      note = Serial.read() ;
      velocity = Serial.read() ;
      writeDac(0) ;
    }
  }
}