Skip to content

Commit

Permalink
Merge pull request #41 from esp-cpp/feature/40-brightness-controls
Browse files Browse the repository at this point in the history
Feature/40 brightness controls
  • Loading branch information
finger563 authored Dec 12, 2023
2 parents 7fcd95b + db15940 commit 9753e80
Show file tree
Hide file tree
Showing 42 changed files with 17,487 additions and 914 deletions.
2 changes: 2 additions & 0 deletions components/box-emu-hal/include/spi_lcd.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ uint8_t* get_frame_buffer0();
uint8_t* get_frame_buffer1();
void lcd_write_frame(const uint16_t x, const uint16_t y, const uint16_t width, const uint16_t height, const uint8_t *data);
void lcd_init();
void set_display_brightness(float brightness);
float get_display_brightness();

#ifdef __cplusplus
}
Expand Down
13 changes: 13 additions & 0 deletions components/box-emu-hal/include/statistics.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#pragma once

#include <algorithm>
#include <atomic>

void update_frame_time(float frame_time);
void reset_frame_time();

float get_fps();
float get_frame_time();
float get_frame_time_max();
float get_frame_time_min();
float get_frame_time_avg();
40 changes: 28 additions & 12 deletions components/box-emu-hal/src/hal_i2c.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,17 +9,33 @@ using namespace box_hal;

