touch buttons set LED programs, added another ribbon LED program
also added PRNG
This commit is contained in:
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 */
|
||||
Reference in New Issue
Block a user