Do not forget. Hardware needs root rights. PB so start with sudo
Update v1.01.6
WS2811.pbi
Code: Select all
;TOP
; Comment : Userspace Raspberry Pi library for controlling WS281X LEDs.
; Author : mk-soft
; Version : v1.01.6
; Create : 21.12.2021
; Update : 28.12.2021
; Lisence : MIT and see github project
; Library : https://github.com/jgarff/rpi_ws281x
; Compile library: (See github projekt)
; -------------------------------------
;
; Open terminal:
;
; first install cmake:
;
; sudo apt-get install cmake
;
; also if git is not installed, install it:
;
; sudo apt-get install git
;
; now get the repository from the web:
;
; git clone https://github.com/jgarff/rpi_ws281x.git
;
; then go to the new directory:
;
; cd rpi_ws281x
;
; follow:
; mkdir build
; cd build
; cmake -D BUILD_SHARED=ON -D BUILD_TEST=OFF .. <--- don't forget double dots ;)
; cmake --build . <--- don't forget dot ;)
; sudo make install
; *********
EnableExplicit
; Header pwm.h
#RPI_PWM_CHANNELS = 2
; Header ws2811.h
#WS2811_TARGET_FREQ = 800000 ; Can go As low As 400000
#WS2811_TARGET_FREQ_LOW = 400000
; 4 color R, G, B And W ordering
#SK6812_STRIP_RGBW = $18100800
#SK6812_STRIP_RBGW = $18100008
#SK6812_STRIP_GRBW = $18081000
#SK6812_STRIP_GBRW = $18080010
#SK6812_STRIP_BRGW = $18001008
#SK6812_STRIP_BGRW = $18000810
#SK6812_SHIFT_WMASK = $f0000000
; 3 color R, G And B ordering
#WS2811_STRIP_RGB = $00100800
#WS2811_STRIP_RBG = $00100008
#WS2811_STRIP_GRB = $00081000
#WS2811_STRIP_GBR = $00080010
#WS2811_STRIP_BRG = $00001008
#WS2811_STRIP_BGR = $00000810
; predefined fixed LED types
#WS2812_STRIP = #WS2811_STRIP_GRB
#SK6812_STRIP = #WS2811_STRIP_GRB
#SK6812W_STRIP = #SK6812_STRIP_GRBW
;struct ws2811_device;
;typedef uint32_t ws2811_led_t; //< 0xWWRRGGBB
Structure ws2811_led_t
Led.l[0]
EndStructure
;typedef struct ws2811_channel_t
Structure ws2811_channel_t Align #PB_Structure_AlignC
;{
gpionum.l ; //< GPIO Pin with PWM alternate function, 0 if unused
invert.l ; //< Invert output signal
count.l ; //< Number of LEDs, 0 if channel is unused
strip_type.l ; //< Strip color layout -- one of WS2811_STRIP_xxx constants
*leds.ws2811_led_t; //< LED buffers, allocated by driver based on count
brightness.a ; //< Brightness value between 0 and 255
wshift.a ; //< White shift value
rshift.a ; //< Red shift value
gshift.a ; //< Green shift value
bshift.a ; //< Blue shift value
*gamma ; //< Gamma correction table
EndStructure
;typedef struct ws2811_t
Structure ws2811_t Align #PB_Structure_AlignC
;{
render_wait_time.q; //< time in µs before the next render can run
*device ; //< Private data for driver use
*rpi_hw ; //< RPI Hardware Information
freq.l ; //< Required output frequency
dmanum.l ; //< DMA number _not_ already in use
channel.ws2811_channel_t[#RPI_PWM_CHANNELS];
EndStructure
;#define WS2811_RETURN_STATES(X)
#WS2811_SUCCESS = 0 ; "Success"
#WS2811_ERROR_GENERIC = -1 ; "Generic failure"
#WS2811_ERROR_OUT_OF_MEMORY = -2 ; "Out of memory"
#WS2811_ERROR_HW_NOT_SUPPORTED = -3 ; "Hardware revision is not supported"
#WS2811_ERROR_MEM_LOCK = -4 ; "Memory lock failed"
#WS2811_ERROR_MMAP = -5 ; "mmap() failed"
#WS2811_ERROR_MAP_REGISTERS = -6 ; "Unable to map registers into userspace"
#WS2811_ERROR_GPIO_INIT = -7 ; "Unable to initialize GPIO"
#WS2811_ERROR_PWM_SETUP = -8 ; "Unable to initialize PWM"
#WS2811_ERROR_MAILBOX_DEVICE = -9 ; "Failed to create mailbox device"
#WS2811_ERROR_DMA = -10 ; "DMA error"
#WS2811_ERROR_ILLEGAL_GPIO = -11 ; "Selected GPIO not possible"
#WS2811_ERROR_PCM_SETUP = -12 ; "Unable to initialize PCM"
#WS2811_ERROR_SPI_SETUP = -13 ; "Unable to initialize SPI"
#WS2811_ERROR_SPI_TRANSFER = -14 ; "SPI transfer error"
; ws2811_return_t ws2811_init(ws2811_t *ws2811); //< Initialize buffers/hardware
; void ws2811_fini(ws2811_t *ws2811); //< Tear it all down
; ws2811_return_t ws2811_render(ws2811_t *ws2811); //< Send LEDs off to hardware
; ws2811_return_t ws2811_wait(ws2811_t *ws2811); //< Wait for DMA completion
; const char * ws2811_get_return_t_str(const ws2811_return_t state); //< Get string representation of the given return state
; void ws2811_set_custom_gamma_factor(ws2811_t *ws2811, double gamma_factor); //< Set a custom Gamma correction array based on a gamma correction factor
PrototypeC ws2811_init(*ws2811.ws2811_t); //< Initialize buffers/hardware
PrototypeC ws2811_fini(*ws2811.ws2811_t); //< Tear it all down
PrototypeC ws2811_render(*ws2811.ws2811_t); //< Send LEDs off to hardware
PrototypeC ws2811_wait(*ws2811.ws2811_t) ; //< Wait for DMA completion
PrototypeC ws2811_get_return_t_str(ws2811_return_t_state); //< Get string representation of the given return state
PrototypeC ws2811_set_custom_gamma_factor(*ws2811.ws2811_t, gamma_factor.d); //< Set a custom Gamma correction array based on a gamma correction factor
Global libws2811
Procedure InitLib_ws2811(pathlib.s = "libws2811.so")
libws2811 = OpenLibrary(#PB_Any, pathlib)
If libws2811
Global ws2811_init.ws2811_init = GetFunction(libws2811, "ws2811_init")
Global ws2811_fini.ws2811_fini = GetFunction(libws2811, "ws2811_fini")
Global ws2811_render.ws2811_render = GetFunction(libws2811, "ws2811_render")
Global ws2811_wait.ws2811_wait = GetFunction(libws2811, "ws2811_wait")
Global __ws2811_get_return_t_str.ws2811_get_return_t_str = GetFunction(libws2811, "ws2811_get_return_t_str")
Global ws2811_set_custom_gamma_factor.ws2811_set_custom_gamma_factor = GetFunction(libws2811, "ws2811_set_custom_gamma_factor")
EndIf
ProcedureReturn libws2811
EndProcedure
Procedure.s ws2811_get_return_t_str(state)
Protected *state
*state = __ws2811_get_return_t_str(state)
If *state
ProcedureReturn PeekS(*state, -1, #PB_UTF8)
EndIf
EndProcedure
Procedure CloseLib_ws2811()
CloseLibrary(libws2811)
EndProcedure
;- Example ws2812b (4 LEDs on GPIO 18 PWM)
CompilerIf #PB_Compiler_IsMainFile
EnableExplicit
;IncludeFile "WS2811.pbi"
If Not InitLib_ws2811()
Debug "Error open library ws2811"
End
EndIf
#TARGET_FREQ = #WS2811_TARGET_FREQ ; Default 800000
#GPIO_PIN = 18
#DMA = 10
; #STRIP_TYPE = WS2811_STRIP_RGB ; WS2812/SK6812RGB integrated chip+leds
#STRIP_TYPE = #WS2811_STRIP_GRB ; WS2812/SK6812RGB integrated chip+leds
;#STRIP_TYPE = #SK6812_STRIP_RGBW ; SK6812RGBW (Not SK6812RGB)
#LED_COUNT = 4
Global ledstring.ws2811_t
Global r1
With ledstring
\freq = #TARGET_FREQ
\dmanum = #DMA
\channel[0]\gpionum = #GPIO_PIN
\channel[0]\count = #LED_COUNT
\channel[0]\invert = 0
\channel[0]\brightness = 255
\channel[0]\strip_type = #STRIP_TYPE
Repeat ; Do
r1 = ws2811_init(ledstring)
If r1 <> #WS2811_SUCCESS
Debug "Error Init: " + ws2811_get_return_t_str(r1)
CloseLib_ws2811()
End
EndIf
; LEDs 0xWWRRGGBB
\channel[0]\leds\led[0] = $00FF0000
\channel[0]\leds\led[1] = $0000FF00
\channel[0]\leds\led[2] = $000000FF
\channel[0]\leds\led[3] = $00FFFFFF
r1 = ws2811_render(ledstring)
If r1 <> #WS2811_SUCCESS
Debug "Error Render: " + ws2811_get_return_t_str(r1)
Break
EndIf
ws2811_wait(ledstring)
Delay(2000)
; LEDs
\channel[0]\leds\led[0] = $00FFFFFF
\channel[0]\leds\led[1] = $00FF0000
\channel[0]\leds\led[2] = $0000FF00
\channel[0]\leds\led[3] = $000000FF
r1 = ws2811_render(ledstring)
If r1 <> #WS2811_SUCCESS
Debug "Error Render: " + ws2811_get_return_t_str(r1)
Break
EndIf
ws2811_wait(ledstring)
Delay(2000)
; LEDs
\channel[0]\leds\led[0] = $000000FF
\channel[0]\leds\led[1] = $00FFFFFF
\channel[0]\leds\led[2] = $00FF0000
\channel[0]\leds\led[3] = $0000FF00
r1 = ws2811_render(ledstring)
If r1 <> #WS2811_SUCCESS
Debug "Error Render: " + ws2811_get_return_t_str(r1)
Break
EndIf
ws2811_wait(ledstring)
Delay(2000)
\channel[0]\leds\led[0] = $00000000
\channel[0]\leds\led[1] = $00000000
\channel[0]\leds\led[2] = $00000000
\channel[0]\leds\led[3] = $00000000
r1 = ws2811_render(ledstring)
If r1 <> #WS2811_SUCCESS
Debug "Error Render: " + ws2811_get_return_t_str(r1)
Break
EndIf
Delay(1000)
\channel[0]\leds\led[0] = $0000FF00
\channel[0]\leds\led[1] = $0000FF00
\channel[0]\leds\led[2] = $0000FF00
\channel[0]\leds\led[3] = $0000FF00
r1 = ws2811_render(ledstring)
If r1 <> #WS2811_SUCCESS
Debug "Error Render: " + ws2811_get_return_t_str(r1)
Break
EndIf
Delay(1000)
\channel[0]\leds\led[0] = $00000000
\channel[0]\leds\led[1] = $00000000
\channel[0]\leds\led[2] = $00000000
\channel[0]\leds\led[3] = $00000000
r1 = ws2811_render(ledstring)
If r1 <> #WS2811_SUCCESS
Debug "Error Render: " + ws2811_get_return_t_str(r1)
Break
EndIf
Delay(1000)
Until #True ; EndDo
EndWith
; Clear controler - DMA, etx
ws2811_fini(ledstring)
; Close library
CloseLib_ws2811()
CompilerEndIf