home.social

#picodexed — Public Fediverse posts

Live and recent posts from across the Fediverse tagged #picodexed, aggregated by home.social.

  1. picoDexed + MiniDexed EuroRack

    Since attempting my picoDexed + StackyPi + MiniDexed EuroRack build and failing, I’ve found another Pico-to-Zero board that is provided as open source, so I’ve had some made.

    This post details how to get that running with my MiniDexed Zero Eurorack module.

    Warning! I strongly recommend using old or second hand equipment for your experiments.  I am not responsible for any damage to expensive instruments!

    If you are new to microcontrollers and single board computers, see the Getting Started pages.

    Pi Zero RP2040s

    As mentioned last time I found a number of options for a RP2040 based dev board in a Raspberry Pi Zero form factor. But this post is about this one:

    It is fairly simple to build. It just requires a Pico and GPIO header pins.

    There is an option for pull-ups on the I2C bus, but I’ve not bothered with them here. There is also a breakout header for a reset switch if required (it will support two sizes of switch by the looks of things).

    Mapping over to MiniDexed/RPi Zero

    The pinout is slightly different to the Stacky-pi, so here is an updated table of the GPIO mappings and which are required to be used with my MiniDexed board.

    RP2040UseRPiRpiUseRP20403V35VGP2LCD SDAGP2 SDA5VGP3LCD SCLGP3 SCLGNDGP4GP4GP14 TXDGP0GNDGP15 RXDMIDI INGP1GP5GP17GP18I2S BCLKGP18GP6GP27GNDGP7GP22GP23GP83V3GP24GP28GP11RE BGP10 MOSIGNDGP12RE AGP9 MISOGP25GP27GP10RE SWGP11 SCLKGP8GP9GNDGP7GP26ID_SDID_SCGP22SW BACKGP5GNDGP13SW HOMEGP6GP12GP21GP14GP13GNDGP19I2S LCLKGP19GP16GP20GP15GP26GP20GP17GNDGP21I2S DATAGP16

    The two key problem areas will be the I2S interface and encoder, which both require consecutive GPIO pins for the PIO code to do its magic.

    The encoder should be fine – pins RE A and RE B map onto the Pico’s GP11 and 12.

    The I2S interface might be ok – with a BCLK on GP18, it will be expecting LCLK on GP19. Data on GP21 should be ok.

    Unlike the previous attempt, I’m hopeful I can just get this running ok with the correct pin mappings…

    Changing I2C Bus and UARTs

    Unlike the first attempt, I2C is mapped onto GP2 and GP3 which is what I was using in the original picoDexed. So that is all fine, multiplexed onto the I2C bus 1.

    There is an issue with the UART however as picoDexed uses the following by default:

    • UART 0 – GP 0,1 – Serial debug
    • UART 1 – GP 4,5 – MIDI

    I can swap these over so that UART0 (GP0,1) is MIDI, but that has to be matched with a change in the debug serial port too. But unfortunately, as far as I can see, that has to be configured in the master CMakeLists.txt file (as I talked about in Part 3).

    New picoDexed GPIO Configuration

    Given the above, the following new GPIO pins should be defined in config.h:

    #define PWM_PIN         10

    #define I2S_DATA_PIN 16
    #define I2S_BCLK_PIN 18
    #define I2S_LRCLK_PIN 19 // Implied by BCLK=12

    #define MIDI_UART 0
    #define MIDI_TX_PIN 0 // Not used
    #define MIDI_RX_PIN 1

    #define DEBUG_UART_TX_PIN 8
    #define DEBUG_UART_RX_PIN 9

    #define DISPLAY_I2C_BUS 1
    #define DISPLAY_I2C_SDA 2
    #define DISPLAY_I2C_SCL 3
    #define DISPLAY_I2C_ADDR 0x3C
    #define DISPLAY_W 128
    #define DISPLAY_H 32

    #define ENCODER_A_PIN 11
    #define ENCODER_B_PIN 12 // Not used
    #define ENCODER_SW_PIN 10 // Not used

    In addition to this, to keep using the debug output requires the following lines adding to ‘target_compile_definitions’ in CMakeLists.txt.

        PICO_DEFAULT_UART=1
    PICO_DEFAULT_UART_TX_PIN=8
    PICO_DEFAULT_UART_RX_PIN=9

    I’ve added a separate configuration file (config-ER.h) in the repository to allow this version to be built, but the CMakelists.txt change above has not been included.

    I’ve also added a picodexed-v0.03-ER.uf2 file in the build area which can be downloaded and installed directly onto the Pico to provide the above configuration ready to go.

    Bringing it all together…

    The nice thing about this PCB is that I can map everything nicely over to the pinouts used with my MiniDexed EuroRack PCB meaning that once the Pico has the custom firmware installed, it will just plug in and work and no hardware changes or patching is required at all!

    I was slightly concerned that the USB port of the Pico might clash with the two installed electrolytic capacitors on the MiniDexed PCB, but in my case I can just about get away with it!

    Here is the final assembled unit.

    Closing Thoughts

    I finally have my Eurorack picoDexed which is pretty neat. Big thanks to bablokb for putting that PCB up online. That saved me a job. And it was particularly nice that things like assuming consecutive pins for the I2S mapping was included as that made using the PIO I2S code a lot easier.

    I’d like to see what the power usage is like now as I’m really after a lower power Dexed engine compared to the full Zero version.

    Naturally at some point I might still make my own picoDexed Eurorack PCB, but this is a pretty good solution as far as I’m concerned, so that wouldn’t really add much for me now.

    Kevin

    #midi #minidexed #pcb #picodexed #raspberryPiPico

  2. picoDexed + MiniDexed EuroRack

    Since attempting my picoDexed + StackyPi + MiniDexed EuroRack build and failing, I’ve found another Pico-to-Zero board that is provided as open source, so I’ve had some made.

    This post details how to get that running with my MiniDexed Zero Eurorack module.

    Warning! I strongly recommend using old or second hand equipment for your experiments.  I am not responsible for any damage to expensive instruments!

    If you are new to microcontrollers and single board computers, see the Getting Started pages.

    Pi Zero RP2040s

    As mentioned last time I found a number of options for a RP2040 based dev board in a Raspberry Pi Zero form factor. But this post is about this one:

    It is fairly simple to build. It just requires a Pico and GPIO header pins.

    There is an option for pull-ups on the I2C bus, but I’ve not bothered with them here. There is also a breakout header for a reset switch if required (it will support two sizes of switch by the looks of things).

    Mapping over to MiniDexed/RPi Zero

    The pinout is slightly different to the Stacky-pi, so here is an updated table of the GPIO mappings and which are required to be used with my MiniDexed board.

    RP2040UseRPiRpiUseRP20403V35VGP2LCD SDAGP2 SDA5VGP3LCD SCLGP3 SCLGNDGP4GP4GP14 TXDGP0GNDGP15 RXDMIDI INGP1GP5GP17GP18I2S BCLKGP18GP6GP27GNDGP7GP22GP23GP83V3GP24GP28GP11RE BGP10 MOSIGNDGP12RE AGP9 MISOGP25GP27GP10RE SWGP11 SCLKGP8GP9GNDGP7GP26ID_SDID_SCGP22SW BACKGP5GNDGP13SW HOMEGP6GP12GP21GP14GP13GNDGP19I2S LCLKGP19GP16GP20GP15GP26GP20GP17GNDGP21I2S DATAGP16

    The two key problem areas will be the I2S interface and encoder, which both require consecutive GPIO pins for the PIO code to do its magic.

    The encoder should be fine – pins RE A and RE B map onto the Pico’s GP11 and 12.

    The I2S interface might be ok – with a BCLK on GP18, it will be expecting LCLK on GP19. Data on GP21 should be ok.

    Unlike the previous attempt, I’m hopeful I can just get this running ok with the correct pin mappings…

    Changing I2C Bus and UARTs

    Unlike the first attempt, I2C is mapped onto GP2 and GP3 which is what I was using in the original picoDexed. So that is all fine, multiplexed onto the I2C bus 1.

    There is an issue with the UART however as picoDexed uses the following by default:

    • UART 0 – GP 0,1 – Serial debug
    • UART 1 – GP 4,5 – MIDI

    I can swap these over so that UART0 (GP0,1) is MIDI, but that has to be matched with a change in the debug serial port too. But unfortunately, as far as I can see, that has to be configured in the master CMakeLists.txt file (as I talked about in Part 3).

    New picoDexed GPIO Configuration

    Given the above, the following new GPIO pins should be defined in config.h:

    #define PWM_PIN         10

    #define I2S_DATA_PIN 16
    #define I2S_BCLK_PIN 18
    #define I2S_LRCLK_PIN 19 // Implied by BCLK=12

    #define MIDI_UART 0
    #define MIDI_TX_PIN 0 // Not used
    #define MIDI_RX_PIN 1

    #define DEBUG_UART_TX_PIN 8
    #define DEBUG_UART_RX_PIN 9

    #define DISPLAY_I2C_BUS 1
    #define DISPLAY_I2C_SDA 2
    #define DISPLAY_I2C_SCL 3
    #define DISPLAY_I2C_ADDR 0x3C
    #define DISPLAY_W 128
    #define DISPLAY_H 32

    #define ENCODER_A_PIN 11
    #define ENCODER_B_PIN 12 // Not used
    #define ENCODER_SW_PIN 10 // Not used

    In addition to this, to keep using the debug output requires the following lines adding to ‘target_compile_definitions’ in CMakeLists.txt.

        PICO_DEFAULT_UART=1
    PICO_DEFAULT_UART_TX_PIN=8
    PICO_DEFAULT_UART_RX_PIN=9

    I’ve added a separate configuration file (config-ER.h) in the repository to allow this version to be built, but the CMakelists.txt change above has not been included.

    I’ve also added a picodexed-v0.03-ER.uf2 file in the build area which can be downloaded and installed directly onto the Pico to provide the above configuration ready to go.

    Bringing it all together…

    The nice thing about this PCB is that I can map everything nicely over to the pinouts used with my MiniDexed EuroRack PCB meaning that once the Pico has the custom firmware installed, it will just plug in and work and no hardware changes or patching is required at all!

    I was slightly concerned that the USB port of the Pico might clash with the two installed electrolytic capacitors on the MiniDexed PCB, but in my case I can just about get away with it!

    Here is the final assembled unit.

    Closing Thoughts

    I finally have my Eurorack picoDexed which is pretty neat. Big thanks to bablokb for putting that PCB up online. That saved me a job. And it was particularly nice that things like assuming consecutive pins for the I2S mapping was included as that made using the PIO I2S code a lot easier.

    I’d like to see what the power usage is like now as I’m really after a lower power Dexed engine compared to the full Zero version.

    Naturally at some point I might still make my own picoDexed Eurorack PCB, but this is a pretty good solution as far as I’m concerned, so that wouldn’t really add much for me now.

    Kevin

    #midi #minidexed #pcb #picodexed #raspberryPiPico

  3. picoDexed + MiniDexed EuroRack

    Since attempting my picoDexed + StackyPi + MiniDexed EuroRack build and failing, I’ve found another Pico-to-Zero board that is provided as open source, so I’ve had some made.

    This post details how to get that running with my MiniDexed Zero Eurorack module.

    Warning! I strongly recommend using old or second hand equipment for your experiments.  I am not responsible for any damage to expensive instruments!

    If you are new to microcontrollers and single board computers, see the Getting Started pages.

    Pi Zero RP2040s

    As mentioned last time I found a number of options for a RP2040 based dev board in a Raspberry Pi Zero form factor. But this post is about this one:

    It is fairly simple to build. It just requires a Pico and GPIO header pins.

    There is an option for pull-ups on the I2C bus, but I’ve not bothered with them here. There is also a breakout header for a reset switch if required (it will support two sizes of switch by the looks of things).

    Mapping over to MiniDexed/RPi Zero

    The pinout is slightly different to the Stacky-pi, so here is an updated table of the GPIO mappings and which are required to be used with my MiniDexed board.

    RP2040UseRPiRpiUseRP20403V35VGP2LCD SDAGP2 SDA5VGP3LCD SCLGP3 SCLGNDGP4GP4GP14 TXDGP0GNDGP15 RXDMIDI INGP1GP5GP17GP18I2S BCLKGP18GP6GP27GNDGP7GP22GP23GP83V3GP24GP28GP11RE BGP10 MOSIGNDGP12RE AGP9 MISOGP25GP27GP10RE SWGP11 SCLKGP8GP9GNDGP7GP26ID_SDID_SCGP22SW BACKGP5GNDGP13SW HOMEGP6GP12GP21GP14GP13GNDGP19I2S LCLKGP19GP16GP20GP15GP26GP20GP17GNDGP21I2S DATAGP16

    The two key problem areas will be the I2S interface and encoder, which both require consecutive GPIO pins for the PIO code to do its magic.

    The encoder should be fine – pins RE A and RE B map onto the Pico’s GP11 and 12.

    The I2S interface might be ok – with a BCLK on GP18, it will be expecting LCLK on GP19. Data on GP21 should be ok.

    Unlike the previous attempt, I’m hopeful I can just get this running ok with the correct pin mappings…

    Changing I2C Bus and UARTs

    Unlike the first attempt, I2C is mapped onto GP2 and GP3 which is what I was using in the original picoDexed. So that is all fine, multiplexed onto the I2C bus 1.

    There is an issue with the UART however as picoDexed uses the following by default:

    • UART 0 – GP 0,1 – Serial debug
    • UART 1 – GP 4,5 – MIDI

    I can swap these over so that UART0 (GP0,1) is MIDI, but that has to be matched with a change in the debug serial port too. But unfortunately, as far as I can see, that has to be configured in the master CMakeLists.txt file (as I talked about in Part 3).

    New picoDexed GPIO Configuration

    Given the above, the following new GPIO pins should be defined in config.h:

    #define PWM_PIN         10

    #define I2S_DATA_PIN 16
    #define I2S_BCLK_PIN 18
    #define I2S_LRCLK_PIN 19 // Implied by BCLK=12

    #define MIDI_UART 0
    #define MIDI_TX_PIN 0 // Not used
    #define MIDI_RX_PIN 1

    #define DEBUG_UART_TX_PIN 8
    #define DEBUG_UART_RX_PIN 9

    #define DISPLAY_I2C_BUS 1
    #define DISPLAY_I2C_SDA 2
    #define DISPLAY_I2C_SCL 3
    #define DISPLAY_I2C_ADDR 0x3C
    #define DISPLAY_W 128
    #define DISPLAY_H 32

    #define ENCODER_A_PIN 11
    #define ENCODER_B_PIN 12 // Not used
    #define ENCODER_SW_PIN 10 // Not used

    In addition to this, to keep using the debug output requires the following lines adding to ‘target_compile_definitions’ in CMakeLists.txt.

        PICO_DEFAULT_UART=1
    PICO_DEFAULT_UART_TX_PIN=8
    PICO_DEFAULT_UART_RX_PIN=9

    I’ve added a separate configuration file (config-ER.h) in the repository to allow this version to be built, but the CMakelists.txt change above has not been included.

    I’ve also added a picodexed-v0.03-ER.uf2 file in the build area which can be downloaded and installed directly onto the Pico to provide the above configuration ready to go.

    Bringing it all together…

    The nice thing about this PCB is that I can map everything nicely over to the pinouts used with my MiniDexed EuroRack PCB meaning that once the Pico has the custom firmware installed, it will just plug in and work and no hardware changes or patching is required at all!

    I was slightly concerned that the USB port of the Pico might clash with the two installed electrolytic capacitors on the MiniDexed PCB, but in my case I can just about get away with it!

    Here is the final assembled unit.

    Closing Thoughts

    I finally have my Eurorack picoDexed which is pretty neat. Big thanks to bablokb for putting that PCB up online. That saved me a job. And it was particularly nice that things like assuming consecutive pins for the I2S mapping was included as that made using the PIO I2S code a lot easier.

    I’d like to see what the power usage is like now as I’m really after a lower power Dexed engine compared to the full Zero version.

    Naturally at some point I might still make my own picoDexed Eurorack PCB, but this is a pretty good solution as far as I’m concerned, so that wouldn’t really add much for me now.

    Kevin

    #midi #minidexed #pcb #picodexed #raspberryPiPico

  4. picoDexed + MiniDexed EuroRack

    Since attempting my picoDexed + StackyPi + MiniDexed EuroRack build and failing, I’ve found another Pico-to-Zero board that is provided as open source, so I’ve had some made.

    This post details how to get that running with my MiniDexed Zero Eurorack module.

    Warning! I strongly recommend using old or second hand equipment for your experiments.  I am not responsible for any damage to expensive instruments!

    If you are new to microcontrollers and single board computers, see the Getting Started pages.

    Pi Zero RP2040s

    As mentioned last time I found a number of options for a RP2040 based dev board in a Raspberry Pi Zero form factor. But this post is about this one:

    It is fairly simple to build. It just requires a Pico and GPIO header pins.

    There is an option for pull-ups on the I2C bus, but I’ve not bothered with them here. There is also a breakout header for a reset switch if required (it will support two sizes of switch by the looks of things).

    Mapping over to MiniDexed/RPi Zero

    The pinout is slightly different to the Stacky-pi, so here is an updated table of the GPIO mappings and which are required to be used with my MiniDexed board.

    RP2040UseRPiRpiUseRP20403V35VGP2LCD SDAGP2 SDA5VGP3LCD SCLGP3 SCLGNDGP4GP4GP14 TXDGP0GNDGP15 RXDMIDI INGP1GP5GP17GP18I2S BCLKGP18GP6GP27GNDGP7GP22GP23GP83V3GP24GP28GP11RE BGP10 MOSIGNDGP12RE AGP9 MISOGP25GP27GP10RE SWGP11 SCLKGP8GP9GNDGP7GP26ID_SDID_SCGP22SW BACKGP5GNDGP13SW HOMEGP6GP12GP21GP14GP13GNDGP19I2S LCLKGP19GP16GP20GP15GP26GP20GP17GNDGP21I2S DATAGP16

    The two key problem areas will be the I2S interface and encoder, which both require consecutive GPIO pins for the PIO code to do its magic.

    The encoder should be fine – pins RE A and RE B map onto the Pico’s GP11 and 12.

    The I2S interface might be ok – with a BCLK on GP18, it will be expecting LCLK on GP19. Data on GP21 should be ok.

    Unlike the previous attempt, I’m hopeful I can just get this running ok with the correct pin mappings…

    Changing I2C Bus and UARTs

    Unlike the first attempt, I2C is mapped onto GP2 and GP3 which is what I was using in the original picoDexed. So that is all fine, multiplexed onto the I2C bus 1.

    There is an issue with the UART however as picoDexed uses the following by default:

    • UART 0 – GP 0,1 – Serial debug
    • UART 1 – GP 4,5 – MIDI

    I can swap these over so that UART0 (GP0,1) is MIDI, but that has to be matched with a change in the debug serial port too. But unfortunately, as far as I can see, that has to be configured in the master CMakeLists.txt file (as I talked about in Part 3).

    New picoDexed GPIO Configuration

    Given the above, the following new GPIO pins should be defined in config.h:

    #define PWM_PIN         10

    #define I2S_DATA_PIN 16
    #define I2S_BCLK_PIN 18
    #define I2S_LRCLK_PIN 19 // Implied by BCLK=12

    #define MIDI_UART 0
    #define MIDI_TX_PIN 0 // Not used
    #define MIDI_RX_PIN 1

    #define DEBUG_UART_TX_PIN 8
    #define DEBUG_UART_RX_PIN 9

    #define DISPLAY_I2C_BUS 1
    #define DISPLAY_I2C_SDA 2
    #define DISPLAY_I2C_SCL 3
    #define DISPLAY_I2C_ADDR 0x3C
    #define DISPLAY_W 128
    #define DISPLAY_H 32

    #define ENCODER_A_PIN 11
    #define ENCODER_B_PIN 12 // Not used
    #define ENCODER_SW_PIN 10 // Not used

    In addition to this, to keep using the debug output requires the following lines adding to ‘target_compile_definitions’ in CMakeLists.txt.

        PICO_DEFAULT_UART=1
    PICO_DEFAULT_UART_TX_PIN=8
    PICO_DEFAULT_UART_RX_PIN=9

    I’ve added a separate configuration file (config-ER.h) in the repository to allow this version to be built, but the CMakelists.txt change above has not been included.

    I’ve also added a picodexed-v0.03-ER.uf2 file in the build area which can be downloaded and installed directly onto the Pico to provide the above configuration ready to go.

    Bringing it all together…

    The nice thing about this PCB is that I can map everything nicely over to the pinouts used with my MiniDexed EuroRack PCB meaning that once the Pico has the custom firmware installed, it will just plug in and work and no hardware changes or patching is required at all!

    I was slightly concerned that the USB port of the Pico might clash with the two installed electrolytic capacitors on the MiniDexed PCB, but in my case I can just about get away with it!

    Here is the final assembled unit.

    Closing Thoughts

    I finally have my Eurorack picoDexed which is pretty neat. Big thanks to bablokb for putting that PCB up online. That saved me a job. And it was particularly nice that things like assuming consecutive pins for the I2S mapping was included as that made using the PIO I2S code a lot easier.

    I’d like to see what the power usage is like now as I’m really after a lower power Dexed engine compared to the full Zero version.

    Naturally at some point I might still make my own picoDexed Eurorack PCB, but this is a pretty good solution as far as I’m concerned, so that wouldn’t really add much for me now.

    Kevin

    #midi #minidexed #pcb #picodexed #raspberryPiPico

  5. picoDexed + MiniDexed EuroRack

    Since attempting my picoDexed + StackyPi + MiniDexed EuroRack build and failing, I’ve found another Pico-to-Zero board that is provided as open source, so I’ve had some made.

    This post details how to get that running with my MiniDexed Zero Eurorack module.

    Warning! I strongly recommend using old or second hand equipment for your experiments.  I am not responsible for any damage to expensive instruments!

    If you are new to microcontrollers and single board computers, see the Getting Started pages.

    Pi Zero RP2040s

    As mentioned last time I found a number of options for a RP2040 based dev board in a Raspberry Pi Zero form factor. But this post is about this one:

    It is fairly simple to build. It just requires a Pico and GPIO header pins.

    There is an option for pull-ups on the I2C bus, but I’ve not bothered with them here. There is also a breakout header for a reset switch if required (it will support two sizes of switch by the looks of things).

    Mapping over to MiniDexed/RPi Zero

    The pinout is slightly different to the Stacky-pi, so here is an updated table of the GPIO mappings and which are required to be used with my MiniDexed board.

    RP2040UseRPiRpiUseRP20403V35VGP2LCD SDAGP2 SDA5VGP3LCD SCLGP3 SCLGNDGP4GP4GP14 TXDGP0GNDGP15 RXDMIDI INGP1GP5GP17GP18I2S BCLKGP18GP6GP27GNDGP7GP22GP23GP83V3GP24GP28GP11RE BGP10 MOSIGNDGP12RE AGP9 MISOGP25GP27GP10RE SWGP11 SCLKGP8GP9GNDGP7GP26ID_SDID_SCGP22SW BACKGP5GNDGP13SW HOMEGP6GP12GP21GP14GP13GNDGP19I2S LCLKGP19GP16GP20GP15GP26GP20GP17GNDGP21I2S DATAGP16

    The two key problem areas will be the I2S interface and encoder, which both require consecutive GPIO pins for the PIO code to do its magic.

    The encoder should be fine – pins RE A and RE B map onto the Pico’s GP11 and 12.

    The I2S interface might be ok – with a BCLK on GP18, it will be expecting LCLK on GP19. Data on GP21 should be ok.

    Unlike the previous attempt, I’m hopeful I can just get this running ok with the correct pin mappings…

    Changing I2C Bus and UARTs

    Unlike the first attempt, I2C is mapped onto GP2 and GP3 which is what I was using in the original picoDexed. So that is all fine, multiplexed onto the I2C bus 1.

    There is an issue with the UART however as picoDexed uses the following by default:

    • UART 0 – GP 0,1 – Serial debug
    • UART 1 – GP 4,5 – MIDI

    I can swap these over so that UART0 (GP0,1) is MIDI, but that has to be matched with a change in the debug serial port too. But unfortunately, as far as I can see, that has to be configured in the master CMakeLists.txt file (as I talked about in Part 3).

    New picoDexed GPIO Configuration

    Given the above, the following new GPIO pins should be defined in config.h:

    #define PWM_PIN         10

    #define I2S_DATA_PIN 16
    #define I2S_BCLK_PIN 18
    #define I2S_LRCLK_PIN 19 // Implied by BCLK=12

    #define MIDI_UART 0
    #define MIDI_TX_PIN 0 // Not used
    #define MIDI_RX_PIN 1

    #define DEBUG_UART_TX_PIN 8
    #define DEBUG_UART_RX_PIN 9

    #define DISPLAY_I2C_BUS 1
    #define DISPLAY_I2C_SDA 2
    #define DISPLAY_I2C_SCL 3
    #define DISPLAY_I2C_ADDR 0x3C
    #define DISPLAY_W 128
    #define DISPLAY_H 32

    #define ENCODER_A_PIN 11
    #define ENCODER_B_PIN 12 // Not used
    #define ENCODER_SW_PIN 10 // Not used

    In addition to this, to keep using the debug output requires the following lines adding to ‘target_compile_definitions’ in CMakeLists.txt.

        PICO_DEFAULT_UART=1
    PICO_DEFAULT_UART_TX_PIN=8
    PICO_DEFAULT_UART_RX_PIN=9

    I’ve added a separate configuration file (config-ER.h) in the repository to allow this version to be built, but the CMakelists.txt change above has not been included.

    I’ve also added a picodexed-v0.03-ER.uf2 file in the build area which can be downloaded and installed directly onto the Pico to provide the above configuration ready to go.

    Bringing it all together…

    The nice thing about this PCB is that I can map everything nicely over to the pinouts used with my MiniDexed EuroRack PCB meaning that once the Pico has the custom firmware installed, it will just plug in and work and no hardware changes or patching is required at all!

    I was slightly concerned that the USB port of the Pico might clash with the two installed electrolytic capacitors on the MiniDexed PCB, but in my case I can just about get away with it!

    Here is the final assembled unit.

    Closing Thoughts

    I finally have my Eurorack picoDexed which is pretty neat. Big thanks to bablokb for putting that PCB up online. That saved me a job. And it was particularly nice that things like assuming consecutive pins for the I2S mapping was included as that made using the PIO I2S code a lot easier.

    I’d like to see what the power usage is like now as I’m really after a lower power Dexed engine compared to the full Zero version.

    Naturally at some point I might still make my own picoDexed Eurorack PCB, but this is a pretty good solution as far as I’m concerned, so that wouldn’t really add much for me now.

    Kevin

    #midi #minidexed #pcb #picodexed #raspberryPiPico

  6. picoDexed + StackyPi + MiniDexed EuroRack

    Now that I have a picoDexed with a display an encoder it is very tempting to create a version of my MiniDexed EuroRack PCB for it.

    But as a short diversion, there is another possibility – can I use a RP2040 that is already in a Pi Zero form factor with my existing MiniDexed EuroRack PCB Design?

    Spoilers: The answer, it turns out, is no. Something is not quite letting this work for me – it’s close, but I’m just not there yet. Here is another attempt where it works: picoDexed + MiniDexed EuroRack.

    Warning! I strongly recommend using old or second hand equipment for your experiments.  I am not responsible for any damage to expensive instruments!

    If you are new to microcontrollers and single board computers, see the Getting Started pages.

    Pi Zero RP2040s

    I’m aware of a couple of products that were available to put a RP2040 into a Raspberry Pi Zero form factor:

    The first two were available on Tindie and other places, and as far as I can see, both appear to use the same mapping of RP2040 GPIO to RPi 40-pin header. The Red Robot board doesn’t seem to be available anymore, and whilst there are a few Stacky-Pis on Tindie, in most places it seems to be discontinued.

    I don’t know anything about the Waveshare or Pico to Pi, but might grab myself one of each.

    I’ll give the open source design a try (and possibly save me designing my own…).

    As can be seen above, the Red Robots board is designed to take an actual Pico, whereas the Stacky-Pi is its own board with an on-board RP2040.

    Mapping over to MiniDexed/RPi Zero

    The following table lists the RPi GPIO connections I used in my MiniDexed board and how they map onto the RP2040 using the above boards.

    RP2040UseRPiRpiUseRP20403V35VGP20LCD SDAGP2 SDA5VGP21LCD SCLGP3 SCLGNDGP4GP14 TXDGP0GNDGP15 RXDMIDI INGP1GP17GP18I2S BCLKGP28GP27GNDGP22GP233V3GP24GP3RE BGP10 MOSIGNDGP4RE AGP9 MISOGP25GP2RE SWGP11 SCLKGP8GNDGP7ID_SDID_SCGP10SW BACKGP5GNDGP11SW HOMEGP6GP12GP12GP13GNDGP13I2S LCLKGP19GP16GP26GP20GNDGP21I2S DATAGP15

    The two key problem areas will be the I2S interface and encoder, which both require consecutive GPIO pins for the PIO code to do its magic.

    The encoder should be fine – pins RE A and RE B map onto the Pico’s GP3 and 4.

    The I2S interface is going to be tricky, as with a BCLK on GP28, it will be expecting LCLK on GP29 rather than the GP13 it is currently routed to on the board. Quite apart from the fact that GP29 isn’t even broken out on a Pico.

    The obvious thing to explore is if the BCLK connection can be routed through to GP13 on the RPi header, or GP12 for the RP2040. That would be handy if so.

    Connecting into GP13 should be possible as this pin is currently unconnected on the MiniDexed PCB. It will involve cutting a track however for GP18. The existing track and its new destination is highlighted below in blue.

    Changing I2C Bus and UARTs

    There is one other complication however. The picoDexed configuration has the ssd1306 connected to GP2 and GP3 which are multiplexed onto the I2C bus 1.

    The adaptor configuration maps SDA/SCL onto GP20/21 which are multiplexed onto I2C bus 0. I updated the code to support changing I2C bus in addition to changing IO pins. Arguably, I should probably have supported this in the first place anyway…

    A similar issue exists for the UART, but unfortunately that isn’t quite so easy to change.

    I can take a similar approach to the above for the Serial MIDI link – allowing it to use either UART0 or UART1.

    But that has to be matched with a change in the debug serial port too. But unfortunately, as far as I can see, that has to be configured in the master CMakeLists.txt file (as I talked about in Part 3).

    New picoDexed GPIO Configuration

    Given the above, the following new GPIO pins should be defined in config.h:

    #define PWM_PIN         10

    #define I2S_DATA_PIN 15
    #define I2S_BCLK_PIN 12
    #define I2S_LRCLK_PIN 13 // Implied by BCLK=12

    #define MIDI_UART 0
    #define MIDI_TX_PIN 0 // Not used
    #define MIDI_RX_PIN 1

    #define DEBUG_UART_TX_PIN 8
    #define DEBUG_UART_RX_PIN 9

    #define DISPLAY_I2C_BUS 0
    #define DISPLAY_I2C_SDA 20
    #define DISPLAY_I2C_SCL 21
    #define DISPLAY_I2C_ADDR 0x3C
    #define DISPLAY_W 128
    #define DISPLAY_H 32

    #define ENCODER_A_PIN 3
    #define ENCODER_B_PIN 4 // Not used
    #define ENCODER_SW_PIN 2 // Not used

    In addition to this, to keep using the debug output requires the following lines adding to ‘target_compile_definitions’ in CMakeLists.txt.

        PICO_DEFAULT_UART=1
    PICO_DEFAULT_UART_TX_PIN=8
    PICO_DEFAULT_UART_RX_PIN=9

    Bringing it all together…

    I decided to hack on my (already pretty hacked) prototype MiniDexed EuroRack board and cut and patch the trace to the DAC as described above.

    The complication being the GPIO header pin I need to get to is under the OLED display, but I could just about do it – see below.

    It doesn’t work. Unfortunately.

    First of, I have to say, I’ve not found the Stacky-Pi particularly reliable. It took me ages to get it to successfully boot up into accepting a uf2 file, and once installed, I was struggling to get it to reliably boot and run.

    Weirdly it seems to work best when I have a finger on the flash chip which seems to imply some board layout/grounding/stability issues to me…

    From what I can see, the display, MIDI, serial debug and encoder are working fine though once it does get up and running.

    But I just can’t get any reliable sound out of the thing at all. I managed sound once, but that was it. It is all quiet unreliable for me – far too unreliable to be useful.

    Shame, as it actually looks really cool!

    Closing Thoughts

    It has been a frustrating afternoon. I’m having to leave this one here for now as there are just too many unknowns at the moment to really get to the bottom of what is going on.

    I thought the Stacky-Pi would be a quick and easy fix, but haven’t ever used them before, and the fact that they are discontinued and there is very little information that I can find online about them makes me think perhaps they aren’t worth persevering with.

    So I have a number of options now:

    • Try a Waveshare RP2040 PiZero. As there are a lot more peripherals, I’m not sure how much what I’m doing will translate across, to be honest, it cost wise, it’s essentially the same as a Zero itself, which I know “just works”.
    • Do I design my own Pico to RPI GPIO converter board to let me use that with my existing MiniDexed EuroRack design? Tempting and probably not that hard.
    • Do I attempt to do something with the Pico version of my EuroRack 6HP MCU Experimenter Module? Sounds initially easy but I suspect forcing a MiniDexed into this module eventually will hit other at the moment unforeseen issues.
    • Or do I just go for it and put together a special picoDexed EuroRack module itself.

    I might have one more go with the Stacky-Pi. I haven’t quite given up. I’ll have to do some research – maybe sprinkling a few capacitors around the board or some updated GND connections might help. Answers on a postcard (or in the comments) if you have any ideas.

    I’ll get a Waveshare RP2040 PiZero on order, as I’ve had quite a bit of success with their own “Zero” miniature boards so far, and now I’d like it know if it would work 🙂

    To be continued…

    Kevin

    #define #midi #minidexed #picodexed #raspberryPiPico #StackyPi

  7. picoDexed + StackyPi + MiniDexed EuroRack

    Now that I have a picoDexed with a display an encoder it is very tempting to create a version of my MiniDexed EuroRack PCB for it.

    But as a short diversion, there is another possibility – can I use a RP2040 that is already in a Pi Zero form factor with my existing MiniDexed EuroRack PCB Design?

    Spoilers: The answer, it turns out, is no. Something is not quite letting this work for me – it’s close, but I’m just not there yet. Here is another attempt where it works: picoDexed + MiniDexed EuroRack.

    Warning! I strongly recommend using old or second hand equipment for your experiments.  I am not responsible for any damage to expensive instruments!

    If you are new to microcontrollers and single board computers, see the Getting Started pages.

    Pi Zero RP2040s

    I’m aware of a couple of products that were available to put a RP2040 into a Raspberry Pi Zero form factor:

    The first two were available on Tindie and other places, and as far as I can see, both appear to use the same mapping of RP2040 GPIO to RPi 40-pin header. The Red Robot board doesn’t seem to be available anymore, and whilst there are a few Stacky-Pis on Tindie, in most places it seems to be discontinued.

    I don’t know anything about the Waveshare or Pico to Pi, but might grab myself one of each.

    I’ll give the open source design a try (and possibly save me designing my own…).

    As can be seen above, the Red Robots board is designed to take an actual Pico, whereas the Stacky-Pi is its own board with an on-board RP2040.

    Mapping over to MiniDexed/RPi Zero

    The following table lists the RPi GPIO connections I used in my MiniDexed board and how they map onto the RP2040 using the above boards.

    RP2040UseRPiRpiUseRP20403V35VGP20LCD SDAGP2 SDA5VGP21LCD SCLGP3 SCLGNDGP4GP14 TXDGP0GNDGP15 RXDMIDI INGP1GP17GP18I2S BCLKGP28GP27GNDGP22GP233V3GP24GP3RE BGP10 MOSIGNDGP4RE AGP9 MISOGP25GP2RE SWGP11 SCLKGP8GNDGP7ID_SDID_SCGP10SW BACKGP5GNDGP11SW HOMEGP6GP12GP12GP13GNDGP13I2S LCLKGP19GP16GP26GP20GNDGP21I2S DATAGP15

    The two key problem areas will be the I2S interface and encoder, which both require consecutive GPIO pins for the PIO code to do its magic.

    The encoder should be fine – pins RE A and RE B map onto the Pico’s GP3 and 4.

    The I2S interface is going to be tricky, as with a BCLK on GP28, it will be expecting LCLK on GP29 rather than the GP13 it is currently routed to on the board. Quite apart from the fact that GP29 isn’t even broken out on a Pico.

    The obvious thing to explore is if the BCLK connection can be routed through to GP13 on the RPi header, or GP12 for the RP2040. That would be handy if so.

    Connecting into GP13 should be possible as this pin is currently unconnected on the MiniDexed PCB. It will involve cutting a track however for GP18. The existing track and its new destination is highlighted below in blue.

    Changing I2C Bus and UARTs

    There is one other complication however. The picoDexed configuration has the ssd1306 connected to GP2 and GP3 which are multiplexed onto the I2C bus 1.

    The adaptor configuration maps SDA/SCL onto GP20/21 which are multiplexed onto I2C bus 0. I updated the code to support changing I2C bus in addition to changing IO pins. Arguably, I should probably have supported this in the first place anyway…

    A similar issue exists for the UART, but unfortunately that isn’t quite so easy to change.

    I can take a similar approach to the above for the Serial MIDI link – allowing it to use either UART0 or UART1.

    But that has to be matched with a change in the debug serial port too. But unfortunately, as far as I can see, that has to be configured in the master CMakeLists.txt file (as I talked about in Part 3).

    New picoDexed GPIO Configuration

    Given the above, the following new GPIO pins should be defined in config.h:

    #define PWM_PIN         10

    #define I2S_DATA_PIN 15
    #define I2S_BCLK_PIN 12
    #define I2S_LRCLK_PIN 13 // Implied by BCLK=12

    #define MIDI_UART 0
    #define MIDI_TX_PIN 0 // Not used
    #define MIDI_RX_PIN 1

    #define DEBUG_UART_TX_PIN 8
    #define DEBUG_UART_RX_PIN 9

    #define DISPLAY_I2C_BUS 0
    #define DISPLAY_I2C_SDA 20
    #define DISPLAY_I2C_SCL 21
    #define DISPLAY_I2C_ADDR 0x3C
    #define DISPLAY_W 128
    #define DISPLAY_H 32

    #define ENCODER_A_PIN 3
    #define ENCODER_B_PIN 4 // Not used
    #define ENCODER_SW_PIN 2 // Not used

    In addition to this, to keep using the debug output requires the following lines adding to ‘target_compile_definitions’ in CMakeLists.txt.

        PICO_DEFAULT_UART=1
    PICO_DEFAULT_UART_TX_PIN=8
    PICO_DEFAULT_UART_RX_PIN=9

    Bringing it all together…

    I decided to hack on my (already pretty hacked) prototype MiniDexed EuroRack board and cut and patch the trace to the DAC as described above.

    The complication being the GPIO header pin I need to get to is under the OLED display, but I could just about do it – see below.

    It doesn’t work. Unfortunately.

    First of, I have to say, I’ve not found the Stacky-Pi particularly reliable. It took me ages to get it to successfully boot up into accepting a uf2 file, and once installed, I was struggling to get it to reliably boot and run.

    Weirdly it seems to work best when I have a finger on the flash chip which seems to imply some board layout/grounding/stability issues to me…

    From what I can see, the display, MIDI, serial debug and encoder are working fine though once it does get up and running.

    But I just can’t get any reliable sound out of the thing at all. I managed sound once, but that was it. It is all quiet unreliable for me – far too unreliable to be useful.

    Shame, as it actually looks really cool!

    Closing Thoughts

    It has been a frustrating afternoon. I’m having to leave this one here for now as there are just too many unknowns at the moment to really get to the bottom of what is going on.

    I thought the Stacky-Pi would be a quick and easy fix, but haven’t ever used them before, and the fact that they are discontinued and there is very little information that I can find online about them makes me think perhaps they aren’t worth persevering with.

    So I have a number of options now:

    • Try a Waveshare RP2040 PiZero. As there are a lot more peripherals, I’m not sure how much what I’m doing will translate across, to be honest, it cost wise, it’s essentially the same as a Zero itself, which I know “just works”.
    • Do I design my own Pico to RPI GPIO converter board to let me use that with my existing MiniDexed EuroRack design? Tempting and probably not that hard.
    • Do I attempt to do something with the Pico version of my EuroRack 6HP MCU Experimenter Module? Sounds initially easy but I suspect forcing a MiniDexed into this module eventually will hit other at the moment unforeseen issues.
    • Or do I just go for it and put together a special picoDexed EuroRack module itself.

    I might have one more go with the Stacky-Pi. I haven’t quite given up. I’ll have to do some research – maybe sprinkling a few capacitors around the board or some updated GND connections might help. Answers on a postcard (or in the comments) if you have any ideas.

    I’ll get a Waveshare RP2040 PiZero on order, as I’ve had quite a bit of success with their own “Zero” miniature boards so far, and now I’d like it know if it would work 🙂

    To be continued…

    Kevin

    #define #midi #minidexed #picodexed #raspberryPiPico #StackyPi

  8. One last thing I definitely wanted for my PicoDexed was the option for PWM output. This post is by way of a short coda detailing how to do PWM on a Raspberry Pi Pico.

    • Part 1 where I work out how to build Synth_Dexed using the Pico SDK and get some sounds coming out.
    • Part 2 where I take a detailed look at the performance with a diversion into the workings of the pico_audio library and floating point maths on the pico, on the way.
    • Part 3 where I managed to get up to 16-note polyphony, by overclocking, and some basic serial MIDI support.
    • Part 4 for the full MIDI implementation, voice loading, SysEx control and USB-MIDI.
    • Part 5 details different options for building hardware to run PicoDexed.

    The latest code can be found on GitHub here: https://github.com/diyelectromusic/picodexed

    Warning! I strongly recommend using old or second hand equipment for your experiments.  I am not responsible for any damage to expensive instruments!

    If you are new to microcontrollers, see the Getting Started pages.

    PWM Output Circuit

    The official “Hardware Design with the RP2040” guide includes a PWM circuit as follows (see section 3.4.1).

    Several others have used a slightly simplified version of this circuit, essentially omitting the buffer stage (U3) and perhaps only implementing a single channel. See for example – Raspberry Pi Pico PWM Audio Output Circuit (Jeremy S. Cook) and “pico-pwm-audio” (Robin Grosset).

    An alternative is this circuit used by Tod Kurt for his Circuitpython-tricks“The output circuitry to get line-out levels is a simple 10:1 voltage-divider and a 1uF capacitor to recenter the signal around 0 volts”:

    I’m going with Jeremy S. Cook and Robin Grosset and using the following (diagram from here):

    This is my solderless breadboard version of the above:

    Raspberry Pi Pico Audio PWM

    There appears to be two ways of getting audio style PWM signals out of a Pico:

    • Use the PWM peripherals.
    • Use the PIO.

    It would appear that Raspberry Pi’s pico_audio library in the pico-extras repository uses PIO. I haven’t found a clear explanation as to why the built-in PWM peripherals haven’t been used.

    Here are some other resources that show alternative descriptions of PWM for audion on a Pico:

    As I’m using the pico_audio library for I2S audio, I’m going to use the default PWM pico_audio library too.

    To initialise the pico_audio PWM library requires the following:

    const audio_pwm_channel_config_t config =
    {
    .core = {
    .base_pin = base_pin,
    .dma_channel = dma_ch,
    .pio_sm = pio_sm
    },
    .pattern = 3,
    };

    const struct audio_format *output_format;
    output_format = audio_pwm_setup(pAudioFormat, -1, &config);
    bool status = audio_pwm_default_connect(pBufferPool, false);
    audio_pwm_set_enabled(true);

    Everything else is the same as for I2S.

    At present, overclocking the Pico causes the PWM frequencies to be messed up, so for now the recommended configuration is 8-note polyphony, 24000 sample rate and no overclocking.

    The build uses GPIO 20 for PWM.

    Closing Thoughts

    I’ve uploaded a prototype PWM UF2 file to GitHub too now in case anyone wants to give that a go too: https://github.com/diyelectromusic/picodexed

    Hopefully there is enough information in the above to get something up and running.

    Kevin

    https://diyelectromusic.wordpress.com/2024/02/19/raspberry-pi-pico-synth_dexed-part-6/

    #dx7 #midi #picodexed #pwm #raspberryPiPico #usbMidi

  9. One last thing I definitely wanted for my PicoDexed was the option for PWM output. This post is by way of a short coda detailing how to do PWM on a Raspberry Pi Pico.

    • Part 1 where I work out how to build Synth_Dexed using the Pico SDK and get some sounds coming out.
    • Part 2 where I take a detailed look at the performance with a diversion into the workings of the pico_audio library and floating point maths on the pico, on the way.
    • Part 3 where I managed to get up to 16-note polyphony, by overclocking, and some basic serial MIDI support.
    • Part 4 for the full MIDI implementation, voice loading, SysEx control and USB-MIDI.
    • Part 5 details different options for building hardware to run PicoDexed.

    The latest code can be found on GitHub here: https://github.com/diyelectromusic/picodexed

    Warning! I strongly recommend using old or second hand equipment for your experiments.  I am not responsible for any damage to expensive instruments!

    If you are new to microcontrollers, see the Getting Started pages.

    PWM Output Circuit

    The official “Hardware Design with the RP2040” guide includes a PWM circuit as follows (see section 3.4.1).

    Several others have used a slightly simplified version of this circuit, essentially omitting the buffer stage (U3) and perhaps only implementing a single channel. See for example – Raspberry Pi Pico PWM Audio Output Circuit (Jeremy S. Cook) and “pico-pwm-audio” (Robin Grosset).

    An alternative is this circuit used by Tod Kurt for his Circuitpython-tricks“The output circuitry to get line-out levels is a simple 10:1 voltage-divider and a 1uF capacitor to recenter the signal around 0 volts”:

    I’m going with Jeremy S. Cook and Robin Grosset and using the following (diagram from here):

    This is my solderless breadboard version of the above:

    Raspberry Pi Pico Audio PWM

    There appears to be two ways of getting audio style PWM signals out of a Pico:

    • Use the PWM peripherals.
    • Use the PIO.

    It would appear that Raspberry Pi’s pico_audio library in the pico-extras repository uses PIO. I haven’t found a clear explanation as to why the built-in PWM peripherals haven’t been used.

    Here are some other resources that show alternative descriptions of PWM for audion on a Pico:

    As I’m using the pico_audio library for I2S audio, I’m going to use the default PWM pico_audio library too.

    To initialise the pico_audio PWM library requires the following:

    const audio_pwm_channel_config_t config =
    {
    .core = {
    .base_pin = base_pin,
    .dma_channel = dma_ch,
    .pio_sm = pio_sm
    },
    .pattern = 3,
    };

    const struct audio_format *output_format;
    output_format = audio_pwm_setup(pAudioFormat, -1, &config);
    bool status = audio_pwm_default_connect(pBufferPool, false);
    audio_pwm_set_enabled(true);

    Everything else is the same as for I2S.

    At present, overclocking the Pico causes the PWM frequencies to be messed up, so for now the recommended configuration is 8-note polyphony, 24000 sample rate and no overclocking.

    The build uses GPIO 20 for PWM.

    Closing Thoughts

    I’ve uploaded a prototype PWM UF2 file to GitHub too now in case anyone wants to give that a go too: https://github.com/diyelectromusic/picodexed

    Hopefully there is enough information in the above to get something up and running.

    Kevin

    https://diyelectromusic.wordpress.com/2024/02/19/raspberry-pi-pico-synth_dexed-part-6/

    #dx7 #midi #picodexed #pwm #raspberryPiPico #usbMidi

  10. One last thing I definitely wanted for my PicoDexed was the option for PWM output. This post is by way of a short coda detailing how to do PWM on a Raspberry Pi Pico.

    • Part 1 where I work out how to build Synth_Dexed using the Pico SDK and get some sounds coming out.
    • Part 2 where I take a detailed look at the performance with a diversion into the workings of the pico_audio library and floating point maths on the pico, on the way.
    • Part 3 where I managed to get up to 16-note polyphony, by overclocking, and some basic serial MIDI support.
    • Part 4 for the full MIDI implementation, voice loading, SysEx control and USB-MIDI.
    • Part 5 details different options for building hardware to run PicoDexed.

    The latest code can be found on GitHub here: https://github.com/diyelectromusic/picodexed

    Warning! I strongly recommend using old or second hand equipment for your experiments.  I am not responsible for any damage to expensive instruments!

    If you are new to microcontrollers, see the Getting Started pages.

    PWM Output Circuit

    The official “Hardware Design with the RP2040” guide includes a PWM circuit as follows (see section 3.4.1).

    Several others have used a slightly simplified version of this circuit, essentially omitting the buffer stage (U3) and perhaps only implementing a single channel. See for example – Raspberry Pi Pico PWM Audio Output Circuit (Jeremy S. Cook) and “pico-pwm-audio” (Robin Grosset).

    An alternative is this circuit used by Tod Kurt for his Circuitpython-tricks“The output circuitry to get line-out levels is a simple 10:1 voltage-divider and a 1uF capacitor to recenter the signal around 0 volts”:

    I’m going with Jeremy S. Cook and Robin Grosset and using the following (diagram from here):

    This is my solderless breadboard version of the above:

    Raspberry Pi Pico Audio PWM

    There appears to be two ways of getting audio style PWM signals out of a Pico:

    • Use the PWM peripherals.
    • Use the PIO.

    It would appear that Raspberry Pi’s pico_audio library in the pico-extras repository uses PIO. I haven’t found a clear explanation as to why the built-in PWM peripherals haven’t been used.

    Here are some other resources that show alternative descriptions of PWM for audion on a Pico:

    As I’m using the pico_audio library for I2S audio, I’m going to use the default PWM pico_audio library too.

    To initialise the pico_audio PWM library requires the following:

    const audio_pwm_channel_config_t config =
    {
    .core = {
    .base_pin = base_pin,
    .dma_channel = dma_ch,
    .pio_sm = pio_sm
    },
    .pattern = 3,
    };

    const struct audio_format *output_format;
    output_format = audio_pwm_setup(pAudioFormat, -1, &config);
    bool status = audio_pwm_default_connect(pBufferPool, false);
    audio_pwm_set_enabled(true);

    Everything else is the same as for I2S.

    At present, overclocking the Pico causes the PWM frequencies to be messed up, so for now the recommended configuration is 8-note polyphony, 24000 sample rate and no overclocking.

    The build uses GPIO 20 for PWM.

    Closing Thoughts

    I’ve uploaded a prototype PWM UF2 file to GitHub too now in case anyone wants to give that a go too: https://github.com/diyelectromusic/picodexed

    Hopefully there is enough information in the above to get something up and running.

    Kevin

    https://diyelectromusic.wordpress.com/2024/02/19/raspberry-pi-pico-synth_dexed-part-6/

    #dx7 #midi #picodexed #pwm #raspberryPiPico #usbMidi

  11. Ok, ignore my last comment about Part 4 being my last post on this topic. I thought I ought to pull together all the hardware notes on how to build one as I haven’t really written that down anywhere.

    So this shows the connections required between the Pico, I2S DAC and MIDI IN.

    • Part 1 where I work out how to build Synth_Dexed using the Pico SDK and get some sounds coming out.
    • Part 2 where I take a detailed look at the performance with a diversion into the workings of the pico_audio library and floating point maths on the pico, on the way.
    • Part 3 where I managed to get up to 16-note polyphony, by overclocking, and some basic serial MIDI support.
    • Part 4 for the full MIDI implementation, voice loading, SysEx control and USB-MIDI.
    • Part 6 includes details of how to use PWM output.

    The latest code can be found on GitHub here: https://github.com/diyelectromusic/picodexed

    Warning! I strongly recommend using old or second hand equipment for your experiments.  I am not responsible for any damage to expensive instruments!

    If you are new to microcontrollers, see the Getting Started pages.

    The Circuit

    The easiest way to get a PicoDexed up and running for me, is to use one of my MIDI Proto PCBs and the Pimoroni I2S Audio Pack. This does not allow for any debug output.

    Note the jumpers are set to use UART 1 on GP4 and GP5.

    If only USB-MIDI is required, then the Audio Pack can be plugged directly onto the back of the Pico, in which case simply plugging into the Pico via USB to a computer and connected up the audio out will work.

    It is also possible to use any 3V3 compatible MIDI module. The following shows the use of a Pimoroni “dual expander” with a MIDI module connected to GND, 3V3_OUT and GP5 (RX1).

    This has the advantage that all other GPIO pins are available, so it is relatively straight forward to include a debug link via GP0/GP1 for UART 0.

    A Solderless Breadboard Circuit

    Of course it is also possible to build everything on a solderless breadboard.

    The diagram below shows how a cheap GY-PCM5102 module can be used as the I2S DAC and a serial MIDI interface (optional) can be built using my standard 3V3 MIDI IN circuit.

    This also allows for some debug output using UART 0 (GP0/GP1).

    Things to note:

    • The PCM5102 board will have to have solder jumpers on the rear set as follows: 1=L, 2=L, 3=H, 4=L. Sometimes these come preconfigured with solder bridges, sometimes with zero-ohm SMT resistors, and sometimes with no connection made at all. More details here.
    • I always get pins 4 and 5 mixed up on MIDI DIN sockets. Here is my MIDI Connections Cheat Sheet which may help.

    Pico GPIO Usage

    The following GPIO pins are in use or allocated:

    GP0Debug UART TX (unused at present)GP1Debug UART RXGP4MIDI TX (unused at present)GP5MIDI RXGP9I2S Data (DATA, DIN)GP10I2S Bit Clock (BCK)GP11I2S “Left/Right” Clock (LCK, LRCK, LR_CLOCK)GP20Optional: PWM outputGP22Optional: Mute pin for the Pimoroni Audio Pack (not used)VSYS5V power to DAC (if required)3V3_OUT3V3 power to MIDI IN (if required)GND

    PWM Audio Output

    It is possible to use PWM audio output on the Pico. Full details can be found here: Raspberry Pi Pico Synth_Dexed? – Part 6.

    But this is a lot more limited than I2S and the quality is a lot poorer too. As a DAC can be obtained quite cheaply, the use of an I2S DAC is strongly recommended.

    Closing Thoughts

    I’ve uploaded a prototype UF2 file to GitHub in case anyone wants to give it a go: everything can be found here: https://github.com/diyelectromusic/picodexed

    Hopefully there is enough information in the above to get something up and running.

    Kevin

    https://diyelectromusic.wordpress.com/2024/02/18/raspberry-pi-pico-synth_dexed-part-5/

    #dx7 #midi #pcm5102 #picodexed #raspberryPiPico #usbMidi

  12. Ok, ignore my last comment about Part 4 being my last post on this topic. I thought I ought to pull together all the hardware notes on how to build one as I haven’t really written that down anywhere.

    So this shows the connections required between the Pico, I2S DAC and MIDI IN.

    • Part 1 where I work out how to build Synth_Dexed using the Pico SDK and get some sounds coming out.
    • Part 2 where I take a detailed look at the performance with a diversion into the workings of the pico_audio library and floating point maths on the pico, on the way.
    • Part 3 where I managed to get up to 16-note polyphony, by overclocking, and some basic serial MIDI support.
    • Part 4 for the full MIDI implementation, voice loading, SysEx control and USB-MIDI.
    • Part 6 includes details of how to use PWM output.

    The latest code can be found on GitHub here: https://github.com/diyelectromusic/picodexed

    Warning! I strongly recommend using old or second hand equipment for your experiments.  I am not responsible for any damage to expensive instruments!

    If you are new to microcontrollers, see the Getting Started pages.

    The Circuit

    The easiest way to get a PicoDexed up and running for me, is to use one of my MIDI Proto PCBs and the Pimoroni I2S Audio Pack. This does not allow for any debug output.

    Note the jumpers are set to use UART 1 on GP4 and GP5.

    If only USB-MIDI is required, then the Audio Pack can be plugged directly onto the back of the Pico, in which case simply plugging into the Pico via USB to a computer and connected up the audio out will work.

    It is also possible to use any 3V3 compatible MIDI module. The following shows the use of a Pimoroni “dual expander” with a MIDI module connected to GND, 3V3_OUT and GP5 (RX1).

    This has the advantage that all other GPIO pins are available, so it is relatively straight forward to include a debug link via GP0/GP1 for UART 0.

    A Solderless Breadboard Circuit

    Of course it is also possible to build everything on a solderless breadboard.

    The diagram below shows how a cheap GY-PCM5102 module can be used as the I2S DAC and a serial MIDI interface (optional) can be built using my standard 3V3 MIDI IN circuit.

    This also allows for some debug output using UART 0 (GP0/GP1).

    Things to note:

    • The PCM5102 board will have to have solder jumpers on the rear set as follows: 1=L, 2=L, 3=H, 4=L. Sometimes these come preconfigured with solder bridges, sometimes with zero-ohm SMT resistors, and sometimes with no connection made at all. More details here.
    • I always get pins 4 and 5 mixed up on MIDI DIN sockets. Here is my MIDI Connections Cheat Sheet which may help.

    Pico GPIO Usage

    The following GPIO pins are in use or allocated:

    GP0Debug UART TX (unused at present)GP1Debug UART RXGP4MIDI TX (unused at present)GP5MIDI RXGP9I2S Data (DATA, DIN)GP10I2S Bit Clock (BCK)GP11I2S “Left/Right” Clock (LCK, LRCK, LR_CLOCK)GP20Optional: PWM outputGP22Optional: Mute pin for the Pimoroni Audio Pack (not used)VSYS5V power to DAC (if required)3V3_OUT3V3 power to MIDI IN (if required)GND

    PWM Audio Output

    It is possible to use PWM audio output on the Pico. Full details can be found here: Raspberry Pi Pico Synth_Dexed? – Part 6.

    But this is a lot more limited than I2S and the quality is a lot poorer too. As a DAC can be obtained quite cheaply, the use of an I2S DAC is strongly recommended.

    Closing Thoughts

    I’ve uploaded a prototype UF2 file to GitHub in case anyone wants to give it a go: everything can be found here: https://github.com/diyelectromusic/picodexed

    Hopefully there is enough information in the above to get something up and running.

    Kevin

    https://diyelectromusic.wordpress.com/2024/02/18/raspberry-pi-pico-synth_dexed-part-5/

    #dx7 #midi #pcm5102 #picodexed #raspberryPiPico #usbMidi

  13. Ok, ignore my last comment about Part 4 being my last post on this topic. I thought I ought to pull together all the hardware notes on how to build one as I haven’t really written that down anywhere.

    So this shows the connections required between the Pico, I2S DAC and MIDI IN.

    • Part 1 where I work out how to build Synth_Dexed using the Pico SDK and get some sounds coming out.
    • Part 2 where I take a detailed look at the performance with a diversion into the workings of the pico_audio library and floating point maths on the pico, on the way.
    • Part 3 where I managed to get up to 16-note polyphony, by overclocking, and some basic serial MIDI support.
    • Part 4 for the full MIDI implementation, voice loading, SysEx control and USB-MIDI.
    • Part 6 includes details of how to use PWM output.

    The latest code can be found on GitHub here: https://github.com/diyelectromusic/picodexed

    Warning! I strongly recommend using old or second hand equipment for your experiments.  I am not responsible for any damage to expensive instruments!

    If you are new to microcontrollers, see the Getting Started pages.

    The Circuit

    The easiest way to get a PicoDexed up and running for me, is to use one of my MIDI Proto PCBs and the Pimoroni I2S Audio Pack. This does not allow for any debug output.

    Note the jumpers are set to use UART 1 on GP4 and GP5.

    If only USB-MIDI is required, then the Audio Pack can be plugged directly onto the back of the Pico, in which case simply plugging into the Pico via USB to a computer and connected up the audio out will work.

    It is also possible to use any 3V3 compatible MIDI module. The following shows the use of a Pimoroni “dual expander” with a MIDI module connected to GND, 3V3_OUT and GP5 (RX1).

    This has the advantage that all other GPIO pins are available, so it is relatively straight forward to include a debug link via GP0/GP1 for UART 0.

    A Solderless Breadboard Circuit

    Of course it is also possible to build everything on a solderless breadboard.

    The diagram below shows how a cheap GY-PCM5102 module can be used as the I2S DAC and a serial MIDI interface (optional) can be built using my standard 3V3 MIDI IN circuit.

    This also allows for some debug output using UART 0 (GP0/GP1).

    Things to note:

    • The PCM5102 board will have to have solder jumpers on the rear set as follows: 1=L, 2=L, 3=H, 4=L. Sometimes these come preconfigured with solder bridges, sometimes with zero-ohm SMT resistors, and sometimes with no connection made at all. More details here.
    • I always get pins 4 and 5 mixed up on MIDI DIN sockets. Here is my MIDI Connections Cheat Sheet which may help.

    Pico GPIO Usage

    The following GPIO pins are in use or allocated:

    GP0Debug UART TX (unused at present)GP1Debug UART RXGP4MIDI TX (unused at present)GP5MIDI RXGP9I2S Data (DATA, DIN)GP10I2S Bit Clock (BCK)GP11I2S “Left/Right” Clock (LCK, LRCK, LR_CLOCK)GP20Optional: PWM outputGP22Optional: Mute pin for the Pimoroni Audio Pack (not used)VSYS5V power to DAC (if required)3V3_OUT3V3 power to MIDI IN (if required)GND

    PWM Audio Output

    It is possible to use PWM audio output on the Pico. Full details can be found here: Raspberry Pi Pico Synth_Dexed? – Part 6.

    But this is a lot more limited than I2S and the quality is a lot poorer too. As a DAC can be obtained quite cheaply, the use of an I2S DAC is strongly recommended.

    Closing Thoughts

    I’ve uploaded a prototype UF2 file to GitHub in case anyone wants to give it a go: everything can be found here: https://github.com/diyelectromusic/picodexed

    Hopefully there is enough information in the above to get something up and running.

    Kevin

    https://diyelectromusic.wordpress.com/2024/02/18/raspberry-pi-pico-synth_dexed-part-5/

    #dx7 #midi #pcm5102 #picodexed #raspberryPiPico #usbMidi

  14. I was going to leave things at Part 3 blog-wise, and just get on with filling in the gaps in code now, but I’ve come back to add a few more notes. But this is likely to be the final part now.

    Recall so far, I have:

    • Part 1 where I work out how to build Synth_Dexed using the Pico SDK and get some sounds coming out.
    • Part 2 where I take a detailed look at the performance with a diversion into the workings of the pico_audio library and floating point maths on the pico, on the way.
    • Part 3 where I managed to get up to 16-note polyphony, by overclocking, and some basic serial MIDI support.

    This is building on the last part and includes notes on how I’ve implemented the following:

    • Fuller MIDI support, including control change, program change and pitch bend messages.
    • Voice and voice banks, selectable over MIDI.
    • MIDI SysEx messages for voice parameters.
    • USB MIDI device support.

    The latest code can be found on GitHub here: https://github.com/diyelectromusic/picodexed

    Warning! I strongly recommend using old or second hand equipment for your experiments.  I am not responsible for any damage to expensive instruments!

    If you are new to microcontrollers, see the Getting Started pages.

    MIDI Support

    I’m not going to walk through all the details of how I’ve added MIDI but suffice to say that once again the implementation owes a lot to MiniDexed and the Arduino MIDI Library.

    At the time of writing the following are all supported as they were already supported in Synth_Dexed, so I just needed to glue the bits together.

    Channel Voice Messages (only channel 1 at present)

    0x80MIDI Note Offnote=0..127, vel=0..1270x90MIDI Note Onnote=0..127, vel=0..1270xA0Channel Aftertouchnote=0..127, val=0..1270xB0Control ChangeSee below0xC0Program Change0..31 (If used with BANKSEL)
    0..127 (if used independently)0xE0Pitch Bend0..16383 (in LSB/MSB 2×7-bit format)

    Channel Control Change Messages

    0Bank Select (MSB)01Modulation0..1272Breath Control0..1274Foot Control0..1277Channel Volume0..12732Bank Select (LSB)0..864Sustain<=63 Off, 64=> On65Portamento<=63 Off, 64=> On95Master Tune0..127 *120All Sound Off0123All Notes Off0126Mono Mode0 **127Poly Mode0

    * There is a bug with the master tuning. It ought to accept -99 to 99 I believe, but only 0..99 will actually register and there is no way to send -99 via MIDI at the moment. I need to read up on what is going on here and what it ought to do!

    ** The Mono Mode parameter has the option for specifying how many of the playable voices can be dedicated to mono mode (at least I think that is what it is saying). I only support a value of 0 which I believe is meant to mean “all available voices”.

    System Messages

    0xF0..0xF7Start/End System ExclusiveSee below0xFEActive SensingFiltered out0xFnOther system messagesIgnored

    System Exclusive Messages

    Any valid Yamaha (DX) system exclusive messages are passed straight into Synth_Dexed. A Yamaha (DX) message has the following format (see the “DX7IIFD/D Supplemental Booklet: Advanced MIDI Data and Charts”):

    F0 - start SysEx message
    43 - Yamaha manufacturer ID
    sd - s=substatus (command class:0,1,2); d=device ID (0..F)
    .. data ..
    F7 - end SysEx message

    The device ID can be set using the UI on a real DX7 to a value between 1 and 16, which becomes a value between 0 and 15 (0..F) as part of the SysEx message (see “DX7IIFD/D Supplemental Booklet: Advanced MIDI Applications, Section 8”). It is a Systems Exclusive value analogous to the MIDI channel for regular channel messages.

    There are a range of Sys Ex parameter settings that have been passed onto Synth_Dexed as follows:

    Mono Mode0..1Pitch Bend Range0..12Pitch Bend Step0..12Portamento Mode0..1Portamento Glissando0..1Portamento Time0..99Mod Wheel Range0..99Mod Wheel Target0..7Foot Control Range0..99Foot Control Target0..7Breath Control Range0..99Breath Control Target0..7Aftertouch Range0..99Aftertouch Target0..7Voice Dump Load<156 bytes of voice data>Voice Parameter SetParameter=0..155; Data=0..99

    At this stage, all of the MIDI support is on a “it’s probably something like this” basis, so it will evolve as I find out what it is meant to be doing!

    Voice and Bank Loading

    Banks of voices are programmed directly into the code. There is a python script from Synth_Dexed that will take a .syx format voice bank and generate a block of C code. I’ve included a script to download the main 8 banks of standard DX voices and run the script:

    #!/bin/sh

    # Get voices from
    # https://yamahablackboxes.com/collection/yamaha-dx7-synthesizer/patches/

    mkdir -p voices

    DIR="https://yamahablackboxes.com/patches/dx7/factory"

    wget -c "${DIR}"/rom1a.syx -O voices/rom1a.syx
    wget -c "${DIR}"/rom1b.syx -O voices/rom1b.syx
    wget -c "${DIR}"/rom2a.syx -O voices/rom2a.syx
    wget -c "${DIR}"/rom2b.syx -O voices/rom2b.syx
    wget -c "${DIR}"/rom3a.syx -O voices/rom3a.syx
    wget -c "${DIR}"/rom3b.syx -O voices/rom3b.syx
    wget -c "${DIR}"/rom4a.syx -O voices/rom4a.syx
    wget -c "${DIR}"/rom4b.syx -O voices/rom4b.syx

    ./synth_dexed/Synth_Dexed/tools/sysex2c.py voices/* > src/voices.h

    This only needs to be run once to create the src/voices.h file which is then included in the build.

    Voices have the following format:

    uint8_t progmem_bank[8][32][128] PROGMEM =
    {
    { // Bank 1
    {<--128 bytes of packed voice data-->} // Voice 1
    ...
    {<--128 bytes of packed voice data-->} // Voice 32
    }
    { // Bank 2
    ...
    }
    ...
    { // Bank 8
    {<--128 bytes of packed voice data-->} // Voice 1
    ...
    {<--128 bytes of packed voice data-->} // Voice 32
    }
    }

    The system assumes 8 banks of 32 voices each, in the “packed” SYX header format, meaning each voice consists of 128 bytes.

    MIDI Bank and Voice Selection

    As there are only 8 banks, only BANKSEL (LSB) values 0..7 are valid. Program Change will work in two ways however:

    • 0..31 will select voices 1 to 32 in the current bank.
    • 31..127 will select voices from the following three adjacent banks.

    To select any voice in all 8 banks thus requires the following sequence:

    BANKSEL MSB = 0
    BANKSEL LSB = 0..7
    PROG CHANGE = 0..31

    But if bank selection is skipped, then Program Change messages can still be used to select one of the first 128 voices across four consecutive banks.

    USB MIDI

    The Raspberry Pi Pico SDK uses the TinyUSB protocol stack to implement USB device or host modes and there is an additional option to implement a second USB host port using the Pico’s PIO.

    However, USB MIDI appears to only be supported for USB devices at the time of writing, so I’m just using the built-in USB port as a USB device, based on the code provided as part of the TinyUSB examples (more details of how to get basic USB MIDI running here).

    TinyUSB MIDI supports two interfaces for reading data, and this wasn’t immediately obvious from the example as that is only sending data and ignores anything coming in.

    • USB MIDI Stream mode: this will fill a provided buffer with MIDI data received over USB.
    • USB MIDI Packet mode: this will return each 4-byte USB packet individually.

    From what I can see of the USB MIDI Spec, all MIDI messages are turned into 4-byte packets for transferring over USB. All normal MIDI messages will consist of 1, 2 or 3 byte messages, and so will fit in a packet each – any unused bytes are padded with 0.

    However SysEx messages are a little more complicated and have to be split across multiple packets.

    This is the format for a USB MIDI Event Packet (see the “Universal Serial Bus Device Class Definition for MIDI Devices”, Release 1.0):

    The code index number is an indication of the contents of each packet. For channel messages, this is basically a repeat of the MIDI command, so a MIDI Note On message might look something like the following:

    09 92 3C 64
    Cable 0
    Code Index Number 9
    MIDI Cmd 0x90 (Note On)
    MIDI Channel 3 (0x0=1; 0x1=2; 0x2=3; ... 0xF=16)
    Note 0x3C (60 = C4)
    Velocity 0x64 (100)

    But things get a little more complex with System Common or System Exclusive messages which have their own set of codes, depending on the chunking of the packets required.

    The critical ones for SysEx are CIN=4,5,6,7 which correspond to SysEx start and then various versions of continuation or end packets. So a larger SysEx message might look something like the following

    04 F0 43 10 -- SysEx Start or Continuation
    04 34 44 4D -- SysEx Start or Continuation
    06 3E F7 00 -- SysEx End after two bytes

    Complete message: F0 43 10 34 44 4D 3E F7

    So, if I opt to use the packet interface to TinyUSB MIDI then all this has to be sorted out in user code myself. However, the streaming interface will take care of all this for me and just return a buffer full of “traditional” MIDI messages.

    Note that there is no concept of Running Status in USB MIDI. Even the oldest USB standard protocol speeds are an order of magnitude, or more, higher than serial MIDI so it isn’t necessary. Every MIDI message will either be a complete 1,2,3 byte message in a single USB packet, or a SysEx multi-packet message as described above.

    The basic structure of the USB MIDI handler is as follows:

    Init:
    Initialise TinyUSB MIDI stack

    Process:
    Run the TinyUSB MIDI task
    IF TinyUSB says MIDI data available:
    Call the stream API to fill our RX buffer
    WHILE data in the RX buffer:
    Call the MIDIParser which reads from the RX buffer
    IF MIDI messages found:
    Call the MIDI Message Handler

    Read:
    Grab the next byte from the RX buffer

    I’ve actually split this over two files: usbmidi.cpp is the companion to serialmidi.cpp and provides the class that inherits from MIDIDevice (which provides the parser and message handler); usbtask.c provides the interface into the TinyUSB C driver code.

    I haven’t done anything special with a USB manufacturer/vendor and device ID yet – so at some point I should see what TinyUSB is using by default and find something unique to PicoDexed (assuming I take it forward in any useful way).

    Closing Thoughts

    I have a fairly complete implementation now, which is quite nice. I do need to find some way to properly exercise the voice loading over SysEx and it would be good to get some idea of the performance when I throw a MIDI file at it over USB!

    I’ve tested some of the parameter changes using the PC version of Dexed. When configured correctly, this can be used to send voice parameter changes to PicoDexed, but I haven’t found a way to download the entire voice as yet.

    It’s a shame I can’t just plug in a USB MIDI controller and play it now, but I’ll work on some kind of interface board that should allow me to do it. It will need to be independently powered to act as a USB host anyway.

    This is probably going to be my last blog post on PicoDexed for now, but I plan to keep tinkering away at the GitHub repository to see how things go. There are still a couple of limitations, the main one being that everything has to be hard-coded in at present. It would be nice to be able to have some kind of system configuration facility for the MIDI channel if nothing else.

    At some point it would also be nice to have a build on the GitHub so others can try it too. And I still need to decide how best to manage the changes I needed to make to Synth_Dexed.

    Kevin

    https://diyelectromusic.wordpress.com/2024/02/16/raspberry-pi-pico-synth_dexed-part-4/

    #dx7 #midi #picodexed #raspberryPiPico #usbMidi

  15. I was going to leave things at Part 3 blog-wise, and just get on with filling in the gaps in code now, but I’ve come back to add a few more notes. But this is likely to be the final part now.

    Recall so far, I have:

    • Part 1 where I work out how to build Synth_Dexed using the Pico SDK and get some sounds coming out.
    • Part 2 where I take a detailed look at the performance with a diversion into the workings of the pico_audio library and floating point maths on the pico, on the way.
    • Part 3 where I managed to get up to 16-note polyphony, by overclocking, and some basic serial MIDI support.

    This is building on the last part and includes notes on how I’ve implemented the following:

    • Fuller MIDI support, including control change, program change and pitch bend messages.
    • Voice and voice banks, selectable over MIDI.
    • MIDI SysEx messages for voice parameters.
    • USB MIDI device support.

    The latest code can be found on GitHub here: https://github.com/diyelectromusic/picodexed

    Warning! I strongly recommend using old or second hand equipment for your experiments.  I am not responsible for any damage to expensive instruments!

    If you are new to microcontrollers, see the Getting Started pages.

    MIDI Support

    I’m not going to walk through all the details of how I’ve added MIDI but suffice to say that once again the implementation owes a lot to MiniDexed and the Arduino MIDI Library.

    At the time of writing the following are all supported as they were already supported in Synth_Dexed, so I just needed to glue the bits together.

    Channel Voice Messages (only channel 1 at present)

    0x80MIDI Note Offnote=0..127, vel=0..1270x90MIDI Note Onnote=0..127, vel=0..1270xA0Channel Aftertouchnote=0..127, val=0..1270xB0Control ChangeSee below0xC0Program Change0..31 (If used with BANKSEL)
    0..127 (if used independently)0xE0Pitch Bend0..16383 (in LSB/MSB 2×7-bit format)

    Channel Control Change Messages

    0Bank Select (MSB)01Modulation0..1272Breath Control0..1274Foot Control0..1277Channel Volume0..12732Bank Select (LSB)0..864Sustain<=63 Off, 64=> On65Portamento<=63 Off, 64=> On95Master Tune0..127 *120All Sound Off0123All Notes Off0126Mono Mode0 **127Poly Mode0

    * There is a bug with the master tuning. It ought to accept -99 to 99 I believe, but only 0..99 will actually register and there is no way to send -99 via MIDI at the moment. I need to read up on what is going on here and what it ought to do!

    ** The Mono Mode parameter has the option for specifying how many of the playable voices can be dedicated to mono mode (at least I think that is what it is saying). I only support a value of 0 which I believe is meant to mean “all available voices”.

    System Messages

    0xF0..0xF7Start/End System ExclusiveSee below0xFEActive SensingFiltered out0xFnOther system messagesIgnored

    System Exclusive Messages

    Any valid Yamaha (DX) system exclusive messages are passed straight into Synth_Dexed. A Yamaha (DX) message has the following format (see the “DX7IIFD/D Supplemental Booklet: Advanced MIDI Data and Charts”):

    F0 - start SysEx message
    43 - Yamaha manufacturer ID
    sd - s=substatus (command class:0,1,2); d=device ID (0..F)
    .. data ..
    F7 - end SysEx message

    The device ID can be set using the UI on a real DX7 to a value between 1 and 16, which becomes a value between 0 and 15 (0..F) as part of the SysEx message (see “DX7IIFD/D Supplemental Booklet: Advanced MIDI Applications, Section 8”). It is a Systems Exclusive value analogous to the MIDI channel for regular channel messages.

    There are a range of Sys Ex parameter settings that have been passed onto Synth_Dexed as follows:

    Mono Mode0..1Pitch Bend Range0..12Pitch Bend Step0..12Portamento Mode0..1Portamento Glissando0..1Portamento Time0..99Mod Wheel Range0..99Mod Wheel Target0..7Foot Control Range0..99Foot Control Target0..7Breath Control Range0..99Breath Control Target0..7Aftertouch Range0..99Aftertouch Target0..7Voice Dump Load<156 bytes of voice data>Voice Parameter SetParameter=0..155; Data=0..99

    At this stage, all of the MIDI support is on a “it’s probably something like this” basis, so it will evolve as I find out what it is meant to be doing!

    Voice and Bank Loading

    Banks of voices are programmed directly into the code. There is a python script from Synth_Dexed that will take a .syx format voice bank and generate a block of C code. I’ve included a script to download the main 8 banks of standard DX voices and run the script:

    #!/bin/sh

    # Get voices from
    # https://yamahablackboxes.com/collection/yamaha-dx7-synthesizer/patches/

    mkdir -p voices

    DIR="https://yamahablackboxes.com/patches/dx7/factory"

    wget -c "${DIR}"/rom1a.syx -O voices/rom1a.syx
    wget -c "${DIR}"/rom1b.syx -O voices/rom1b.syx
    wget -c "${DIR}"/rom2a.syx -O voices/rom2a.syx
    wget -c "${DIR}"/rom2b.syx -O voices/rom2b.syx
    wget -c "${DIR}"/rom3a.syx -O voices/rom3a.syx
    wget -c "${DIR}"/rom3b.syx -O voices/rom3b.syx
    wget -c "${DIR}"/rom4a.syx -O voices/rom4a.syx
    wget -c "${DIR}"/rom4b.syx -O voices/rom4b.syx

    ./synth_dexed/Synth_Dexed/tools/sysex2c.py voices/* > src/voices.h

    This only needs to be run once to create the src/voices.h file which is then included in the build.

    Voices have the following format:

    uint8_t progmem_bank[8][32][128] PROGMEM =
    {
    { // Bank 1
    {<--128 bytes of packed voice data-->} // Voice 1
    ...
    {<--128 bytes of packed voice data-->} // Voice 32
    }
    { // Bank 2
    ...
    }
    ...
    { // Bank 8
    {<--128 bytes of packed voice data-->} // Voice 1
    ...
    {<--128 bytes of packed voice data-->} // Voice 32
    }
    }

    The system assumes 8 banks of 32 voices each, in the “packed” SYX header format, meaning each voice consists of 128 bytes.

    MIDI Bank and Voice Selection

    As there are only 8 banks, only BANKSEL (LSB) values 0..7 are valid. Program Change will work in two ways however:

    • 0..31 will select voices 1 to 32 in the current bank.
    • 31..127 will select voices from the following three adjacent banks.

    To select any voice in all 8 banks thus requires the following sequence:

    BANKSEL MSB = 0
    BANKSEL LSB = 0..7
    PROG CHANGE = 0..31

    But if bank selection is skipped, then Program Change messages can still be used to select one of the first 128 voices across four consecutive banks.

    USB MIDI

    The Raspberry Pi Pico SDK uses the TinyUSB protocol stack to implement USB device or host modes and there is an additional option to implement a second USB host port using the Pico’s PIO.

    However, USB MIDI appears to only be supported for USB devices at the time of writing, so I’m just using the built-in USB port as a USB device, based on the code provided as part of the TinyUSB examples (more details of how to get basic USB MIDI running here).

    TinyUSB MIDI supports two interfaces for reading data, and this wasn’t immediately obvious from the example as that is only sending data and ignores anything coming in.

    • USB MIDI Stream mode: this will fill a provided buffer with MIDI data received over USB.
    • USB MIDI Packet mode: this will return each 4-byte USB packet individually.

    From what I can see of the USB MIDI Spec, all MIDI messages are turned into 4-byte packets for transferring over USB. All normal MIDI messages will consist of 1, 2 or 3 byte messages, and so will fit in a packet each – any unused bytes are padded with 0.

    However SysEx messages are a little more complicated and have to be split across multiple packets.

    This is the format for a USB MIDI Event Packet (see the “Universal Serial Bus Device Class Definition for MIDI Devices”, Release 1.0):

    The code index number is an indication of the contents of each packet. For channel messages, this is basically a repeat of the MIDI command, so a MIDI Note On message might look something like the following:

    09 92 3C 64
    Cable 0
    Code Index Number 9
    MIDI Cmd 0x90 (Note On)
    MIDI Channel 3 (0x0=1; 0x1=2; 0x2=3; ... 0xF=16)
    Note 0x3C (60 = C4)
    Velocity 0x64 (100)

    But things get a little more complex with System Common or System Exclusive messages which have their own set of codes, depending on the chunking of the packets required.

    The critical ones for SysEx are CIN=4,5,6,7 which correspond to SysEx start and then various versions of continuation or end packets. So a larger SysEx message might look something like the following

    04 F0 43 10 -- SysEx Start or Continuation
    04 34 44 4D -- SysEx Start or Continuation
    06 3E F7 00 -- SysEx End after two bytes

    Complete message: F0 43 10 34 44 4D 3E F7

    So, if I opt to use the packet interface to TinyUSB MIDI then all this has to be sorted out in user code myself. However, the streaming interface will take care of all this for me and just return a buffer full of “traditional” MIDI messages.

    Note that there is no concept of Running Status in USB MIDI. Even the oldest USB standard protocol speeds are an order of magnitude, or more, higher than serial MIDI so it isn’t necessary. Every MIDI message will either be a complete 1,2,3 byte message in a single USB packet, or a SysEx multi-packet message as described above.

    The basic structure of the USB MIDI handler is as follows:

    Init:
    Initialise TinyUSB MIDI stack

    Process:
    Run the TinyUSB MIDI task
    IF TinyUSB says MIDI data available:
    Call the stream API to fill our RX buffer
    WHILE data in the RX buffer:
    Call the MIDIParser which reads from the RX buffer
    IF MIDI messages found:
    Call the MIDI Message Handler

    Read:
    Grab the next byte from the RX buffer

    I’ve actually split this over two files: usbmidi.cpp is the companion to serialmidi.cpp and provides the class that inherits from MIDIDevice (which provides the parser and message handler); usbtask.c provides the interface into the TinyUSB C driver code.

    I haven’t done anything special with a USB manufacturer/vendor and device ID yet – so at some point I should see what TinyUSB is using by default and find something unique to PicoDexed (assuming I take it forward in any useful way).

    Closing Thoughts

    I have a fairly complete implementation now, which is quite nice. I do need to find some way to properly exercise the voice loading over SysEx and it would be good to get some idea of the performance when I throw a MIDI file at it over USB!

    I’ve tested some of the parameter changes using the PC version of Dexed. When configured correctly, this can be used to send voice parameter changes to PicoDexed, but I haven’t found a way to download the entire voice as yet.

    It’s a shame I can’t just plug in a USB MIDI controller and play it now, but I’ll work on some kind of interface board that should allow me to do it. It will need to be independently powered to act as a USB host anyway.

    This is probably going to be my last blog post on PicoDexed for now, but I plan to keep tinkering away at the GitHub repository to see how things go. There are still a couple of limitations, the main one being that everything has to be hard-coded in at present. It would be nice to be able to have some kind of system configuration facility for the MIDI channel if nothing else.

    At some point it would also be nice to have a build on the GitHub so others can try it too. And I still need to decide how best to manage the changes I needed to make to Synth_Dexed.

    Kevin

    https://diyelectromusic.wordpress.com/2024/02/16/raspberry-pi-pico-synth_dexed-part-4/

    #dx7 #midi #picodexed #raspberryPiPico #usbMidi

  16. I was going to leave things at Part 3 blog-wise, and just get on with filling in the gaps in code now, but I’ve come back to add a few more notes. But this is likely to be the final part now.

    Recall so far, I have:

    • Part 1 where I work out how to build Synth_Dexed using the Pico SDK and get some sounds coming out.
    • Part 2 where I take a detailed look at the performance with a diversion into the workings of the pico_audio library and floating point maths on the pico, on the way.
    • Part 3 where I managed to get up to 16-note polyphony, by overclocking, and some basic serial MIDI support.

    This is building on the last part and includes notes on how I’ve implemented the following:

    • Fuller MIDI support, including control change, program change and pitch bend messages.
    • Voice and voice banks, selectable over MIDI.
    • MIDI SysEx messages for voice parameters.
    • USB MIDI device support.

    The latest code can be found on GitHub here: https://github.com/diyelectromusic/picodexed

    Warning! I strongly recommend using old or second hand equipment for your experiments.  I am not responsible for any damage to expensive instruments!

    If you are new to microcontrollers, see the Getting Started pages.

    MIDI Support

    I’m not going to walk through all the details of how I’ve added MIDI but suffice to say that once again the implementation owes a lot to MiniDexed and the Arduino MIDI Library.

    At the time of writing the following are all supported as they were already supported in Synth_Dexed, so I just needed to glue the bits together.

    Channel Voice Messages (only channel 1 at present)

    0x80MIDI Note Offnote=0..127, vel=0..1270x90MIDI Note Onnote=0..127, vel=0..1270xA0Channel Aftertouchnote=0..127, val=0..1270xB0Control ChangeSee below0xC0Program Change0..31 (If used with BANKSEL)
    0..127 (if used independently)0xE0Pitch Bend0..16383 (in LSB/MSB 2×7-bit format)

    Channel Control Change Messages

    0Bank Select (MSB)01Modulation0..1272Breath Control0..1274Foot Control0..1277Channel Volume0..12732Bank Select (LSB)0..864Sustain<=63 Off, 64=> On65Portamento<=63 Off, 64=> On95Master Tune0..127 *120All Sound Off0123All Notes Off0126Mono Mode0 **127Poly Mode0

    * There is a bug with the master tuning. It ought to accept -99 to 99 I believe, but only 0..99 will actually register and there is no way to send -99 via MIDI at the moment. I need to read up on what is going on here and what it ought to do!

    ** The Mono Mode parameter has the option for specifying how many of the playable voices can be dedicated to mono mode (at least I think that is what it is saying). I only support a value of 0 which I believe is meant to mean “all available voices”.

    System Messages

    0xF0..0xF7Start/End System ExclusiveSee below0xFEActive SensingFiltered out0xFnOther system messagesIgnored

    System Exclusive Messages

    Any valid Yamaha (DX) system exclusive messages are passed straight into Synth_Dexed. A Yamaha (DX) message has the following format (see the “DX7IIFD/D Supplemental Booklet: Advanced MIDI Data and Charts”):

    F0 - start SysEx message
    43 - Yamaha manufacturer ID
    sd - s=substatus (command class:0,1,2); d=device ID (0..F)
    .. data ..
    F7 - end SysEx message

    The device ID can be set using the UI on a real DX7 to a value between 1 and 16, which becomes a value between 0 and 15 (0..F) as part of the SysEx message (see “DX7IIFD/D Supplemental Booklet: Advanced MIDI Applications, Section 8”). It is a Systems Exclusive value analogous to the MIDI channel for regular channel messages.

    There are a range of Sys Ex parameter settings that have been passed onto Synth_Dexed as follows:

    Mono Mode0..1Pitch Bend Range0..12Pitch Bend Step0..12Portamento Mode0..1Portamento Glissando0..1Portamento Time0..99Mod Wheel Range0..99Mod Wheel Target0..7Foot Control Range0..99Foot Control Target0..7Breath Control Range0..99Breath Control Target0..7Aftertouch Range0..99Aftertouch Target0..7Voice Dump Load<156 bytes of voice data>Voice Parameter SetParameter=0..155; Data=0..99

    At this stage, all of the MIDI support is on a “it’s probably something like this” basis, so it will evolve as I find out what it is meant to be doing!

    Voice and Bank Loading

    Banks of voices are programmed directly into the code. There is a python script from Synth_Dexed that will take a .syx format voice bank and generate a block of C code. I’ve included a script to download the main 8 banks of standard DX voices and run the script:

    #!/bin/sh

    # Get voices from
    # https://yamahablackboxes.com/collection/yamaha-dx7-synthesizer/patches/

    mkdir -p voices

    DIR="https://yamahablackboxes.com/patches/dx7/factory"

    wget -c "${DIR}"/rom1a.syx -O voices/rom1a.syx
    wget -c "${DIR}"/rom1b.syx -O voices/rom1b.syx
    wget -c "${DIR}"/rom2a.syx -O voices/rom2a.syx
    wget -c "${DIR}"/rom2b.syx -O voices/rom2b.syx
    wget -c "${DIR}"/rom3a.syx -O voices/rom3a.syx
    wget -c "${DIR}"/rom3b.syx -O voices/rom3b.syx
    wget -c "${DIR}"/rom4a.syx -O voices/rom4a.syx
    wget -c "${DIR}"/rom4b.syx -O voices/rom4b.syx

    ./synth_dexed/Synth_Dexed/tools/sysex2c.py voices/* > src/voices.h

    This only needs to be run once to create the src/voices.h file which is then included in the build.

    Voices have the following format:

    uint8_t progmem_bank[8][32][128] PROGMEM =
    {
    { // Bank 1
    {<--128 bytes of packed voice data-->} // Voice 1
    ...
    {<--128 bytes of packed voice data-->} // Voice 32
    }
    { // Bank 2
    ...
    }
    ...
    { // Bank 8
    {<--128 bytes of packed voice data-->} // Voice 1
    ...
    {<--128 bytes of packed voice data-->} // Voice 32
    }
    }

    The system assumes 8 banks of 32 voices each, in the “packed” SYX header format, meaning each voice consists of 128 bytes.

    MIDI Bank and Voice Selection

    As there are only 8 banks, only BANKSEL (LSB) values 0..7 are valid. Program Change will work in two ways however:

    • 0..31 will select voices 1 to 32 in the current bank.
    • 31..127 will select voices from the following three adjacent banks.

    To select any voice in all 8 banks thus requires the following sequence:

    BANKSEL MSB = 0
    BANKSEL LSB = 0..7
    PROG CHANGE = 0..31

    But if bank selection is skipped, then Program Change messages can still be used to select one of the first 128 voices across four consecutive banks.

    USB MIDI

    The Raspberry Pi Pico SDK uses the TinyUSB protocol stack to implement USB device or host modes and there is an additional option to implement a second USB host port using the Pico’s PIO.

    However, USB MIDI appears to only be supported for USB devices at the time of writing, so I’m just using the built-in USB port as a USB device, based on the code provided as part of the TinyUSB examples (more details of how to get basic USB MIDI running here).

    TinyUSB MIDI supports two interfaces for reading data, and this wasn’t immediately obvious from the example as that is only sending data and ignores anything coming in.

    • USB MIDI Stream mode: this will fill a provided buffer with MIDI data received over USB.
    • USB MIDI Packet mode: this will return each 4-byte USB packet individually.

    From what I can see of the USB MIDI Spec, all MIDI messages are turned into 4-byte packets for transferring over USB. All normal MIDI messages will consist of 1, 2 or 3 byte messages, and so will fit in a packet each – any unused bytes are padded with 0.

    However SysEx messages are a little more complicated and have to be split across multiple packets.

    This is the format for a USB MIDI Event Packet (see the “Universal Serial Bus Device Class Definition for MIDI Devices”, Release 1.0):

    The code index number is an indication of the contents of each packet. For channel messages, this is basically a repeat of the MIDI command, so a MIDI Note On message might look something like the following:

    09 92 3C 64
    Cable 0
    Code Index Number 9
    MIDI Cmd 0x90 (Note On)
    MIDI Channel 3 (0x0=1; 0x1=2; 0x2=3; ... 0xF=16)
    Note 0x3C (60 = C4)
    Velocity 0x64 (100)

    But things get a little more complex with System Common or System Exclusive messages which have their own set of codes, depending on the chunking of the packets required.

    The critical ones for SysEx are CIN=4,5,6,7 which correspond to SysEx start and then various versions of continuation or end packets. So a larger SysEx message might look something like the following

    04 F0 43 10 -- SysEx Start or Continuation
    04 34 44 4D -- SysEx Start or Continuation
    06 3E F7 00 -- SysEx End after two bytes

    Complete message: F0 43 10 34 44 4D 3E F7

    So, if I opt to use the packet interface to TinyUSB MIDI then all this has to be sorted out in user code myself. However, the streaming interface will take care of all this for me and just return a buffer full of “traditional” MIDI messages.

    Note that there is no concept of Running Status in USB MIDI. Even the oldest USB standard protocol speeds are an order of magnitude, or more, higher than serial MIDI so it isn’t necessary. Every MIDI message will either be a complete 1,2,3 byte message in a single USB packet, or a SysEx multi-packet message as described above.

    The basic structure of the USB MIDI handler is as follows:

    Init:
    Initialise TinyUSB MIDI stack

    Process:
    Run the TinyUSB MIDI task
    IF TinyUSB says MIDI data available:
    Call the stream API to fill our RX buffer
    WHILE data in the RX buffer:
    Call the MIDIParser which reads from the RX buffer
    IF MIDI messages found:
    Call the MIDI Message Handler

    Read:
    Grab the next byte from the RX buffer

    I’ve actually split this over two files: usbmidi.cpp is the companion to serialmidi.cpp and provides the class that inherits from MIDIDevice (which provides the parser and message handler); usbtask.c provides the interface into the TinyUSB C driver code.

    I haven’t done anything special with a USB manufacturer/vendor and device ID yet – so at some point I should see what TinyUSB is using by default and find something unique to PicoDexed (assuming I take it forward in any useful way).

    Closing Thoughts

    I have a fairly complete implementation now, which is quite nice. I do need to find some way to properly exercise the voice loading over SysEx and it would be good to get some idea of the performance when I throw a MIDI file at it over USB!

    I’ve tested some of the parameter changes using the PC version of Dexed. When configured correctly, this can be used to send voice parameter changes to PicoDexed, but I haven’t found a way to download the entire voice as yet.

    It’s a shame I can’t just plug in a USB MIDI controller and play it now, but I’ll work on some kind of interface board that should allow me to do it. It will need to be independently powered to act as a USB host anyway.

    This is probably going to be my last blog post on PicoDexed for now, but I plan to keep tinkering away at the GitHub repository to see how things go. There are still a couple of limitations, the main one being that everything has to be hard-coded in at present. It would be nice to be able to have some kind of system configuration facility for the MIDI channel if nothing else.

    At some point it would also be nice to have a build on the GitHub so others can try it too. And I still need to decide how best to manage the changes I needed to make to Synth_Dexed.

    Kevin

    https://diyelectromusic.wordpress.com/2024/02/16/raspberry-pi-pico-synth_dexed-part-4/

    #dx7 #midi #picodexed #raspberryPiPico #usbMidi