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

wangnick2
 
Posts: 6
Joined: Sun Jan 11, 2015 5:19 pm

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

Sun Jan 11, 2015 6:43 pm

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

Vonger
 
Posts: 567
Joined: Sun Oct 19, 2014 6:00 am

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

Mon Jan 12, 2015 12:50 am

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.

wangnick2
 
Posts: 6
Joined: Sun Jan 11, 2015 5:19 pm

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

Sun Jan 18, 2015 4:19 pm

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

wangnick2
 
Posts: 6
Joined: Sun Jan 11, 2015 5:19 pm

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

Fri Jan 23, 2015 6:24 pm

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

wangnick2
 
Posts: 6
Joined: Sun Jan 11, 2015 5:19 pm

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

Sat Jan 24, 2015 1:14 pm

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

wangnick2
 
Posts: 6
Joined: Sun Jan 11, 2015 5:19 pm

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

Sun Feb 15, 2015 6:28 pm

No ideas?

alanwangwang
 
Posts: 1
Joined: Wed Nov 16, 2016 3:07 am

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

Wed Dec 14, 2016 2:44 am

i want to know if Vocore can support WS2813 led Rather than WS2812B?

Return to VoCore & VoCore+dock

Who is online

Users browsing this forum: No registered users and 1 guest