OLED and Multithreading

Hi,
I just wonder if it is possible to make multithreading on daisy?
I make a project, something like an Arturia Microfreak, so I need to have MIDI in and OLED working at the same time.
I would like to get the OLED screen to be updated on a different thread than the MIDI being read.
Is it possible?
Right now, they are working together in the infinite loop, but each time the OLED is Updated, the MIDI stream is slowed down.

int count = 0;
    
    // Loop forever...
    while(1)
    {
        midi.Listen();
        if(midi.HasEvents())
        {
            HandleMidiMessage(midi.PopEvent());
        }
        count ++;

        if (count > 100000) {
            display->Update();
            count = 0;
        }
    }

The “count” method is a bit ugly I know, but it was a fast way to verify if updating the screen at lower frequency would solve my issue … it seems not.
Just to be clear : the Update() method will only update the screen if it needs to be updated.

Thanks for your ideas.

Even if we forget about the software side, do you expect it to do two things at once on a single core? If your display code is reasonably fast, uses DMA to send data and the display is small, there should be no problems.

Also, it looks like your code would make more sense if it used while (midi.HasEvents()) in order to process all received events instead of just the first one before updating display. This would guarantee that there are no pending messages that could be delayed.

Also, it looks like your code would make more sense if it used while (midi.HasEvents()) in order to process all received events instead of just the first one before updating display. This would guarantee that there are no pending messages that could be delayed.

Oh thanks ! I spent all days on this piece of code and forgot to change this if into a while … this will fix things for sure !

uses DMA to send data and the display is small, there should be no problems.

I’m not sure about what is DMA, but I use the OledDisplay class to manage the display. It seems that the Update() method is a bit long to process. But maybe the if/while thing will fix it.

Any insights on this?

Ok, so I figured out that pthreads is not available on STM32 (I presume daisy in STM32 based, right?)
I read that if I want to “multithread” I have to do it by myself, since multithreading seems to be managed by the OS, and there’s no OS on daisy.

So I hacked the SSD130xDriver class, especially the Update method

void Update()
    {
        uint8_t i;
        uint8_t high_column_addr;
        switch(height)
        {
            case 32: high_column_addr = 0x12; break;

            default: high_column_addr = 0x10; break;
        }
        for(i = 0; i < (height / 8); i++)
        {
            
            transport_.SendCommand(0xB0 + i);
            transport_.SendCommand(0x00);
            transport_.SendCommand(high_column_addr);
            transport_.SendData(&buffer_[width * i], width);
            
        }
    };

This is the for loop part who’s interesting here. If I replace it by

for(i = 0; i < 1; i++)

It will only redraw the 4 first lines of the OLED, and the performances are WAY better … So I can manage to write my own class that will update not everything at once in order to not blocking the MIDI stream.

It’s possible to send the whole buffer in a single DMA transaction if you keep data in the same format that the display controller expects to receive. And this is an asynchronous operation, so you won’t have to wait for its completion.

It’s probably nontrivial to modify libDaisy for this and may also require also customizing display rendering code to store data with a matching buffer format.

Thank you, I would be very grateful if you could direct me, on how to do this, so I take the opportunity to learn how to do something with DMA, it would be very interesting for me.