musiclight2/sk6812.c

121 lines
3.1 KiB
C

/*
* vim: sw=2 ts=2 expandtab
*
* "THE PIZZA-WARE LICENSE" (derived from "THE BEER-WARE LICENCE"):
* Thomas Kolb <cfr34k@tkolb.de> wrote this file. As long as you retain this
* notice you can do whatever you want with this stuff. If we meet some day,
* and you think this stuff is worth it, you can buy me a pizza in return.
* - Thomas Kolb
*/
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <unistd.h>
#include <string.h>
#include <stdio.h>
#include "sk6812.h"
#define SET_COLOR 0
#define FADE_COLOR 1
#define ADD_COLOR 2
#define SET_FADESTEP 3
struct __attribute__((__packed__)) SK6812Packet {
uint8_t action;
uint16_t module;
uint8_t data[4];
};
int sk6812_socket = -1;
struct __attribute__((__packed__)) SK6812Packet packetQueue[1024];
int queueIndex = 0;
// creates the socket needed for steering the LED strip
int sk6812_init(const char *host, unsigned short port) {
struct addrinfo hints;
struct addrinfo *result;
char portstr[6];
memset(&hints, 0, sizeof(struct addrinfo));
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_DGRAM;
hints.ai_flags = 0;
hints.ai_protocol = 0;
sprintf(portstr, "%u", port);
if(getaddrinfo(host, portstr, &hints, &result) != 0) {
perror("getaddrinfo() failed");
return 1;
}
sk6812_socket = socket(result->ai_family, result->ai_socktype, result->ai_protocol);
if (sk6812_socket == -1) {
perror("socket() failed");
freeaddrinfo(result);
return 2;
}
if (connect(sk6812_socket, result->ai_addr, result->ai_addrlen) == -1) {
perror("connect() failed");
freeaddrinfo(result);
return 3;
}
freeaddrinfo(result);
return 0;
}
void sk6812_set_color(uint16_t module, uint8_t r, uint8_t g, uint8_t b, uint8_t w) {
packetQueue[queueIndex].action = SET_COLOR;
packetQueue[queueIndex].module = htons(module);
packetQueue[queueIndex].data[0] = r;
packetQueue[queueIndex].data[1] = g;
packetQueue[queueIndex].data[2] = b;
packetQueue[queueIndex].data[3] = w;
queueIndex++;
}
void sk6812_fade_color(uint16_t module, uint8_t r, uint8_t g, uint8_t b, uint8_t w) {
packetQueue[queueIndex].action = FADE_COLOR;
packetQueue[queueIndex].module = htons(module);
packetQueue[queueIndex].data[0] = r;
packetQueue[queueIndex].data[1] = g;
packetQueue[queueIndex].data[2] = b;
packetQueue[queueIndex].data[3] = w;
queueIndex++;
}
void sk6812_add_color(uint16_t module, uint8_t r, uint8_t g, uint8_t b, uint8_t w) {
packetQueue[queueIndex].action = ADD_COLOR;
packetQueue[queueIndex].module = htons(module);
packetQueue[queueIndex].data[0] = r;
packetQueue[queueIndex].data[1] = g;
packetQueue[queueIndex].data[2] = b;
packetQueue[queueIndex].data[3] = w;
queueIndex++;
}
void sk6812_set_fadestep(uint8_t fadestep) {
packetQueue[queueIndex].action = SET_FADESTEP;
packetQueue[queueIndex].data[0] = fadestep;
queueIndex++;
}
int sk6812_commit(void) {
if(send(sk6812_socket, packetQueue, queueIndex * sizeof(struct SK6812Packet), 0) == -1) {
return 1;
}
queueIndex = 0;
return 0;
}
void sk6812_shutdown() {
close(sk6812_socket);
}