Skip to content

Commit

Permalink
Backlight and wave scheme works in simulator
Browse files Browse the repository at this point in the history
  • Loading branch information
malcx95 committed Jan 19, 2024
1 parent abacfbe commit c3dcba4
Show file tree
Hide file tree
Showing 15 changed files with 176 additions and 28 deletions.
11 changes: 9 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ TEST_CXX_FLAGS = -c -g -Wall -Wextra -std=gnu++23
CXX = $(TEENSY_COMPILE)/arm-none-eabi-g++
CC = $(TEENSY_COMPILE)/arm-none-eabi-gcc
AR = $(TEENSY_COMPILE)/arm-none-eabi-gcc-ar
SIZE = $(TEENSY_COMPILE)/arm-none-eabi-size
PRECOMPILE_HELPER = $(TEENSY_TOOLS)/teensy-tools/1.58.0/precompile_helper
OBJCOPY = $(TEENSY_COMPILE)/arm-none-eabi-objcopy
POST_COMPILE = $(TEENSY_TOOLS)/teensy-tools/1.58.0/teensy_post_compile
Expand Down Expand Up @@ -65,8 +66,10 @@ OCTOWS2811_SOURCES = $(wildcard $(TEENSY_LIBS)/OctoWS2811/*.cpp)
CORE_CPP_SOURCES = $(wildcard $(TEENSY4_CORE)/*.cpp)
CORE_C_SOURCES = $(wildcard $(TEENSY4_CORE)/*.c)
LIB_SOURCES = $(FASTLED_SOURCES) $(SPI_SOURCES) $(OCTOWS2811_SOURCES)
NON_HARDWARE_SOURCES = $(wildcard core/*.cpp) $(wildcard core/**/*.cpp) $(wildcard common/*.cpp) $(wildcard common/**/*.cpp)
TEST_SOURCES = $(NON_HARDWARE_SOURCES) $(wildcard core/test/*.cpp) $(wildcard core/**/test/*.cpp) $(CATCH2_PATH)/extras/catch_amalgamated.cpp
NON_HARDWARE_SOURCES_NON_FILTERED = $(wildcard core/*.cpp) $(wildcard core/**/**/*.cpp) $(wildcard core/**/*.cpp) $(wildcard common/*.cpp) $(wildcard common/**/*.cpp) $(wildcard common/**/**/*.cpp)
TEST_CPP = $(wildcard core/test/*.cpp) $(wildcard core/**/test/*.cpp) $(CATCH2_PATH)/extras/catch_amalgamated.cpp
TEST_SOURCES = $(NON_HARDWARE_SOURCES) $(TEST_CPP)
NON_HARDWARE_SOURCES = $(filter-out $(TEST_CPP), $(NON_HARDWARE_SOURCES_NON_FILTERED))
SOURCES = $(wildcard *.cpp) $(NON_HARDWARE_SOURCES)

all: build/firmware.hex
Expand Down Expand Up @@ -106,6 +109,10 @@ TEST_TARGETS = $(patsubst %.cpp,build/test/%.o,$(TEST_SOURCES))

build/firmware.elf: $(TARGETS)
@$(CC) $(LINK_FLAGS) -o $@ $(TARGETS) build/core/core.a -Lbuild/ -larm_cortexM7lfsp_math -lm -lstdc++
@echo
@echo "Firmware size:"
@$(SIZE) -B -d $@
@echo

build/firmware.hex: build/firmware.elf
$(OBJCOPY) -O ihex -R .eeprom $< $@
Expand Down
2 changes: 1 addition & 1 deletion core/backlight/backlight.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ namespace core::backlight
class Backlight
{
public:
Backlight(Device& device, schemes::Scheme* schemes[], int num_schemes);
Backlight(Device& device, schemes::Scheme** schemes, int num_schemes);
void update(const core::keyboard::KeyboardScanResult& scan_result);
void increment_scheme();

Expand Down
40 changes: 40 additions & 0 deletions core/backlight/color.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#pragma once

#include <stdint.h>
#include <cmath>

namespace core::backlight
{
Expand Down Expand Up @@ -41,6 +42,45 @@ struct Color
static_cast<float>(g + other.g),
static_cast<float>(b + other.b)};
}

/**
* Creates a color from HSV values, where the hue, saturation and value
* is in the range [0, 1].
*/
static Color from_hsv(float hue, float saturation, float value)
{
// This function was AI-generated
const float h = hue * 6.0f;
const float f = h - floor(h);
const float p = value * (1.0f - saturation);
const float q = value * (1.0f - saturation * f);
const float t = value * (1.0f - saturation * (1.0f - f));

if (h < 1.0f)
{
return Color{value, t, p};
}
else if (h < 2.0f)
{
return Color{q, value, p};
}
else if (h < 3.0f)
{
return Color{p, value, t};
}
else if (h < 4.0f)
{
return Color{p, q, value};
}
else if (h < 5.0f)
{
return Color{t, p, value};
}
else
{
return Color{value, p, q};
}
}
};

}
3 changes: 2 additions & 1 deletion core/backlight/schemes/scheme.h
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#pragma once

