Skip to content

Commit

Permalink
Store firmware path when running firmwares from SD card (#10)
Browse files Browse the repository at this point in the history
lib: store firmware path when starting multiboot
lib: cleanup logs
lib: do not clear firmware path from OTA partition end
keira: show multiboot progress dialog sooner
keira: fix SD card item selection
keira: fix Lua demos
doom: read firmware path from OTA
doc: update docs on running Doom
doc: update render -> queue_draw
  • Loading branch information
and3rson authored Mar 20, 2024
1 parent 4daae5a commit 86fa10e
Show file tree
Hide file tree
Showing 10 changed files with 66 additions and 23 deletions.
2 changes: 1 addition & 1 deletion docs/keira/features.rst
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ Keira підтримує запуск другорядних прошивок з
- Вам не потрібно щоразу перепрошивати Лілку, щоб випробувати другорядні прошивки: просто скопіюйте їх на SD-картку.
- Ви можете ділитися своїми скомпільованими прошивками (у вигляді ``.bin``-файлів) з іншими користувачами Лілки, без необхідності відправляти їм весь код вашої власної прошивки.

Найяскравіший приклад використання цієї функції - запуск Doom. Достатньо скопіювати в корінь SD-карти файли ``doom.bin`` і ``doom.wad`` (або ``doom1.wad``), і ви зможете грати в Doom!
Найяскравіший приклад використання цієї функції - запуск Doom. Достатньо скопіювати на SD-карту файли ``doom.bin`` і ``doom.wad`` (або ``doom1.wad``), і ви зможете грати в Doom!

.. note:: Щоб отримати ``doom.bin``, вам потрібно скомпілювати прошивку, що знаходиться в папці ``firmware/doom``, і тоді скопіювати файл ``doom.bin`` на SD-картку.

Expand Down
4 changes: 2 additions & 2 deletions docs/keira/lua/reference/lilka.rst
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@

Ви повинні визначити її в своєму коді, якщо ви хочете використовувати її для оновлення вашої програми.

.. lua:function:: render()
.. lua:function:: draw()
Ця функція автоматично викликається після `lilka.update`. Тут відбувається відображення графіки.

Expand All @@ -32,4 +32,4 @@
.. lua:autoclass:: lilka
.. Does not work with aliases... So we have to copy-paste the stuff above.
.. :members: init, update, render
.. :members: init, update, draw
19 changes: 16 additions & 3 deletions firmware/doom/src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -105,9 +105,22 @@ void setup() {
char arg[] = "doomgeneric";
char arg2[] = "-iwad";
char arg3[64];

// Get firmware arg
String firmwareFile = lilka::multiboot.getFirmwarePath();
lilka::serial_log("Firmware file: %s\n", firmwareFile.c_str());
String firmwareDir;
if (firmwareFile.length()) {
// Get directory from firmware file
int lastSlash = firmwareFile.lastIndexOf('/');
firmwareDir = firmwareFile.substring(0, lastSlash);
} else {
firmwareDir = "/";
}

bool found = false;
// Find the wad file
File root = SD.open("/");
// Find the WAD file
File root = SD.open(firmwareDir.c_str());
File file;
while ((file = root.openNextFile())) {
if (file.isDirectory()) {
Expand All @@ -118,7 +131,7 @@ void setup() {
name.toLowerCase();
lilka::serial_log("Checking file: %s\n", name.c_str());
if (name.startsWith("doom") && name.endsWith(".wad")) {
strcpy(arg3, (String("/sd/") + file.name()).c_str());
strcpy(arg3, (String("/sd") + firmwareDir + "/" + file.name()).c_str());
lilka::serial_log("Found .WAD file: %s\n", arg3);
found = true;
file.close();
Expand Down
2 changes: 1 addition & 1 deletion firmware/keira/sdcard/counter/counter.lua
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,5 @@ state.counter = state.counter + 1
display.fill_screen(display.color565(64, 0, 64))
display.set_cursor(0, 64)
display.print('Лічильник запусків\nпрограми: ', state.counter)
display.render()
display.queue_draw()
util.sleep(0.5)
7 changes: 3 additions & 4 deletions firmware/keira/sdcard/test.lua
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,11 @@ for i = 10, 1, -1 do
local y = math.random(280 - 64)
display.draw_image(face, x, y)

display.render()
display.queue_draw()

util.sleep(0.25)
end

-- Now, we want to draw random lines & faces really fast directly to display, without any buffering!
display.set_buffered(false)

local key = controller.get_state()
while not key.a.just_pressed do
local x1 = math.random(240)
Expand All @@ -34,5 +31,7 @@ while not key.a.just_pressed do
local y = math.random(280 - 64)
display.draw_image(face, x, y)

display.queue_draw()

key = controller.get_state()
end
9 changes: 5 additions & 4 deletions firmware/keira/src/apps/launcher.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,7 @@ void LauncherApp::sdBrowserMenu(String path) {
queueDraw();
}
int16_t index = menu.getCursor();
if (index >= numEntries - 1) break;
if (index == numEntries) break;
if (entries[index].type == lilka::EntryType::ENT_DIRECTORY) {
sdBrowserMenu(path + entries[index].name + "/");
} else {
Expand Down Expand Up @@ -229,15 +229,16 @@ void LauncherApp::selectFile(String path) {
alert("Помилка", "Ця операція потребує Лілку 2.0");
return;
#else
lilka::ProgressDialog dialog("Завантаження", path + "\n\nПочинаємо...");
dialog.draw(canvas);
queueDraw();
int error;
error = lilka::multiboot.start(path);
if (error) {
alert("Помилка", String("Етап: 1\nКод: ") + error);
return;
}
lilka::ProgressDialog dialog(
"Завантаження", path + "\nРозмір: " + String(lilka::multiboot.getBytesTotal()) + " Б"
);
dialog.setMessage(path + "\n\nРозмір: " + String(lilka::multiboot.getBytesTotal()) + " Б");
dialog.draw(canvas);
queueDraw();
while ((error = lilka::multiboot.process()) > 0) {
Expand Down
2 changes: 1 addition & 1 deletion sdk/addons/lualilka/library/lilka.lua
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,6 @@ lilka = {}
---Ця функція автоматично викликається після `lilka.update`. Тут відбувається відображення графіки.
---
---Ви повинні визначити її в своєму коді, якщо ви хочете використовувати її для малювання вашої програми.
---@alias lilka.render fun()
---@alias lilka.draw fun()

return lilka
2 changes: 1 addition & 1 deletion sdk/addons/lualilka/library/state.lua
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,6 @@
--- display.fill_screen(display.color565(64, 0, 64))
--- display.set_cursor(0, 64)
--- display.print('Лічильник запусків\nпрограми: ', state.counter)
--- display.render()
--- display.queue_draw()
--- util.sleep(0.5)
state = {}
40 changes: 34 additions & 6 deletions sdk/lib/lilka/src/lilka/multiboot.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ int MultiBoot::start(String path) {
ota_partition = esp_ota_get_next_update_partition(current_partition); // get ota1 (we're in ota0 now)
if (ota_partition == NULL) {
serial_err("Failed to get next OTA partition");
return -3;
return -4;
}
serial_log(
"OTA partition: %s, type: %d, subtype: %d, size: %d",
Expand All @@ -137,7 +137,21 @@ int MultiBoot::start(String path) {
esp_err_t err = esp_ota_begin(ota_partition, bytesTotal, &ota_handle);
if (err != ESP_OK) {
serial_err("Failed to begin OTA: %d", err);
return -4;
return -5;
}

// Write path to last 256 bytes of the OTA partition
size_t partition_size = ota_partition->size;
size_t offset = partition_size - 256;
String arg = path;
// Remove "/sd" prefix
// TODO: Maybe we should use absolute path (including "/sd")?
if (arg.startsWith("/sd/")) {
arg = arg.substring(3);
}
if (esp_partition_write(ota_partition, offset, arg.c_str(), arg.length() + 1) != ESP_OK) {
serial_err("Failed to write arg to OTA partition");
return -6;
}

return 0;
Expand All @@ -159,13 +173,12 @@ int MultiBoot::process() {
esp_err_t err = esp_ota_write(ota_handle, buf, len);
if (err != ESP_OK) {
serial_err("Failed to write OTA: %d", err);
return -5;
return -7;
}

bytesWritten += len;
}

serial_log("Written %d bytes", bytesWritten);
return bytesWritten;
}

Expand Down Expand Up @@ -193,14 +206,14 @@ int MultiBoot::finishAndReboot() {
esp_err_t err = esp_ota_end(ota_handle);
if (err != ESP_OK) {
serial_err("Failed to end OTA: %d", err);
return -6;
return -8;
}

// Перевстановлення активного розділу на OTA-розділ (його буде запущено лише один раз, після чого активним залишиться основний розділ).
err = esp_ota_set_boot_partition(ota_partition);
if (err != ESP_OK) {
serial_err("Failed to set boot partition: %d", err);
return -7;
return -9;
}

// Запуск нової прошивки.
Expand All @@ -209,6 +222,21 @@ int MultiBoot::finishAndReboot() {
return 0; // unreachable
}

String MultiBoot::getFirmwarePath() {
size_t partition_size = current_partition->size;
size_t offset = partition_size - 256;
char buf[256];
if (esp_partition_read(current_partition, offset, buf, sizeof(buf)) != ESP_OK) {
serial_err("Failed to read firmware path from current partition");
return "";
}
if (static_cast<uint8_t>(buf[0]) == 0xFF) {
serial_err("Firmware path is not set");
return "";
}
return String(buf);
}

MultiBoot multiboot;

} // namespace lilka
2 changes: 2 additions & 0 deletions sdk/lib/lilka/src/lilka/multiboot.h
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,8 @@ class MultiBoot {
/// \return <0 - у разі помилки. В разі успіху цей метод не повертається, оскільки пристрій перезавантажується.
int finishAndReboot();

String getFirmwarePath();

private:
String path;
FILE* file;
Expand Down

0 comments on commit 86fa10e

Please sign in to comment.