70 lines
1.2 KiB
C++
70 lines
1.2 KiB
C++
// Copyright (C) 2017 Marius Schellenberger
|
|
|
|
#include <stdint.h>
|
|
#include <avr/interrupt.h>
|
|
#include <avr/wdt.h>
|
|
|
|
// data
|
|
#define ALPHA_MAX 36
|
|
char _itoa[ALPHA_MAX];
|
|
|
|
void init_itoa(void) {
|
|
for (int i = 0; i < 10; i++)
|
|
_itoa[i] = (char)48 + i;
|
|
for (int i = 10; i < ALPHA_MAX; i++)
|
|
_itoa[i] = (char)55 + i;
|
|
}
|
|
|
|
// random
|
|
#define CHAR_MAX 256
|
|
volatile unsigned char _r_sample = 0;
|
|
volatile char _r_new = 0;
|
|
unsigned char _r = 0;
|
|
const unsigned char _r_max = CHAR_MAX - (CHAR_MAX % ALPHA_MAX);
|
|
|
|
ISR(WDT_vect) {
|
|
_r_sample = TCNT1L;
|
|
_r_new = 1;
|
|
}
|
|
|
|
void _r_init(void) {
|
|
cli();
|
|
MCUSR = 0;
|
|
WDTCSR |= _BV(WDCE) | _BV(WDE);
|
|
WDTCSR = _BV(WDIE);
|
|
sei();
|
|
}
|
|
|
|
char _r_rotl_one(const char v) {
|
|
int shift = 1;
|
|
if ((shift &= sizeof(v) * 8 - 1) == 0)
|
|
return v;
|
|
return (v << shift) | (v >> (sizeof(v) * 8 - shift));
|
|
}
|
|
|
|
char _r_char(void) {
|
|
char i = 0;
|
|
while (1) {
|
|
if (_r_new) {
|
|
_r_new = 0;
|
|
_r = _r_rotl_one(_r);
|
|
_r ^= _r_sample;
|
|
if (i++ > 7) {
|
|
if (_r < _r_max)
|
|
return _itoa[_r % ALPHA_MAX];
|
|
else
|
|
i = 0;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void setup(void) {
|
|
Serial.begin(115200);
|
|
_r_init();
|
|
init_itoa();
|
|
}
|
|
|
|
void loop(void) {
|
|
Serial.write(_r_char());
|
|
}
|