#include "../../../device.h"
#include "../../keyboard/keyscan.h"
#include "../ledstate.h"
Expand All @@ -12,7 +13,7 @@ namespace core::backlight::schemes
class Scheme
{
public:
Scheme(Device& device) : device(device) { }
Scheme(Device& device) : device{device} { }

virtual void reset() = 0;

Expand Down
40 changes: 40 additions & 0 deletions core/backlight/schemes/wave.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
#include "wave.h"
#include <cmath>


namespace core::backlight::schemes
{

void Wave::reset()
{
it = 0;
}


void Wave::update(const core::keyboard::KeyboardScanResult& scan_result,
core::backlight::LEDState led_states[common::constants::TOTAL_NUM_LEDS])
{
const float fade_x = sin(it * SPEED * X_SPEED);
const float fade_y = sin(it * SPEED * Y_SPEED);
for (int i = 0; i < common::constants::TOTAL_NUM_LEDS; ++i)
{
auto& state = led_states[i];
const auto x = state.description->x;
const auto y = state.description->y;

const float hue = (cos((it * SPEED + x * fade_x + y * fade_y) * MAX_PHASE_DIFFERENCE) + 1.0f) / 2.0f;
const Color color = Color::from_hsv(hue, 1.0f, 1.0f);
state.color = color;
}

for (int i = 0; i < scan_result.num_pressed; ++i)
{
const common::LEDDescription pressed = scan_result.just_pressed[i]->get_associated_led();
led_states[pressed.strip_index].start_fade(
device, Color{1.0f, 1.0f, 1.0f}, PRESS_FADE_TIME);
}

it++;
}

}
31 changes: 31 additions & 0 deletions core/backlight/schemes/wave.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
#pragma once

#include "../../../device.h"
#include "../../keyboard/keyscan.h"
#include "../ledstate.h"
#include "scheme.h"

namespace core::backlight::schemes
{

const float SPEED = 0.00005f;
const float X_SPEED = 0.8f;
const float Y_SPEED = 1.1f;
const float MAX_PHASE_DIFFERENCE = 0.3f;
const uint32_t PRESS_FADE_TIME = 2000;


class Wave : public Scheme
{
public:
Wave(Device& device) : Scheme{device} { }

void reset() override;

void update(const core::keyboard::KeyboardScanResult& scan_result,
core::backlight::LEDState led_states[common::constants::TOTAL_NUM_LEDS]) override;
private:
uint64_t it = 0;
};

}
8 changes: 8 additions & 0 deletions core/backlight/test/test_backlight.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ TEST_CASE("Test backlight", "[Backlight]")
backlight.update(core::keyboard::KeyboardScanResult{});
for (uint8_t i = 0; i < common::constants::TOTAL_NUM_LEDS; ++i)
{
REQUIRE(device.leds_updated);
auto c = static_cast<uint8_t>(255.0f * static_cast<float>(i) / static_cast<float>(common::constants::TOTAL_NUM_LEDS));
auto not_c = static_cast<uint8_t>(255.0f * (1.0f - static_cast<float>(i) / static_cast<float>(common::constants::TOTAL_NUM_LEDS)));
REQUIRE(device.led_colors_r[i] == c);
Expand All @@ -73,24 +74,28 @@ TEST_CASE("Test backlight", "[Backlight]")

device.current_millis = 0;
backlight.update(core::keyboard::KeyboardScanResult{});
REQUIRE(device.leds_updated);
CHECK(device.led_colors_r[0] == 255);
CHECK(device.led_colors_g[0] == 127);
CHECK(device.led_colors_b[0] == 255);

device.current_millis = 99;
backlight.update(core::keyboard::KeyboardScanResult{});
REQUIRE(device.leds_updated);
CHECK(device.led_colors_r[0] == 255);
CHECK(device.led_colors_g[0] == 127);
CHECK(device.led_colors_b[0] == 255);

device.current_millis = 150;
backlight.update(core::keyboard::KeyboardScanResult{});
REQUIRE(device.leds_updated);
CHECK(device.led_colors_r[0] == 0);
CHECK(device.led_colors_g[0] == 0);
CHECK(device.led_colors_b[0] == 0);

device.current_millis = 251;
backlight.update(core::keyboard::KeyboardScanResult{});
REQUIRE(device.leds_updated);
CHECK(device.led_colors_r[0] == 255);
CHECK(device.led_colors_g[0] == 127);
CHECK(device.led_colors_b[0] == 255);
Expand All @@ -106,18 +111,21 @@ TEST_CASE("Test backlight", "[Backlight]")

device.current_millis = 0;
backlight.update(core::keyboard::KeyboardScanResult{});
REQUIRE(device.leds_updated);
CHECK(device.led_colors_r[0] == 0);
CHECK(device.led_colors_g[0] == 0);
CHECK(device.led_colors_b[0] == 255);

device.current_millis = 50;
backlight.update(core::keyboard::KeyboardScanResult{});
REQUIRE(device.leds_updated);
CHECK(device.led_colors_r[0] == 127);
CHECK(device.led_colors_g[0] == 0);
CHECK(device.led_colors_b[0] == 127);

device.current_millis = 100;
backlight.update(core::keyboard::KeyboardScanResult{});
REQUIRE(device.leds_updated);
CHECK(device.led_colors_r[0] == 255);
CHECK(device.led_colors_g[0] == 0);
CHECK(device.led_colors_b[0] == 0);
Expand Down
17 changes: 9 additions & 8 deletions core/firmware.cpp
Original file line number Diff line number Diff line change
@@ -1,13 +1,20 @@
#include "firmware.h"
#include "../common/constants.h"
#include "backlight/schemes/wave.h"
#include "keyboard/communication.h"

namespace core
{

const int CYCLE_TIME_MICROS = 16000;

Firmware::Firmware(Device& device) : device{device}, key_scanner{device}
Firmware::Firmware(Device& device) :
device{device},
key_scanner{device},

wave{device},

backlight{device, schemes, 1}
{
// TODO load from SD card when possible
keymap.load_default();
Expand All @@ -20,13 +27,7 @@ void Firmware::update()
key_scanner.scan(result);
keymap.translate_keyboard_scan_result(result, key_queue);
keyboard::communication::send_key_report(key_queue, device);

// TODO remove this
for (int i = 0; i < common::constants::TOTAL_NUM_LEDS; ++i)
{
device.set_led(i, 255, 0, 0);
}
device.update_leds();
backlight.update(result);

const uint32_t elapsed = device.get_timer_micros();
if (elapsed < CYCLE_TIME_MICROS)
Expand Down
13 changes: 13 additions & 0 deletions core/firmware.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
#pragma once

#include "../device.h"
#include "backlight/backlight.h"
#include "backlight/schemes/wave.h"
#include "keyboard/keymap.h"
#include "keyboard/keyscan.h"

Expand All @@ -22,6 +24,17 @@ class Firmware
keyboard::KeyScanner key_scanner;
keyboard::KeyQueue key_queue;
keyboard::KeyMap keymap;

// Backlight schemes
backlight::schemes::Wave wave;

static constexpr int NUM_SCHEMES = 1;
backlight::schemes::Scheme* schemes[NUM_SCHEMES] =
{
&wave
};

backlight::Backlight backlight;
};

}
1 change: 1 addition & 0 deletions core/testutil/testdevice.h
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ class TestTimerLEDDevice : public TestDeviceBase
led_colors_r[index] = r;
led_colors_g[index] = g;
led_colors_b[index] = b;
leds_updated = false;
}
};

