AlbertR Newbie
 Joined: 29/05/2025 Location: GermanyPosts: 26 |
Posted: 11:26am 31 Aug 2025 |
Copy link to clipboard |
 Print this post |
|
I make some tests with the Picomite PIO for the WS2812-Output. Because the implemented function "Device WS2812" is blocking during output-time, I was looking for an other possibility. The PIO should be a candidate.
Option EXPLICIT Option DEFAULT NONE Dim integer leds(255) Dim integer pack(127) Dim integer Busy = 0'as Mutex: ready to send
SetPin gp22,pio1 ' The PIO program - PIO WS2812 driver on GP22 -------------------------------- ' ____ ________ '(0) __| |______ (1) __| |__ ' .2us .4us .6us .2us .8us .2us PIO CLEAR 1 PIO ASSEMBLE 1, ".program leds" PIO ASSEMBLE 1, ".line 0" PIO ASSEMBLE 1, "SET PINDIRS, 1" PIO ASSEMBLE 1, ".wrap target" 'steps |delay PIO ASSEMBLE 1, "OUT x, 1 " '1 lo 0.2us PIO ASSEMBLE 1, "SET PINS, 1 [1]"'2 hi 0.4us PIO ASSEMBLE 1, "MOV PINS, x [1]"'2 data 0.4us PIO ASSEMBLE 1, "SET PINS, 0 " '1 lo 0.2us PIO ASSEMBLE 1, ".wrap" '6 sum 1.2us = 833kHz PIO ASSEMBLE 1, ".end program list"
Dim integer ExeC = Pio(execctrl GP22,Pio(.wrap target),Pio(.wrap)) Dim integer PinC = Pio(pinctrl 0,1,1,,,gp22,gp22) Dim integer ShiC = Pio(shiftctrl 0,24,0,1) 'Set Auto Pull at 24bits Dim integer Freq = 5000000 '5MHz -> 1 step -> 0.2us 'setup the machine. PIO init machine 1,0,Freq,PinC,ExeC,ShiC,0 'init Math set &hf0,leds()'all blue 'test-pattern leds(0)=&hcdabef <<8 leds(1)=&h341256 <<8 leds(2)=&haaaaaa <<8 leds(3)=&h555555 <<8 'main loop Do Pause 100 'simulate some calculation with leds()
Do :Loop While Busy 'wait for ready Memory pack leds(),pack(),256,32 'copy and pack Busy = 1 'set busy-flag PIO DMA TX 1,0,4,pack() ',FinI
Pause 1 PIO stop 1,0 PIO init machine 1,0,Freq,PinC,ExeC,ShiC,0 Busy = 0 'ready to start 'OutL() Loop'end main End
'subs/functions ------------------------------------------------------------- Sub FinI 'stop the PIO and re-init for next run Pause 1 PIO stop 1,0 PIO init machine 1,0,Freq,PinC,ExeC,ShiC,0 Busy = 0 'ready to start End Sub
Sub OutL Local integer i=0 PIO start 1,0 'start the PIO Do While i < 4 PIO WRITE 1,0,1,leds(i) Inc i Loop PIO stop 1,0 'stop the PIO End Sub
For testing the PIO-program I use the "PIO WRITE" command, DMA with interupt and with Pause. Thats the results:
 1. PIO WRITE always kills the last bit. If CPUSPEED is only 150MHz it generates a "Break" 2. PIO with TX-DMA works very good but if I use the Ready-Interupt it stops the PIO, even if there is some data left in the OSR and even if there is no PIO STOP in the sub. 3. The version with "pause 1" works spable, but then I am blocking again. That is not what I expected when I use DMA. I think I am not the only one who use PIO. Where did I thing wrong?
Greetings Albert |
AlbertR Newbie
 Joined: 29/05/2025 Location: GermanyPosts: 26 |
Posted: 12:31pm 31 Aug 2025 |
Copy link to clipboard |
 Print this post |
|
Ok, a non blocking solution could be, using a Timer-Interupt with precalculated delay.
'Do 'main loop Do ' do something Do : Loop While Busy 'wait for ready Memory pack leds(),pack(),1024,32 'copy and pack Busy = 1 'set busy-flag PIO DMA TX 1,0,1024,pack()',FinI SetTick 29,FinI,1 ' 29us/24bit Loop End
'subs/functions ------------------------------------------------------------- Sub FinI 'stop the PIO and re-init for next run SetTick 0,FinI,1 PIO stop 1,0 PIO init machine 1,0,Freq,PinC,ExeC,ShiC,0 Busy = 0 'ready to start End Sub
But is this the right way/solution?
Albert |