Page 1 of 2

Use Vocore to control WS2811/WS2812/WS2812B RGB LED strip?

Posted: Sun Jan 11, 2015 6:43 pm
by wangnick2
Dear all,

I would like to use my Vocore to control a WS2812B RGB LED strip. These consist of RGB LEDs which each have a built-in controller chip. Refer for example http://www.adafruit.com/datasheets/WS2812B.pdf.

As these RGB LED controllers work with only one data line (that means, without a clock line), they require a bit stream of uninterrupted timing. A logical 1 is transmitted as 800ns+-150ns HIGH, 450ns+-150ns LOW, a logical 0 is transmitted as 400ns+-150ns HIGH, 850ns+-150ns LOW. Each LED requires 24 bits (8 bits blue intensity, 8 bits green intensity, 8 bits red intensity), and my strip is 108 LEDs long. A pause of 50us LOW resets all LED controllers, so that new colors can be programmed from the beginning again.

I would hope that either the PCM or the I2S hardware of the RT5350, coupled with DMA, could do the job. I was planning to set the bit frequency to 2.4MHz (by setting DIVINT to 8 and DIVCOMP to 171), and then to serialize 110 for a logical 1 and 100 for a locical 0 onto either GPIO#9 (I2S_SDO) or GPIO#14 (PCM_DTX).

Now, I have a bit of experience with Linux (I have once written a simple kernel module some time ago), and SoC like the Teensy 3.0 (ARM Cortex M4) with which I did some DMA trials a while ago. However, I am struggling to get all the pieces of the puzzle together for the DMA under OpenWrt with Vocore:
  • I need to adapt the VOCORE.dts in order to select "pcm i2s" mode of the uartf_func as of rt305x.c in OpenWrt. I must probably then also disable the LED functions of GPIO#10 (UARTF_RXD) and GPIO#11 (UARTF_DTR). But how?
  • I then need to determine whether the DMA business should be done in userland, or whether a kernel device driver module is the better approach. Any suggestions here?

Anybody can give me some hints how to approach this project, or give me a hand to get this done?

Kind regards,
Sebastian

Re: Use Vocore to control WS2811/WS2812/WS2812B RGB LED stri

Posted: Mon Jan 12, 2015 12:50 am
by Vonger
When I try to write SPI driver, I read all the source of pinctrl module, and tried every register of spi, IMHO, read the datasheet first, then export the interface of I2S to user interface(sysfs), understand how openwrt and pin control works, that should be enough.

Re: Use Vocore to control WS2811/WS2812/WS2812B RGB LED stri

Posted: Sun Jan 18, 2015 4:19 pm
by wangnick2
Dear all,

before embarking on the DMA business I decided to try instead to send the RGB data to an Atmega via SPI or UART, and the Atmega would then emit the data to the LED strip.

This approach seemed initially to work well. I can emit data on /dev/spidev32766.1 at 4MHz, and on /dev/ttyS0 at 2MHz or so.

HOWEVER:

I have to wait a while between data emissions on the Vocore, to allow the Atmega to forward the received data to the LED strip, so I call usleep(10000). When doing this I observe a strange phenomenon: After about 1000ms the output of the Vocore stops for about 300ms, then continues.

I wrote a small test program for you to reproduce the issue:
Code: Select all
#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <termios.h>
#include <fcntl.h>
#include <sys/select.h>
#include <linux/types.h>
#include <sched.h>

static const char *DEVICE = "/dev/ttyS0";
#define SPEED B57600
static const char PROGRESS[] = {'.'};

static void pabort (const char *s) {
    perror(s);
    abort();
}

int main (int argc, char *argv[]) {
    int fd = open(DEVICE,O_WRONLY);
    if (fd<0) {
        pabort("Can't open device");
    }
    struct termios tios;
    int ret = tcgetattr(fd,&tios);
    if (ret<0) {
        pabort("can't tcgetattr");
    }
    tios.c_oflag &= ~OPOST;
    tios.c_lflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN);
    tios.c_cflag &= ~(CSIZE | PARENB);
    tios.c_cflag |= CS8;
    ret = cfsetospeed(&tios,SPEED);
    if (ret<0) {
        pabort("can't cfsetospeed");
    }
    ret = cfsetispeed(&tios,SPEED);
    if (ret<0) {
        pabort("can't cfsetispeed");
    }
    ret = tcsetattr(fd,TCSANOW,&tios);
    if (ret<0) {
        pabort("can't tcsetattr");
    }
    struct sched_param schedparam;
    schedparam.sched_priority = 99;
    ret = sched_setscheduler(0,SCHED_FIFO,&schedparam);
    if (ret<0) {
        pabort("can't sched_setscheduler");
    }
    for (;;) {
        write(fd,PROGRESS,sizeof(PROGRESS));
        //struct timeval wait = {.tv_sec=0, .tv_usec=10000};
        //select(0,NULL,NULL,NULL,&wait);
        usleep(100000);
    }
}


You will observe that always after one second of dots there is a small pause of 300ms.

This happens with or without the Dock attached.

Any idea what causes this, and how to circumvent?

Kind regards,
Sebastian

Re: Use Vocore to control WS2811/WS2812/WS2812B RGB LED stri

