#include #include #include #include #include #include #include #include #include //#include #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); }