Fix issues with importing my entire library

custom
jacqueline 2 years ago
parent c6bb42cdd2
commit 5b7b88420b
  1. 61
      src/app_console/app_console.cpp
  2. 5
      src/app_console/include/app_console.hpp
  3. 8
      src/database/database.cpp
  4. 5
      src/database/env_esp.cpp
  5. 2
      src/database/include/env_esp.hpp
  6. 6
      src/database/tag_parser.cpp
  7. 6
      src/drivers/samd.cpp
  8. 4
      src/drivers/touchwheel.cpp
  9. 4
      src/system_fsm/booting.cpp
  10. 5
      src/system_fsm/include/system_fsm.hpp
  11. 4
      src/system_fsm/running.cpp
  12. 2
      src/system_fsm/system_fsm.cpp
  13. 22
      src/tasks/tasks.cpp
  14. 5
      src/tasks/tasks.hpp

@ -20,14 +20,11 @@
#include "esp_console.h" #include "esp_console.h"
#include "esp_log.h" #include "esp_log.h"
#include "event_queue.hpp" #include "event_queue.hpp"
#include "ff.h"
namespace console { namespace console {
static AppConsole* sInstance = nullptr; std::weak_ptr<database::Database> AppConsole::sDatabase;
std::string toSdPath(const std::string& filepath) {
return std::string("/") + filepath;
}
int CmdListDir(int argc, char** argv) { int CmdListDir(int argc, char** argv) {
static const std::string usage = "usage: ls [directory]"; static const std::string usage = "usage: ls [directory]";
@ -36,7 +33,7 @@ int CmdListDir(int argc, char** argv) {
return 1; return 1;
} }
auto lock = sInstance->database_.lock(); auto lock = AppConsole::sDatabase.lock();
if (lock == nullptr) { if (lock == nullptr) {
std::cout << "storage is not available" << std::endl; std::cout << "storage is not available" << std::endl;
return 1; return 1;
@ -44,18 +41,38 @@ int CmdListDir(int argc, char** argv) {
std::string path; std::string path;
if (argc == 2) { if (argc == 2) {
path = toSdPath(argv[1]); path = argv[1];
} else { } else {
path = toSdPath(""); path = "";
}
FF_DIR dir;
FRESULT res = f_opendir(&dir, path.c_str());
if (res != FR_OK) {
std::cout << "failed to open directory. does it exist?" << std::endl;
return 1;
} }
DIR* dir; for (;;) {
struct dirent* ent; FILINFO info;
dir = opendir(path.c_str()); res = f_readdir(&dir, &info);
while ((ent = readdir(dir))) { if (res != FR_OK || info.fname[0] == 0) {
std::cout << ent->d_name << std::endl; // No more files in the directory.
break;
} else {
std::cout << path;
if (!path.ends_with('/') && !path.empty()) {
std::cout << '/';
}
std::cout << info.fname;
if (info.fattrib & AM_DIR) {
std::cout << '/';
}
std::cout << std::endl;
}
} }
closedir(dir);
f_closedir(&dir);
return 0; return 0;
} }
@ -101,7 +118,7 @@ int CmdDbInit(int argc, char** argv) {
return 1; return 1;
} }
auto db = sInstance->database_.lock(); auto db = AppConsole::sDatabase.lock();
if (!db) { if (!db) {
std::cout << "no database open" << std::endl; std::cout << "no database open" << std::endl;
return 1; return 1;
@ -128,13 +145,13 @@ int CmdDbTracks(int argc, char** argv) {
return 1; return 1;
} }
auto db = sInstance->database_.lock(); auto db = AppConsole::sDatabase.lock();
if (!db) { if (!db) {
std::cout << "no database open" << std::endl; std::cout << "no database open" << std::endl;
return 1; return 1;
} }
std::unique_ptr<database::Result<database::Track>> res( std::unique_ptr<database::Result<database::Track>> res(
db->GetTracks(5).get()); db->GetTracks(20).get());
while (true) { while (true) {
for (database::Track s : res->values()) { for (database::Track s : res->values()) {
std::cout << s.tags().title.value_or("[BLANK]") << std::endl; std::cout << s.tags().title.value_or("[BLANK]") << std::endl;
@ -166,7 +183,7 @@ int CmdDbDump(int argc, char** argv) {
return 1; return 1;
} }
auto db = sInstance->database_.lock(); auto db = AppConsole::sDatabase.lock();
if (!db) { if (!db) {
std::cout << "no database open" << std::endl; std::cout << "no database open" << std::endl;
return 1; return 1;
@ -201,14 +218,6 @@ void RegisterDbDump() {
esp_console_cmd_register(&cmd); esp_console_cmd_register(&cmd);
} }
AppConsole::AppConsole(const std::weak_ptr<database::Database>& database)
: database_(database) {
sInstance = this;
}
AppConsole::~AppConsole() {
sInstance = nullptr;
}
auto AppConsole::RegisterExtraComponents() -> void { auto AppConsole::RegisterExtraComponents() -> void {
RegisterListDir(); RegisterListDir();
RegisterPlayFile(); RegisterPlayFile();

@ -15,10 +15,7 @@ namespace console {
class AppConsole : public Console { class AppConsole : public Console {
public: public:
explicit AppConsole(const std::weak_ptr<database::Database>& database); static std::weak_ptr<database::Database> sDatabase;
virtual ~AppConsole();
const std::weak_ptr<database::Database>& database_;
protected: protected:
virtual auto RegisterExtraComponents() -> void; virtual auto RegisterExtraComponents() -> void;

@ -17,6 +17,7 @@
#include "esp_log.h" #include "esp_log.h"
#include "ff.h" #include "ff.h"
#include "freertos/projdefs.h"
#include "leveldb/cache.h" #include "leveldb/cache.h"
#include "leveldb/db.h" #include "leveldb/db.h"
#include "leveldb/iterator.h" #include "leveldb/iterator.h"
@ -68,12 +69,13 @@ auto Database::Open(IFileGatherer* gatherer, ITagParser* parser)
return cpp::fail(DatabaseError::ALREADY_OPEN); return cpp::fail(DatabaseError::ALREADY_OPEN);
} }
leveldb::sBackgroundThread.reset(
tasks::Worker::Start<tasks::Type::kDatabaseBackground>());
std::shared_ptr<tasks::Worker> worker( std::shared_ptr<tasks::Worker> worker(
tasks::Worker::Start<tasks::Type::kDatabase>()); tasks::Worker::Start<tasks::Type::kDatabase>());
leveldb::sBackgroundThread = std::weak_ptr<tasks::Worker>(worker);
return worker return worker
->Dispatch<cpp::result<Database*, DatabaseError>>( ->Dispatch<cpp::result<Database*, DatabaseError>>(
[&]() -> cpp::result<Database*, DatabaseError> { [=]() -> cpp::result<Database*, DatabaseError> {
leveldb::DB* db; leveldb::DB* db;
leveldb::Cache* cache = leveldb::NewLRUCache(24 * 1024); leveldb::Cache* cache = leveldb::NewLRUCache(24 * 1024);
leveldb::Options options; leveldb::Options options;
@ -121,7 +123,7 @@ Database::~Database() {
delete db_; delete db_;
delete cache_; delete cache_;
leveldb::sBackgroundThread = std::weak_ptr<tasks::Worker>(); leveldb::sBackgroundThread.reset();
sIsDbOpen.store(false); sIsDbOpen.store(false);
} }

@ -15,6 +15,7 @@
#include <cstring> #include <cstring>
#include <functional> #include <functional>
#include <limits> #include <limits>
#include <memory>
#include <mutex> #include <mutex>
#include <queue> #include <queue>
#include <set> #include <set>
@ -39,7 +40,7 @@
namespace leveldb { namespace leveldb {
std::weak_ptr<tasks::Worker> sBackgroundThread; std::shared_ptr<tasks::Worker> sBackgroundThread;
std::string ErrToStr(FRESULT err) { std::string ErrToStr(FRESULT err) {
switch (err) { switch (err) {
@ -463,7 +464,7 @@ EspEnv::EspEnv() {}
void EspEnv::Schedule( void EspEnv::Schedule(
void (*background_work_function)(void* background_work_arg), void (*background_work_function)(void* background_work_arg),
void* background_work_arg) { void* background_work_arg) {
auto worker = sBackgroundThread.lock(); auto worker = sBackgroundThread;
if (worker) { if (worker) {
worker->Dispatch<void>( worker->Dispatch<void>(
[=]() { std::invoke(background_work_function, background_work_arg); }); [=]() { std::invoke(background_work_function, background_work_arg); });

@ -18,7 +18,7 @@
namespace leveldb { namespace leveldb {
extern std::weak_ptr<tasks::Worker> sBackgroundThread; extern std::shared_ptr<tasks::Worker> sBackgroundThread;
// Tracks the files locked by EspEnv::LockFile(). // Tracks the files locked by EspEnv::LockFile().
// //

@ -73,6 +73,12 @@ static const char* kTag = "TAGS";
auto TagParserImpl::ReadAndParseTags(const std::string& path, TrackTags* out) auto TagParserImpl::ReadAndParseTags(const std::string& path, TrackTags* out)
-> bool { -> bool {
if (path.ends_with(".m4a")) {
// TODO(jacqueline): Re-enabled once libtags is fixed.
ESP_LOGW(kTag, "skipping m4a %s", path.c_str());
return false;
}
libtags::Aux aux; libtags::Aux aux;
aux.tags = out; aux.tags = out;
if (f_stat(path.c_str(), &aux.info) != FR_OK || if (f_stat(path.c_str(), &aux.info) != FR_OK ||

@ -38,7 +38,7 @@ Samd::Samd() {
.read(&raw_res, I2C_MASTER_NACK) .read(&raw_res, I2C_MASTER_NACK)
.stop(); .stop();
ESP_LOGI(kTag, "checking samd firmware rev"); ESP_LOGI(kTag, "checking samd firmware rev");
ESP_ERROR_CHECK(transaction.Execute()); transaction.Execute();
ESP_LOGI(kTag, "samd firmware: %u", raw_res); ESP_LOGI(kTag, "samd firmware: %u", raw_res);
} }
Samd::~Samd() {} Samd::~Samd() {}
@ -53,7 +53,7 @@ auto Samd::ReadChargeStatus() -> std::optional<ChargeStatus> {
.read(&raw_res, I2C_MASTER_NACK) .read(&raw_res, I2C_MASTER_NACK)
.stop(); .stop();
ESP_LOGI(kTag, "checking charge status"); ESP_LOGI(kTag, "checking charge status");
ESP_ERROR_CHECK(transaction.Execute()); transaction.Execute();
ESP_LOGI(kTag, "raw charge status: %x", raw_res); ESP_LOGI(kTag, "raw charge status: %x", raw_res);
uint8_t usb_state = raw_res & 0b11; uint8_t usb_state = raw_res & 0b11;
@ -83,7 +83,7 @@ auto Samd::WriteAllowUsbMsc(bool is_allowed) -> void {
.write_addr(kAddress, I2C_MASTER_WRITE) .write_addr(kAddress, I2C_MASTER_WRITE)
.write_ack(kRegisterUsbMsc, is_allowed) .write_ack(kRegisterUsbMsc, is_allowed)
.stop(); .stop();
ESP_ERROR_CHECK(transaction.Execute()); transaction.Execute();
} }
auto Samd::ReadUsbMscStatus() -> UsbMscStatus { auto Samd::ReadUsbMscStatus() -> UsbMscStatus {

@ -65,7 +65,7 @@ void TouchWheel::WriteRegister(uint8_t reg, uint8_t val) {
.write_addr(kTouchWheelAddress, I2C_MASTER_WRITE) .write_addr(kTouchWheelAddress, I2C_MASTER_WRITE)
.write_ack(reg, val) .write_ack(reg, val)
.stop(); .stop();
ESP_ERROR_CHECK(transaction.Execute()); transaction.Execute();
} }
uint8_t TouchWheel::ReadRegister(uint8_t reg) { uint8_t TouchWheel::ReadRegister(uint8_t reg) {
@ -78,7 +78,7 @@ uint8_t TouchWheel::ReadRegister(uint8_t reg) {
.write_addr(kTouchWheelAddress, I2C_MASTER_READ) .write_addr(kTouchWheelAddress, I2C_MASTER_READ)
.read(&res, I2C_MASTER_NACK) .read(&res, I2C_MASTER_NACK)
.stop(); .stop();
ESP_ERROR_CHECK(transaction.Execute()); transaction.Execute();
return res; return res;
} }

@ -27,8 +27,6 @@ namespace states {
static const char kTag[] = "BOOT"; static const char kTag[] = "BOOT";
console::AppConsole* Booting::sAppConsole;
auto Booting::entry() -> void { auto Booting::entry() -> void {
ESP_LOGI(kTag, "beginning tangara boot"); ESP_LOGI(kTag, "beginning tangara boot");
ESP_LOGI(kTag, "installing early drivers"); ESP_LOGI(kTag, "installing early drivers");
@ -78,7 +76,7 @@ auto Booting::entry() -> void {
auto Booting::exit() -> void { auto Booting::exit() -> void {
// TODO(jacqueline): Gate this on something. Debug flag? Flashing mode? // TODO(jacqueline): Gate this on something. Debug flag? Flashing mode?
sAppConsole = new console::AppConsole(sDatabase); sAppConsole = new console::AppConsole();
sAppConsole->Launch(); sAppConsole->Launch();
} }

@ -56,6 +56,8 @@ class SystemState : public tinyfsm::Fsm<SystemState> {
static std::shared_ptr<drivers::SdStorage> sStorage; static std::shared_ptr<drivers::SdStorage> sStorage;
static std::shared_ptr<drivers::Display> sDisplay; static std::shared_ptr<drivers::Display> sDisplay;
static std::shared_ptr<database::Database> sDatabase; static std::shared_ptr<database::Database> sDatabase;
static console::AppConsole* sAppConsole;
}; };
namespace states { namespace states {
@ -65,9 +67,6 @@ namespace states {
* looks good. * looks good.
*/ */
class Booting : public SystemState { class Booting : public SystemState {
private:
static console::AppConsole* sAppConsole;
public: public:
void entry() override; void entry() override;
void exit() override; void exit() override;

@ -4,6 +4,7 @@
* SPDX-License-Identifier: GPL-3.0-only * SPDX-License-Identifier: GPL-3.0-only
*/ */
#include "app_console.hpp"
#include "freertos/projdefs.h" #include "freertos/projdefs.h"
#include "result.hpp" #include "result.hpp"
@ -28,6 +29,7 @@ void Running::entry() {
vTaskDelay(pdMS_TO_TICKS(250)); vTaskDelay(pdMS_TO_TICKS(250));
auto storage_res = drivers::SdStorage::Create(sGpioExpander.get()); auto storage_res = drivers::SdStorage::Create(sGpioExpander.get());
if (storage_res.has_error()) { if (storage_res.has_error()) {
ESP_LOGW(kTag, "failed to mount!");
events::Dispatch<StorageError, SystemState, audio::AudioState, ui::UiState>( events::Dispatch<StorageError, SystemState, audio::AudioState, ui::UiState>(
StorageError()); StorageError());
return; return;
@ -38,11 +40,13 @@ void Running::entry() {
ESP_LOGI(kTag, "opening database"); ESP_LOGI(kTag, "opening database");
auto database_res = database::Database::Open(); auto database_res = database::Database::Open();
if (database_res.has_error()) { if (database_res.has_error()) {
ESP_LOGW(kTag, "failed to open!");
events::Dispatch<StorageError, SystemState, audio::AudioState, ui::UiState>( events::Dispatch<StorageError, SystemState, audio::AudioState, ui::UiState>(
StorageError()); StorageError());
return; return;
} }
sDatabase.reset(database_res.value()); sDatabase.reset(database_res.value());
console::AppConsole::sDatabase = sDatabase;
ESP_LOGI(kTag, "storage loaded okay"); ESP_LOGI(kTag, "storage loaded okay");
events::Dispatch<StorageMounted, SystemState, audio::AudioState, ui::UiState>( events::Dispatch<StorageMounted, SystemState, audio::AudioState, ui::UiState>(

@ -20,6 +20,8 @@ std::shared_ptr<drivers::SdStorage> SystemState::sStorage;
std::shared_ptr<drivers::Display> SystemState::sDisplay; std::shared_ptr<drivers::Display> SystemState::sDisplay;
std::shared_ptr<database::Database> SystemState::sDatabase; std::shared_ptr<database::Database> SystemState::sDatabase;
console::AppConsole* SystemState::sAppConsole;
void SystemState::react(const FatalError& err) { void SystemState::react(const FatalError& err) {
if (!is_in_state<states::Error>()) { if (!is_in_state<states::Error>()) {
transit<states::Error>(); transit<states::Error>();

@ -5,7 +5,9 @@
*/ */
#include "tasks.hpp" #include "tasks.hpp"
#include <functional> #include <functional>
#include "esp_heap_caps.h" #include "esp_heap_caps.h"
#include "freertos/FreeRTOS.h" #include "freertos/FreeRTOS.h"
#include "freertos/portmacro.h" #include "freertos/portmacro.h"
@ -31,6 +33,10 @@ template <>
auto Name<Type::kDatabase>() -> std::string { auto Name<Type::kDatabase>() -> std::string {
return "DB"; return "DB";
} }
template <>
auto Name<Type::kDatabaseBackground>() -> std::string {
return "DB_BG";
}
template <Type t> template <Type t>
auto AllocateStack() -> cpp::span<StackType_t>; auto AllocateStack() -> cpp::span<StackType_t>;
@ -39,7 +45,7 @@ auto AllocateStack() -> cpp::span<StackType_t>;
// amount of stack space. // amount of stack space.
template <> template <>
auto AllocateStack<Type::kAudio>() -> cpp::span<StackType_t> { auto AllocateStack<Type::kAudio>() -> cpp::span<StackType_t> {
std::size_t size = 48 * 1024; std::size_t size = 32 * 1024;
return {static_cast<StackType_t*>(heap_caps_malloc(size, MALLOC_CAP_DEFAULT)), return {static_cast<StackType_t*>(heap_caps_malloc(size, MALLOC_CAP_DEFAULT)),
size}; size};
} }
@ -67,6 +73,12 @@ auto AllocateStack<Type::kDatabase>() -> cpp::span<StackType_t> {
return {static_cast<StackType_t*>(heap_caps_malloc(size, MALLOC_CAP_SPIRAM)), return {static_cast<StackType_t*>(heap_caps_malloc(size, MALLOC_CAP_SPIRAM)),
size}; size};
} }
template <>
auto AllocateStack<Type::kDatabaseBackground>() -> cpp::span<StackType_t> {
std::size_t size = 256 * 1024;
return {static_cast<StackType_t*>(heap_caps_malloc(size, MALLOC_CAP_SPIRAM)),
size};
}
// 2048 bytes in internal ram // 2048 bytes in internal ram
// 302 KiB in external ram. // 302 KiB in external ram.
@ -106,6 +118,10 @@ template <>
auto Priority<Type::kDatabase>() -> UBaseType_t { auto Priority<Type::kDatabase>() -> UBaseType_t {
return 8; return 8;
} }
template <>
auto Priority<Type::kDatabaseBackground>() -> UBaseType_t {
return 7;
}
template <Type t> template <Type t>
auto WorkerQueueSize() -> std::size_t; auto WorkerQueueSize() -> std::size_t;
@ -114,6 +130,10 @@ template <>
auto WorkerQueueSize<Type::kDatabase>() -> std::size_t { auto WorkerQueueSize<Type::kDatabase>() -> std::size_t {
return 8; return 8;
} }
template <>
auto WorkerQueueSize<Type::kDatabaseBackground>() -> std::size_t {
return 8;
}
template <> template <>
auto WorkerQueueSize<Type::kUiFlush>() -> std::size_t { auto WorkerQueueSize<Type::kUiFlush>() -> std::size_t {

@ -36,6 +36,8 @@ enum class Type {
kAudio, kAudio,
// Task for running database queries. // Task for running database queries.
kDatabase, kDatabase,
// Task for internal database operations
kDatabaseBackground,
}; };
template <Type t> template <Type t>
@ -102,6 +104,9 @@ class Worker {
} }
~Worker(); ~Worker();
Worker(const Worker&) = delete;
Worker& operator=(const Worker&) = delete;
}; };
/* Specialisation of Evaluate for functions that return nothing. */ /* Specialisation of Evaluate for functions that return nothing. */

Loading…
Cancel
Save