Minimal MIDI decoder

Designing hardware that uses VLSI Solution's devices as slave codecs such as an external MP3 decoder chip for a host microcontroller.
Davidelvig
Senior User
Posts: 38
Joined: Mon 2015-08-24 5:25

Re: Minimal MIDI decoder

Post by Davidelvig » Mon 2017-10-16 4:19

OK, more looking around.
I've found in related messages the page:
http://www.vlsi.fi/en/support/software/ ... tches.html
and the zip file under:
VS1053b Realtime MIDI Start code


Sounds like that plugin enables Real-Time MIDI when a chip does not have it active at start-up.
It would be best to be able to toggle RT MIDI on and off using SCI.
  • Is there a similar (or modified) plugin that turns Real-Time MIDI off?
My current board design is hardwired for RTMIDI at start-up (GPIO0 is tied low and GPIO1 is tied high).

I suppose that I have the option to:
- leave RT MIDI OFF at start-up
- turn RT MIDI on with the plugin when needed
- turn it off again with a hardware reset.

User avatar
pasi
VLSI Staff
Posts: 1702
Joined: Thu 2010-07-15 16:04

Re: Minimal MIDI decoder

Post by pasi » Mon 2017-11-20 13:33

If the GPIO pins have pull-down/pull-up resistors, you could try to configure the pins as outputs and to your desired states through SCI_WRAMADDR/SCI_WRAM, and then give software reset. If they are hardwired to GND or IOVDD, this would not work.

0xc017 -> WRAMADDR, 3 -> WRAM, 0 -> WRAM, state -> WRAM.
Visit https://www.facebook.com/VLSISolution VLSI Solution on Facebook

Davidelvig
Senior User
Posts: 38
Joined: Mon 2015-08-24 5:25

Re: Minimal MIDI decoder

Post by Davidelvig » Tue 2020-04-14 6:43

I may get an award for resurrecting an old post.

On the VS1053...
I'd like to use Realtime MIDI (by setting GPIO0 low and GPIO1 high), and still adjust EarSpeaker.

Can I do this without SPI?

That is, could I set GPIO2 and GPIO3 high (or low) and then do a reset (with GPIO0 still low and GPIO1 high) and and get various configurations of EarSpeaker?

What's the sequence to use for the proper reset (hardware or software)?

User avatar
pasi
VLSI Staff
Posts: 1702
Joined: Thu 2010-07-15 16:04

Re: Minimal MIDI decoder

Post by pasi » Tue 2020-04-14 14:08

Davidelvig wrote:
Tue 2020-04-14 6:43
That is, could I set GPIO2 and GPIO3 high (or low) and then do a reset (with GPIO0 still low and GPIO1 high) and and get various configurations of EarSpeaker?
Yes. GPIO2 and GPIO3 are copied to EarSpeaker settings during startup if the real time MIDI mode is started by GPIO0=low and GPIO1=high.
Davidelvig wrote:
Tue 2020-04-14 6:43
What's the sequence to use for the proper reset (hardware or software)?
Hardrware: Assert reset (xRESET low), wait a bit, optionally set GPIO states, release reset.
Software: Write the reset bit in the SCI_MODE register. Wait until DREQ goes up again.
Visit https://www.facebook.com/VLSISolution VLSI Solution on Facebook

Davidelvig
Senior User
Posts: 38
Joined: Mon 2015-08-24 5:25

Re: Minimal MIDI decoder

Post by Davidelvig » Tue 2020-04-14 19:54

Thanks!

Davidelvig
Senior User
Posts: 38
Joined: Mon 2015-08-24 5:25

Re: Minimal MIDI decoder

Post by Davidelvig » Wed 2020-07-29 0:29

Regarding MIDI through SDI while in RT MIDI mode:
I have the VS1053b on my own board, running well with RT MIDI initialized at startup.
Serial MIDI streams through the Rx pin work well.
SCI commands work perfectly (tested for SCI_VOL, SCI_BASS and SCI_MODE for EarSpeaker).