void i2c_init() {
if (initialized) return;
internal_i2c = std::make_shared<espp::I2c>(espp::I2c::Config{
.port = internal_i2c_port,
.sda_io_num = internal_i2c_sda,
.scl_io_num = internal_i2c_scl,
.sda_pullup_en = GPIO_PULLUP_ENABLE,
.scl_pullup_en = GPIO_PULLUP_ENABLE});
external_i2c = std::make_shared<espp::I2c>(espp::I2c::Config{
.port = external_i2c_port,
.sda_io_num = external_i2c_sda,
.scl_io_num = external_i2c_scl,
.sda_pullup_en = GPIO_PULLUP_ENABLE,
.scl_pullup_en = GPIO_PULLUP_ENABLE});
// make the i2c on core 1 so that the i2c interrupts are handled on core 1
std::atomic<bool> i2c_initialized = false;
auto i2c_task = espp::Task::make_unique(espp::Task::Config{
.name = "i2c",
.callback = [&](auto &m, auto&cv) -> bool {
internal_i2c = std::make_shared<espp::I2c>(espp::I2c::Config{
.port = internal_i2c_port,
.sda_io_num = internal_i2c_sda,
.scl_io_num = internal_i2c_scl,
.sda_pullup_en = GPIO_PULLUP_ENABLE,
.scl_pullup_en = GPIO_PULLUP_ENABLE});
external_i2c = std::make_shared<espp::I2c>(espp::I2c::Config{
.port = external_i2c_port,
.sda_io_num = external_i2c_sda,
.scl_io_num = external_i2c_scl,
.sda_pullup_en = GPIO_PULLUP_ENABLE,
.scl_pullup_en = GPIO_PULLUP_ENABLE});
i2c_initialized = true;
return true; // stop the task
},
.stack_size_bytes = 2*1024,
.core_id = 1
});
i2c_task->start();
while (!i2c_initialized) {
std::this_thread::sleep_for(std::chrono::milliseconds(10));
}

initialized = true;
}
16 changes: 13 additions & 3 deletions components/box-emu-hal/src/i2s_audio.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -189,9 +189,19 @@ static void init_mute_button(void) {
// restarted without power loss)
set_muted(!gpio_get_level(mute_pin));

//install gpio isr service
gpio_install_isr_service(0);
gpio_isr_handler_add(mute_pin, gpio_isr_handler, (void*) mute_pin);
// create a task on core 1 for initializing the gpio interrupt so that the
// gpio ISR runs on core 1
auto gpio_task = espp::Task::make_unique(espp::Task::Config{
.name = "gpio",
.callback = [](auto &m, auto&cv) -> bool {
gpio_install_isr_service(0);
gpio_isr_handler_add(mute_pin, gpio_isr_handler, (void*) mute_pin);
return true; // stop the task
},
.stack_size_bytes = 2*1024,
.core_id = 1
});
gpio_task->start();

// register that we publish the mute button state
espp::EventManager::get().add_publisher(mute_button_topic, "i2s_audio");
Expand Down
30 changes: 22 additions & 8 deletions components/box-emu-hal/src/spi_lcd.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -77,12 +77,18 @@ extern "C" void lcd_write(const uint8_t *data, size_t length, uint32_t user_data
}
lcd_wait_lines();
esp_err_t ret;
memset(&trans[0], 0, sizeof(spi_transaction_t));
trans[0].length = length * 8;
trans[0].user = (void*)user_data;
trans[0].tx_buffer = data;
trans[0].flags = 0; // maybe look at the length of data (<=32 bits) and see
// if we should use SPI_TRANS_USE_TXDATA and copy the
// data into the tx_data field
// look at the length of the data and use tx_data if it is <= 32 bits
if (length <= 4) {
// copy the data pointer to trans[0].tx_data
memcpy(trans[0].tx_data, data, length);
trans[0].flags = SPI_TRANS_USE_TXDATA;
} else {
trans[0].tx_buffer = data;
trans[0].flags = 0;
}
ret = spi_device_queue_trans(spi, &trans[0], 10 / portTICK_PERIOD_MS);
if (ret != ESP_OK) {
fmt::print("Couldn't queue trans: {} '{}'\n", ret, esp_err_to_name(ret));
Expand Down Expand Up @@ -143,7 +149,7 @@ extern "C" void lcd_send_lines(int xs, int ys, int xe, int ye, const uint8_t *da
//transactions sent. That happens mostly using DMA, so the CPU doesn't have
//much to do here. We're not going to wait for the transaction to finish
//because we may as well spend the time calculating the next line. When that
//is done, we can call send_line_finish, which will wait for the transfers
//is done, we can call lcd_wait_lines, which will wait for the transfers
//to be done and check their status.
}

Expand Down Expand Up @@ -196,7 +202,7 @@ extern "C" void lcd_init() {
buscfg.sclk_io_num = lcd_sclk;
buscfg.quadwp_io_num = -1;
buscfg.quadhd_io_num = -1;
buscfg.max_transfer_sz = pixel_buffer_size * sizeof(lv_color_t) + 10;
buscfg.max_transfer_sz = frame_buffer_size * sizeof(lv_color_t) + 10;

memset(&devcfg, 0, sizeof(devcfg));
devcfg.mode = 0;
Expand All @@ -220,8 +226,6 @@ extern "C" void lcd_init() {
.lcd_send_lines = lcd_send_lines,
.reset_pin = lcd_reset,
.data_command_pin = lcd_dc,
.backlight_pin = backlight,
.backlight_on_value = backlight_value,
.reset_value = reset_value,
.invert_colors = invert_colors,
.mirror_x = mirror_x,
Expand All @@ -234,6 +238,8 @@ extern "C" void lcd_init() {
.height = display_height,
.pixel_buffer_size = pixel_buffer_size,
.flush_callback = DisplayDriver::flush,
.backlight_pin = backlight,
.backlight_on_value = backlight_value,
.update_period = 5ms,
.double_buffered = true,
.allocation_flags = MALLOC_CAP_8BIT | MALLOC_CAP_DMA,
Expand All @@ -245,3 +251,11 @@ extern "C" void lcd_init() {
frame_buffer1 = (uint8_t*)heap_caps_malloc(frame_buffer_size, MALLOC_CAP_8BIT | MALLOC_CAP_SPIRAM);
initialized = true;
}

extern "C" void set_display_brightness(float brightness) {
display->set_brightness(brightness);
}

extern "C" float get_display_brightness() {
return display->get_brightness();
}
51 changes: 51 additions & 0 deletions components/box-emu-hal/src/statistics.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
#include "statistics.hpp"

static uint32_t num_frames = 0;
static float frame_time = 0.0f;
static float frame_time_total = 0.0f;
static float frame_time_max = 0.0f;
static float frame_time_min = 0.0f;
static float frame_time_avg = 0.0f;

void update_frame_time(float frame_time)
{
num_frames++;
::frame_time = frame_time;
frame_time_total = frame_time_total + frame_time;
frame_time_max = std::max(frame_time_max, frame_time);
frame_time_min = std::min(frame_time_min, frame_time);
frame_time_avg = frame_time_total / num_frames;
}

void reset_frame_time()
{
num_frames = 0;
frame_time = 0.0f;
frame_time_total = 0.0f;
frame_time_max = 0.0f;
frame_time_min = 100000.0f; // some large number
frame_time_avg = 0.0f;
}

float get_fps() {
if (frame_time_total == 0.0f) {
return 0.0f;
}
return num_frames / frame_time_total;
}

float get_frame_time() {
return frame_time;
}

float get_frame_time_max() {
return frame_time_max;
}

float get_frame_time_min() {
return frame_time_min;
}

float get_frame_time_avg() {
return frame_time_avg;
}
2 changes: 1 addition & 1 deletion components/espp
Submodule espp updated 95 files
+1 −1 .github/workflows/build.yml
+44 −4 components/display/include/display.hpp
+3 −1 components/display_drivers/CMakeLists.txt
+3 −4 components/display_drivers/example/main/display_drivers_example.cpp
+2 −10 components/display_drivers/include/display_drivers.hpp
+1 −4 components/display_drivers/include/ili9341.hpp
+3 −4 components/display_drivers/include/st7789.hpp
+0 −1 components/display_drivers/src/ili9341.cpp
+0 −1 components/display_drivers/src/st7789.cpp
+8 −8 components/led/include/led.hpp
+2 −2 docs/adc/adc_types.html
+2 −2 docs/adc/ads1x15.html
+2 −2 docs/adc/ads7138.html
+2 −2 docs/adc/continuous_adc.html
+1 −1 docs/adc/index.html
+2 −2 docs/adc/oneshot_adc.html
+2 −2 docs/adc/tla2528.html
+2 −2 docs/bldc/bldc_driver.html
+4 −4 docs/bldc/bldc_motor.html
+1 −1 docs/bldc/index.html
+2 −2 docs/button.html
+3 −3 docs/cli.html
+2 −2 docs/color.html
+2 −2 docs/controller.html
+3 −3 docs/csv.html
+48 −2 docs/display/display.html
+9 −11 docs/display/display_drivers.html
+1 −1 docs/display/index.html
+2 −2 docs/encoder/abi_encoder.html
+2 −2 docs/encoder/as5600.html
+2 −2 docs/encoder/encoder_types.html
+1 −1 docs/encoder/index.html
+2 −2 docs/encoder/mt6701.html
+2 −2 docs/event_manager.html
+2 −2 docs/file_system.html
+2 −2 docs/filters/biquad.html
+2 −2 docs/filters/butterworth.html
+1 −1 docs/filters/index.html
+2 −2 docs/filters/lowpass.html
+2 −2 docs/filters/sos.html
+2 −2 docs/filters/transfer_function.html
+4 −4 docs/ftp/ftp_server.html
+1 −1 docs/ftp/index.html
+16 −4 docs/genindex.html
+4 −4 docs/haptics/bldc_haptics.html
+2 −2 docs/haptics/drv2605.html
+1 −1 docs/haptics/index.html
+2 −2 docs/i2c.html
+1 −1 docs/index.html
+2 −2 docs/input/encoder_input.html
+2 −2 docs/input/ft5x06.html
+2 −2 docs/input/gt911.html
+1 −1 docs/input/index.html
+2 −2 docs/input/keypad_input.html
+2 −2 docs/input/t_keyboard.html
+2 −2 docs/input/touchpad_input.html
+2 −2 docs/input/tt21100.html
+2 −2 docs/io_expander/aw9523.html
+1 −1 docs/io_expander/index.html
+2 −2 docs/io_expander/mcp23x17.html
+2 −2 docs/joystick.html
+6 −6 docs/led.html
+2 −2 docs/led_strip.html
+2 −2 docs/logger.html
+2 −2 docs/math/bezier.html
+2 −2 docs/math/fast_math.html
+2 −2 docs/math/gaussian.html
+1 −1 docs/math/index.html
+2 −2 docs/math/range_mapper.html
+2 −2 docs/math/vector2d.html
+2 −2 docs/monitor.html
+1 −1 docs/network/index.html
+2 −2 docs/network/socket.html
+2 −2 docs/network/tcp_socket.html
+2 −2 docs/network/udp_socket.html
+1 −1 docs/nfc/index.html
+2 −2 docs/nfc/ndef.html
+2 −2 docs/nfc/st25dv.html
+ docs/objects.inv
+2 −2 docs/pid.html
+3 −3 docs/qwiicnes.html
+3 −3 docs/rmt.html
+5 −5 docs/rtc/bm8563.html
+1 −1 docs/rtc/index.html
+9 −9 docs/rtsp.html
+1 −1 docs/searchindex.js
+3 −3 docs/serialization.html
+5 −5 docs/state_machine.html
+2 −2 docs/tabulate.html
+2 −2 docs/task.html
+2 −2 docs/thermistor.html
+2 −2 docs/timer.html
+1 −1 docs/wifi/index.html
+2 −2 docs/wifi/wifi_ap.html
+2 −2 docs/wifi/wifi_sta.html
9 changes: 3 additions & 6 deletions components/gbc/src/gameboy.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include <memory>

#include "fs_init.hpp"
#include "statistics.hpp"

#include "format.hpp"
#include "spi_lcd.h"
Expand Down Expand Up @@ -58,7 +59,6 @@ extern "C" void die(char *fmt, ...) {
static std::shared_ptr<espp::Task> gbc_task;
static std::shared_ptr<espp::Task> gbc_video_task;
static QueueHandle_t video_queue;
static float totalElapsedSeconds = 0;
static struct InputState state;

static std::atomic<bool> scaled = false;
Expand Down Expand Up @@ -182,10 +182,7 @@ bool run_to_vblank(std::mutex &m, std::condition_variable& cv) {
++frame;
auto end = std::chrono::high_resolution_clock::now();
auto elapsed = std::chrono::duration<float>(end-start).count();
totalElapsedSeconds += elapsed;
if ((frame % 60) == 0) {
fmt::print("gameboy: FPS {}\n", (float) frame / totalElapsedSeconds);
}
update_frame_time(elapsed);
// frame rate should be 60 FPS, so 1/60th second is what we want to sleep for
static constexpr auto delay = std::chrono::duration<float>(1.0f/60.0f);
std::this_thread::sleep_until(start + delay);
Expand Down Expand Up @@ -245,7 +242,6 @@ void init_gameboy(const std::string& rom_filename, uint8_t *romdata, size_t rom_

loader_init(romdata, rom_data_size);
emu_reset();
totalElapsedSeconds = 0;
frame = 0;
if (!initialized) {
gbc_task = std::make_shared<espp::Task>(espp::Task::Config{
Expand All @@ -265,6 +261,7 @@ void init_gameboy(const std::string& rom_filename, uint8_t *romdata, size_t rom_
video_queue = xQueueCreate(1, sizeof(uint16_t*));
}
initialized = true;
reset_frame_time();
}

void run_gameboy_rom() {
Expand Down
1 change: 1 addition & 0 deletions components/gui/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
squareline/autosave
2 changes: 1 addition & 1 deletion components/gui/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
idf_component_register(
SRC_DIRS "src" "generated"
SRC_DIRS "src" "generated" "generated/screens" "generated/components"
INCLUDE_DIRS "include"
PRIV_INCLUDE_DIRS "generated"
REQUIRES lvgl task display logger jpeg box-emu-hal)
7 changes: 7 additions & 0 deletions components/gui/generated/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
SET(SOURCES screens/ui_romscreen.c
screens/ui_settingsscreen.c
ui.c
components/ui_comp_hook.c
ui_helpers.c)

add_library(ui ${SOURCES})
5 changes: 5 additions & 0 deletions components/gui/generated/components/ui_comp_hook.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
// This file was generated by SquareLine Studio
// SquareLine Studio version: SquareLine Studio 1.3.3
// LVGL version: 8.3.3
// Project name: emu

5 changes: 5 additions & 0 deletions components/gui/generated/filelist.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
screens/ui_romscreen.c
screens/ui_settingsscreen.c
ui.c
components/ui_comp_hook.c
ui_helpers.c
74 changes: 74 additions & 0 deletions components/gui/generated/screens/ui_romscreen.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
// This file was generated by SquareLine Studio
// SquareLine Studio version: SquareLine Studio 1.3.3
// LVGL version: 8.3.3
// Project name: emu

#include "../ui.h"

void ui_romscreen_screen_init(void)
{
ui_romscreen = lv_obj_create(NULL);
lv_obj_clear_flag( ui_romscreen, LV_OBJ_FLAG_SCROLLABLE ); /// Flags

ui_header = lv_obj_create(ui_romscreen);
lv_obj_set_height( ui_header, 75);
lv_obj_set_width( ui_header, lv_pct(100));
lv_obj_set_align( ui_header, LV_ALIGN_TOP_MID );
lv_obj_clear_flag( ui_header, LV_OBJ_FLAG_SCROLLABLE ); /// Flags

ui_settingsbutton = lv_btn_create(ui_header);
lv_obj_set_width( ui_settingsbutton, 48);
lv_obj_set_height( ui_settingsbutton, 48);
lv_obj_set_align( ui_settingsbutton, LV_ALIGN_LEFT_MID );
lv_obj_add_flag( ui_settingsbutton, LV_OBJ_FLAG_SCROLL_ON_FOCUS ); /// Flags
lv_obj_clear_flag( ui_settingsbutton, LV_OBJ_FLAG_SCROLLABLE ); /// Flags

ui_Screen1_Label2 = lv_label_create(ui_settingsbutton);
lv_obj_set_width( ui_Screen1_Label2, LV_SIZE_CONTENT); /// 1
lv_obj_set_height( ui_Screen1_Label2, LV_SIZE_CONTENT); /// 1
lv_obj_set_align( ui_Screen1_Label2, LV_ALIGN_CENTER );
lv_label_set_text(ui_Screen1_Label2,LV_SYMBOL_SETTINGS);

ui_Screen1_Label1 = lv_label_create(ui_header);
lv_obj_set_width( ui_Screen1_Label1, LV_SIZE_CONTENT); /// 1
lv_obj_set_height( ui_Screen1_Label1, LV_SIZE_CONTENT); /// 1
lv_obj_set_align( ui_Screen1_Label1, LV_ALIGN_CENTER );
lv_label_set_text(ui_Screen1_Label1,"Select Rom");

ui_playbutton = lv_btn_create(ui_header);
lv_obj_set_width( ui_playbutton, 48);
lv_obj_set_height( ui_playbutton, 48);
lv_obj_set_align( ui_playbutton, LV_ALIGN_RIGHT_MID );
lv_obj_add_state( ui_playbutton, LV_STATE_CHECKED ); /// States
lv_obj_add_flag( ui_playbutton, LV_OBJ_FLAG_SCROLL_ON_FOCUS ); /// Flags
lv_obj_clear_flag( ui_playbutton, LV_OBJ_FLAG_SCROLLABLE ); /// Flags

ui_Screen1_Label3 = lv_label_create(ui_playbutton);
lv_obj_set_width( ui_Screen1_Label3, LV_SIZE_CONTENT); /// 1
lv_obj_set_height( ui_Screen1_Label3, LV_SIZE_CONTENT); /// 1
lv_obj_set_align( ui_Screen1_Label3, LV_ALIGN_CENTER );
lv_label_set_text(ui_Screen1_Label3,LV_SYMBOL_PLAY);

ui_rompanel = lv_obj_create(ui_romscreen);
lv_obj_set_width( ui_rompanel, 220);
lv_obj_set_height( ui_rompanel, 165);
lv_obj_set_align( ui_rompanel, LV_ALIGN_BOTTOM_LEFT );
lv_obj_add_flag( ui_rompanel, LV_OBJ_FLAG_SCROLL_ON_FOCUS | LV_OBJ_FLAG_SCROLL_ONE ); /// Flags
lv_obj_set_scroll_dir(ui_rompanel, LV_DIR_VER);

ui_boxartpanel = lv_obj_create(ui_romscreen);
lv_obj_set_width( ui_boxartpanel, 100);
lv_obj_set_height( ui_boxartpanel, 165);
lv_obj_set_align( ui_boxartpanel, LV_ALIGN_BOTTOM_RIGHT );
lv_obj_clear_flag( ui_boxartpanel, LV_OBJ_FLAG_SCROLLABLE ); /// Flags

ui_boxart = lv_img_create(ui_boxartpanel);
lv_obj_set_width( ui_boxart, 100);
lv_obj_set_height( ui_boxart, LV_SIZE_CONTENT); /// 1
lv_obj_set_align( ui_boxart, LV_ALIGN_CENTER );
lv_obj_add_flag( ui_boxart, LV_OBJ_FLAG_ADV_HITTEST ); /// Flags
lv_obj_clear_flag( ui_boxart, LV_OBJ_FLAG_SCROLLABLE ); /// Flags

lv_obj_add_event_cb(ui_settingsbutton, ui_event_settingsbutton, LV_EVENT_ALL, NULL);

}
Loading

0 comments on commit 9753e80

Please sign in to comment.