#define SSD1306_128X32 #include "ch32v003fun.h" #include #include "ssd1306_i2c.h" #include "ssd1306.h" #define PIN_LED PC4 #define PIN_BTN PC7 #define u8 uint8_t #define u16 uint16_t uint8_t gol_tmp[sizeof(ssd1306_buffer)]; uint32_t lfsr = 1; // PRNG state u8 rand8(); u8 get_pixel(u8 x, u8 y); void gol_step(); void r_pentomino(); void randomise(); int main() { SystemInit(); funGpioInitAll(); funPinMode(PIN_LED, GPIO_CFGLR_OUT_10Mhz_PP); funPinMode(PIN_BTN, GPIO_CFGLR_IN_PUPD); ssd1306_i2c_init(); ssd1306_init(); randomise(); while (1) { ssd1306_refresh(); gol_step(); memcpy(ssd1306_buffer, gol_tmp, sizeof(ssd1306_buffer)); if (funDigitalRead(PIN_BTN)) { randomise(); ssd1306_refresh(); funDigitalWrite(PIN_LED, FUN_HIGH); Delay_Ms(100); funDigitalWrite(PIN_LED, FUN_LOW); } } } void r_pentomino() { ssd1306_setbuf(0); ssd1306_drawPixel(20, 20, 1); ssd1306_drawPixel(21, 20, 1); ssd1306_drawPixel(21, 21, 1); ssd1306_drawPixel(22, 21, 1); ssd1306_drawPixel(21, 22, 1); } void randomise() { lfsr = SysTick->CNT; for (u16 b = 0; b < sizeof(ssd1306_buffer); b++) { ssd1306_buffer[b] = rand8(); } } u8 get_pixel(u8 x, u8 y) { x = x & 127; y = y & 31; u8 slice = ssd1306_buffer[(y / 8) * 128 + x]; return (slice & (1 << (y & 7))) != 0; } void gol_step() { // slow pixel-by-pixel implementation for (u8 x = 0; x < 128; x++) { for (u8 y = 0; y < 32; y++) { u8 this = get_pixel(x, y); u8 sum = 0; sum += get_pixel(x + 127, y + 31); sum += get_pixel(x + 127, y); sum += get_pixel(x + 127, y + 1); sum += get_pixel(x, y + 31); sum += get_pixel(x, y + 1); sum += get_pixel(x + 1, y + 31); sum += get_pixel(x + 1, y); sum += get_pixel(x + 1, y + 1); u8 new_state = (sum == 3) | ((sum == 2) & this); u16 addr = x + (y / 8) * 128; if (new_state) gol_tmp[addr] |= (1 << (y & 7)); else gol_tmp[addr] &= ~(1 << (y & 7)); } } } /* White Noise Generator State */ #define NOISE_BITS 8 #define NOISE_MASK ((1 << NOISE_BITS) - 1) #define NOISE_POLY_TAP0 31 #define NOISE_POLY_TAP1 21 #define NOISE_POLY_TAP2 1 #define NOISE_POLY_TAP3 0 /* * random byte generator, taken from ch32v003fun examples */ uint8_t rand8(void) { uint8_t bit; uint32_t new_data; for (bit = 0; bit < NOISE_BITS; bit++) { new_data = ((lfsr >> NOISE_POLY_TAP0) ^ (lfsr >> NOISE_POLY_TAP1) ^ (lfsr >> NOISE_POLY_TAP2) ^ (lfsr >> NOISE_POLY_TAP3)); lfsr = (lfsr << 1) | (new_data & 1); } return lfsr & NOISE_MASK; }