1
0
mirror of https://github.com/whowechina/aic_pico.git synced 2025-01-19 03:17:24 +01:00

LED and stuff working

This commit is contained in:
whowechina 2023-11-04 20:30:53 +08:00
parent c1c8848b0d
commit 2d42b221da
8 changed files with 222 additions and 3 deletions

View File

@ -4,7 +4,7 @@ set(LWIP_ROOT ${PICO_SDK_PATH}/lib/lwip)
function(make_firmware board board_def)
pico_sdk_init()
add_executable(${board}
main.c save.c config.c commands.c
main.c save.c config.c commands.c rgb.c
aime.c cli.c pn532.c
usb_descriptors.c)
target_compile_definitions(${board} PUBLIC ${board_def})

View File

@ -10,7 +10,7 @@
#define I2C_SDA 20
#define I2C_FREQ 733*1000
#define RGB_PIN 2
#define RGB_PIN 22
#define RGB_ORDER GRB // or RGB
#else

View File

@ -30,6 +30,12 @@ void fps_count(int core)
counter[core] = 0;
}
static void handle_display()
{
printf("[Config]\n");
printf(" LED level: %d\n", aic_cfg->led.level);
}
static void handle_save()
{
save_request(true);
@ -84,9 +90,30 @@ static void handle_nfc()
printf("\n");
}
static void handle_level(int argc, char *argv[])
{
const char *usage = "Usage: level <0..255>\n";
if (argc != 1) {
printf(usage);
return;
}
int level = cli_extract_non_neg_int(argv[0], 0);
if ((level < 0) || (level > 255)) {
printf(usage);
return;
}
aic_cfg->led.level = level;
config_changed();
handle_display();
}
void commands_init()
{
cli_register("display", handle_display, "Display all settings.");
cli_register("save", handle_save, "Save config to flash.");
cli_register("factory", handle_factory_reset, "Reset everything to default.");
cli_register("nfc", handle_nfc, "NFC debug.");
cli_register("level", handle_level, "Set LED level.");
}

View File

@ -11,7 +11,9 @@
aic_cfg_t *aic_cfg;
static aic_cfg_t default_cfg = { 0 };
static aic_cfg_t default_cfg = {
.led = { .level = 127, }
};
aic_runtime_t *aic_runtime;

View File

@ -10,6 +10,9 @@
#include <stdbool.h>
typedef struct __attribute__((packed)) {
struct {
uint8_t level;
} led;
uint32_t reserved;
} aic_cfg_t;

View File

@ -27,6 +27,7 @@
#include "config.h"
#include "cli.h"
#include "commands.h"
#include "rgb.h"
#include "pn532.h"
#include "aime.h"
@ -44,6 +45,11 @@ static void core1_loop()
if (mutex_try_enter(&core1_io_lock, NULL)) {
mutex_exit(&core1_io_lock);
}
rgb_set_color(0, 0x800000);
rgb_set_color(1, 0x008000);
rgb_set_color(2, 0x000080);
rgb_set_color(3, 0x808080);
rgb_update();
cli_fps_count(1);
sleep_ms(1);
}
@ -61,6 +67,7 @@ static void core0_loop()
cli_fps_count(0);
report_usb_hid();
sleep_ms(1);
}
}
@ -71,6 +78,7 @@ void init()
board_init();
tusb_init();
stdio_init_all();
rgb_init();
config_init();
mutex_init(&core1_io_lock);

155
firmware/src/rgb.c Normal file
View File