I'd like to try sending the MIDI data through SDI to free up the Rx line, though I need clarification on one item in the data sheet, bolded and underlined below:
10.10 Real-Time MIDI
If GPIO0 is low and GPIO1 is high during boot, real-time MIDI mode is activated. In this mode the PLL is configured to 4.0×, the UART is configured to the MIDI data rate 31250 bps, and real-time MIDI data is then read from UART and SDI. Both input methods should not be used simultaneously. If you use SDI, first send 0x00 and then send the MIDI data byte.
My MIDI message sequences typically are 2 and 3 byte values.
Where does the 0x00 go in those sequences?

It would help to get a couple of SDI byte-wise examples, perhaps for:
  • noteOn(NOTE_ON|channel, note, velocity)
    noteOff(NOTE_OFF|channel, note, 0)
    setProgram(PROGRAM_CHANGE|channel, program)
    setController(CONTROL_CHANGE|channel, controllerNumber, val)
...where
NOTE_ON = 0x80
NOTE_OFF = 0x90
PROGRAM_CHANGE = 0xC0
CONTROL_CHANGE = 0xB0

... and my WriteSDI() method looks like this:

Code: Select all

bool dbMIDISynth::WriteSDI(const uint8_t *data, uint8_t bytes) {
    if (bytes > 32) {
        Serial.printf("Request to WriteSDI is limited to 32 bytes. Requested bytes was %d\n", bytes);
        return(false);
    }
    if (DREQ_Rises()) {
        SPI.beginTransaction(_spiSettings);
        spiOn(_dataSSPin);
        for (int x = 0; x < bytes; x++) {
            Serial.printf("WriteSDI(): %c\t%d\t\t",data[x], data[x]);
            char c = SPI.transfer(data[x]);
            Serial.printf("SPI Returns: %c\t%d\n", c, c);
        }
        spiOff(_dataSSPin);
        SPI.endTransaction();
        return(true);
    }
    return(false);
}
In addition to sending the proper bytes through SDI, is there any additional configuration of the VS1053b needed, other than RTMDI being enabled?

User avatar
pasi
VLSI Staff
Posts: 1702
Joined: Thu 2010-07-15 16:04

Re: Minimal MIDI decoder

Post by pasi » Wed 2020-07-29 9:50

Davidelvig wrote:
Wed 2020-07-29 0:29
My MIDI message sequences typically are 2 and 3 byte values.
Where does the 0x00 go in those sequences?
Before every and each one of the bytes you send. 3-byte commands become 6-byte transmissions.
Davidelvig wrote:
Wed 2020-07-29 0:29
In addition to sending the proper bytes through SDI, is there any additional configuration of the VS1053b needed, other than RTMDI being enabled?
No. SDI and UART are parallel ways to send MIDI bytes. But don't use both at the same time! :)
Visit https://www.facebook.com/VLSISolution VLSI Solution on Facebook

Davidelvig
Senior User
Posts: 38
Joined: Mon 2015-08-24 5:25

Re: Minimal MIDI decoder

Post by Davidelvig » Wed 2020-07-29 18:44

Brilliant!
Implemented in 10 minutes.
Thanks @pasi!
For those interested, here's a snippet.
I added the if (MIDIThroughSPI) clauses to two MIDI message sending methods.

Code: Select all

void dbMIDISynth::writeTwo(unsigned char a, unsigned char b) {
    if (MIDIThroughSPI) {
        uint8_t bytes[4] = {0, a, 0, b};
        if (!WriteSDI(bytes, 4))
            Serial.println("writeTwo bytes failed");
    } else { // MIDI through Serial
        MIDI_SERIAL_PORT.write(a);
        MIDI_SERIAL_PORT.write(b);
    }
}
void dbMIDISynth::writeThree(unsigned char a, unsigned char b, unsigned char c) {
    if (MIDIThroughSPI) {
        uint8_t bytes[6] = {0, a, 0, b, 0, c};
        if (!WriteSDI(bytes, 6))
            Serial.println("writeThree bytes failed");
    } else { // MIDI through Serial
        MIDI_SERIAL_PORT.write(a);
        MIDI_SERIAL_PORT.write(b);
        MIDI_SERIAL_PORT.write(c);
    }
}

Post Reply