Merge remote-tracking branch 'origin/main'

This commit is contained in:
Adolfo Reyna
2026-06-28 21:13:35 -04:00
222 changed files with 1713 additions and 2257 deletions
@@ -1,84 +0,0 @@
#pragma once
#include <tactility/hal/Device.h>
#include <Tactility/Lock.h>
#include <Tactility/TactilityCore.h>
struct FileSystem;
namespace tt::hal::sdcard {
/**
* Warning: getLock() does not have to be used when calling any of the functions of this class.
* The lock is only used for file access on the path where the SD card is mounted.
* This is mainly used when accessing the SD card on a shared SPI bus.
*/
class SdCardDevice : public Device {
public:
enum class State {
Mounted,
Unmounted,
Error,
Timeout // Failed to retrieve state due to timeout
};
enum class MountBehaviour {
AtBoot, /** Only mount at boot */
Anytime /** Mount/dismount any time */
};
private:
MountBehaviour mountBehaviour;
FileSystem* fileSystem;
public:
explicit SdCardDevice(MountBehaviour mountBehaviour);
~SdCardDevice() override;
Type getType() const final { return Type::SdCard; };
/**
* Mount the device.
* @param mountPath the path to mount at
* @return true on successful mount
*/
virtual bool mount(const std::string& mountPath) = 0;
/**
* Unmount the device.
* @return true on successful unmount
*/
virtual bool unmount() = 0;
virtual State getState(TickType_t timeout = kernel::MAX_TICKS) const = 0;
/** @return empty string when not mounted or the mount path if mounted */
virtual std::string getMountPath() const = 0;
/** @return non-null lock, used by code that wants to access files on the mount path of this SD card */
virtual std::shared_ptr<Lock> getLock() const = 0;
/** @return the MountBehaviour of this device */
virtual MountBehaviour getMountBehaviour() const { return mountBehaviour; }
/** @return true if the SD card was mounted, returns false when it was not or when a timeout happened. */
bool isMounted(TickType_t timeout = kernel::MAX_TICKS) const { return getState(timeout) == State::Mounted; }
};
/** Return the SdCard device if the path is within the SdCard mounted path (path std::string::starts_with() check), otherwise return nullptr */
std::shared_ptr<SdCardDevice> find(const std::string& path);
/**
* Attempt to find an SD card that the specified belongs to,
* and returns its lock if the SD card is mounted. Otherwise it returns nullptr.
* @param[in] a path on a file system (e.g. file, directory, etc.)
* @return the lock of a mounted SD card or otherwise null
*/
std::shared_ptr<Lock> findSdCardLock(const std::string& path);
} // namespace tt::hal
@@ -1,104 +0,0 @@
#ifdef ESP_PLATFORM
#pragma once
#include "SdCardDevice.h"
#include "Tactility/kernel/SpiDeviceLock.h"
#include <driver/gpio.h>
#include <driver/spi_common.h>
#include <sd_protocol_types.h>
#include <utility>
#include <vector>
namespace tt::hal::sdcard {
/**
* SD card interface at the default SPI interface
*/
class SpiSdCardDevice final : public SdCardDevice {
public:
struct Config {
Config(
gpio_num_t spiPinCs,
gpio_num_t spiPinCd,
gpio_num_t spiPinWp,
gpio_num_t spiPinInt,
MountBehaviour mountBehaviourAtBoot,
/** When customLock is a nullptr, use the SPI default one */
std::shared_ptr<Lock> customLock = nullptr,
std::vector<gpio_num_t> csPinWorkAround = std::vector<gpio_num_t>(),
spi_host_device_t spiHost = SPI2_HOST,
int spiFrequencyKhz = SDMMC_FREQ_DEFAULT
) : spiFrequencyKhz(spiFrequencyKhz),
spiPinCs(spiPinCs),
spiPinCd(spiPinCd),
spiPinWp(spiPinWp),
spiPinInt(spiPinInt),
mountBehaviourAtBoot(mountBehaviourAtBoot),
customLock(customLock ? std::move(customLock) : nullptr),
csPinWorkAround(std::move(csPinWorkAround)),
spiHost(spiHost)
{}
int spiFrequencyKhz;
gpio_num_t spiPinCs; // Clock
gpio_num_t spiPinCd; // Card detect
gpio_num_t spiPinWp; // Write-protect
gpio_num_t spiPinInt; // Interrupt
MountBehaviour mountBehaviourAtBoot;
std::shared_ptr<Lock> customLock; // can be nullptr
std::vector<gpio_num_t> csPinWorkAround;
spi_host_device_t spiHost;
bool formatOnMountFailed = false;
uint16_t maxOpenFiles = 4;
uint16_t allocUnitSize = 16 * 1024;
bool statusCheckEnabled = false;
};
private:
std::string mountPath;
sdmmc_card_t* card = nullptr;
std::shared_ptr<Config> config;
std::shared_ptr<Lock> lock;
bool applyGpioWorkAround();
bool mountInternal(const std::string& mountPath);
public:
explicit SpiSdCardDevice(std::unique_ptr<Config> newConfig, ::Device* spiController) : SdCardDevice(newConfig->mountBehaviourAtBoot),
config(std::move(newConfig))
{
if (config->customLock == nullptr) {
auto spi_lock = std::make_shared<SpiDeviceLock>(spiController);
lock = std::static_pointer_cast<Lock>(spi_lock);
} else {
lock = config->customLock;
}
}
std::string getName() const override { return "SD Card"; }
std::string getDescription() const override { return "SD card via SPI interface"; }
bool mount(const std::string& mountPath) override;
bool unmount() override;
std::string getMountPath() const override { return mountPath; }
std::shared_ptr<Lock> getLock() const override {
return lock;
}
State getState(TickType_t timeout) const override;
/** return card when mounted, otherwise return nullptr */
sdmmc_card_t* getCard() { return card; }
};
}
#endif