First Teensy Project: Interfacing with an SPI of unkown configuration

Status
Not open for further replies.
Hi Folks,

This will my first project with Teensy, I've messed with a Razz Pi for a CS4 course so I believe the learning curve won't too bad. For the project I have chosen a Teensy 3.5 which should arrive by the end of the week.
Let me start by introducing my project:

I bought a Rock Band 3 Mustang Wii Guitar Controller from amazon to fool around with. I don't have a Wii and various sources cited it should have been midi capable (it has a built in midi port) out of the box. After a full day and a half messing with configurations/settings/drivers etc, I can't get anything but an active sensing signal on the midi. I believe it has something to the pairing routine that the Wii uses, preventing the controller from fully starting up to process midi signals, it could also be a manufacture issue (bought it new). I don't really care about the wii/wireless capability and have seen quite a few midi arduino projects around online. So the idea in a nutshell is to gut the internal chip and replace it with a Teensy.

The "string" inputs and body buttons should be very easy to interface with the Teensy, and I'm not worried about the midi aspect of the project. There is a teensy problem (bet you've never heard that one) when it comes to the 150+ button fret board. The board multiplex's a resistor/diode matrix that is connect to the 150+ buttons into a micro-controller chip, that then communicates with the main board in the guitar body. I was about to give up the idea of the project until I flipped over the main board and saw that the pins to the micro-controller were labeled SO, SI, SCK, and CS. A quick google search resulted with SPI and I did a little research into how SPI works.

This brings me to the purpose of my post:

I have an SPI device that I want to interface the Teensy with and have no idea how it is configured, I don't even know if the device is the master or slave device.

What I want to accomplish:
1. Determine the SPI configuration so I can interface the Teensy to the micro-controller.
2. Analyze the communication from the micro-controller to understand what message, for example, what is sent via the buttons.
3. Create a program to use the commands and send midi signals.

Right now my game plan is to:
1. Make a small side project to orient myself with Teensy and ensure my setup works (ei wiring and computer communication)
2. Create a program that can display information from the Teensy spi (bus?) onto the computer (or at worst somehow create logs of the information to view).
3. Use the program to attempt combinations of SPI settings until I get lucky and I see relevant communication happen (I'm hoping to improve this part of the plan)
4. Analyze the SPI messages while hitting buttons etc and determine the format of the communication
5. Use the info to build my midi controller

As mentioned above I am hoping to improve Step 3, and get idea of how feasible it would be to accomplish such a task.

Any direction in maybe how to maybe better figure out the SPI configuration would definitely be appreciated.

I don't have any code as I don't even have the Teensy yet. I'm just trying to get ideas and maybe hammer out the game plan a bit while I wait for it to arrive.

I have include few pictures below of what I plan on working with, Thanks in advance for any assistance :cool:.

body_front (1).jpg

body_internal (1).jpg

fret_board_internal (1).jpg

main_board_back (1).jpg
 
If you are into this type of hardware hacking I would recommend you invest in a BusPirate for $30. I just ordered one for myself :)
Otherwise you could just analogread the voltage of the SO, SI, SCK, and CS pins and see if the board sets the CS pin low. Then you know it works as a master. Then you can try the Teensy as SPI Slave library and read the data sent to the Teensy.
 
Wii uses Bluetooth HID. Maybe that is why you do not get MIDI 'out of the box'. With software like EventGhost it is possible to map incoming HID events to MIDI.
Could it be an idea to use the Teensy to 'emulate' the Bluetooth module and catch the data to work on that?

Anyway, i see the board seems to have been soaked in sea water... if this still works?
 
If you are into this type of hardware hacking I would recommend you invest in a BusPirate for $30. I just ordered one for myself :)
Otherwise you could just analogread the voltage of the SO, SI, SCK, and CS pins and see if the board sets the CS pin low. Then you know it works as a master. Then you can try the Teensy as SPI Slave library and read the data sent to the Teensy.

Ah ha! Thank you for the direction, analogRead() looks like a really good tool to get visibility on a specific pin behavior, I wil give this a try :)
 
Wii uses Bluetooth HID. Maybe that is why you do not get MIDI 'out of the box'. With software like EventGhost it is possible to map incoming HID events to MIDI.
Could it be an idea to use the Teensy to 'emulate' the Bluetooth module and catch the data to work on that?

Anyway, i see the board seems to have been soaked in sea water... if this still works?

Yes I was able to get the HID stuff working, sort of, with the wireless USB dongle it came with. The controller has a midi plug port that is just supposed to work, I have seen videos with the ps4 and xbox360 versions and they didn't require any additional setup,but there isn't much on the Wii variant. I'm using a midi to USB cable that has been tested with a Casio keyboard. I don't think this controller uses Bluetooth, because of the USB dongle. I was able to get HID input to work via default drivers windows installs for the controller but not all the fret buttons work or maybe the driver couldn't handle them, and I've tried various other drivers Wii specific ones, etc with no luck. The fret board looks a lot healthier than the main board so I'm hoping it'll be fine, but I did notice the main board looks pretty grody and that makes me feel more comfortable just the replacing it with something else.
 
I've found MIDI ports that actually had some sort of leaking current, so a low-power opto at receiver side saw only "light on". I solved that with soldering 330Ω across the pins 4 and 5 of the cable (the MIDI signal wires), to "drain" that current, so a proper MIDI signal could be decoded.

Anyway, I've used the WiiMote and other wireless controllers for DJ/VJ performaces many years ago, until this became a "mass phenomenon". Links I made with a CSR bluetooth dongle.
 
