
/*
 * sendLeds.c
 *
 *  Created on: 17 Aug 2019
 *      Author: Mike
 */

#include "main.h"
#include "libWS2812/leds.h"
#include "libWS2812/spiInterface.h"
#include "sendLeds.h"

#include <stdint.h>

/* This is xoroshiro128+ 1.0, our best and fastest small-state generator
 for floating-point numbers. We suggest to use its upper bits for
 floating-point generation, as it is slightly faster than
 xoroshiro128**. It passes all tests we are aware of except for the four
 lower bits, which might fail linearity tests (and just those), so if
 low linear complexity is not considered an issue (as it is usually the
 case) it can be used to generate 64-bit outputs, too; moreover, this
 generator has a very mild Hamming-weight dependency making our test
 (http://prng.di.unimi.it/hwd.php) fail after 5 TB of output; we believe
 this slight bias cannot affect any application. If you are concerned,
 use xoroshiro128++, xoroshiro128** or xoshiro256+.

 We suggest to use a sign test to extract a random Boolean value, and
 right shifts to extract subsets of bits.

 The state must be seeded so that it is not everywhere zero. If you have
 a 64-bit seed, we suggest to seed a splitmix64 generator and use its
 output to fill s.

 NOTE: the parameters (a=24, b=16, b=37) of this version give slightly
 better results in our test than the 2016 version (a=55, b=14, c=36).
 */

static inline uint64_t
rotl (const uint64_t x, int k)
{
  return (x << k) | (x >> (64 - k));
}

static uint64_t s[2] =
  { 102, 33 };

uint64_t
next (void)
{
  const uint64_t s0 = s[0];
  uint64_t s1 = s[1];
  const uint64_t result = s0 + s1;

  s1 ^= s0;
  s[0] = rotl (s0, 24) ^ s1 ^ (s1 << 16); // a, b
  s[1] = rotl (s1, 37); // c

  return result;
}

#if defined WS2812
frgbw_t led0 = { 128, 0, 0, 0 };
frgbw_t led1 = { 128, 0, 0, 2 };
frgbw_t ledZ = { 0,0,0 };
#else
frgbw_t led0 =
  { 128, 0, 0, 0 };
frgbw_t led1 =
  { 128, 0, 0, 2 };
frgbw_t ledZ =
  { 0, 0, 0, };
#endif
int counter = 1;

void
sendLeds ()
{

  initCode ();
  codeReset ();

  int target = 128;
  counter--;

  if (counter == 0)
    {
      counter = (next () & 0xF0) + 16;

      led0.red = next () & 0xFF;
      led0.green = next () & 0xFF;
      led0.blue = next () & 0xFF;
#if defined WS2812
      led0.white = 0;
      // led0.white = next() & 0xFF;
#endif

      led1.red = next () & 0xFF;
      led1.green = next () & 0xFF;
      led1.blue = next () & 0xFF;
#if defined WS2812
      led1.white = 0;
      //led1.white = next() & 0xFF;
#endif


    }
  if (led1.fader < target)
    led1.fader++;
  if (led1.fader > target)
    led1.fader--;

  if ((counter & 8) == 0)
    target = (next () & 0x70) + 0x00;

  codeFRGBW (led0);
  codeFRGBW (led1);
  // send terminal

  codeStop ();
  sendCode (); // send coded pattern
}