Posted: Fri Jan 23, 2015 6:24 pm
by wangnick2
Dear all,

no ideas? Can at least someone check whether this is reproducable on other Vocores?

Code: Select all
#include <unistd.h>
#include <stdio.h>
#include <fcntl.h>

static const char *DEVICE = "/dev/ttyS0";
static const char PROGRESS[] = {'.'};

int main (int argc, char *argv[]) {
    int fd = open(DEVICE,O_WRONLY);
    if (fd<0) {
        perror("Can't open device");
        return 2;
    }
    for (;;) {
        write(fd,PROGRESS,sizeof(PROGRESS));
        usleep(100000);
    }
}


I'm trying hard to get oprofile running on the Vocore, but have difficulties to configure nfs-client on openwrt such that I could mount vmlinux.debug (which is 13MB) remotely ...

Kind regards,
Sebastian

Re: Use Vocore to control WS2811/WS2812/WS2812B RGB LED stri

Posted: Sat Jan 24, 2015 1:14 pm
by wangnick2
Dear all,

I managed to get an oprofile:
Code: Select all
CPU: MIPS 24K, speed 718 MHz (estimated)
Counted INSTRUCTIONS events (1-0 Instructions completed) with a unit mask of 0x00 (No unit mask) count 100000
samples  %        app name                 symbol name
-------------------------------------------------------------------------------
109      16.0059  vmlinux.debug            __do_softirq
  109      100.000  vmlinux.debug            __do_softirq [self]
-------------------------------------------------------------------------------
84       12.3348  busybox                  /bin/busybox
  84       100.000  busybox                  /bin/busybox [self]
-------------------------------------------------------------------------------
78       11.4537  ld-uClibc-0.9.33.2.so    /lib/ld-uClibc-0.9.33.2.so
  78       100.000  ld-uClibc-0.9.33.2.so    /lib/ld-uClibc-0.9.33.2.so [self]
-------------------------------------------------------------------------------
36        5.2863  libuClibc-0.9.33.2.so    /lib/libuClibc-0.9.33.2.so
  36       100.000  libuClibc-0.9.33.2.so    /lib/libuClibc-0.9.33.2.so [self]
-------------------------------------------------------------------------------
24        3.5242  vmlinux.debug            __delay
  24       100.000  vmlinux.debug            __delay [self]
-------------------------------------------------------------------------------
19        2.7900  vmlinux.debug            finish_task_switch.isra.68
  19       100.000  vmlinux.debug            finish_task_switch.isra.68 [self]
-------------------------------------------------------------------------------
17        2.4963  vmlinux.debug            copy_page
  17       100.000  vmlinux.debug            copy_page [self]
-------------------------------------------------------------------------------
16        2.3495  vmlinux.debug            __r4k_wait
  16       100.000  vmlinux.debug            __r4k_wait [self]
-------------------------------------------------------------------------------
13        1.9090  vmlinux.debug            crc32_be
  13       100.000  vmlinux.debug            crc32_be [self]
-------------------------------------------------------------------------------
11        1.6153  vmlinux.debug            __copy_user_common
  11       100.000  vmlinux.debug            __copy_user_common [self]
-------------------------------------------------------------------------------
11        1.6153  vmlinux.debug            __do_fault
  11       100.000  vmlinux.debug            __do_fault [self]
-------------------------------------------------------------------------------
10        1.4684  mac80211                 /mac80211
  10       100.000  mac80211                 /mac80211 [self]


Any idea why __do_softirq and busybox are so demanding when only running my litte test program?

Kind regards,
Sebastian

Re: Use Vocore to control WS2811/WS2812/WS2812B RGB LED stri

Posted: Sun Feb 15, 2015 6:28 pm
by wangnick2
No ideas?

Re: Use Vocore to control WS2811/WS2812/WS2812B RGB LED stri

Posted: Wed Dec 14, 2016 2:44 am
by alanwangwang
i want to know if Vocore can support WS2813 led Rather than WS2812B?

Re: Use Vocore to control WS2811/WS2812/WS2812B RGB LED stri

Posted: Wed Jan 31, 2018 4:38 pm
by CoraDias
Hi...i would like to add my suggestion here. As per my knowledge the maximum power of the power supply depends on the number of LEDs. According to the data sheet, an LED under full load (= maximum brightness) needs about 60mA. At 5m and 30 LEDs / m, this is 9 amps. So, a power supply, which has up to 10A is suitable. If you have more LEDs in use, you may need more than one power supply (more on that later).In addition, of course, the actual RGB LED strip of the type WS2812 (B) or WS2811 (also called NeoPixel) is required. These are available in three different versions, which differ in the number of LEDs per meter.

bittele electronics

Re: Use Vocore to control WS2811/WS2812/WS2812B RGB LED stri

Posted: Fri Feb 02, 2018 2:33 am
by Vonger
Please also check my blog, I am using I2S to control WS2812B. http://vonger.cn/?p=14302

Re: Use Vocore to control WS2811/WS2812/WS2812B RGB LED stri

Posted: Fri Aug 20, 2021 11:55 am
by sarge
Vonger wrote:Please also check my blog, I am using I2S to control WS2812B. http://vonger.cn/?p=14302


The post is about Vocore2. Does this patch fit VoCore1?