32x32 Pixel RGB LED Matrix [XCore beginner here]

XCore Project reviews, ideas, videos and proposals.
User avatar
Folknology
XCore Legend
Posts: 1274
Joined: Thu Dec 10, 2009 10:20 pm
Contact:

Post by Folknology »

I would also add that set and get pixels are also a very primitive interface between tasks, it will be more difficult for the compiler to optimise these intertask primitives than for those within a single thread. These low level primitives are better operated as inline functions within the server task (thread) itself. interfaces exposed to the client should be higher level like setline/getline or graphic primitives like drawline etc..


lberezy
Member
Posts: 13
Joined: Sat May 17, 2014 11:51 am

Post by lberezy »

I tried out the timer solution, but got weird behaviour.

The display sits there blank for ~20 seconds, and then displays a static frame (that appears to be refreshed correctly) for another ~20 seconds. This repeats forever.

This 20 seconds or so, that wouldn't be approximately the time it takes for the timer to overflow a 32 bit int on XCore, would it?


I'll look into adjusting the client to write lines into a buffer. It's surprising at the sheer difference in speed though between the parallel solution and the old sequential code.
User avatar
Folknology
XCore Legend
Posts: 1274
Joined: Thu Dec 10, 2009 10:20 pm
Contact:

Post by Folknology »

Can you show me the latest code?

Or commit it to your test branch?
User avatar
Folknology
XCore Legend
Posts: 1274
Joined: Thu Dec 10, 2009 10:20 pm
Contact:

Post by Folknology »

The 20 sec refresh indicates somthing is wrong, I would need to see the code to diagnose that.

BTW if there was an issue with the case timer being beaten to the punch by the setpixal cases you could use ordered select statements

Code: Select all

timer t;
uint32_t time;
const uint32_t delay = 500
....
t :> time
while(1){
  #pragma ordered
  select {
  case t when timerafter(time) :> void : 
        time += delay;
        //refresh code here
        break;
  case disp.setpixel(uint8_t x, uint8_t, pixel_t pixel) :
        // Implement setpixel as before here or..
        setpixel(uint8_t x, uint8_t, pixel_t pixel)
        break;
  case disp.getPixelAt(uint8_t x, uint8_t y) -> pixel :
        // implement get pixel or..
        pixel = getPixelAt(x,y);
        break;
  }
}
..
This will prioritise the timer case. also check you are using 'timerafter' and not 'timeafter'

I getting some Zzzz now, speak tomorrow..

regards
Al
lberezy
Member
Posts: 13
Joined: Sat May 17, 2014 11:51 am

Post by lberezy »

Thanks for your help.

I've pushed my changes to the test branch. I'm at Uni all day today so I won't have time to test the ordered select statement, but I'll do so when I get home.
User avatar
Folknology
XCore Legend
Posts: 1274
Joined: Thu Dec 10, 2009 10:20 pm
Contact:

Post by Folknology »

I would loose the select default in the display client, just use the while for now as this is adding nothing useful (it may even be adding issues). Later you could use a select with a timer case to periodically run the sine sequences, but in the long run setpixel based client would not make sense (beyond perf testing), that kind of thing could actually be added to the server as a screen saver for instance.

remember that a setpixel function will be convereted into 3 data moves by the compiler in the case of the sequential code, however for task based across threads the optimisation is far more complex. In reality this kind of operation is only useful for things like displaying bitmaps and this could be done with either setline or setbmp type interface calls exposed to the client. In other words keep the real low level primitives within the server so the compiler can deal with them simply.

For now lets see if we can get the setpixel working however to see what is possible client to server, before moving to a higher level. There are also more granular options like channels we could experiment with, those would enable eithe a 32bit uint to carry 7 bits for each X and Y along with 18Bits of colour info, or even streaming channels if continual pixel updates are required.

regards
Al
User avatar
Folknology
XCore Legend
Posts: 1274
Joined: Thu Dec 10, 2009 10:20 pm
Contact:

Post by Folknology »

Before you try anything else, try increasing delay to 5000-40000.

(The delay needs to be longer than the refresh execution duration)

You might have to play around with the value.
User avatar
Folknology
XCore Legend
Posts: 1274
Joined: Thu Dec 10, 2009 10:20 pm
Contact:

Post by Folknology »

OK been playing around with your code using the built in led matrix on the StartKit which isn't the same obviously as the refresh is faster, but try keeping the delay as 50 and making the following change to the timer case this allows for refresh processing so that the timer doesn't exceed its range:

Code: Select all

case t when timerafter(time) :> void :
        refreshDisplay(framebuffer);
        t :> time;
        time += delay;
        break;
Let me know how you get on

P.S. keep the select - default in the client for now I did without issue.

regards
Al
User avatar
Folknology
XCore Legend
Posts: 1274
Joined: Thu Dec 10, 2009 10:20 pm
Contact:

Post by Folknology »

Hi lberezy


I forked your code and and converted it into a more optimised distributed version. It is still slightly slower than you original sequenced version, but we can probably even optimise it further :

https://github.com/folknology/rgb-matri ... /tree/test

Take a look

regards
Al
User avatar
Folknology
XCore Legend
Posts: 1274
Joined: Thu Dec 10, 2009 10:20 pm
Contact:

Post by Folknology »

Now actually faster than original sequenced after inlining ColorHSV

*Thus maybe there should be an optimised display.setpixelHSV(x,y, long hue, uint8_t sat, uint8_t val)

regards
Al
Post Reply