Expand Down
6 changes: 4 additions & 2 deletions simulator/Makefile
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
KEYBOARD_LAYOUT_JSON = ../submodules/scripts/resources/keyboard-layout.json
EXTRA_LEDS_JSON = submodules/scripts/resources/extra_leds.json
EXTRA_LEDS_JSON = ../submodules/scripts/resources/extra_leds.json
PYTHON = python3
GENERATE_LAYOUT = ../submodules/scripts/generate_layout.py

CXX = g++
CXX_FLAGS = -c -g -Wall -Wextra -std=gnu++23
SOURCES = $(wildcard *.cpp) $(wildcard **/*.cpp) $(wildcard ../core/*.cpp) $(wildcard ../core/**/*.cpp) $(wildcard ../common/*.cpp) $(wildcard ../common/**/*.cpp)
TEST_CXX = $(wildcard ../core/test/*.cpp) $(wildcard ../core/**/test/*.cpp)
SOURCES_NON_FILTERED = $(wildcard *.cpp) $(wildcard **/*.cpp) $(wildcard ../core/*.cpp) $(wildcard ../core/**/*.cpp) $(wildcard ../core/**/**/*.cpp) $(wildcard ../common/*.cpp) $(wildcard ../common/**/*.cpp)
SOURCES = $(filter-out $(TEST_CXX), $(SOURCES_NON_FILTERED))
HEADERS = $(wildcard *.h) $(wildcard **/*.h) $(wildcard ../core/*.h) $(wildcard ../core/**/*.h) $(wildcard ../generated/*.h) $(wildcard ../common/*.h) $(wildcard ../common/**/*.h)

