Add a lock around the SPI bus

This seems to have been the cause of recurring deadlocks that have been
difficult to repo.
custom
jacqueline 2 years ago
parent c53802f308
commit ba940baa0a
  1. 5
      src/audio/fatfs_audio_input.cpp
  2. 22
      src/database/tag_parser.cpp
  3. 9
      src/drivers/display.cpp
  4. 2
      src/drivers/include/spi.hpp
  5. 6
      src/drivers/spi.cpp

@ -91,12 +91,7 @@ auto FatfsAudioInput::NextStream() -> std::shared_ptr<codecs::IStream> {
{
std::lock_guard<std::mutex> guard{new_stream_mutex_};
// If the path is a future, then wait for it to complete.
// TODO(jacqueline): We should really make some kind of
// FreeRTOS-integrated way to block a task whilst awaiting a future.
if (pending_path_) {
while (!pending_path_->Finished()) {
vTaskDelay(pdMS_TO_TICKS(100));
}
auto res = pending_path_->Result();
pending_path_.reset();

@ -14,6 +14,7 @@
#include "esp_log.h"
#include "ff.h"
#include "opusfile.h"
#include "spi.hpp"
#include "tags.h"
#include "memory_resource.hpp"
@ -184,10 +185,14 @@ auto GenericTagParser::ReadAndParseTags(const std::pmr::string& path)
libtags::Aux aux;
auto out = std::make_shared<TrackTags>();
aux.tags = out.get();
if (f_stat(path.c_str(), &aux.info) != FR_OK ||
f_open(&aux.file, path.c_str(), FA_READ) != FR_OK) {
ESP_LOGW(kTag, "failed to open file %s", path.c_str());
return {};
{
auto lock = drivers::acquire_spi();
if (f_stat(path.c_str(), &aux.info) != FR_OK ||
f_open(&aux.file, path.c_str(), FA_READ) != FR_OK) {
ESP_LOGW(kTag, "failed to open file %s", path.c_str());
return {};
}
}
// Fine to have this on the stack; this is only called on tasks with large
// stacks anyway, due to all the string handling.
@ -200,8 +205,13 @@ auto GenericTagParser::ReadAndParseTags(const std::pmr::string& path)
ctx.aux = &aux;
ctx.buf = buf;
ctx.bufsz = kBufSize;
int res = tagsget(&ctx);
f_close(&aux.file);
int res;
{
auto lock = drivers::acquire_spi();
res = tagsget(&ctx);
f_close(&aux.file);
}
if (res != 0) {
// Parsing failed.

@ -34,6 +34,7 @@
#include "gpios.hpp"
#include "misc/lv_color.h"
#include "soc/soc.h"
#include "spi.hpp"
#include "tasks.hpp"
static const char* kTag = "DISPLAY";
@ -267,8 +268,12 @@ void Display::SendTransaction(TransactionType type,
gpio_set_level(kDisplayDr, type);
// TODO(jacqueline): Handle these errors.
esp_err_t ret = spi_device_transmit(handle_, &sTransaction);
esp_err_t ret;
{
auto lock = drivers::acquire_spi();
// TODO(jacqueline): Handle these errors.
ret = spi_device_transmit(handle_, &sTransaction);
}
ESP_ERROR_CHECK(ret);
}

@ -6,11 +6,13 @@
#pragma once
#include <mutex>
#include "esp_err.h"
namespace drivers {
esp_err_t init_spi(void);
esp_err_t deinit_spi(void);
std::lock_guard<std::mutex> acquire_spi(void);
} // namespace drivers

@ -20,6 +20,8 @@ static const gpio_num_t kSpiSdoPin = GPIO_NUM_23;
static const gpio_num_t kSpiSdiPin = GPIO_NUM_19;
static const gpio_num_t kSpiSclkPin = GPIO_NUM_18;
static std::mutex sSpiMutex{};
esp_err_t init_spi(void) {
spi_bus_config_t config = {
.mosi_io_num = kSpiSdoPin,
@ -52,4 +54,8 @@ esp_err_t deinit_spi(void) {
return spi_bus_free(kSpiHost);
}
std::lock_guard<std::mutex> acquire_spi(void) {
return std::lock_guard<std::mutex>{sSpiMutex};
}
} // namespace drivers

Loading…
Cancel
Save