1
0
mirror of https://github.com/tdaede/td-io.git synced 2025-02-23 13:50:08 +01:00
td-io/firmware/ws2812.c
Thomas Daede 57ccfa7505 ws2812
2021-05-09 00:39:40 -07:00

156 lines
3.6 KiB
C

/**
* Copyright (c) 2020 Raspberry Pi (Trading) Ltd.
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include <stdio.h>
#include <stdlib.h>
#include "pico/stdlib.h"
#include "hardware/pio.h"
#include "hardware/clocks.h"
#include "ws2812.pio.h"
static inline void put_pixel(uint32_t pixel_grb) {
pio_sm_put_blocking(pio0, 0, pixel_grb << 8u);
}
static inline uint32_t urgb_u32(uint8_t r, uint8_t g, uint8_t b) {
return
((uint32_t) (r) << 8) |
((uint32_t) (g) << 16) |
(uint32_t) (b);
}
void pattern_snakes(uint len, uint t) {
for (uint i = 0; i < len; ++i) {
uint x = (i + (t >> 1)) % 64;
if (x < 10)
put_pixel(urgb_u32(0xff, 0, 0));
else if (x >= 15 && x < 25)
put_pixel(urgb_u32(0, 0xff, 0));
else if (x >= 30 && x < 40)
put_pixel(urgb_u32(0, 0, 0xff));
else
put_pixel(0);
}
}
void pattern_snakes_green(uint len, uint t) {
for (uint i = 0; i < len; ++i) {
uint x = (i + (t >> 1)) % 64;
if (x < 10)
put_pixel(urgb_u32(0, 0x10, 0));
else if (x >= 15 && x < 25)
put_pixel(urgb_u32(0, 0x30, 0));
else if (x >= 30 && x < 40)
put_pixel(urgb_u32(0, 0xff, 0));
else
put_pixel(0);
}
}
void pattern_snakes_green_fast(uint len, uint t) {
for (uint i = 0; i < len; ++i) {
uint x = (i + (t >> 0)) % 64;
if (x < 10)
put_pixel(urgb_u32(0, 0x10, 0));
else if (x >= 15 && x < 25)
put_pixel(urgb_u32(0, 0x30, 0));
else if (x >= 30 && x < 40)
put_pixel(urgb_u32(0, 0xff, 0));
else
put_pixel(0);
}
}
void pattern_random(uint len, uint t) {
if (t % 8)
return;
for (int i = 0; i < len; ++i)
put_pixel(rand());
}
void pattern_sparkle(uint len, uint t) {
if (t % 4)
return;
for (int i = 0; i < len; ++i)
put_pixel(rand() % 8 ? 0 : 0xffffffff);
}
void pattern_sparkle_green(uint len, uint t) {
if (t % 8)
return;
for (int i = 0; i < len; ++i) {
uint8_t a = rand() % 16 ? 0 : 0xff;
put_pixel(urgb_u32(0, 0xa, 0));
}
}
void pattern_sparkle_yellow(uint len, uint t) {
if (t % 4)
return;
for (int i = 0; i < len; ++i) {
uint8_t a = rand() % 8 ? 0 : 0xff;
put_pixel(urgb_u32(a, a, 0));
}
}
void pattern_greys(uint len, uint t) {
int max = 100; // let's not draw too much current!
t %= max;
for (int i = 0; i < len; ++i) {
put_pixel(t * 0x10101);
if (++t >= max) t = 0;
}
}
typedef void (*pattern)(uint len, uint t);
const struct {
pattern pat;
const char *name;
} pattern_table[] = {
{pattern_snakes, "Snakes!"},
{pattern_random, "Random data"},
{pattern_sparkle, "Sparkles"},
{pattern_greys, "Greys"},
};
const int PIN_TX = 27;
void init_ws2812(int pin) {
// todo get free sm
PIO pio = pio0;
int sm = 0;
uint offset = pio_add_program(pio, &ws2812_program);
ws2812_program_init(pio, sm, offset, pin, 800000, false);
}
int run_ws2812() {
//set_sys_clock_48();
stdio_init_all();
puts("WS2812 Smoke Test");
// todo get free sm
PIO pio = pio0;
int sm = 0;
uint offset = pio_add_program(pio, &ws2812_program);
ws2812_program_init(pio, sm, offset, PIN_TX, 80000, false);
int t = 0;
while (1) {
int pat = rand() % count_of(pattern_table);
int dir = (rand() >> 30) & 1 ? 1 : -1;
puts(pattern_table[pat].name);
puts(dir == 1 ? "(forward)" : "(backward)");
for (int i = 0; i < 1000; ++i) {
pattern_table[pat].pat(150, t);
sleep_ms(10);
t += dir;
}
}
}