I am posting this here, because I am unsure of where else to get help, as the original forum for the i2c SID thing appears to be closed to new registration. Anybody having any ideas would be most appreciated.
I have a teensy 2++, and I want it to run as a standard midi device that triggers the SID emulator over i2c.
I have a ATMEGA328P chip + 16MHz resonator, a teensy 2++, and a standard Duemilanove w/ 328P.
I burned the i2c SID emulator code onto the ATMEGA328P chip using ArduinoISP on my Duemilanove. Before doing this, I burned Arduino bootloader and other things on the chip, to test that I was doing it right. All went well. It blinks with Arduino firmware, and cycles through the SID emulation gate LEDs, when it starts up. For SID firmware, pin 11 needs to be hooked to pin 17 for timing, so I did this.
I hooked pin 27 (SDA) of 328P to my teensy SDA (D1) and pin 28 (SCL) of 328P to teensy SCL (D0.)
I set device to teensy 2++ as MIDI device in Arduino IDE, and loaded a simple "when you receive noteon, turn on LED, when you receive noteoff, turn off LED." This worked fine when I sent the teensy MIDI device notes, happily blinking the LED like crazy.
Next, looking at the example interface code that comes with the i2c-SID, I tried to just port it straight, which would make it never get to my noteon/off functions (I left LED blinking at end of functions.)
Deciding that all the i2c stuff was a bit over-complicated (I couldn't really follow the code, I am a simple man) I came up with this:
uint8_t i2c_sendbytes(uint8_t address, uint8_t data1, uint8_t data2) {
Wire.beginTransmission(address);
Wire.send(data1);
Wire.send(data2);
Wire.endTransmission();
return 0;
}
to replace the original function. In my setup(), I am calling this, to initialize:
Wire.begin();
Wire.beginTransmission(I2C_SLAVE_ADDR);
Wire.send(0);
Wire.endTransmission();
All the other functions that were in i2c SID original demo code are unchanged:
set_adsr, set_frequency, set_wave, set_pulsewidth, reset_siduino
All this in place, I made my noteon/off callbacks look like this:
void NoteOn(byte channel, byte note, byte velocity) {
uint16_t envelope = 0x41F4;
uint8_t gate = 1;
uint8_t program = 0;
if (velocity == 0){
gate = 0;
}
envelope &= 0xFF0F; // set Sustain Bits to 0
envelope |= ((velocity >> 3) << 4) & 0x00F0; // set sustain bits to velocity
if (gate){
for(i=0;i<3;i++) {
if(voices[i] == 0) {
set_adsr(envelope,i*7);
play_tone(1, note, i*7, programs[program]);
voices[i] = note;
break;
}
}
}
// LED on!
digitalWrite(6, HIGH);
}
void NoteOff(byte channel, byte note, byte velocity) {
uint8_t program = 0;
for(i=0;i<3;i++) {
if(voices[i] == note) {
play_tone(0, note, i*7, programs[program]);
voices[i] = 0;
break;
}
}
// LED off!
digitalWrite(6, LOW);
}
The LEDs now blink, but the SID still doesn't seem to be getting the i2c messages properly. After this, I took my arduino and set it up as a slave_receiver and set the teensy as master_writer (both from Wire example.) I wanted to make sure that I was doing the i2c stuff correct, at least. It worked, no prob, and in serial monitor for arduino, it said "x is ..." and counted.
At this point, I was going a bit batty, and tried the only other test I could think of:
teensy as midi i2c master_sender -> arduino i2c slave_receiver.
Here is the full code for that:
#include <Wire.h>
#define LEDPIN 6
void NoteOn(byte channel, byte note, byte velocity) {
Wire.beginTransmission(4); // transmit to device #4
Wire.send("1");
Wire.send(channel);
Wire.send(note);
Wire.send(velocity);
Wire.endTransmission();
digitalWrite(LEDPIN, HIGH);
}
void NoteOff(byte channel, byte note, byte velocity) {
Wire.beginTransmission(4); // transmit to device #4
Wire.send("0");
Wire.send(channel);
Wire.send(note);
Wire.send(velocity);
Wire.endTransmission();
digitalWrite(LEDPIN, LOW);
}
void setup() {
usbMIDI.setHandleNoteOff(NoteOff);
usbMIDI.setHandleNoteOn(NoteOn);
pinMode(LEDPIN, OUTPUT);
Wire.begin();
}
void loop() {
usbMIDI.read();
}
On my arduino, I just ran the slave_receiver Wire example. I get lots of byte data (starting with correct 1/0) in serial console when I send the teensy midi messages, so it appears to be working.
The only other thing I can think of is that I am sending incorrectly formatted noteon/off messages for the SID chip. Anybody have experience with this, or see some other issue?
I am not sure what else to test here. As far as I can tell, everything is hooked up right, and all the individual parts are working correctly. I have no experience with the SID i2c, so it may be not working or something, but it seems happy when it starts (flashing all the LEDs.)