touch buttons set LED programs, added another ribbon LED program
also added PRNG
This commit is contained in:
@@ -3,7 +3,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "matrix.h"
|
#include "matrix.h"
|
||||||
|
#include "misc/tinymt.h"
|
||||||
|
|
||||||
|
|
||||||
static uint32_t s[8] = {0};
|
static uint32_t s[8] = {0};
|
||||||
@@ -31,6 +31,17 @@ void lp_ribbon_upward(uint16_t wait, uint16_t rate, uint8_t fade)
|
|||||||
1: timeout
|
1: timeout
|
||||||
2: index
|
2: index
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
if (fade > 0x80)
|
||||||
|
fade = 0x80;
|
||||||
|
|
||||||
|
// reduce 1-frame bright blip
|
||||||
|
for (i = 0; i < sizeof(led_set.ribbon); i++) {
|
||||||
|
if (led_set.ribbon[i] >= 0xd0) {
|
||||||
|
led_set.ribbon[i] = 0xd0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
switch (s[0]) {
|
switch (s[0]) {
|
||||||
case 0: { // timeout
|
case 0: { // timeout
|
||||||
if (!s[1]) {
|
if (!s[1]) {
|
||||||
@@ -64,16 +75,62 @@ void lp_ribbon_upward(uint16_t wait, uint16_t rate, uint8_t fade)
|
|||||||
// fade in and up
|
// fade in and up
|
||||||
led_set.ribbon[x] = 0x20;
|
led_set.ribbon[x] = 0x20;
|
||||||
if (x) led_set.ribbon[x - 1] = 0x66;
|
if (x) led_set.ribbon[x - 1] = 0x66;
|
||||||
if (x > 1) led_set.ribbon[x - 2] = 0xd0;
|
if (x > 1) led_set.ribbon[x - 2] = 0xef;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// fade out LEDs
|
// fade out LEDs
|
||||||
for (i = 0; i < sizeof(led_set.ribbon); i++) {
|
for (i = 0; i < sizeof(led_set.ribbon); i++) {
|
||||||
|
if (led_set.ribbon[i] >= 0x70) {
|
||||||
|
led_set.ribbon[i] -= fade;
|
||||||
|
}
|
||||||
if (led_set.ribbon[i] >= fade) {
|
if (led_set.ribbon[i] >= fade) {
|
||||||
led_set.ribbon[i] -= fade;
|
led_set.ribbon[i] -= fade;
|
||||||
} else {
|
} else {
|
||||||
led_set.ribbon[i] >>= 1;
|
// led_set.ribbon[i] >>= 1;
|
||||||
|
if (led_set.ribbon[i])
|
||||||
|
led_set.ribbon[i]--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
matrix_flag_update();
|
||||||
|
}
|
||||||
|
|
||||||
|
void lp_ribbon_twinkle(uint8_t idle, uint8_t max, uint8_t thresh_lo, uint8_t thresh_hi)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
idle: attempted idle target. ideally an odd number not a power of two.
|
||||||
|
max: maximum brightness. anything higher is clamped to this
|
||||||
|
thresh_lo: rand must be lower than this to make any adjustment this cycle
|
||||||
|
thresh_hi: rand must be this or higher to force a bright twinkle
|
||||||
|
*/
|
||||||
|
|
||||||
|
uint32_t i;
|
||||||
|
uint32_t w, x;
|
||||||
|
|
||||||
|
s[1]++;
|
||||||
|
|
||||||
|
for (i = 0; i < sizeof(led_set.ribbon); i++) {
|
||||||
|
x = prng_get8();
|
||||||
|
|
||||||
|
if (x < thresh_lo) {
|
||||||
|
w = (idle > 3) ? 3 : idle;
|
||||||
|
|
||||||
|
// swing around idle level
|
||||||
|
if (led_set.ribbon[i] > idle) {
|
||||||
|
led_set.ribbon[i] >>= 1;
|
||||||
|
} else {
|
||||||
|
led_set.ribbon[i] += (w - 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// only make bright stars every 4 frames
|
||||||
|
if ((x >= thresh_hi) && ((s[1] & 3) == 0)) {
|
||||||
|
w = prng_get8();
|
||||||
|
led_set.ribbon[i] += w;
|
||||||
|
if (led_set.ribbon[i] > max) {
|
||||||
|
led_set.ribbon[i] = max;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
|
|
||||||
void lp_ribbon_init();
|
void lp_ribbon_init();
|
||||||
void lp_ribbon_upward(uint16_t wait, uint16_t rate, uint8_t fade);
|
void lp_ribbon_upward(uint16_t wait, uint16_t rate, uint8_t fade);
|
||||||
|
void lp_ribbon_twinkle(uint8_t idle, uint8_t max, uint8_t thresh_lo, uint8_t thresh_hi);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -29,6 +29,8 @@
|
|||||||
#include "ui/btn.h"
|
#include "ui/btn.h"
|
||||||
#include "ui/temp_ui.h"
|
#include "ui/temp_ui.h"
|
||||||
|
|
||||||
|
#include "misc/tinymt.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
*@Note
|
*@Note
|
||||||
***Only PA0--PA15 and PC16--PC17 support input pull-down.
|
***Only PA0--PA15 and PC16--PC17 support input pull-down.
|
||||||
@@ -166,6 +168,9 @@ int main(void)
|
|||||||
// set up user interface
|
// set up user interface
|
||||||
tempui_init();
|
tempui_init();
|
||||||
|
|
||||||
|
// set up random
|
||||||
|
tinymt32_init(&tinymt32_s, 1337);
|
||||||
|
|
||||||
// configure AWU to provide ~997Hz wakeup interrupt for main program
|
// configure AWU to provide ~997Hz wakeup interrupt for main program
|
||||||
// TODO: confirm if the counter is reset / preloaded
|
// TODO: confirm if the counter is reset / preloaded
|
||||||
awu_init();
|
awu_init();
|
||||||
@@ -175,7 +180,7 @@ int main(void)
|
|||||||
// rendering next LED program output frame
|
// rendering next LED program output frame
|
||||||
if (lp_render) {
|
if (lp_render) {
|
||||||
lp_render = 0;
|
lp_render = 0;
|
||||||
lp_ribbon_upward(200, 3, 4);
|
tempui_lp_runprog();
|
||||||
}
|
}
|
||||||
|
|
||||||
// stay a while
|
// stay a while
|
||||||
|
|||||||
162
firmware/app/misc/tinymt.c
Normal file
162
firmware/app/misc/tinymt.c
Normal file
@@ -0,0 +1,162 @@
|
|||||||
|
/**
|
||||||
|
* Tiny Mersenne Twister: only 127-bit internal state.
|
||||||
|
* Derived from the reference implementation version 1.1 (2015/04/24)
|
||||||
|
* by Mutsuo Saito (Hiroshima University) and Makoto Matsumoto
|
||||||
|
* (Hiroshima University).
|
||||||
|
*/
|
||||||
|
#include <stdint.h>
|
||||||
|
#include "tinymt.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
static void tinymt32_next_state(tinymt32_t *s);
|
||||||
|
static uint32_t tinymt32_temper(tinymt32_t *s);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
tinymt32_t tinymt32_s;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parameter set to use for this IETF specification. Don't change.
|
||||||
|
* This parameter set is the first entry of the precalculated
|
||||||
|
* parameter sets in tinymt32dc/tinymt32dc.0.1048576.txt by
|
||||||
|
* Kenji Rikitake, available at:
|
||||||
|
* https://github.com/jj1bdx/tinymtdc-longbatch/.
|
||||||
|
* It is also the parameter set used in:
|
||||||
|
* Rikitake, K., "TinyMT pseudo random number generator for
|
||||||
|
* Erlang", Proceedings of the 11th ACM SIGPLAN Erlang Workshop,
|
||||||
|
* September 2012.
|
||||||
|
*/
|
||||||
|
const uint32_t TINYMT32_MAT1_PARAM = UINT32_C(0x8f7011ee);
|
||||||
|
const uint32_t TINYMT32_MAT2_PARAM = UINT32_C(0xfc78ff1f);
|
||||||
|
const uint32_t TINYMT32_TMAT_PARAM = UINT32_C(0x3793fdff);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This function initializes the internal state array with a
|
||||||
|
* 32-bit unsigned integer seed.
|
||||||
|
* @param s pointer to tinymt internal state.
|
||||||
|
* @param seed a 32-bit unsigned integer used as a seed.
|
||||||
|
*/
|
||||||
|
void tinymt32_init(tinymt32_t* s, uint32_t seed)
|
||||||
|
{
|
||||||
|
const uint32_t MIN_LOOP = 8;
|
||||||
|
const uint32_t PRE_LOOP = 8;
|
||||||
|
s->status[0] = seed;
|
||||||
|
s->status[1] = s->mat1 = TINYMT32_MAT1_PARAM;
|
||||||
|
s->status[2] = s->mat2 = TINYMT32_MAT2_PARAM;
|
||||||
|
s->status[3] = s->tmat = TINYMT32_TMAT_PARAM;
|
||||||
|
for (int i = 1; i < MIN_LOOP; i++) {
|
||||||
|
s->status[i & 3] ^= i + UINT32_C(1812433253)
|
||||||
|
* (s->status[(i - 1) & 3]
|
||||||
|
^ (s->status[(i - 1) & 3] >> 30));
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
* NB: The parameter set of this specification warrants
|
||||||
|
* that none of the possible 2^^32 seeds leads to an
|
||||||
|
* all-zero 127-bit internal state. Therefore, the
|
||||||
|
* period_certification() function of the original
|
||||||
|
* TinyMT32 source code has been safely removed. If
|
||||||
|
* another parameter set is used, this function will
|
||||||
|
* have to be reintroduced here.
|
||||||
|
*/
|
||||||
|
for (int i = 0; i < PRE_LOOP; i++) {
|
||||||
|
tinymt32_next_state(s);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This function outputs a 32-bit unsigned integer from
|
||||||
|
* the internal state.
|
||||||
|
* @param s pointer to tinymt internal state.
|
||||||
|
* @return 32-bit unsigned integer r (0 <= r < 2^32).
|
||||||
|
*/
|
||||||
|
uint32_t tinymt32_get_uint32(tinymt32_t* s)
|
||||||
|
{
|
||||||
|
tinymt32_next_state(s);
|
||||||
|
return tinymt32_temper(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Internal tinymt32 constants and functions.
|
||||||
|
* Users should not call these functions directly.
|
||||||
|
*/
|
||||||
|
const uint32_t TINYMT32_SH0 = 1;
|
||||||
|
const uint32_t TINYMT32_SH1 = 10;
|
||||||
|
const uint32_t TINYMT32_SH8 = 8;
|
||||||
|
const uint32_t TINYMT32_MASK = UINT32_C(0x7fffffff);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This function changes the internal state of tinymt32.
|
||||||
|
* @param s pointer to tinymt internal state.
|
||||||
|
*/
|
||||||
|
void tinymt32_next_state(tinymt32_t* s)
|
||||||
|
{
|
||||||
|
uint32_t x;
|
||||||
|
uint32_t y;
|
||||||
|
|
||||||
|
y = s->status[3];
|
||||||
|
x = (s->status[0] & TINYMT32_MASK)
|
||||||
|
^ s->status[1]
|
||||||
|
^ s->status[2];
|
||||||
|
x ^= (x << TINYMT32_SH0);
|
||||||
|
y ^= (y >> TINYMT32_SH0) ^ x;
|
||||||
|
s->status[0] = s->status[1];
|
||||||
|
s->status[1] = s->status[2];
|
||||||
|
s->status[2] = x ^ (y << TINYMT32_SH1);
|
||||||
|
s->status[3] = y;
|
||||||
|
/*
|
||||||
|
* The if (y & 1) {...} block below replaces:
|
||||||
|
* s->status[1] ^= -((int32_t)(y & 1)) & s->mat1;
|
||||||
|
* s->status[2] ^= -((int32_t)(y & 1)) & s->mat2;
|
||||||
|
* The adopted code is equivalent to the original code
|
||||||
|
* but does not depend on the representation of negative
|
||||||
|
* integers by 2's complements. It is therefore more
|
||||||
|
* portable but includes an if branch, which may slow
|
||||||
|
* down the generation speed.
|
||||||
|
*/
|
||||||
|
if (y & 1) {
|
||||||
|
s->status[1] ^= s->mat1;
|
||||||
|
s->status[2] ^= s->mat2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This function outputs a 32-bit unsigned integer from
|
||||||
|
* the internal state.
|
||||||
|
* @param s pointer to tinymt internal state.
|
||||||
|
* @return 32-bit unsigned pseudorandom number.
|
||||||
|
*/
|
||||||
|
uint32_t tinymt32_temper (tinymt32_t* s)
|
||||||
|
{
|
||||||
|
uint32_t t0, t1;
|
||||||
|
t0 = s->status[3];
|
||||||
|
t1 = s->status[0] + (s->status[2] >> TINYMT32_SH8);
|
||||||
|
t0 ^= t1;
|
||||||
|
/*
|
||||||
|
* The if (t1 & 1) {...} block below replaces:
|
||||||
|
* t0 ^= -((int32_t)(t1 & 1)) & s->tmat;
|
||||||
|
* The adopted code is equivalent to the original code
|
||||||
|
* but does not depend on the representation of negative
|
||||||
|
* integers by 2's complements. It is therefore more
|
||||||
|
* portable but includes an if branch, which may slow
|
||||||
|
* down the generation speed.
|
||||||
|
*/
|
||||||
|
if (t1 & 1) {
|
||||||
|
t0 ^= s->tmat;
|
||||||
|
}
|
||||||
|
return t0;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t prng_scale16(uint16_t min, uint16_t max)
|
||||||
|
{
|
||||||
|
uint32_t rnd;
|
||||||
|
|
||||||
|
rnd = prng_get16();
|
||||||
|
rnd *= (max - min);
|
||||||
|
rnd >>= 16;
|
||||||
|
rnd += min;
|
||||||
|
|
||||||
|
return rnd;
|
||||||
|
}
|
||||||
39
firmware/app/misc/tinymt.h
Normal file
39
firmware/app/misc/tinymt.h
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
/**
|
||||||
|
* Tiny Mersenne Twister
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef TINYMT_RAND_H_
|
||||||
|
#define TINYMT_RAND_H_
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* tinymt32 internal state vector and parameters
|
||||||
|
*/
|
||||||
|
typedef struct {
|
||||||
|
uint32_t status[4];
|
||||||
|
uint32_t mat1;
|
||||||
|
uint32_t mat2;
|
||||||
|
uint32_t tmat;
|
||||||
|
} tinymt32_t;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
extern tinymt32_t tinymt32_s;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void tinymt32_init(tinymt32_t *s, uint32_t seed);
|
||||||
|
uint32_t tinymt32_get_uint32(tinymt32_t* s);
|
||||||
|
|
||||||
|
#define prng_get8() (tinymt32_get_uint32(&tinymt32_s) & 0xff)
|
||||||
|
#define prng_get16() (tinymt32_get_uint32(&tinymt32_s) & 0xffff)
|
||||||
|
#define prng_get32() tinymt32_get_uint32(&tinymt32_s)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
uint16_t prng_scale16(uint16_t min, uint16_t max);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* TINYMT_RAND_H */
|
||||||
@@ -6,14 +6,19 @@
|
|||||||
#include "btn.h"
|
#include "btn.h"
|
||||||
|
|
||||||
#include "led/matrix.h"
|
#include "led/matrix.h"
|
||||||
|
#include "led/ledprog.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static uint32_t brt = 28;
|
static uint32_t brt = 28;
|
||||||
|
|
||||||
|
uint8_t ribbon_prog = 0;
|
||||||
|
uint8_t a_prog = 0;
|
||||||
|
uint8_t ii_prog = 0;
|
||||||
|
|
||||||
|
|
||||||
void brt_set(uint8_t idx)
|
|
||||||
|
static void brt_set(uint8_t idx)
|
||||||
{
|
{
|
||||||
switch (idx) {
|
switch (idx) {
|
||||||
case 1: {
|
case 1: {
|
||||||
@@ -31,8 +36,48 @@ void brt_set(uint8_t idx)
|
|||||||
aw20x_set_dim_global(&awled, brt);
|
aw20x_set_dim_global(&awled, brt);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void prog_set(uint8_t idx)
|
||||||
|
{
|
||||||
|
switch (idx) {
|
||||||
|
case 3: { // trio bottom left
|
||||||
|
ribbon_prog = 0;
|
||||||
|
lp_ribbon_init();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 4: { // trio upper
|
||||||
|
ribbon_prog = 1;
|
||||||
|
lp_ribbon_init();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 5: { // da erf
|
||||||
|
ribbon_prog = 3;
|
||||||
|
lp_ribbon_init();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 6: { // big crater
|
||||||
|
lp_ribbon_init();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 7: { // next to big crater
|
||||||
|
lp_ribbon_init();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 8: { // bottom crater
|
||||||
|
lp_ribbon_init();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 9: { // trio right
|
||||||
|
ribbon_prog = 2;
|
||||||
|
lp_ribbon_init();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void tempui_init()
|
void tempui_init()
|
||||||
{
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
btn[2].cb_push = brt_set;
|
btn[2].cb_push = brt_set;
|
||||||
btn[2].cb_hold = brt_set;
|
btn[2].cb_hold = brt_set;
|
||||||
btn[2].repeat = 200;
|
btn[2].repeat = 200;
|
||||||
@@ -40,4 +85,30 @@ void tempui_init()
|
|||||||
btn[1].cb_push = brt_set;
|
btn[1].cb_push = brt_set;
|
||||||
btn[1].cb_hold = brt_set;
|
btn[1].cb_hold = brt_set;
|
||||||
btn[1].repeat = 200;
|
btn[1].repeat = 200;
|
||||||
|
|
||||||
|
for (i = 3; i < 10; i++) {
|
||||||
|
btn[i].cb_push = prog_set;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void tempui_lp_runprog()
|
||||||
|
{
|
||||||
|
switch (ribbon_prog) {
|
||||||
|
case 0: {
|
||||||
|
lp_ribbon_upward(400, 3, 4);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 1: {
|
||||||
|
lp_ribbon_upward(800, 1, 2);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 2: {
|
||||||
|
lp_ribbon_upward(1500, 4, 7);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 3: {
|
||||||
|
lp_ribbon_twinkle(3, 0x7f, 0x1f, 0xfd);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -1 +1,3 @@
|
|||||||
void tempui_init();
|
void tempui_init();
|
||||||
|
|
||||||
|
void tempui_lp_runprog();
|
||||||
Reference in New Issue
Block a user