New Daisy user here, but experienced in STM32 hardware and software development.
I’m working on a VA polysynth which is progressing well.
I set up UART4 as a MIDI input and can play the synth from a MIDI keyboard.
So far, so good.
To provide a user interface I plan to add an external STM32F103 or ATmega128 to handle the pots & switches. I decided the use MIDI CC messages to USART1 as it seemed a simple solution rather than concocting my own protocol over UART or SPI and having to write my own drivers.
Adding USART1 as a MIDI interface is where I have come unstuck.
I can use UART4 for MIDI or I can use USART1, but I can’t use both.
As far as I can tell from the comments in the MIDI drivers it’s supposed to work?
Here’s my (abbreviated) code, there are #defines to incrementally enable the second UART as part of my investigation.
#define USING_USART1A
#define USING_USART1B
#define USING_USART1C
#define USING_USART1D
#define USING_USART1E
//#define USING_USART1F
#define USING_UART4
DaisyPatchSM hw;
#ifdef USING_UART4
MidiUartHandler midiUart4;
#endif
#ifdef USING_USART1A
MidiUartHandler midiUsart1;
#endif
static constexpr size_t kMidiBufferSize = 256;
#ifdef USING_UART4
static uint8_t DMA_BUFFER_MEM_SECTION buffMidiUart4[kMidiBufferSize];
#endif
#ifdef USING_USART1B
static uint8_t DMA_BUFFER_MEM_SECTION buffMidiUsart1[kMidiBufferSize];
#endif
int main(void)
{
#ifdef USING_UART4
MidiUartHandler::Config midiUart4Config;
#endif
#ifdef USING_USART1C
MidiUartHandler::Config midiUsart1Config;
#endif
// initialise the keyboard MIDI interface
#ifdef USING_UART4
midiUart4Config.transport_config.periph = UartHandler::Config::Peripheral::UART_4;
midiUart4Config.transport_config.rx = {DSY_GPIOA, 1}; // Pin A2
midiUart4Config.transport_config.tx = {DSY_GPIOA, 0}; // Pin A3
midiUart4Config.transport_config.rx_buffer_size = kMidiBufferSize;
midiUart4Config.transport_config.rx_buffer = buffMidiUart4;
midiUart4.Init(midiUart4Config);
#endif
#ifdef USING_USART1D
// initialise the controls MIDI interface
midiUsart1Config.transport_config.periph = UartHandler::Config::Peripheral::USART_1;
midiUsart1Config.transport_config.rx = {DSY_GPIOB, 15}; // Pin A9
midiUsart1Config.transport_config.tx = {DSY_GPIOB, 14}; // Pin A8
midiUsart1Config.transport_config.rx_buffer_size = kMidiBufferSize;
midiUsart1Config.transport_config.rx_buffer = buffMidiUsart1;
midiUsart1.Init(midiUsart1Config);
#endif
// start the MIDI interfaces
#ifdef USING_USART1E
midiUsart1.StartReceive();
#endif
#ifdef USING_UART4
midiUart4.StartReceive();
#endif
while(1)
{
// handle MIDI events
#ifdef USING_UART4
midiUart4.Listen();
while(midiUart4.HasEvents())
{
HandleMidiKeyboardMessage(midiUart4.PopEvent());
}
#endif
#ifdef USING_USART1F
midiUsart1.Listen();
while(midiUsart1.HasEvents())
{
// HandleMidiContolMessage(midiUsart1.PopEvent());
HandleMidiKeyboardMessage(midiUsart1.PopEvent());
}
#endif
}
}
For USART1 steps A through D there is no effect on UART4, it continues to work correctly.
When USART1 step E is enabled (the call to StartReceive()) things start to go wrong.
The effect is slightly different depending on the sequence of calling StartReceive() on each UART.
midiUart4.StartReceive();
midiUsart1.StartReceive();
while (1)
{
midiUart4.Listen();
while (midiUart4.HasEvents())
This sequence doesn’t seem to work, as midiUart4.HasEvents() never returns true.
midiUsart1.StartReceive();
midiUart4.StartReceive();
while (1)
{
midiUart4.Listen();
while (midiUart4.HasEvents())
This sequence does work UNTIL a message is received on USART1.
Does anyone have any suggestions?