jgarff / rpi_ws281x

Userspace Raspberry Pi PWM library for WS281X LEDs
BSD 2-Clause "Simplified" License
1.8k stars 623 forks source link

Running from Banana Pi with Armbian #293

Open FlauschBert opened 6 years ago

FlauschBert commented 6 years ago

All builds and installs fine. According to similar GPIO wiring works fine. After hacking hardware detection in rpihw.c, /dev/vcio is not found. Is there another way to get it working on BPi? Thx.

penfold42 commented 6 years ago

Try the spi pins instead.

Pwm will not work without porting as it hits the hardware directly

FlauschBert commented 6 years ago

Ah well. So I change the GPIO_PIN in main.c to 10 and get further: Can't open /dev/mem: No such file or directory ws2811_init failed: Unable to initialize SPI

The error means the /dev/gpiomem can't be openend. It is not available on armbian. Can I simply use /dev/mem instead? Thx.

FlauschBert commented 6 years ago

Wow ok. I can. It works! 😄

FlauschBert commented 6 years ago

Hi again. It still works except the first of the pixels. That is green all the time at full brightness. I use the WS2811_STRIP_GBR inside main.c or strandtest.py and all colors are correct except for the first pixel. I've found https://github.com/jgarff/rpi_ws281x/issues/33 which describes my problem I think and this should be fixed?! If I run the strandtest.py a little longer also the first pixel changes a little bit always at full brightness and having a different color than the other pixels. In very rare cases I see a very short flickering in one of the pixels. Could this be a hardware problem? Or software? Thx.

penfold42 commented 6 years ago

What level shifter are you using ?

FlauschBert commented 6 years ago

I do not use a level shifter.

I use a unicorn shield: https://image.codingworld.io/storage/2136/show https://image.codingworld.io/storage/2127/show https://github.com/coding-world/coding-unicorn-shield-projects/tree/master/demo%2Bdocumentation The problem is that they use PWM and this does not work on the BPi. So I tried to find an alternative.

I connect 5V, GND and GPIO18 (MOSI is GPIO10 on BPi) directly to the unicorn shield.

pietrodn commented 6 years ago

I had this problem (first LED green all the time) by using the Python spidev library. The solution is to send a null byte (0x00) on the SPI line, before the color data, in the same message.

https://github.com/joosteto/ws2812-spi/issues/2

FlauschBert commented 6 years ago

I had this problem (first LED green all the time) by using the Python spidev library. The solution is to send a null byte (0x00) on the SPI line, before the color data, in the same message.

joosteto/ws2812-spi#2

Thanks for the information. I tested this meanwhile and it works much better. But there is still a little timing issue. It could be that sending the 0x0 before has to be done in the same time window as before. Just guessing. I will try to recalculate timing ... in the future ... err ... when i have time ;)

lordjaxom commented 5 years ago

Since this issue is the only viable match on how to run a ws281x led strip from a banana pi, and since I've been able to reconstruct the necessary steps from FlauschBert's description, I'd like to ask if a pull request would be acceptable to help other users with the same problem in the future :-) I have disabled the hardware detection in my version, but I'd be willing to try and implement a proper banana pi detection if this has a chance of merging.

Also I'd like to ask FlauschBert (since he has not provided means of contact): Were you able to fix the "first pixel green" problem?

FlauschBert commented 5 years ago

Also I'd like to ask FlauschBert (since he has not provided means of contact): Were you able to fix the "first pixel green" problem?

Yes. I was. It works with the following changes. But is only a bad hack right now:

diff --git a/mailbox.h b/mailbox.h
index e5b5563..dee77b6 100644
--- a/mailbox.h
+++ b/mailbox.h
@@ -31,7 +31,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 #define IOCTL_MBOX_PROPERTY _IOWR(MAJOR_NUM, 0, char *)

 #define DEV_MEM     "/dev/mem"
-#define DEV_GPIOMEM "/dev/gpiomem"
+#define DEV_GPIOMEM "/dev/mem"
+//#define DEV_GPIOMEM "/dev/gpiomem"

 int mbox_open(void);
 void mbox_close(int file_desc);
diff --git a/main.c b/main.c
index 85ecd67..edd1192 100644
--- a/main.c
+++ b/main.c
@@ -57,21 +57,21 @@ static char VERSION[] = "XX.YY.ZZ";

 // defaults for cmdline options
 #define TARGET_FREQ             WS2811_TARGET_FREQ
