diff --git a/CMakeLists.txt b/CMakeLists.txt index 30d88d8..ab1dab2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -21,7 +21,8 @@ add_executable(${PROJECT_NAME} ${${PROJECT_NAME}_SOURCES}) target_include_directories(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_LIST_DIR}/include) -target_link_libraries(${PROJECT_NAME} PUBLIC pico_stdlib pio_ws2812) +target_link_libraries(${PROJECT_NAME} PUBLIC pico_stdlib pico_multicore + pio_ws2812) pico_enable_stdio_usb(${PROJECT_NAME} 1) pico_enable_stdio_uart(${PROJECT_NAME} 0) diff --git a/include/GlobalConfiguration.h b/include/GlobalConfiguration.h index a6fa157..7425697 100644 --- a/include/GlobalConfiguration.h +++ b/include/GlobalConfiguration.h @@ -2,6 +2,7 @@ #define _GLOBALCONFIGURATION_H_ #include "peripherals/Drum.h" +#include "peripherals/StatusLed.h" namespace Doncon::Config::Default { @@ -21,6 +22,18 @@ const Peripherals::Drum::Config drum_config = { 10, // Debounce delay in milliseconds }; +const Peripherals::StatusLed::Config led_config = { + {255, 0, 0}, // Don Left Color + {0, 0, 255}, // Ka Left Color + {255, 255, 0}, // Don Right Color + {0, 255, 255}, // Ka Right Color + + 11, // LED Enable Pin, + 12, // LED Pin + false, // Is RGBW + 255, // Brightness +}; + } // namespace Doncon::Config::Default #endif // _GLOBALCONFIGURATION_H_ \ No newline at end of file diff --git a/include/peripherals/StatusLed.h b/include/peripherals/StatusLed.h new file mode 100644 index 0000000..a5b67dd --- /dev/null +++ b/include/peripherals/StatusLed.h @@ -0,0 +1,45 @@ +#ifndef _PERIPHERALS_STATUSLED_H_ +#define _PERIPHERALS_STATUSLED_H_ + +#include "utils/InputState.h" + +#include + +namespace Doncon::Peripherals { + +class StatusLed { + public: + struct Config { + struct Color { + uint8_t r; + uint8_t g; + uint8_t b; + }; + + Color don_left_color; + Color ka_left_color; + Color don_right_color; + Color ka_right_color; + + uint8_t led_enable_pin; + uint8_t led_pin; + bool is_rgbw; + uint8_t brightness; + }; + + private: + Config m_config; + + Utils::InputState m_input_state; + + public: + StatusLed(const Config &config); + + void setInputState(const Utils::InputState input_state); + + void update(); +}; + +} // namespace Doncon::Peripherals + +#endif // _PERIPHERALS_STATUSLED_H_ \ No newline at end of file diff --git a/src/main.cpp b/src/main.cpp index 557a56e..e91269b 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,19 +1,45 @@ #include "peripherals/Drum.h" +#include "peripherals/StatusLed.h" #include "GlobalConfiguration.h" +#include "pico/multicore.h" #include "pico/stdlib.h" +#include "pico/util/queue.h" #include using namespace Doncon; +queue_t input_queue; + +void core1_task() { + multicore_lockout_victim_init(); + + Utils::InputState input_state; + Peripherals::StatusLed led(Config::Default::led_config); + + while (true) { + if (queue_try_remove(&input_queue, &input_state)) { + led.setInputState(input_state); + } + + led.update(); + + sleep_ms(1); + } +} + int main() { + queue_init(&input_queue, sizeof(Utils::InputState), 1); + Utils::InputState input_state; Peripherals::Drum drum(Config::Default::drum_config); stdio_init_all(); + multicore_launch_core1(core1_task); + while (true) { drum.updateInputState(input_state); @@ -29,6 +55,8 @@ int main() { if (input_state.drum.ka_right) { printf("KA RIGHT\n"); } + + queue_try_add(&input_queue, &input_state); } return 0; diff --git a/src/peripherals/StatusLed.cpp b/src/peripherals/StatusLed.cpp new file mode 100644 index 0000000..1c3da3a --- /dev/null +++ b/src/peripherals/StatusLed.cpp @@ -0,0 +1,62 @@ +#include "peripherals/StatusLed.h" + +#include "hardware/gpio.h" +#include "pio_ws2812/ws2812.h" + +namespace Doncon::Peripherals { + +StatusLed::StatusLed(const Config &config) : m_config(config) { + gpio_init(m_config.led_enable_pin); + gpio_set_dir(m_config.led_enable_pin, GPIO_OUT); + gpio_put(m_config.led_enable_pin, 1); + + ws2812_init(config.led_pin, m_config.is_rgbw); +} + +void StatusLed::setInputState(const Utils::InputState input_state) { m_input_state = input_state; } + +void StatusLed::update() { + static float brightness_factor = m_config.brightness / static_cast(UINT8_MAX); + + uint16_t mixed_red = 0; + uint16_t mixed_green = 0; + uint16_t mixed_blue = 0; + + uint8_t num_colors = 0; + + if (m_input_state.drum.don_left) { + mixed_red += m_config.don_left_color.r; + mixed_green += m_config.don_left_color.g; + mixed_blue += m_config.don_left_color.b; + num_colors++; + } + if (m_input_state.drum.ka_left) { + mixed_red += m_config.ka_left_color.r; + mixed_green += m_config.ka_left_color.g; + mixed_blue += m_config.ka_left_color.b; + num_colors++; + } + if (m_input_state.drum.don_right) { + mixed_red += m_config.don_right_color.r; + mixed_green += m_config.don_right_color.g; + mixed_blue += m_config.don_right_color.b; + num_colors++; + } + if (m_input_state.drum.ka_right) { + mixed_red += m_config.ka_right_color.r; + mixed_green += m_config.ka_right_color.g; + mixed_blue += m_config.ka_right_color.b; + num_colors++; + } + + if (num_colors > 0) { + ws2812_put_pixel(ws2812_rgb_to_gamma_corrected_u32pixel( + static_cast((mixed_red / num_colors) * brightness_factor), + static_cast((mixed_green / num_colors) * brightness_factor), + static_cast((mixed_blue / num_colors) * brightness_factor))); + } else { + ws2812_put_pixel(0); + } +} + +} // namespace Doncon::Peripherals \ No newline at end of file