parent
f033119aa8
commit
bca64a858a
@ -0,0 +1,45 @@
|
||||
#include <time.h>
|
||||
#include <string.h>
|
||||
#include <malloc.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/types.h>
|
||||
#include <linux/spi/spidev.h>
|
||||
|
||||
#include "logger.h"
|
||||
#include "sk6812.h"
|
||||
|
||||
int sk6812_init(struct sk6812_ctx *ctx, uint32_t gpio_idx, void *phys_baseptr, uint32_t num_modules)
|
||||
{
|
||||
// TODO:
|
||||
// - map memory
|
||||
// - setup GPIO
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void sk6812_shutdown(struct sk6812_ctx *ctx)
|
||||
{
|
||||
// TODO:
|
||||
// - unmap memory
|
||||
}
|
||||
|
||||
void sk6812_set_colour(struct sk6812_ctx *ctx, uint32_t module, uint8_t red, uint8_t green, uint8_t blue, uint8_t white)
|
||||
{
|
||||
uint32_t value =
|
||||
((uint32_t)red << 24U) |
|
||||
((uint32_t)green << 16U) |
|
||||
((uint32_t)blue << 8U) |
|
||||
(uint32_t)white;
|
||||
|
||||
ctx->memptr->led_data[module] = value;
|
||||
}
|
||||
|
||||
void sk6812_send_update(struct sk6812_ctx *ctx)
|
||||
{
|
||||
// TODO: generate rising edge on GPIO
|
||||
}
|
||||
|
@ -0,0 +1,23 @@
|
||||
#ifndef SK6812_H
|
||||
#define SK6812_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
struct sk6812_memory
|
||||
{
|
||||
uint32_t num_leds;
|
||||
uint32_t led_data[];
|
||||
};
|
||||
|
||||
struct sk6812_ctx
|
||||
{
|
||||
struct sk6812_memory *memptr;
|
||||
char *gpio_value_path;
|
||||
};
|
||||
|
||||
int sk6812_init(struct sk6812_ctx *ctx, uint32_t gpio_idx, void *phys_baseptr, uint32_t num_modules);
|
||||
void sk6812_shutdown(struct sk6812_ctx *ctx);
|
||||
void sk6812_set_colour(struct sk6812_ctx *ctx, uint32_t module, uint8_t red, uint8_t green, uint8_t blue, uint8_t white);
|
||||
void sk6812_send_update(struct sk6812_ctx *ctx);
|
||||
|
||||
#endif // SK6812_H
|
@ -1,107 +0,0 @@
|
||||
#include <time.h>
|
||||
#include <string.h>
|
||||
#include <malloc.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/types.h>
|
||||
#include <linux/spi/spidev.h>
|
||||
|
||||
//#include <wiringPi.h>
|
||||
|
||||
#include "logger.h"
|
||||
#include "ws2801.h"
|
||||
|
||||
static const char *spi_dev = "/dev/spidev0.0";
|
||||
static const uint32_t spi_speed = 1000000; // clock freq in Hz
|
||||
static const uint16_t spi_delay = 0; // us
|
||||
static const uint8_t spi_bits = 8; // bits per word
|
||||
|
||||
uint32_t numModules;
|
||||
uint8_t *message;
|
||||
|
||||
int spi_fd = 0;
|
||||
|
||||
void send_message(void)
|
||||
{
|
||||
struct spi_ioc_transfer tr = {
|
||||
.tx_buf = (unsigned long)message,
|
||||
.rx_buf = (unsigned long)NULL,
|
||||
.len = 3 * numModules,
|
||||
.delay_usecs = spi_delay,
|
||||
.speed_hz = spi_speed,
|
||||
.bits_per_word = 8
|
||||
};
|
||||
|
||||
if(ioctl(spi_fd, SPI_IOC_MESSAGE(1), &tr) < 0) {
|
||||
LOG(LVL_ERR, "ws2801: could not send SPI message: %s", strerror(errno));
|
||||
}
|
||||
}
|
||||
|
||||
int ws2801_init(uint32_t nMod)
|
||||
{
|
||||
// Initialize SPI
|
||||
// We need to have stable data at falling edge of the spi interface (this
|
||||
// means rising edge at the led strip, as the signal is inverted.
|
||||
uint8_t spi_mode = SPI_NO_CS; // | SPI_CPOL;
|
||||
|
||||
spi_fd = open(spi_dev, O_RDWR);
|
||||
if(spi_fd < 0) {
|
||||
LOG(LVL_ERR, "ws2801: cannot open %s: %s", spi_dev, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(ioctl(spi_fd, SPI_IOC_WR_MODE, &spi_mode) == -1) {
|
||||
LOG(LVL_ERR, "ws2801: cannot change SPI mode: %s", strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(ioctl(spi_fd, SPI_IOC_WR_BITS_PER_WORD, &spi_bits) == -1) {
|
||||
LOG(LVL_ERR, "ws2801: cannot change SPI bits per word: %s", strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(ioctl(spi_fd, SPI_IOC_WR_MAX_SPEED_HZ, &spi_speed) == -1) {
|
||||
LOG(LVL_ERR, "ws2801: cannot change SPI speed: %s", strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
// create the message array
|
||||
numModules = nMod;
|
||||
message = malloc(3 * nMod * sizeof(uint8_t));
|
||||
|
||||
if(!message) {
|
||||
LOG(LVL_ERR, "ws2801: could not allocate the message array!");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void ws2801_shutdown(void)
|
||||
{
|
||||
close(spi_fd);
|
||||
|
||||
if(message != NULL) { free(message); message = NULL; }
|
||||
}
|
||||
|
||||
void ws2801_set_colour(uint32_t module, uint8_t red, uint8_t green, uint8_t blue)
|
||||
{
|
||||
//message[3*module + 0] = ~red;
|
||||
//message[3*module + 1] = ~green;
|
||||
//message[3*module + 2] = ~blue;
|
||||
message[3*module + 0] = red;
|
||||
message[3*module + 1] = blue;
|
||||
message[3*module + 2] = green;
|
||||
}
|
||||
|
||||
void ws2801_send_update(void)
|
||||
{
|
||||
send_message();
|
||||
|
||||
static const struct timespec sleepval = {0, 550000};
|
||||
nanosleep(&sleepval, NULL);
|
||||
}
|
||||
|
@ -1,11 +0,0 @@
|
||||
#ifndef WS2801_H
|
||||
#define WS2801_H
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
int ws2801_init(uint32_t num_modules);
|
||||
void ws2801_shutdown(void);
|
||||
void ws2801_set_colour(uint32_t module, uint8_t red, uint8_t green, uint8_t blue);
|
||||
void ws2801_send_update(void);
|
||||
|
||||
#endif // WS2801_H
|
Loading…
Reference in new issue