-#define GPIO_PIN                18
+#define GPIO_PIN                10
 #define DMA                     10
 //#define STRIP_TYPE            WS2811_STRIP_RGB               // WS2812/SK6812RGB integrated chip+leds
-#define STRIP_TYPE              WS2811_STRIP_GBR               // WS2812/SK6812RGB integrated chip+leds
+#define STRIP_TYPE              WS2811_STRIP_GRBW              // WS2812/SK6812RGB integrated chip+leds
 //#define STRIP_TYPE            SK6812_STRIP_RGBW              // SK6812RGBW (NOT SK6812RGB)
------------- further changes for my strip go here -------------
diff --git a/rpihw.c b/rpihw.c
index a0df569..d99555c 100644
--- a/rpihw.c
+++ b/rpihw.c
@@ -50,205 +50,6 @@
 #define RPI_WARRANTY_MASK                        (0x3 << 24)

 static const rpi_hw_t rpi_hw_info[] = {
-    //
-    // Model B Rev 1.0
-    //
-    {
----snip----
-        .type = RPI_HWVER_TYPE_PI1,
-        .periph_base = PERIPH_BASE_RPI,
-        .videocore_base = VIDEOCORE_BASE_RPI,
-        .desc = "Model A+",
-    },

     //
     // Pi 2 Model B
@@ -324,10 +125,15 @@ static const rpi_hw_t rpi_hw_info[] = {

 const rpi_hw_t *rpi_hw_detect(void)
 {
+#if 0
     FILE *f = fopen("/proc/cpuinfo", "r");
     char line[LINE_WIDTH_MAX];
+#endif
+
     const rpi_hw_t *result = NULL;
+                    result = &rpi_hw_info[0];

+#if 0
     if (!f)
     {
         return NULL;
@@ -374,7 +180,7 @@ const rpi_hw_t *rpi_hw_detect(void)

 done:
     fclose(f);
-
+#endif
     return result;
 }
diff --git a/ws2811.c b/ws2811.c
index 6ac82bf..0767a2d 100644
--- a/ws2811.c
+++ b/ws2811.c
@@ -1178,10 +1178,13 @@ ws2811_return_t  ws2811_render(ws2811_t *ws2811)
                         if ((driver_mode != PWM) && channel->invert) symbol = SYMBOL_HIGH_INV;
                     }

+                       // first byte has to be zero before color bgr for bpi
+                        volatile uint8_t  *byteptr = &pxl_raw[0];    // SPI
+                       *byteptr = 0;
                     for (l = 2; l >= 0; l--)               // Symbol
                     {
                         uint32_t *wordptr = &((uint32_t *)pxl_raw)[wordpos];   // PWM & PCM
-                        volatile uint8_t  *byteptr = &pxl_raw[bytepos];    // SPI
+                        volatile uint8_t  *byteptr = &pxl_raw[bytepos+1];    // SPI

                         if (driver_mode == SPI)
                         {
diff --git a/ws2811.h b/ws2811.h
index 882b6c5..d452363 100644
--- a/ws2811.h
+++ b/ws2811.h
@@ -57,11 +57,12 @@ extern "C" {
 #define WS2811_STRIP_GBR                         0x00080010
 #define WS2811_STRIP_BRG                         0x00001008
 #define WS2811_STRIP_BGR                         0x00000810
+#define WS2811_STRIP_GRBW                        0x10081000

 // predefined fixed LED types
-#define WS2812_STRIP                             WS2811_STRIP_GRB
-#define SK6812_STRIP                             WS2811_STRIP_GRB
-#define SK6812W_STRIP                            SK6812_STRIP_GRBW
+#define WS2812_STRIP                             WS2811_STRIP_RGB
+#define SK6812_STRIP                             WS2811_STRIP_RGB
+#define SK6812W_STRIP                            SK6812_STRIP_RGBW

 struct ws2811_device;

Running the built executable test shows still nice results but sometimes there is still a green flicker in it. Thus I speculated that something could be wrong with timing. (I run as root).

I managed to get a video to get the problem at least: https://youtu.be/6nfuVWAVA0o. See the lower left led.

Feel free to use my changes and thanks for motivating me. You`re welcome :)

rafaelmaeuer commented 4 years ago

@FlauschBert thank you so much for your detailed docukmentation. It helped me to get the library running on a NanoPi Neo Air, after trying several other libs without success. If anyone wants to try something else, I made a fork of this lib and included all of FlauschBerts modifications: https://github.com/rafaelmaeuer/rpi_ws281x