Hey Guys,

I'm back with more of a technical question, so let me know if you want me to move this to a new thread in the appropriate sub forum.

So just a progress update of where I am atm, I do believe the IC is an SPI master. With the SS line low (output) and the SCLK line set low as input I get a pretty consistent voltage fluctuations/frequency, it's just not enough to trigger the high/low to read them as digital. Setting up the SCLK pin as input_pulldown gives a better or more distinct reading on the voltages. Anyway the MOSI pin also has voltage on it that fluctuates while the MISO line is flat with no voltage on it.

I need to set the Teensy(3.5) up as an SPI Slave, which doesn't seem to be natively supported by the SPI API so I have to take some time and research to figure that out.

For now though I had setup a loop in an attempt to measure the clock speed on the SCLK line and it worked kindof successfully, where from 30s samples I was getting 1.65 Hz consistently. However I think the clock is actually alot faster than that guessing @ maybe ~16 MHz. Trying to analyze the MISO line in a similar way is giving me pretty sporadic results. I think the restriction is in how fast the loop executes (I run it asynchronously {I think} to the serial dump). I'm dropping the code below, most of the auxiliary stuff I was using is commented out, but even with this loop gutted to the basic counter to measure the Hz I only get 5 MHz (~52067352 counts per 10 seconds) which isn't even a fraction of the 120 MHz this thing is supposed be capable of. Is there really that much going on in the API stuff to drop it down to 5MHz? Running with the pin reads enabled drops it down to like 4KHz, So I don't even get 1 MHz at that point.

Some other information, I'm using PIO with VSCode and the platformio.ini is using this to compile:
[env:teensy35]
platform = teensy
framework = arduino
board = teensy35
board_build.f_cpu = 120000000L

I have tried different values for f_cpu thinking maybe the setup was restricting, but further research reveals the .json file uses 120Mhz by default so it doesn't look like that's the issue.

I want to try to get the loops to operate @ around a least 20 MHz which I thought would be reasonable considering the 120 MHz top limit, that way I have overhead for the voltage reads, etc.
With that I can start maybe analyzing the MISO line, so I can either make my own SPI communication routine if it comes to that or at least have data to make sure I'm setting the Teensy properly as a SPI Slave.

Maybe there is something obvious I'm doing that could be straightened out, thanks in advance :)

Code:
#include <Arduino.h>
#include <SPI.h>

//used to enable/disable printing voltage
boolean printVoltage = false;
int voltagePrintMulti;

//loop counter to display
long count;
long freqCount;

//Pin constants
int slaveSelectPin = 10;
int clockPin       = 14;
int mosiPin        = 11;
int misoPin        = 12;

int     clockVoltage;
boolean clockHigh;
int     mosiVoltage;
boolean mosiHigh;

boolean toggle;

//used measure clock speed
elapsedMillis timer;
long initTime;
long currentTime;

void setup()
{
  //Start serial @ 12 Mbit/sec
  Serial.begin(115200);
  pinMode(slaveSelectPin, OUTPUT);
  pinMode(clockPin, INPUT_PULLDOWN);
  pinMode(misoPin, OUTPUT);
  //pinMode(mosiPin, INPUT_PULLUP);
  //SPI.begin();
  //SPI.setSCK(clockPin);

  //SPI.beginTransaction(SPISettings(2000000, MSBFIRST, SPI_MODE0));
  digitalWrite(slaveSelectPin,LOW);


  // initialize LED digital pin as an output.
  pinMode(LED_BUILTIN, OUTPUT);
  digitalWrite(LED_BUILTIN, HIGH);
  delay(2000);
  initTime = timer;
  toggle = false;
  Serial.printf("Beginning monitor... \n");
}


void loop()
{
  for(;;)
  {
    // turn the LED on (HIGH is the voltage level)
    //digitalWrite(LED_BUILTIN, HIGH);
    // wait for a second
    //delay(5);
    // turn the LED off by making the voltage LOW
    //digitalWrite(LED_BUILTIN, LOW);
    // wait for a second
    currentTime = timer;
    if((currentTime - initTime) >= 10000)
    {
        Serial.printf("Teensy Cycles Per 10 Second: %d \n", count);
        Serial.printf("Clock pin Cycles Per 10 Second: %d \n", freqCount);
        //Clock appears to run @ 1.65 hz (tested per 30s samples)
        Serial.printf("Frequency of Clock pin over 10 Second: %f \n", freqCount/10.0);
        count = 0;
        //freqCount = 0;
        //voltagePrintMulti = 0;
        initTime = timer;
    }
    else
    {
      count++;
      //clockVoltage = analogRead(clockPin);
      //mosiVoltage = analogRead(mosiPin);
      //clockHigh = clockVoltage > 100;
      //mosiHigh = digitalRead(mosiPin); //mosiVoltage > 100;

      //if(toggle && clockVoltage < 100)
      //{
      //  freqCount++;
      //  toggle = false;
      //}
      //else if(!toggle && clockVoltage >= 100)
      //{
      //  toggle = true;
      //}
    }

    //if(printVoltage &&((currentTime - initTime) >= (5 * voltagePrintMulti)))
    //{
    //    //Serial.printf("%d : %d \n", count, mosiVoltage);
    //    Serial.printf("%d : %d | %d \n", count, clockHigh, mosiVoltage);
    //    voltagePrintMulti ++;
    //}
  }
}
 
Status
Not open for further replies.
Back
Top