TARGETS = $(patsubst %.cpp,obj/%.o,$(SOURCES))
Expand Down
18 changes: 8 additions & 10 deletions simulator/keyboard_state.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -109,15 +109,6 @@ void KeyboardState::draw(sf::RenderWindow& window)
rectangle.setFillColor(sf::Color{100, 100, 100, 255});
rectangle.setOutlineThickness(5);

const sf::Color colors[6] = {
sf::Color::Red,
sf::Color::Green,
sf::Color::Blue,
sf::Color::Yellow,
sf::Color::Magenta,
sf::Color::Cyan
};

for (const auto& key : keys)
{
if (key.pressed)
Expand All @@ -133,7 +124,13 @@ void KeyboardState::draw(sf::RenderWindow& window)
rectangle.setFillColor(sf::Color{100, 100, 100, 255});
}

rectangle.setOutlineColor(colors[key.description->row]);
const auto led_description = key.description->get_associated_led();
const auto led_index = led_description.strip_index;
const auto r = device.led_colors_r[led_index];
const auto g = device.led_colors_g[led_index];
const auto b = device.led_colors_b[led_index];

rectangle.setOutlineColor(sf::Color{r, g, b, 255});
const auto width = key.description->width * KEY_SIZE;
const auto height = key.description->height * KEY_SIZE;
rectangle.setSize(sf::Vector2f{width, height});
Expand All @@ -145,4 +142,5 @@ void KeyboardState::draw(sf::RenderWindow& window)
}
}


}
9 changes: 5 additions & 4 deletions simulator/simulator_device.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -131,13 +131,14 @@ uint32_t SimulatorDevice::get_timer_micros()

void SimulatorDevice::set_led(uint16_t index, uint8_t r, uint8_t g, uint8_t b)
{
// TODO implement
std::lock_guard<std::mutex> lock(mutex);
led_colors_r[index] = r;
led_colors_g[index] = g;
led_colors_b[index] = b;
}

void SimulatorDevice::update_leds()
{
// TODO implement
}
{ }

uint32_t SimulatorDevice::millis() const
{
Expand Down
4 changes: 4 additions & 0 deletions simulator/simulator_device.h
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,10 @@ class SimulatorDevice : public Device
uint8_t current_modifier;
uint8_t current_media;

uint8_t led_colors_r[common::constants::TOTAL_NUM_LEDS];
uint8_t led_colors_g[common::constants::TOTAL_NUM_LEDS];
uint8_t led_colors_b[common::constants::TOTAL_NUM_LEDS];

private:
uint32_t start_time;

Expand Down
Loading

0 comments on commit c3dcba4

Please sign in to comment.