main.c 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251
  1. /*
  2. * newtest.c
  3. *
  4. * Copyright (c) 2014 Jeremy Garff <jer @ jers.net>
  5. * Copyright (c) 2017 Daniel 'grindhold' Brendle
  6. *
  7. * All rights reserved.
  8. *
  9. * Redistribution and use in source and binary forms, with or without modification, are permitted
  10. * provided that the following conditions are met:
  11. *
  12. * 1. Redistributions of source code must retain the above copyright notice, this list of
  13. * conditions and the following disclaimer.
  14. * 2. Redistributions in binary form must reproduce the above copyright notice, this list
  15. * of conditions and the following disclaimer in the documentation and/or other materials
  16. * provided with the distribution.
  17. * 3. Neither the name of the owner nor the names of its contributors may be used to endorse
  18. * or promote products derived from this software without specific prior written permission.
  19. *
  20. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
  21. * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
  22. * FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE
  23. * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  24. * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
  25. * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  26. * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
  27. * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  28. *
  29. */
  30. #include <stdint.h>
  31. #include <stdio.h>
  32. #include <time.h>
  33. #include <stdlib.h>
  34. #include <string.h>
  35. #include <unistd.h>
  36. #include <sys/types.h>
  37. #include <sys/stat.h>
  38. #include <fcntl.h>
  39. #include <sys/mman.h>
  40. #include <signal.h>
  41. #include <stdarg.h>
  42. #include <getopt.h>
  43. #include "clk.h"
  44. #include "gpio.h"
  45. #include "dma.h"
  46. #include "pwm.h"
  47. #include "version.h"
  48. #include "ws2811.h"
  49. // defaults for cmdline options
  50. #define TARGET_FREQ WS2811_TARGET_FREQ
  51. #define GPIO_PIN 18
  52. #define DMA 5
  53. #define STRIP_TYPE WS2811_STRIP_RGB // WS2812/SK6812RGB integrated chip+leds
  54. //#define STRIP_TYPE WS2811_STRIP_GBR // WS2812/SK6812RGB integrated chip+leds
  55. //#define STRIP_TYPE SK6812_STRIP_RGBW // SK6812RGBW (NOT SK6812RGB)
  56. #define WIDTH 149
  57. #define HEIGHT 1
  58. #define LED_COUNT (WIDTH * HEIGHT)
  59. int width = WIDTH;
  60. int height = HEIGHT;
  61. int led_count = LED_COUNT;
  62. ws2811_t ledstring =
  63. {
  64. .freq = TARGET_FREQ,
  65. .dmanum = DMA,
  66. .channel =
  67. {
  68. [0] =
  69. {
  70. .gpionum = GPIO_PIN,
  71. .count = LED_COUNT,
  72. .invert = 0,
  73. .brightness = 255,
  74. .strip_type = STRIP_TYPE,
  75. },
  76. [1] =
  77. {
  78. .gpionum = 0,
  79. .count = 0,
  80. .invert = 0,
  81. .brightness = 0,
  82. },
  83. },
  84. };
  85. static uint8_t running = 1;
  86. typedef struct parable {
  87. float squeeze;
  88. float x;
  89. float y;
  90. float speed;
  91. int color;
  92. } Parable;
  93. #define N_PARABLES 16
  94. Parable parables[N_PARABLES];
  95. ws2811_led_t wavecolors[] =
  96. {
  97. 0x00201000,
  98. 0x00101000,
  99. 0x00202000,
  100. 0x00200500,
  101. 0x00151000,
  102. 0x000f1003,
  103. 0x00010010,
  104. 0x00220010,
  105. };
  106. void parable_init(Parable *p) {
  107. p->squeeze = (float)((rand() % 20)+1)/300.0f;
  108. p->x = rand() % 2 > 0 ? 0.0f : 149.0f;
  109. p->y = 1.0f;
  110. p->speed = ((float)(rand() % 60)+1.0f) / 20000.0f;
  111. if (p->x > 0) p->speed *= -1.0f;
  112. p->color = wavecolors[rand() % 8];
  113. }
  114. void parable_check_done(Parable *p) {
  115. if (p->speed < 0) {
  116. if (p->x < 10) parable_init(p);
  117. } else {
  118. if (p->x > 159) parable_init(p);
  119. }
  120. }
  121. unsigned int mix_colors(unsigned int a, unsigned int b) {
  122. if (a == 0 && b==0) {
  123. return 0;
  124. }
  125. unsigned int target = 0x00000000;
  126. unsigned int i = 0;
  127. unsigned int component_a, component_b, mix = 0;
  128. for (i = 0; i < 4; i++) {
  129. component_a = a & 0xff;
  130. component_b = b & 0xff;
  131. a >>= 8;
  132. b >>= 8;
  133. mix = component_a+component_b;
  134. target |= (mix > 0x60 ? 0x60 : mix) << 24;
  135. if (i != 3)
  136. target >>= 8;
  137. }
  138. return target;
  139. }
  140. unsigned int parable_get_color(Parable* p, int x) {
  141. float factor = -p->squeeze * ((float)x - p->x)*((float)x - p->x) + p->y;
  142. if (factor <= 0)
  143. return 0;
  144. unsigned int target = 0x00000000;
  145. unsigned int color = p->color;
  146. int icomponent, i;
  147. float component;
  148. for (i = 0; i < 4; i++) {
  149. component = (float)(color & 0x000000ff);
  150. component *= factor;
  151. icomponent = (int)component;
  152. icomponent = icomponent < 0x00 ? 0x00 : icomponent;
  153. icomponent = icomponent > 0x60 ? 0x60 : icomponent;
  154. target |= (unsigned int) icomponent << 24;
  155. color >>= 8;
  156. if (i != 3)
  157. target >>= 8;
  158. }
  159. return target;
  160. }
  161. void wave_render(void)
  162. {
  163. int x, i;
  164. unsigned int color;
  165. for (x = 0; x < width; x++)
  166. {
  167. color = 0x0;
  168. for (i = 0; i < N_PARABLES; i++) {
  169. Parable* p = &(parables[i]);
  170. color = mix_colors(color, parable_get_color(p,x));
  171. parable_check_done(p);
  172. p->x += p->speed;
  173. }
  174. ledstring.channel[0].leds[x] = (ws2811_led_t) color;
  175. }
  176. }
  177. static void ctrl_c_handler(int signum)
  178. {
  179. running = 0;
  180. }
  181. static void setup_handlers(void)
  182. {
  183. struct sigaction sa =
  184. {
  185. .sa_handler = ctrl_c_handler,
  186. };
  187. sigaction(SIGINT, &sa, NULL);
  188. sigaction(SIGTERM, &sa, NULL);
  189. }
  190. int main(int argc, char *argv[])
  191. {
  192. ws2811_return_t ret;
  193. srand((unsigned int)time(NULL));
  194. int i = 0;
  195. for (i = 0; i < N_PARABLES; i++) {
  196. parable_init(&parables[i]);
  197. }
  198. setup_handlers();
  199. if ((ret = ws2811_init(&ledstring)) != WS2811_SUCCESS)
  200. {
  201. fprintf(stderr, "ws2811_init failed: %s\n", ws2811_get_return_t_str(ret));
  202. return ret;
  203. }
  204. while (running)
  205. {
  206. wave_render();
  207. if ((ret = ws2811_render(&ledstring)) != WS2811_SUCCESS)
  208. {
  209. fprintf(stderr, "ws2811_render failed: %s\n", ws2811_get_return_t_str(ret));
  210. break;
  211. }
  212. usleep(1000000 / 120);
  213. }
  214. ws2811_fini(&ledstring);
  215. printf ("\n");
  216. return ret;
  217. }