@ -0,0 +1,155 @@
/*
* RGB LED (WS2812) Strip control
* WHowe <github.com/whowechina>
*
*/
#include "rgb.h"
#include <stdio.h>
#include <string.h>
#include <stdint.h>
#include <stdbool.h>
#include "bsp/board.h"
#include "hardware/pio.h"
#include "hardware/timer.h"
#include "ws2812.pio.h"
#include "board_defs.h"
#include "config.h"
#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
static uint32_t rgb_buf[16];
#define _MAP_LED(x) _MAKE_MAPPER(x)
#define _MAKE_MAPPER(x) MAP_LED_##x
#define MAP_LED_RGB { c1 = r; c2 = g; c3 = b; }
#define MAP_LED_GRB { c1 = g; c2 = r; c3 = b; }
#define REMAP_BUTTON_RGB _MAP_LED(BUTTON_RGB_ORDER)
#define REMAP_TT_RGB _MAP_LED(TT_RGB_ORDER)
static inline uint32_t _rgb32(uint32_t c1, uint32_t c2, uint32_t c3, bool gamma_fix)
{
if (gamma_fix) {
c1 = ((c1 + 1) * (c1 + 1) - 1) >> 8;
c2 = ((c2 + 1) * (c2 + 1) - 1) >> 8;
c3 = ((c3 + 1) * (c3 + 1) - 1) >> 8;
}
return (c1 << 16) | (c2 << 8) | (c3 << 0);
}
uint32_t rgb32(uint32_t r, uint32_t g, uint32_t b, bool gamma_fix)
{
#if BUTTON_RGB_ORDER == GRB
return _rgb32(g, r, b, gamma_fix);
#else
return _rgb32(r, g, b, gamma_fix);
#endif
}
uint32_t rgb32_from_hsv(uint8_t h, uint8_t s, uint8_t v)
{
uint32_t region, remainder, p, q, t;
if (s == 0) {
return v << 16 | v << 8 | v;
}
region = h / 43;
remainder = (h % 43) * 6;
p = (v * (255 - s)) >> 8;
q = (v * (255 - ((s * remainder) >> 8))) >> 8;
t = (v * (255 - ((s * (255 - remainder)) >> 8))) >> 8;
switch (region) {
case 0:
return v << 16 | t << 8 | p;
case 1:
return q << 16 | v << 8 | p;
case 2:
return p << 16 | v << 8 | t;
case 3:
return p << 16 | q << 8 | v;
case 4:
return t << 16 | p << 8 | v;
default:
return v << 16 | p << 8 | q;
}
}
static void drive_led()
{
static uint64_t last = 0;
uint64_t now = time_us_64();
if (now - last < 4000) { // no faster than 250Hz
return;
}
last = now;
for (int i = 0; i < ARRAY_SIZE(rgb_buf); i++) {
pio_sm_put_blocking(pio0, 0, rgb_buf[i] << 8u);
}
}
static inline uint32_t apply_level(uint32_t color)
{
unsigned r = (color >> 16) & 0xff;
unsigned g = (color >> 8) & 0xff;
unsigned b = color & 0xff;
r = r * aic_cfg->led.level / 255;
g = g * aic_cfg->led.level / 255;
b = b * aic_cfg->led.level / 255;
return r << 16 | g << 8 | b;
}
void rgb_set_color(unsigned index, uint32_t color)
{
if (index >= ARRAY_SIZE(rgb_buf)) {
return;
}
rgb_buf[index] = apply_level(color);
}
void rgb_set_color_all(uint32_t color)
{
for (int i = 0; i < ARRAY_SIZE(rgb_buf); i++) {
rgb_buf[i] = apply_level(color);
}
}
void rgb_set_brg(unsigned index, const uint8_t *brg_array, size_t num)
{
if (index >= ARRAY_SIZE(rgb_buf)) {
return;
}
if (index + num > ARRAY_SIZE(rgb_buf)) {
num = ARRAY_SIZE(rgb_buf) - index;
}
for (int i = 0; i < num; i++) {
uint8_t b = brg_array[i * 3 + 0];
uint8_t r = brg_array[i * 3 + 1];
uint8_t g = brg_array[i * 3 + 2];
rgb_buf[index + i] = apply_level(rgb32(r, g, b, false));
}
}
void rgb_init()
{
uint pio0_offset = pio_add_program(pio0, &ws2812_program);
gpio_set_drive_strength(RGB_PIN, GPIO_DRIVE_STRENGTH_2MA);
ws2812_program_init(pio0, 0, pio0_offset, RGB_PIN, 800000, false);
}
void rgb_update()
{
drive_led();
}

24
firmware/src/rgb.h Normal file
View File

@ -0,0 +1,24 @@
/*
* RGB LED (WS2812) Strip control
* WHowe <github.com/whowechina>
*/
#ifndef RGB_H
#define RGB_H
#include <stdlib.h>
#include <stdint.h>
#include <stdbool.h>
#include "config.h"
void rgb_init();
void rgb_update();
uint32_t rgb32(uint32_t r, uint32_t g, uint32_t b, bool gamma_fix);
uint32_t rgb32_from_hsv(uint8_t h, uint8_t s, uint8_t v);
void rgb_set_color(unsigned index, uint32_t color);
void rgb_set_color_all(uint32_t color);
#endif