Go to most recent revision | Details | Last modification | View Log | RSS feed
| Rev | Author | Line No. | Line |
|---|---|---|---|
| 8 | mjames | 1 | /* |
| 2 | * sendLeds.c |
||
| 3 | * |
||
| 4 | * Created on: 17 Aug 2019 |
||
| 5 | * Author: Mike |
||
| 6 | */ |
||
| 7 | |||
| 8 | #include "main.h" |
||
| 9 | #include "leds.h" |
||
| 10 | #include "sendLeds.h" |
||
| 11 | |||
| 12 | |||
| 13 | #include <stdint.h> |
||
| 14 | |||
| 15 | /* This is xoroshiro128+ 1.0, our best and fastest small-state generator |
||
| 16 | for floating-point numbers. We suggest to use its upper bits for |
||
| 17 | floating-point generation, as it is slightly faster than |
||
| 18 | xoroshiro128**. It passes all tests we are aware of except for the four |
||
| 19 | lower bits, which might fail linearity tests (and just those), so if |
||
| 20 | low linear complexity is not considered an issue (as it is usually the |
||
| 21 | case) it can be used to generate 64-bit outputs, too; moreover, this |
||
| 22 | generator has a very mild Hamming-weight dependency making our test |
||
| 23 | (http://prng.di.unimi.it/hwd.php) fail after 5 TB of output; we believe |
||
| 24 | this slight bias cannot affect any application. If you are concerned, |
||
| 25 | use xoroshiro128++, xoroshiro128** or xoshiro256+. |
||
| 26 | |||
| 27 | We suggest to use a sign test to extract a random Boolean value, and |
||
| 28 | right shifts to extract subsets of bits. |
||
| 29 | |||
| 30 | The state must be seeded so that it is not everywhere zero. If you have |
||
| 31 | a 64-bit seed, we suggest to seed a splitmix64 generator and use its |
||
| 32 | output to fill s. |
||
| 33 | |||
| 34 | NOTE: the parameters (a=24, b=16, b=37) of this version give slightly |
||
| 35 | better results in our test than the 2016 version (a=55, b=14, c=36). |
||
| 36 | */ |
||
| 37 | |||
| 38 | static inline uint64_t rotl(const uint64_t x, int k) { |
||
| 39 | return (x << k) | (x >> (64 - k)); |
||
| 40 | } |
||
| 41 | |||
| 42 | |||
| 43 | static uint64_t s[2] = { 102,33 }; |
||
| 44 | |||
| 45 | uint64_t next(void) { |
||
| 46 | const uint64_t s0 = s[0]; |
||
| 47 | uint64_t s1 = s[1]; |
||
| 48 | const uint64_t result = s0 + s1; |
||
| 49 | |||
| 50 | s1 ^= s0; |
||
| 51 | s[0] = rotl(s0, 24) ^ s1 ^ (s1 << 16); // a, b |
||
| 52 | s[1] = rotl(s1, 37); // c |
||
| 53 | |||
| 54 | return result; |
||
| 55 | } |
||
| 56 | |||
| 57 | |||
| 58 | frgbw_t led0 = { 128, 0, 0, 0, 0 }; |
||
| 59 | frgbw_t led1 = { 128, 0, 0, 0, 2 }; |
||
| 60 | frgbw_t ledZ = { 0,0,0,0 }; |
||
| 61 | |||
| 62 | int counter = 1; |
||
| 63 | |||
| 64 | void sendLeds() |
||
| 65 | { |
||
| 66 | |||
| 67 | initCode(); |
||
| 68 | codeReset(); |
||
| 69 | |||
| 70 | int target = 128; |
||
| 71 | counter--; |
||
| 72 | |||
| 73 | if(counter == 0) |
||
| 74 | { |
||
| 75 | counter = (next() & 0xF0)+16; |
||
| 76 | |||
| 77 | led0.red = next() & 0xFF; |
||
| 78 | led0.green =next() & 0xFF; |
||
| 79 | led0.blue = next() & 0xFF; |
||
| 80 | led0.white = next() & 0xFF; |
||
| 81 | |||
| 82 | } |
||
| 83 | if(led0.fader < target) |
||
| 84 | led0.fader++; |
||
| 85 | if(led0.fader > target) |
||
| 86 | led0.fader--; |
||
| 87 | |||
| 88 | if((counter & 8) == 0) |
||
| 89 | target = (next() & 0xE0) + 0x20; |
||
| 90 | |||
| 91 | codeFRGBW(led0); |
||
| 92 | |||
| 93 | // send terminal |
||
| 94 | |||
| 95 | codeStop(); |
||
| 96 | sendCode(); // send coded pattern |
||
| 97 | } |
||
| 98 | |||
| 99 | |||
| 100 |