From 94ccd405e37bd1cfc74b9f173bdd31c6f16ef890 Mon Sep 17 00:00:00 2001 From: jacqueline Date: Tue, 24 Sep 2024 13:28:42 +1000 Subject: [PATCH] Retry SD card mounting a few times when talking to the card fails --- src/tangara/lua/lua_database.cpp | 41 ++++++++++++++++++------ src/tangara/system_fsm/running.cpp | 20 +++++++++--- src/tangara/system_fsm/system_events.hpp | 4 ++- 3 files changed, 49 insertions(+), 16 deletions(-) diff --git a/src/tangara/lua/lua_database.cpp b/src/tangara/lua/lua_database.cpp index e184265a..2e00f427 100644 --- a/src/tangara/lua/lua_database.cpp +++ b/src/tangara/lua/lua_database.cpp @@ -39,6 +39,7 @@ static constexpr char kDbIteratorMetatable[] = "db_iterator"; struct LuaIndexInfo { database::IndexId id; + database::MediaType type; size_t name_size; char name_data[]; @@ -64,6 +65,7 @@ static auto indexes(lua_State* state) -> int { luaL_setmetatable(state, kDbIndexMetatable); *data = LuaIndexInfo{ .id = i.id, + .type = i.type, .name_size = i.name.size(), }; std::memcpy(data->name_data, i.name.data(), i.name.size()); @@ -119,8 +121,6 @@ static void pushTrack(lua_State* L, const database::Track& track) { lua_pushliteral(L, "saved_position"); lua_pushinteger(L, track.data().last_position); lua_settable(L, -3); - - } static auto version(lua_State* L) -> int { @@ -181,8 +181,9 @@ static auto track_by_id(lua_State* L) -> int { } static const struct luaL_Reg kDatabaseFuncs[] = { - {"indexes", indexes}, {"version", version}, {"size", size}, - {"recreate", recreate}, {"update", update}, {"track_by_id", track_by_id}, + {"indexes", indexes}, {"version", version}, + {"size", size}, {"recreate", recreate}, + {"update", update}, {"track_by_id", track_by_id}, {NULL, NULL}}; /* @@ -222,8 +223,8 @@ auto db_check_iterator(lua_State* L, int stack_pos) -> database::Iterator* { return it; } -static auto push_iterator(lua_State* state, - const database::Iterator& it) -> void { +static auto push_iterator(lua_State* state, const database::Iterator& it) + -> void { database::Iterator** data = reinterpret_cast( lua_newuserdata(state, sizeof(uintptr_t))); *data = new database::Iterator(it); @@ -319,6 +320,26 @@ static auto index_name(lua_State* state) -> int { return 1; } +static auto index_id(lua_State* state) -> int { + LuaIndexInfo* data = reinterpret_cast( + luaL_checkudata(state, 1, kDbIndexMetatable)); + if (data == NULL) { + return 0; + } + lua_pushinteger(state, static_cast(data->id)); + return 1; +} + +static auto index_type(lua_State* state) -> int { + LuaIndexInfo* data = reinterpret_cast( + luaL_checkudata(state, 1, kDbIndexMetatable)); + if (data == NULL) { + return 0; + } + lua_pushinteger(state, static_cast(data->type)); + return 1; +} + static auto index_iter(lua_State* state) -> int { LuaIndexInfo* data = reinterpret_cast( luaL_checkudata(state, 1, kDbIndexMetatable)); @@ -334,10 +355,10 @@ static auto index_iter(lua_State* state) -> int { return 1; } -static const struct luaL_Reg kDbIndexFuncs[] = {{"name", index_name}, - {"iter", index_iter}, - {"__tostring", index_name}, - {NULL, NULL}}; +static const struct luaL_Reg kDbIndexFuncs[] = { + {"name", index_name}, {"id", index_id}, {"type", index_type}, + {"iter", index_iter}, {"__tostring", index_name}, {NULL, NULL}, +}; static auto lua_database(lua_State* state) -> int { // Metatable for indexes diff --git a/src/tangara/system_fsm/running.cpp b/src/tangara/system_fsm/running.cpp index 33c6c7dc..f065737b 100644 --- a/src/tangara/system_fsm/running.cpp +++ b/src/tangara/system_fsm/running.cpp @@ -40,7 +40,7 @@ void Running::entry() { sUnmountTimer = xTimerCreate("unmount_timeout", kTicksBeforeUnmount, false, NULL, timer_callback); } - events::System().Dispatch(internal::Mount{}); + events::System().Dispatch(internal::Mount{.attempt = 1}); } void Running::exit() { @@ -72,7 +72,7 @@ void Running::react(const SdDetectChanged& ev) { } if (ev.has_sd_card && !sStorage) { - events::System().Dispatch(internal::Mount{}); + events::System().Dispatch(internal::Mount{.attempt = 1}); return; } @@ -121,7 +121,7 @@ void Running::react(const SamdUsbMscChanged& ev) { gpios.WriteSync(drivers::IGpios::Pin::kSdPowerEnable, 0); // Now it's ready for us. - events::System().Dispatch(internal::Mount{}); + events::System().Dispatch(internal::Mount{.attempt = 1}); } } @@ -146,13 +146,18 @@ auto Running::updateSdState(drivers::SdState state) -> void { events::System().Dispatch(SdStateChanged{}); } -void Running::react(const internal::Mount&) { +void Running::react(const internal::Mount& ev) { // Only mount our storage if we know it's not currently in use by the SAMD. if (sServices->samd().UsbMassStorage()) { updateSdState(drivers::SdState::kNotMounted); return; } + if (ev.attempt > 3) { + updateSdState(drivers::SdState::kNotPresent); + return; + } + ESP_LOGI(kTag, "mounting sd card"); auto storage_res = drivers::SdStorage::Create(sServices->gpios()); if (storage_res.has_error()) { @@ -163,7 +168,12 @@ void Running::react(const internal::Mount&) { break; case drivers::SdStorage::FAILED_TO_READ: default: - updateSdState(drivers::SdState::kNotPresent); + if (!sServices->gpios().Get(drivers::Gpios::Pin::kSdCardDetect)) { + vTaskDelay(pdMS_TO_TICKS(100)); + events::System().Dispatch(internal::Mount{.attempt = ev.attempt + 1}); + } else { + updateSdState(drivers::SdState::kNotPresent); + } break; } return; diff --git a/src/tangara/system_fsm/system_events.hpp b/src/tangara/system_fsm/system_events.hpp index c93c14d5..c2e3a2ab 100644 --- a/src/tangara/system_fsm/system_events.hpp +++ b/src/tangara/system_fsm/system_events.hpp @@ -82,7 +82,9 @@ struct SamdInterrupt : tinyfsm::Event {}; struct IdleTimeout : tinyfsm::Event {}; struct UnmountTimeout : tinyfsm::Event {}; -struct Mount : tinyfsm::Event {}; +struct Mount : tinyfsm::Event { + int attempt; +}; } // namespace internal