Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

can this be used on SBCs other than the rpi? #338

Open
mentaluproar opened this issue Nov 25, 2018 · 9 comments
Open

can this be used on SBCs other than the rpi? #338

mentaluproar opened this issue Nov 25, 2018 · 9 comments
Labels
notice Issues that are solved/do not require input, but preserved and marked of interest to users.

Comments

@mentaluproar
Copy link

I would like to use this on a rock64. (My pi blew up and I'm in a time crunch.). Is this possible?

@penfold42
Copy link
Contributor

SPI might work - the other methods won’t

@mentaluproar
Copy link
Author

Thank you for replying so quickly. Unfortunately, I am using SPI for this project. Do you know of any similar projects that might work for me? I can't think of anything else other than using an Arduino as an interface to the neopixels rather than connecting directly to the SBC.

@penfold42
Copy link
Contributor

SPI might work - it should work if the rock64 has a well written kernel with SPI DMA support

@mentaluproar
Copy link
Author

But I'm already using SPI for something else. Can I share SPI with something like this?

@penfold42
Copy link
Contributor

Maybe - Linux on Pi (and I presume rock64) supports multiple devices with separate slave select signals.

You’d need some logic to hide the data line from the leds when slave select is inactive.

Does your other SPI device use slave select ?

@mentaluproar
Copy link
Author

mentaluproar commented Nov 25, 2018 via email

@bendem
Copy link

bendem commented May 30, 2019

It won't work because the driver modes are hardcoded based on the pin layout of the raspberry pi.

See

rpi_ws281x/ws2811.c

Lines 647 to 673 in a8441f6

static int set_driver_mode(ws2811_t *ws2811, int gpionum)
{
int gpionum2;
if (gpionum == 18 || gpionum == 12) {
ws2811->device->driver_mode = PWM;
// Check gpio for PWM1 (2nd channel) is OK if used
gpionum2 = ws2811->channel[1].gpionum;
if (gpionum2 == 0 || gpionum2 == 13 || gpionum2 == 19) {
return 0;
}
}
else if (gpionum == 21 || gpionum == 31) {
ws2811->device->driver_mode = PCM;
}
else if (gpionum == 10) {
ws2811->device->driver_mode = SPI;
}
else {
fprintf(stderr, "gpionum %d not allowed\n", gpionum);
return -1;
}
// For PCM and SPI zero the 2nd channel
memset(&ws2811->channel[1], 0, sizeof(ws2811_channel_t));
return 0;
}
and

rpi_ws281x/ws2811.c

Lines 675 to 733 in a8441f6

static int check_hwver_and_gpionum(ws2811_t *ws2811)
{
const rpi_hw_t *rpi_hw;
int hwver, gpionum;
int gpionums_B1[] = { 10, 18, 21 };
int gpionums_B2[] = { 10, 18, 31 };
int gpionums_40p[] = { 10, 12, 18, 21};
int i;
rpi_hw = ws2811->rpi_hw;
hwver = rpi_hw->hwver & 0x0000ffff;
gpionum = ws2811->channel[0].gpionum;
if (hwver < 0x0004) // Model B Rev 1
{
for ( i = 0; i < (int)(sizeof(gpionums_B1) / sizeof(gpionums_B1[0])); i++)
{
if (gpionums_B1[i] == gpionum) {
// Set driver mode (PWM, PCM, or SPI)
return set_driver_mode(ws2811, gpionum);
}
}
}
else if (hwver >= 0x0004 && hwver <= 0x000f) // Models B Rev2, A
{
for ( i = 0; i < (int)(sizeof(gpionums_B2) / sizeof(gpionums_B2[0])); i++)
{
if (gpionums_B2[i] == gpionum) {
// Set driver mode (PWM, PCM, or SPI)
return set_driver_mode(ws2811, gpionum);
}
}
}
else if (hwver >= 0x010) // Models B+, A+, 2B, 3B, Zero Zero-W
{
if ((ws2811->channel[0].count == 0) && (ws2811->channel[1].count > 0))
{
// Special case: nothing in channel 0, channel 1 only PWM1 allowed
// PWM1 only available on 40 pin GPIO interface
gpionum = ws2811->channel[1].gpionum;
if ((gpionum == 13) || (gpionum == 19))
{
ws2811->device->driver_mode = PWM;
return 0;
}
else {
return -1;
}
}
for ( i = 0; i < (int)(sizeof(gpionums_40p) / sizeof(gpionums_40p[0])); i++)
{
if (gpionums_40p[i] == gpionum) {
// Set driver mode (PWM, PCM, or SPI)
return set_driver_mode(ws2811, gpionum);
}
}
}
fprintf(stderr, "Gpio %d is illegal for LED channel 0\n", gpionum);
return -1;
}

@zsoltmazlo
Copy link

Hi! Can you esteem how big effort would be to port this library to odroid c2 if it's feasible at all? If not, what do you think, what would be the best approach to drive a NeoPixel strip from an odroid c2? I'm thinking about using an ESP8266 as a "driver IC" which would receive data over UART/I2C and would translate it and send to the strip, but it is a rather excessive solution.

@mentaluproar
Copy link
Author

You can already drive neopixels with an esp, or Arduino, or teensy, or trinket or whatever. Just connect it to the odroid via usb, i2c, or uart and send commands directly to it. You might need a level shifter if you aren't using USB to communicate with it. Serial and USB are the easiest methods.

@Gadgetoid Gadgetoid added the notice Issues that are solved/do not require input, but preserved and marked of interest to users. label Jul 2, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
notice Issues that are solved/do not require input, but preserved and marked of interest to users.
Projects
None yet
Development

No branches or pull requests

5 participants