Skip to content

Commit

Permalink
Merge pull request #785 from Daft-Freak/blit-size
Browse files Browse the repository at this point in the history
Minor firmware blit flashing improvements
  • Loading branch information
Gadgetoid authored Jan 13, 2023
2 parents 0de5ee4 + 02454ff commit 75e837a
Show file tree
Hide file tree
Showing 4 changed files with 39 additions and 36 deletions.
65 changes: 33 additions & 32 deletions firmware/firmware.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,8 @@ static bool parse_file_metadata(FIL &fh, GameInfo &info) {
if(header.magic != blit_game_magic)
return false;

info.size = header.end - qspi_flash_address;

bool result = false;

// get metadata
Expand Down Expand Up @@ -292,8 +294,7 @@ static uint32_t get_flash_offset_for_file(uint32_t file_size) {
return std::get<0>(space) * qspi_flash_sector_size;
}

// TODO: handle flash full
return 0;
return 0xFFFFFFFF;
}

static bool flash_buffer(uint32_t offset, uint8_t *buffer, size_t size) {
Expand Down Expand Up @@ -327,24 +328,17 @@ static void apply_relocs(uint32_t file_offset, uint32_t flash_base_offset, uint8
}

// Flash a file from the SDCard to external flash
static uint32_t flash_from_sd_to_qspi_flash(FIL &file, uint32_t flash_offset) {
static uint32_t flash_from_sd_to_qspi_flash(FIL &file, uint32_t file_size, uint32_t flash_offset) {
FRESULT res;

// get file length
FSIZE_t bytes_total = f_size(&file);
UINT bytes_read = 0;
FSIZE_t bytes_flashed = 0;

// check for prepended relocation info
char buf[4];
f_lseek(&file, 0);
f_read(&file, buf, 4, &bytes_read);
// get prepended relocation info
f_lseek(&file, 4);
std::vector<uint32_t> relocation_offsets;
size_t cur_reloc = 0;

if(memcmp(buf, "RELO", 4) != 0)
return 0xFFFFFFFF;

uint32_t num_relocs;
f_read(&file, (void *)&num_relocs, 4, &bytes_read);
relocation_offsets.reserve(num_relocs);
Expand All @@ -356,22 +350,24 @@ static uint32_t flash_from_sd_to_qspi_flash(FIL &file, uint32_t flash_offset) {
relocation_offsets.push_back(reloc_offset - qspi_flash_address);
}

bytes_total -= num_relocs * 4 + 8; // size of relocation data
if(flash_offset == 0xFFFFFFFF)
flash_offset = get_flash_offset_for_file(file_size);

// failed to find offset
if(flash_offset == 0xFFFFFFFF)
flash_offset = get_flash_offset_for_file(bytes_total);
return flash_offset;

// erase the sectors needed to write the image
erase_qspi_flash(flash_offset, bytes_total);
erase_qspi_flash(flash_offset, file_size);

progress.show("Copying from SD card to flash...", bytes_total);
progress.show("Copying from SD card to flash...", file_size);

const int buffer_size = SD_BUFFER_SIZE;
const uint32_t buffer_size = SD_BUFFER_SIZE;
uint8_t buffer[buffer_size];

while(bytes_flashed < bytes_total) {
while(bytes_flashed < file_size) {
// limited ram so a bit at a time
res = f_read(&file, (void *)buffer, buffer_size, &bytes_read);
res = f_read(&file, (void *)buffer, std::min(file_size - bytes_flashed, buffer_size), &bytes_read);

if(res != FR_OK)
break;
Expand All @@ -392,18 +388,19 @@ static uint32_t flash_from_sd_to_qspi_flash(FIL &file, uint32_t flash_offset) {
// update free space
for(auto &space : free_space) {
if(std::get<0>(space) == flash_offset / qspi_flash_sector_size) {
auto size = calc_num_blocks(bytes_total);
auto size = calc_num_blocks(file_size);
std::get<0>(space) += size;
std::get<1>(space) -= size;
}
}

return bytes_flashed == bytes_total ? flash_offset : 0xFFFFFFFF;
return bytes_flashed == file_size ? flash_offset : 0xFFFFFFFF;
}

// runs a .blit file, flashing it if required
static bool launch_game_from_sd(const char *path, bool auto_delete = false) {
if(is_qspi_memorymapped()) {
bool qspi_was_mapped = is_qspi_memorymapped();
if(qspi_was_mapped) {
qspi_disable_memorymapped_mode();
blit_disable_user_code(); // assume user running
}
Expand All @@ -416,16 +413,13 @@ static bool launch_game_from_sd(const char *path, bool auto_delete = false) {
if(res != FR_OK)
return false;

// get size
// this is a little duplicated...
FSIZE_t bytes_total = f_size(&file);
// check for required relocation info
char buf[8];
UINT read;
f_read(&file, buf, 8, &read);
if(memcmp(buf, "RELO", 4) == 0) {
auto num_relocs = *(uint32_t *)(buf + 4);
bytes_total -= num_relocs * 4 + 8;
}

if(memcmp(buf, "RELO", 4) != 0)
return 0xFFFFFFFF;

GameInfo meta;
if(parse_file_metadata(file, meta)) {
Expand All @@ -437,7 +431,7 @@ static bool launch_game_from_sd(const char *path, bool auto_delete = false) {
break;
} else if(strcmp(flash_game.title, meta.title) == 0 && strcmp(flash_game.author, meta.author) == 0) {
// same game, different version
if(calc_num_blocks(flash_game.size) >= calc_num_blocks(bytes_total)) {
if(calc_num_blocks(flash_game.size) >= calc_num_blocks(meta.size)) {
flash_offset = flash_game.offset;
break;
}
Expand All @@ -449,8 +443,8 @@ static bool launch_game_from_sd(const char *path, bool auto_delete = false) {
cleanup_duplicates(meta, launch_offset);
}

if(launch_offset == 0xFFFFFFFF) {
launch_offset = flash_from_sd_to_qspi_flash(file, flash_offset);
if(launch_offset == 0xFFFFFFFF && meta.size) {
launch_offset = flash_from_sd_to_qspi_flash(file, meta.size, flash_offset);
scan_flash();
}

Expand All @@ -462,6 +456,8 @@ static bool launch_game_from_sd(const char *path, bool auto_delete = false) {

return blit_switch_execution(launch_offset, true);
}
else if(qspi_was_mapped)
qspi_enable_memorymapped_mode();

blit_enable_user_code();

Expand Down Expand Up @@ -1047,6 +1043,11 @@ bool FlashLoader::prepare_for_data() {
cur_reloc = 0;
flash_start_offset = get_flash_offset_for_file(m_uFilelen);

if(flash_start_offset == 0xFFFFFFFF) {
debugf("Failed to find free space\n\r");
return false;
}

// erase
erase_qspi_flash(flash_start_offset, m_uFilelen);

Expand Down
2 changes: 1 addition & 1 deletion firmware/firmware.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ struct {
screen.rectangle(Rect(0, screen.bounds.h - 25, screen.bounds.w, 25));
screen.pen = Pen(255, 255, 255);
screen.text(this->message, minimal_font, Point(5, screen.bounds.h - 20));
uint32_t progress_width = ((this->value * (screen.bounds.w - 10)) / this->total);
uint32_t progress_width = float(this->value) / this->total * (screen.bounds.w - 10);
screen.rectangle(Rect(5, screen.bounds.h - 10, progress_width, 5));
}
}
Expand Down
5 changes: 3 additions & 2 deletions launcher-shared/dialog.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,11 @@ struct Dialog {
AnswerFunc on_answer;
bool is_question;

static constexpr Rect dialog_rect{45, 77, 230, 85};

void show(std::string title, std::string message, AnswerFunc on_answer, bool is_question = true) {
this->title = title;
this->message = message;
this->message = screen.wrap_text(message, dialog_rect.w - 12, minimal_font);
this->on_answer = on_answer;
this->is_question = is_question;
}
Expand Down Expand Up @@ -56,7 +58,6 @@ struct Dialog {
if(title.empty())
return;

const Rect dialog_rect(45, 77, 230, 85);
const int header_height = 16;

screen.pen = Pen(235, 245, 255);
Expand Down
3 changes: 2 additions & 1 deletion launcher/launcher.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -703,7 +703,8 @@ void update(uint32_t time) {
currentScreen = Screen::screenshot;
}
else {
launch_current_game();
if(!launch_current_game())
dialog.show("Error!", "Failed to launch " + selected_game.filename, [](bool){}, false);
}
}
}
Expand Down

0 comments on commit 75e837a

Please sign in to comment.