Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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