Page 4 of 4

Re: Minimal MIDI decoder

Posted: Mon 2017-10-16 4:19
by Davidelvig
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.

Re: Minimal MIDI decoder

Posted: Mon 2017-11-20 13:33
by pasi
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.

Re: Minimal MIDI decoder

Posted: Tue 2020-04-14 6:43
by Davidelvig
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)?

Re: Minimal MIDI decoder

Posted: Tue 2020-04-14 14:08
by pasi
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.

Re: Minimal MIDI decoder

Posted: Tue 2020-04-14 19:54
by Davidelvig
Thanks!

Re: Minimal MIDI decoder

Posted: Wed 2020-07-29 0:29
by Davidelvig
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?

Re: Minimal MIDI decoder

Posted: Wed 2020-07-29 9:50
by pasi
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! :)

Re: Minimal MIDI decoder

Posted: Wed 2020-07-29 18:44
by Davidelvig
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);
    }
}