|
@@ -0,0 +1,273 @@
|
|
|
+/*
|
|
|
+ * stripe.cpp
|
|
|
+ *
|
|
|
+ * Created on: Sep 25, 2017
|
|
|
+ * Author: Philipp Hinz
|
|
|
+ */
|
|
|
+
|
|
|
+#include <wiringPiI2C.h>
|
|
|
+#include <stdlib.h>
|
|
|
+#include <errno.h>
|
|
|
+#include <pthread.h>
|
|
|
+#include <unistd.h>
|
|
|
+#include <string.h>
|
|
|
+#include "stripe.h"
|
|
|
+#include "global.h"
|
|
|
+#include "timer.h"
|
|
|
+#include "logger.h"
|
|
|
+
|
|
|
+stripe_color currentColor;
|
|
|
+stripe_color effectColor;
|
|
|
+int currentWhite = 0, currentDim = 0;
|
|
|
+stripe_transient_t currentTransient = TRANS_DIRECT;
|
|
|
+timer stripeTimer(stripeTimerHandler);
|
|
|
+int i2cfd;
|
|
|
+
|
|
|
+/**
|
|
|
+ * This is the handler for time based stripe effects
|
|
|
+ * @param *threadid Thread ID
|
|
|
+ */
|
|
|
+void *stripeTimerHandler(void *threadid) {
|
|
|
+ if (currentColor.red == effectColor.red
|
|
|
+ && currentColor.green == effectColor.green
|
|
|
+ && currentColor.blue == effectColor.blue) {
|
|
|
+ stripeSetRGB(0,0,0);
|
|
|
+ } else {
|
|
|
+ stripeSetColor(effectColor);
|
|
|
+ }
|
|
|
+ pthread_exit(NULL);
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * Thread for the stripe control. Requests data from other threads or HAL
|
|
|
+ * @param *threadid Thread ID
|
|
|
+ */
|
|
|
+void *stripeThread(void *threadid) {
|
|
|
+ logger(V_STRIPE, "Initializing Stripe thread...\n");
|
|
|
+ stripeInit();
|
|
|
+ stripeTimer.setDivider(40);
|
|
|
+ stripeTimer.stop();
|
|
|
+ logger(V_BASIC, "Initialized Stripe thread\n");
|
|
|
+
|
|
|
+ stripe_color col;
|
|
|
+ col.red = 255;
|
|
|
+ //stripeEffectPulse(col);
|
|
|
+ int tmp = 0, inc = 1;
|
|
|
+ while (1) {
|
|
|
+ stripeEffectHeating(tmp);
|
|
|
+ logger(V_NONE, LOG_ERRORC, "Simulating %d%% percent heating\n", tmp);
|
|
|
+ sleep(1);
|
|
|
+ if (inc) {
|
|
|
+ if (++tmp >= 100) inc = 0;
|
|
|
+ } else {
|
|
|
+ if (--tmp <= 0) inc = 1;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ pthread_exit(NULL);
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * Initializes i2c communication to stripe controller
|
|
|
+ */
|
|
|
+void stripeInit() {
|
|
|
+ i2cfd = wiringPiI2CSetup(I2C_ADDRESS_STRIPE);
|
|
|
+ if (i2cfd < 0) {
|
|
|
+ logger_error("Could not initialize i2c with device ID 0x%.2x (%s)\n",
|
|
|
+ I2C_ADDRESS_STRIPE, strerror(errno));
|
|
|
+ pthread_exit(NULL);
|
|
|
+ }
|
|
|
+ logger(V_STRIPE, "Initialized i2c device on address 0x%.2x\n",
|
|
|
+ I2C_ADDRESS_STRIPE);
|
|
|
+ currentColor.red = 0;
|
|
|
+ currentColor.green = 0;
|
|
|
+ currentColor.blue = 0;
|
|
|
+ currentWhite = 0;
|
|
|
+ currentDim = 0xff;
|
|
|
+ currentTransient = TRANS_DIRECT;
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * Sends out command data to the stripe controller via i2c
|
|
|
+ * @param len Length of the data array
|
|
|
+ * @param *data Pointer to data array
|
|
|
+ */
|
|
|
+int stripeCommand(int len, char* data) {
|
|
|
+ int ret = 0;
|
|
|
+ int i = 0;
|
|
|
+ pthread_mutex_lock(&mutex);
|
|
|
+ for (i = 0; i < len; i++) {
|
|
|
+ ret += wiringPiI2CWriteReg8(i2cfd, i, data[i]);
|
|
|
+ }
|
|
|
+ logger(V_STRIPE, "Wrote %d bytes to i2c device\n", len);
|
|
|
+ if (ret)
|
|
|
+ logger(V_NONE, LOG_WARN, "Failed to write %d of %d bytes on i2c device\n", ret, len);
|
|
|
+ pthread_mutex_unlock(&mutex);
|
|
|
+ return ret;
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * Updates the color data and prepares the stripe command
|
|
|
+ */
|
|
|
+void stripeUpdate(void) {
|
|
|
+ char data[7];
|
|
|
+ int len = 7;
|
|
|
+
|
|
|
+ if (currentTransient == TRANS_DIRECT) {
|
|
|
+ data[0] = STRIPE_CMD_SET;
|
|
|
+ data[1] = currentDim;
|
|
|
+ data[2] = currentColor.red;
|
|
|
+ data[3] = currentColor.green;
|
|
|
+ data[4] = currentColor.blue;
|
|
|
+ data[5] = currentWhite;
|
|
|
+ len = 6;
|
|
|
+ } else {
|
|
|
+ data[0] = STRIPE_CMD_FADETO;
|
|
|
+ data[1] = currentColor.red;
|
|
|
+ data[2] = currentColor.green;
|
|
|
+ data[3] = currentColor.blue;
|
|
|
+ data[4] = currentWhite;
|
|
|
+ data[5] = (currentTransient >> 8) & 0xff;
|
|
|
+ data[6] = currentTransient & 0xff;
|
|
|
+ }
|
|
|
+
|
|
|
+ stripeCommand(len, data);
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * Updates the dimmer value of the stripe
|
|
|
+ */
|
|
|
+void stripeUpdateDim(void) {
|
|
|
+ char data[2];
|
|
|
+ int len = 2;
|
|
|
+
|
|
|
+ data[0] = STRIPE_CMD_SETDIM;
|
|
|
+ data[1] = currentDim;
|
|
|
+
|
|
|
+ stripeCommand(len, data);
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * Updates the color of the stripe
|
|
|
+ * @param red Red value (max 255)
|
|
|
+ * @param green Green value (max 255)
|
|
|
+ * @param blue Blue value (max 255)
|
|
|
+ */
|
|
|
+void stripeSetRGB(int red, int green, int blue) {
|
|
|
+ currentColor.red = red & 0xff;
|
|
|
+ currentColor.green = green & 0xff;
|
|
|
+ currentColor.blue = blue & 0xff;
|
|
|
+ stripeUpdate();
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * Updates the color of the stripe
|
|
|
+ * @param color Color struct
|
|
|
+ */
|
|
|
+void stripeSetColor(stripe_color color) {
|
|
|
+ stripeSetRGB(color.red, color.green, color.blue);
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * Updates the transient time for the stripe (fading)
|
|
|
+ * @param transient Transient time in ticks
|
|
|
+ */
|
|
|
+void stripeSetTransient(stripe_transient_t transient) {
|
|
|
+ currentTransient = transient;
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * Updates the dimmer value of the stripe
|
|
|
+ * @param dim Dimmer value
|
|
|
+ */
|
|
|
+void stripeSetDim(int dim) {
|
|
|
+ dim = dim & 0xff;
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * Updates the white value of the stripe (4th channel)
|
|
|
+ * @param white White value
|
|
|
+ */
|
|
|
+void stripeSetWhite(int white) {
|
|
|
+ currentWhite = white & 0xff;
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * Turns the stripe on (Sets dimmer to 100%)
|
|
|
+ */
|
|
|
+void stripeOn(void) {
|
|
|
+ if (!currentDim) {
|
|
|
+ currentDim = 0xff;
|
|
|
+ }
|
|
|
+ stripeUpdateDim();
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * Turns the stripe on (Sets dimmer to 0%)
|
|
|
+ */
|
|
|
+void stripeOff(void) {
|
|
|
+ currentDim = 0;
|
|
|
+ stripeUpdateDim();
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * Reads the current stripe color
|
|
|
+ * @param *red Pointer to red variable
|
|
|
+ * @param *green Pointer to green variable
|
|
|
+ * @param *blue Pointer to blue variable
|
|
|
+ */
|
|
|
+void stripeGetRGB(int* red, int* green, int* blue) {
|
|
|
+ *red = currentColor.red;
|
|
|
+ *green = currentColor.green;
|
|
|
+ *blue = currentColor.blue;
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * Reads the current stripe dimmer value
|
|
|
+ * @param *dim Pointer to dimmer variable
|
|
|
+ */
|
|
|
+void stripeGetDim(int* dim) {
|
|
|
+ *dim = currentDim;
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * Reads the current stripe white value (4th channel)
|
|
|
+ * @param *white Pointer to white variable
|
|
|
+ */
|
|
|
+void stripeGetWhite(int* white) {
|
|
|
+ *white = currentWhite;
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * Stops current running effects
|
|
|
+ */
|
|
|
+void stripeEffectDisable(void) {
|
|
|
+ stripeTimer.stop();
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * Sets the stripe to a correspondending color to the heating status
|
|
|
+ * @param percent Heating level (0-100%)
|
|
|
+ */
|
|
|
+void stripeEffectHeating(int percent) {
|
|
|
+ long red, blue;
|
|
|
+
|
|
|
+ if (percent > 100) percent = 100;
|
|
|
+
|
|
|
+ red = percent * 255;
|
|
|
+ blue = (100-percent) * 255;
|
|
|
+
|
|
|
+ stripeSetTransient(TRANS_FAST);
|
|
|
+ stripeSetRGB(red/100,0,blue/100);
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * Enables pulsing with a given color of the stripe
|
|
|
+ * @param color Effect color
|
|
|
+ */
|
|
|
+void stripeEffectPulse(stripe_color color) {
|
|
|
+ effectColor = color;
|
|
|
+ stripeSetTransient(TRANS_MEDIUM);
|
|
|
+ stripeTimer.setDivider(40);
|
|
|
+ stripeTimer.start();
|
|
|
+}
|