mirror of
https://github.com/m5stack/M5HAL.git
synced 2026-05-20 11:27:38 -07:00
Change .clang-format to the latest M5 one
This commit is contained in:
+2
-3
@@ -7,11 +7,10 @@
|
||||
#define M5HAL_STATIC_MACRO_PATH_IMPL M5HAL_STATIC_MACRO_CONCAT(M5HAL_TARGET_PLATFORM_PATH, impl.inl)
|
||||
|
||||
#if M5HAL_TARGET_PLATFORM_NUMBER != 0
|
||||
#include M5HAL_STATIC_MACRO_PATH_IMPL
|
||||
#include M5HAL_STATIC_MACRO_PATH_IMPL
|
||||
#endif
|
||||
|
||||
// Arduino環境の場合のみ、Arduino用の実装を用意
|
||||
#if M5HAL_FRAMEWORK_HAS_ARDUINO
|
||||
#include "./m5_hal/frameworks/arduino/impl.inl"
|
||||
#include "./m5_hal/frameworks/arduino/impl.inl"
|
||||
#endif
|
||||
|
||||
|
||||
+12
-12
@@ -11,30 +11,30 @@
|
||||
#include "./m5_hal/bus/bus.hpp"
|
||||
#include "./m5_hal/interface/gpio.hpp"
|
||||
|
||||
#define M5HAL_STATIC_MACRO_STRING(x) #x
|
||||
#define M5HAL_STATIC_MACRO_CONCAT(x, y) M5HAL_STATIC_MACRO_STRING(x/y)
|
||||
#define M5HAL_STATIC_MACRO_PATH_HEADER M5HAL_STATIC_MACRO_CONCAT(M5HAL_TARGET_PLATFORM_PATH, header.hpp)
|
||||
#define M5HAL_STATIC_MACRO_STRING(x) #x
|
||||
#define M5HAL_STATIC_MACRO_CONCAT(x, y) M5HAL_STATIC_MACRO_STRING(x / y)
|
||||
#define M5HAL_STATIC_MACRO_PATH_HEADER M5HAL_STATIC_MACRO_CONCAT(M5HAL_TARGET_PLATFORM_PATH, header.hpp)
|
||||
|
||||
#if M5HAL_TARGET_PLATFORM_NUMBER != 0
|
||||
#include M5HAL_STATIC_MACRO_PATH_HEADER
|
||||
#include M5HAL_STATIC_MACRO_PATH_HEADER
|
||||
#endif
|
||||
|
||||
#undef M5HAL_STATIC_MACRO_PATH_HEADER
|
||||
|
||||
// Arduinoフレームワークがある場合は準備
|
||||
#if M5HAL_FRAMEWORK_HAS_ARDUINO
|
||||
#include "./m5_hal/frameworks/arduino/header.hpp"
|
||||
#include "./m5_hal/frameworks/arduino/header.hpp"
|
||||
|
||||
// 対象プラットフォームが特定されない場合は Arduino経由の実装を利用
|
||||
#if 1 // M5HAL_TARGET_PLATFORM_NUMBER == 0
|
||||
#if 1 // M5HAL_TARGET_PLATFORM_NUMBER == 0
|
||||
|
||||
namespace m5 {
|
||||
namespace hal {
|
||||
using namespace frameworks::arduino;
|
||||
}
|
||||
}
|
||||
namespace m5 {
|
||||
namespace hal {
|
||||
using namespace frameworks::arduino;
|
||||
}
|
||||
} // namespace m5
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
+93
-45
@@ -24,7 +24,7 @@ struct Accessor;
|
||||
//-------------------------------------------------------------------------
|
||||
// 通信バスの初期化に必要な条件を記述するため基底インターフェイス
|
||||
struct BusConfig {
|
||||
virtual ~BusConfig() = default;
|
||||
virtual ~BusConfig() = default;
|
||||
virtual types::bus_type_t getBusType(void) const = 0;
|
||||
types::periph_t periph;
|
||||
};
|
||||
@@ -32,71 +32,105 @@ struct BusConfig {
|
||||
//-------------------------------------------------------------------------
|
||||
// 実際の通信に必要な条件を記述するための基底インターフェイス
|
||||
struct AccessConfig {
|
||||
virtual ~AccessConfig() = default;
|
||||
virtual ~AccessConfig() = default;
|
||||
virtual types::bus_type_t getBusType(void) const = 0;
|
||||
void (*callback_begin)(Accessor*) = nullptr; // 通信開始時時に呼び出すコールバック関数
|
||||
void (*callback_end)(Accessor*) = nullptr; // 通信終了時に呼び出すコールバック関数
|
||||
void (*callback_begin)(Accessor*) = nullptr; // 通信開始時時に呼び出すコールバック関数
|
||||
void (*callback_end)(Accessor*) = nullptr; // 通信終了時に呼び出すコールバック関数
|
||||
};
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// 特定の通信相手との各種通信条件を記述するため基底インターフェイス
|
||||
struct Accessor : public interface::io::Output, public interface::io::Input
|
||||
{
|
||||
virtual ~Accessor(void) = default;
|
||||
virtual types::bus_type_t getBusType(void) const = 0;
|
||||
struct Accessor : public interface::io::Output, public interface::io::Input {
|
||||
virtual ~Accessor(void) = default;
|
||||
virtual types::bus_type_t getBusType(void) const = 0;
|
||||
virtual const AccessConfig& getAccessConfig(void) const = 0;
|
||||
|
||||
Accessor(Bus& bus) : _bus { bus } {}
|
||||
Bus& getBus(void) const { return _bus; };
|
||||
Accessor(Bus& bus) : _bus{bus}
|
||||
{
|
||||
}
|
||||
Bus& getBus(void) const
|
||||
{
|
||||
return _bus;
|
||||
};
|
||||
const BusConfig& getBusConfig(void) const;
|
||||
|
||||
virtual m5::stl::expected<void, m5::hal::error::error_t> startWrite(void) { return {}; }
|
||||
virtual m5::stl::expected<void, m5::hal::error::error_t> startRead(void) { return {}; }
|
||||
virtual m5::stl::expected<void, m5::hal::error::error_t> stop(void) { return {}; }
|
||||
virtual m5::stl::expected<size_t, m5::hal::error::error_t> readLastNack(uint8_t* data, size_t len) { return readWithLastNackFlag(data, len, true); }
|
||||
virtual m5::stl::expected<size_t, m5::hal::error::error_t> readWithLastNackFlag(uint8_t* data, size_t len, bool last_nack = false) { return read(data, len); }
|
||||
virtual m5::stl::expected<void, m5::hal::error::error_t> startWrite(void)
|
||||
{
|
||||
return {};
|
||||
}
|
||||
virtual m5::stl::expected<void, m5::hal::error::error_t> startRead(void)
|
||||
{
|
||||
return {};
|
||||
}
|
||||
virtual m5::stl::expected<void, m5::hal::error::error_t> stop(void)
|
||||
{
|
||||
return {};
|
||||
}
|
||||
virtual m5::stl::expected<size_t, m5::hal::error::error_t> readLastNack(uint8_t* data, size_t len)
|
||||
{
|
||||
return readWithLastNackFlag(data, len, true);
|
||||
}
|
||||
virtual m5::stl::expected<size_t, m5::hal::error::error_t> readWithLastNackFlag(uint8_t* data, size_t len,
|
||||
bool last_nack = false)
|
||||
{
|
||||
return read(data, len);
|
||||
}
|
||||
|
||||
protected:
|
||||
Bus& _bus;
|
||||
};
|
||||
|
||||
template<typename TBusAccessInterface>
|
||||
template <typename TBusAccessInterface>
|
||||
struct DefaultBusExtension {
|
||||
DefaultBusExtension(TBusAccessInterface&) {}
|
||||
DefaultBusExtension(TBusAccessInterface&)
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
template<typename TBus, typename TBusAccessInterface, typename TExtension = DefaultBusExtension<TBusAccessInterface>>
|
||||
template <typename TBus, typename TBusAccessInterface, typename TExtension = DefaultBusExtension<TBusAccessInterface>>
|
||||
struct BusAccessor {
|
||||
BusAccessor() = delete;
|
||||
BusAccessor(TBus& bus, TBusAccessInterface& access) : _bus(bus), _access(access), _extension(access) {}
|
||||
BusAccessor(const BusAccessor&) = delete;
|
||||
BusAccessor(TBus& bus, TBusAccessInterface& access) : _bus(bus), _access(access), _extension(access)
|
||||
{
|
||||
}
|
||||
BusAccessor(const BusAccessor&) = delete;
|
||||
BusAccessor& operator=(const BusAccessor&) = delete;
|
||||
BusAccessor(BusAccessor&& other) : _owner(other.owner), _bus(other.bus), _access(other.access), _extension(other.access) {
|
||||
BusAccessor(BusAccessor&& other)
|
||||
: _owner(other.owner), _bus(other.bus), _access(other.access), _extension(other.access)
|
||||
{
|
||||
other._owner = false;
|
||||
}
|
||||
void release() {
|
||||
if( this->_owner ) {
|
||||
void release()
|
||||
{
|
||||
if (this->_owner) {
|
||||
this->_bus.release();
|
||||
}
|
||||
this->_owner = false;
|
||||
}
|
||||
BusAccessor& operator=(BusAccessor&& other) {
|
||||
BusAccessor& operator=(BusAccessor&& other)
|
||||
{
|
||||
this->release();
|
||||
this->_owner = other._owner;
|
||||
this->_bus = other._bus;
|
||||
this->_access = other._access;
|
||||
this->_owner = other._owner;
|
||||
this->_bus = other._bus;
|
||||
this->_access = other._access;
|
||||
this->_extension = TExtension(this->_access);
|
||||
other._owner = false;
|
||||
other._owner = false;
|
||||
}
|
||||
/*
|
||||
void read() { this->_access.read(this->_bus);}
|
||||
void write() { this->_access.write(this->_bus); }
|
||||
void transmit() { this->_access.transmit(this->_bus); }
|
||||
*/
|
||||
TExtension& extension()
|
||||
{
|
||||
return this->_extension;
|
||||
}
|
||||
/*
|
||||
void read() { this->_access.read(this->_bus);}
|
||||
void write() { this->_access.write(this->_bus); }
|
||||
void transmit() { this->_access.transmit(this->_bus); }
|
||||
*/
|
||||
TExtension& extension() { return this->_extension; }
|
||||
|
||||
~BusAccessor() {
|
||||
~BusAccessor()
|
||||
{
|
||||
this->release();
|
||||
}
|
||||
|
||||
protected:
|
||||
bool _owner = true;
|
||||
TBus& _bus;
|
||||
@@ -108,7 +142,7 @@ protected:
|
||||
// 通信バスの基底インターフェイス
|
||||
struct Bus {
|
||||
public:
|
||||
virtual ~Bus() = default;
|
||||
virtual ~Bus() = default;
|
||||
virtual types::bus_type_t getBusType(void) const = 0;
|
||||
|
||||
// initとreleaseはユーザーは直接呼ばない。 createBus / releaseBus経由で使用する。
|
||||
@@ -116,14 +150,21 @@ public:
|
||||
virtual const BusConfig& getConfig(void) const = 0;
|
||||
|
||||
// バスの初期化
|
||||
virtual error::error_t init(const BusConfig& config) { return error::error_t::NOT_IMPLEMENTED; }
|
||||
virtual error::error_t init(const BusConfig& config)
|
||||
{
|
||||
return error::error_t::NOT_IMPLEMENTED;
|
||||
}
|
||||
// バスの解放
|
||||
virtual error::error_t release(void) { return error::error_t::NOT_IMPLEMENTED; }
|
||||
virtual error::error_t release(void)
|
||||
{
|
||||
return error::error_t::NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
/// @note expectedは参照をサポートしていないのでポインタを含める形とした。
|
||||
virtual m5::stl::expected<Accessor*, m5::hal::error::error_t> beginAccess(const AccessConfig& access_config) = 0;
|
||||
|
||||
virtual error::error_t endAccess(Accessor* Accessor) {
|
||||
virtual error::error_t endAccess(Accessor* Accessor)
|
||||
{
|
||||
if (Accessor && _Accessor.get() == Accessor) {
|
||||
_Accessor.reset(nullptr);
|
||||
return error::error_t::OK;
|
||||
@@ -132,18 +173,25 @@ public:
|
||||
}
|
||||
|
||||
// 無条件でバスをロックしたい場合に使用する
|
||||
virtual m5::stl::expected<void, error::error_t> lock(void) { return m5::stl::make_unexpected(error::error_t::NOT_IMPLEMENTED); }
|
||||
virtual m5::stl::expected<void, error::error_t> unlock(void) { return m5::stl::make_unexpected(error::error_t::NOT_IMPLEMENTED); }
|
||||
virtual m5::stl::expected<void, error::error_t> lock(void)
|
||||
{
|
||||
return m5::stl::make_unexpected(error::error_t::NOT_IMPLEMENTED);
|
||||
}
|
||||
virtual m5::stl::expected<void, error::error_t> unlock(void)
|
||||
{
|
||||
return m5::stl::make_unexpected(error::error_t::NOT_IMPLEMENTED);
|
||||
}
|
||||
|
||||
protected:
|
||||
std::unique_ptr<Accessor> _Accessor;
|
||||
};
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// error::error_t Bus::beginAccess(const Accessor* Accessor) { return (Accessor->getBusType() != getBusType()) ? error::error_t::INVALID_ARGUMENT : error::error_t::OK; }
|
||||
// error::error_t Bus::beginAccess(const Accessor* Accessor) { return (Accessor->getBusType() != getBusType()) ?
|
||||
// error::error_t::INVALID_ARGUMENT : error::error_t::OK; }
|
||||
|
||||
} // namespace bus
|
||||
} // namespace hal
|
||||
} // namespace m5
|
||||
} // namespace bus
|
||||
} // namespace hal
|
||||
} // namespace m5
|
||||
|
||||
#endif
|
||||
|
||||
@@ -10,6 +10,6 @@ const BusConfig& Accessor::getBusConfig(void) const
|
||||
return _bus.getConfig();
|
||||
}
|
||||
|
||||
} // namespace bus
|
||||
} // namespace hal
|
||||
} // namespace m5
|
||||
} // namespace bus
|
||||
} // namespace hal
|
||||
} // namespace m5
|
||||
|
||||
+70
-43
@@ -8,74 +8,101 @@ namespace hal {
|
||||
namespace bus {
|
||||
|
||||
struct I2CBusConfig : public BusConfig {
|
||||
types::bus_type_t getBusType(void) const override { return types::bus_type_t::I2C; };
|
||||
types::bus_type_t getBusType(void) const override
|
||||
{
|
||||
return types::bus_type_t::I2C;
|
||||
};
|
||||
interface::gpio::Pin* pin_scl;
|
||||
interface::gpio::Pin* pin_sda;
|
||||
};
|
||||
|
||||
struct I2CMasterAccessConfig : public AccessConfig {
|
||||
types::bus_type_t getBusType(void) const override { return types::bus_type_t::I2C; };
|
||||
uint32_t freq = 100000;
|
||||
types::bus_type_t getBusType(void) const override
|
||||
{
|
||||
return types::bus_type_t::I2C;
|
||||
};
|
||||
uint32_t freq = 100000;
|
||||
uint32_t timeout_msec = 1000;
|
||||
uint16_t i2c_addr;
|
||||
bool address_is_10bit = false;
|
||||
};
|
||||
|
||||
namespace i2c {
|
||||
struct I2CMasterAccessor : public Accessor
|
||||
struct I2CMasterAccessor : public Accessor {
|
||||
I2CMasterAccessor(Bus& bus, const I2CMasterAccessConfig& access_config)
|
||||
: Accessor{bus}, _access_config{access_config}
|
||||
{
|
||||
I2CMasterAccessor(Bus& bus, const I2CMasterAccessConfig& access_config) : Accessor { bus }, _access_config { access_config } {}
|
||||
types::bus_type_t getBusType(void) const override { return types::bus_type_t::I2C; };
|
||||
const AccessConfig& getAccessConfig(void) const override { return _access_config; }
|
||||
}
|
||||
types::bus_type_t getBusType(void) const override
|
||||
{
|
||||
return types::bus_type_t::I2C;
|
||||
};
|
||||
const AccessConfig& getAccessConfig(void) const override
|
||||
{
|
||||
return _access_config;
|
||||
}
|
||||
|
||||
m5::stl::expected<void, m5::hal::error::error_t> startWrite(void) override;
|
||||
m5::stl::expected<void, m5::hal::error::error_t> startRead(void) override;
|
||||
m5::stl::expected<void, m5::hal::error::error_t> stop(void) override;
|
||||
m5::stl::expected<void, m5::hal::error::error_t> startWrite(void) override;
|
||||
m5::stl::expected<void, m5::hal::error::error_t> startRead(void) override;
|
||||
m5::stl::expected<void, m5::hal::error::error_t> stop(void) override;
|
||||
|
||||
// read with ack
|
||||
m5::stl::expected<size_t, m5::hal::error::error_t> read(uint8_t* data, size_t len) override { return readWithLastNackFlag(data, len, false); };
|
||||
|
||||
// virtual m5::stl::expected<size_t, m5::hal::error::error_t> readLastNack(uint8_t* data, size_t len) { return readWithLastNackFlag(data, len, true); }
|
||||
// virtual m5::stl::expected<size_t, m5::hal::error::error_t> readWithLastNackFlag(uint8_t* data, size_t len, bool last_nack = false) = 0;
|
||||
protected:
|
||||
I2CMasterAccessConfig _access_config;
|
||||
virtual m5::stl::expected<void, m5::hal::error::error_t> sendStartCondition(void);
|
||||
virtual m5::stl::expected<void, m5::hal::error::error_t> sendStopCondition(void);
|
||||
virtual m5::stl::expected<void, m5::hal::error::error_t> sendDummyClockWhileSdaLow(size_t count = 9);
|
||||
virtual m5::stl::expected<void, m5::hal::error::error_t> waitClockStretch(uint_fast16_t msec);
|
||||
// read with ack
|
||||
m5::stl::expected<size_t, m5::hal::error::error_t> read(uint8_t* data, size_t len) override
|
||||
{
|
||||
return readWithLastNackFlag(data, len, false);
|
||||
};
|
||||
|
||||
class SoftwareI2CMasterAccessor : public I2CMasterAccessor
|
||||
// virtual m5::stl::expected<size_t, m5::hal::error::error_t> readLastNack(uint8_t* data, size_t len) { return
|
||||
// readWithLastNackFlag(data, len, true); } virtual m5::stl::expected<size_t, m5::hal::error::error_t>
|
||||
// readWithLastNackFlag(uint8_t* data, size_t len, bool last_nack = false) = 0;
|
||||
protected:
|
||||
I2CMasterAccessConfig _access_config;
|
||||
virtual m5::stl::expected<void, m5::hal::error::error_t> sendStartCondition(void);
|
||||
virtual m5::stl::expected<void, m5::hal::error::error_t> sendStopCondition(void);
|
||||
virtual m5::stl::expected<void, m5::hal::error::error_t> sendDummyClockWhileSdaLow(size_t count = 9);
|
||||
virtual m5::stl::expected<void, m5::hal::error::error_t> waitClockStretch(uint_fast16_t msec);
|
||||
};
|
||||
|
||||
class SoftwareI2CMasterAccessor : public I2CMasterAccessor {
|
||||
public:
|
||||
SoftwareI2CMasterAccessor(Bus& bus, const I2CMasterAccessConfig& access_config)
|
||||
: I2CMasterAccessor{bus, access_config}
|
||||
{
|
||||
public:
|
||||
SoftwareI2CMasterAccessor(Bus& bus, const I2CMasterAccessConfig& access_config) : I2CMasterAccessor { bus, access_config } {}
|
||||
m5::stl::expected<size_t, m5::hal::error::error_t> write(const uint8_t* data, size_t len) override;
|
||||
m5::stl::expected<size_t, m5::hal::error::error_t> readWithLastNackFlag(uint8_t* data, size_t len, bool last_nack = false) override;
|
||||
};
|
||||
}
|
||||
m5::stl::expected<size_t, m5::hal::error::error_t> write(const uint8_t* data, size_t len) override;
|
||||
m5::stl::expected<size_t, m5::hal::error::error_t> readWithLastNackFlag(uint8_t* data, size_t len,
|
||||
bool last_nack = false) override;
|
||||
};
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
struct I2CBus : public Bus {
|
||||
types::bus_type_t getBusType(void) const override { return types::bus_type_t::I2C; };
|
||||
const BusConfig& getConfig(void) const override { return _config; }
|
||||
protected:
|
||||
I2CBusConfig _config;
|
||||
};
|
||||
|
||||
class SoftwareI2CBus : public I2CBus
|
||||
struct I2CBus : public Bus {
|
||||
types::bus_type_t getBusType(void) const override
|
||||
{
|
||||
public:
|
||||
error::error_t init(const BusConfig& config) override;
|
||||
m5::stl::expected<Accessor*, m5::hal::error::error_t> beginAccess(const AccessConfig& access_config) override;
|
||||
return types::bus_type_t::I2C;
|
||||
};
|
||||
const BusConfig& getConfig(void) const override
|
||||
{
|
||||
return _config;
|
||||
}
|
||||
|
||||
m5::stl::expected<I2CBus*, m5::hal::error::error_t> getBus(const I2CBusConfig& config);
|
||||
} // namespace i2c
|
||||
protected:
|
||||
I2CBusConfig _config;
|
||||
};
|
||||
|
||||
class SoftwareI2CBus : public I2CBus {
|
||||
public:
|
||||
error::error_t init(const BusConfig& config) override;
|
||||
m5::stl::expected<Accessor*, m5::hal::error::error_t> beginAccess(const AccessConfig& access_config) override;
|
||||
};
|
||||
|
||||
m5::stl::expected<I2CBus*, m5::hal::error::error_t> getBus(const I2CBusConfig& config);
|
||||
} // namespace i2c
|
||||
|
||||
// static inline bus::I2CBus* createI2CBus(const bus::I2CBusConfig& config) { return i2c::createBus(config); }
|
||||
|
||||
} // namespace bus
|
||||
} // namespace hal
|
||||
} // namespace m5
|
||||
} // namespace bus
|
||||
} // namespace hal
|
||||
} // namespace m5
|
||||
|
||||
#endif
|
||||
|
||||
+158
-173
@@ -2,20 +2,17 @@
|
||||
#include "i2c.hpp"
|
||||
#include "../error.hpp"
|
||||
|
||||
|
||||
namespace m5 {
|
||||
namespace hal {
|
||||
namespace bus {
|
||||
namespace i2c {
|
||||
|
||||
//constexpr uint32_t DELAY_CYCLE{400};
|
||||
// constexpr uint32_t DELAY_CYCLE{400};
|
||||
constexpr uint32_t DELAY_CYCLE{200};
|
||||
|
||||
|
||||
void delayCycle(uint32_t count)
|
||||
{
|
||||
for (uint32_t i = count; i > 0; --i)
|
||||
{
|
||||
for (uint32_t i = count; i > 0; --i) {
|
||||
__asm__ __volatile__("nop");
|
||||
}
|
||||
}
|
||||
@@ -28,15 +25,16 @@ m5::stl::expected<I2CBus*, m5::hal::error::error_t> getBus(const I2CBusConfig& c
|
||||
return &bus;
|
||||
}
|
||||
|
||||
error::error_t SoftwareI2CBus::init(const BusConfig& config) {
|
||||
error::error_t SoftwareI2CBus::init(const BusConfig& config)
|
||||
{
|
||||
if (config.getBusType() != types::bus_type_t::I2C) {
|
||||
M5_LIB_LOGE("SoftwareI2C::init: error %s", __PRETTY_FUNCTION__);
|
||||
return error::error_t::INVALID_ARGUMENT;
|
||||
}
|
||||
_config = static_cast<const I2CBusConfig&>(config);
|
||||
if (_config.pin_scl == nullptr || _config.pin_sda == nullptr) {
|
||||
M5_LIB_LOGE("SoftwareI2C::init: error %s", __PRETTY_FUNCTION__);
|
||||
return error::error_t::INVALID_ARGUMENT;
|
||||
M5_LIB_LOGE("SoftwareI2C::init: error %s", __PRETTY_FUNCTION__);
|
||||
return error::error_t::INVALID_ARGUMENT;
|
||||
}
|
||||
M5_LIB_LOGV("SoftwareI2C::init: ok %s", __PRETTY_FUNCTION__);
|
||||
|
||||
@@ -51,16 +49,17 @@ error::error_t SoftwareI2CBus::init(const BusConfig& config) {
|
||||
return error::error_t::OK;
|
||||
}
|
||||
|
||||
m5::stl::expected<m5::hal::bus::Accessor*, m5::hal::error::error_t> SoftwareI2CBus::beginAccess(const m5::hal::bus::AccessConfig& access_config)
|
||||
m5::stl::expected<m5::hal::bus::Accessor*, m5::hal::error::error_t> SoftwareI2CBus::beginAccess(
|
||||
const m5::hal::bus::AccessConfig& access_config)
|
||||
{
|
||||
/// @TODO ここで排他制御&ロック処理を行うこと。
|
||||
if (_Accessor.get() != nullptr) {
|
||||
M5_LIB_LOGE("SoftwareI2C::beginAccess: error %s", __PRETTY_FUNCTION__);
|
||||
return m5::stl::make_unexpected( m5::hal::error::error_t::INVALID_ARGUMENT );
|
||||
return m5::stl::make_unexpected(m5::hal::error::error_t::INVALID_ARGUMENT);
|
||||
}
|
||||
if (access_config.getBusType() != getBusType()) {
|
||||
M5_LIB_LOGE("SoftwareI2C::beginAccess: error %s", __PRETTY_FUNCTION__);
|
||||
return m5::stl::make_unexpected( m5::hal::error::error_t::INVALID_ARGUMENT );
|
||||
return m5::stl::make_unexpected(m5::hal::error::error_t::INVALID_ARGUMENT);
|
||||
}
|
||||
auto result = new SoftwareI2CMasterAccessor(*this, (I2CMasterAccessConfig&)access_config);
|
||||
_Accessor.reset(result);
|
||||
@@ -76,25 +75,25 @@ m5::stl::expected<void, m5::hal::error::error_t> I2CMasterAccessor::sendDummyClo
|
||||
auto scl = bc.pin_scl;
|
||||
|
||||
/// SDAがLOWになっている場合は処理
|
||||
if (!sda->read())
|
||||
{
|
||||
/// @TODO:ディレイサイクル数を求める仕組みを作っておくこと。
|
||||
int delay_cycle = DELAY_CYCLE;//_nop_wait_w >> 1;
|
||||
if (!sda->read()) {
|
||||
/// @TODO:ディレイサイクル数を求める仕組みを作っておくこと。
|
||||
int delay_cycle = DELAY_CYCLE; //_nop_wait_w >> 1;
|
||||
|
||||
scl->writeLow();
|
||||
sda->writeHigh();
|
||||
delayCycle(delay_cycle);
|
||||
|
||||
// SDAがHIGHになるまでクロック送出しながら待機する。;
|
||||
while (!(sda->read()) && (--count))
|
||||
{
|
||||
scl->writeHigh();
|
||||
delayCycle(delay_cycle);
|
||||
scl->writeLow();
|
||||
sda->writeHigh();
|
||||
delayCycle(delay_cycle);
|
||||
}
|
||||
|
||||
// SDAがHIGHになるまでクロック送出しながら待機する。;
|
||||
while (!(sda->read()) && (--count)) {
|
||||
scl->writeHigh();
|
||||
delayCycle(delay_cycle);
|
||||
scl->writeLow();
|
||||
delayCycle(delay_cycle);
|
||||
}
|
||||
}
|
||||
if (count == 0) {
|
||||
return m5::stl::make_unexpected(error::error_t::I2C_BUS_ERROR);
|
||||
}
|
||||
if (count == 0) { return m5::stl::make_unexpected ( error::error_t::I2C_BUS_ERROR ); }
|
||||
return {};
|
||||
}
|
||||
|
||||
@@ -105,10 +104,10 @@ m5::stl::expected<void, m5::hal::error::error_t> I2CMasterAccessor::sendStartCon
|
||||
auto sda = bc.pin_sda;
|
||||
auto scl = bc.pin_scl;
|
||||
|
||||
/// @TODO:ディレイサイクル数を求める仕組みを作っておくこと。
|
||||
int delay_cycle = DELAY_CYCLE;//_nop_wait_w >> 1;
|
||||
/// @TODO:ディレイサイクル数を求める仕組みを作っておくこと。
|
||||
int delay_cycle = DELAY_CYCLE; //_nop_wait_w >> 1;
|
||||
|
||||
// start condition
|
||||
// start condition
|
||||
scl->writeHigh();
|
||||
delayCycle(delay_cycle);
|
||||
sda->writeLow();
|
||||
@@ -120,46 +119,44 @@ int delay_cycle = DELAY_CYCLE;//_nop_wait_w >> 1;
|
||||
|
||||
m5::stl::expected<void, m5::hal::error::error_t> I2CMasterAccessor::sendStopCondition(void)
|
||||
{
|
||||
auto bc = static_cast<const I2CBusConfig&>(getBusConfig());
|
||||
auto bc = static_cast<const I2CBusConfig&>(getBusConfig());
|
||||
auto sda = bc.pin_sda;
|
||||
auto scl = bc.pin_scl;
|
||||
|
||||
/// @TODO:ディレイサイクル数を求める仕組みを作っておくこと。
|
||||
int delay_cycle = DELAY_CYCLE;//_nop_wait_w >> 1;
|
||||
/// @TODO:ディレイサイクル数を求める仕組みを作っておくこと。
|
||||
int delay_cycle = DELAY_CYCLE; //_nop_wait_w >> 1;
|
||||
|
||||
auto res = sendDummyClockWhileSdaLow();
|
||||
if (res.has_value()) {
|
||||
// stop condition
|
||||
sda->writeLow();
|
||||
scl->writeHigh();
|
||||
delayCycle(delay_cycle);
|
||||
sda->writeHigh();
|
||||
// stop condition
|
||||
sda->writeLow();
|
||||
scl->writeHigh();
|
||||
delayCycle(delay_cycle);
|
||||
sda->writeHigh();
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
m5::stl::expected<void, m5::hal::error::error_t> I2CMasterAccessor::waitClockStretch(uint_fast16_t msec)
|
||||
{
|
||||
auto bc = static_cast<const I2CBusConfig&>(getBusConfig());
|
||||
auto bc = static_cast<const I2CBusConfig&>(getBusConfig());
|
||||
auto scl = bc.pin_scl;
|
||||
auto ms = m5::utility::millis();
|
||||
do
|
||||
{
|
||||
std::this_thread::yield();
|
||||
if (scl->read())
|
||||
{
|
||||
return {};
|
||||
}
|
||||
auto ms = m5::utility::millis();
|
||||
do {
|
||||
std::this_thread::yield();
|
||||
if (scl->read()) {
|
||||
return {};
|
||||
}
|
||||
} while ((m5::utility::millis() - ms) < msec);
|
||||
return m5::stl::make_unexpected ( error::error_t::I2C_BUS_ERROR );
|
||||
return m5::stl::make_unexpected(error::error_t::I2C_BUS_ERROR);
|
||||
}
|
||||
|
||||
m5::stl::expected<void, m5::hal::error::error_t> I2CMasterAccessor::startWrite(void)
|
||||
{
|
||||
auto ac = static_cast<const I2CMasterAccessConfig&>(getAccessConfig());
|
||||
sendStartCondition();
|
||||
uint8_t data[] = { (uint8_t)(ac.i2c_addr << 1) };
|
||||
auto result = write(data, sizeof(data));
|
||||
uint8_t data[] = {(uint8_t)(ac.i2c_addr << 1)};
|
||||
auto result = write(data, sizeof(data));
|
||||
if (result.has_value()) return {};
|
||||
return m5::stl::make_unexpected(result.error());
|
||||
}
|
||||
@@ -168,8 +165,8 @@ m5::stl::expected<void, m5::hal::error::error_t> I2CMasterAccessor::startRead(vo
|
||||
{
|
||||
auto ac = static_cast<const I2CMasterAccessConfig&>(getAccessConfig());
|
||||
sendStartCondition();
|
||||
uint8_t data[] = { (uint8_t)(ac.i2c_addr << 1 | 1) };
|
||||
auto result = write(data, sizeof(data));
|
||||
uint8_t data[] = {(uint8_t)(ac.i2c_addr << 1 | 1)};
|
||||
auto result = write(data, sizeof(data));
|
||||
if (result.has_value()) return {};
|
||||
return m5::stl::make_unexpected(result.error());
|
||||
}
|
||||
@@ -187,80 +184,75 @@ m5::stl::expected<size_t, m5::hal::error::error_t> SoftwareI2CMasterAccessor::wr
|
||||
auto scl = bc.pin_scl;
|
||||
auto sda = bc.pin_sda;
|
||||
|
||||
/// @TODO:ディレイサイクル数を求める仕組みを作っておくこと。
|
||||
int delay_cycle = DELAY_CYCLE;//_nop_wait_w >> 1;
|
||||
/// @TODO:ディレイサイクル数を求める仕組みを作っておくこと。
|
||||
int delay_cycle = DELAY_CYCLE; //_nop_wait_w >> 1;
|
||||
int_fast16_t dc0 = (delay_cycle) >> 2;
|
||||
int_fast16_t dc1 = delay_cycle - dc0;
|
||||
size_t result = 0;
|
||||
do
|
||||
{
|
||||
uint_fast8_t mask = 0x80;
|
||||
uint_fast8_t d = *data++;
|
||||
size_t result = 0;
|
||||
do {
|
||||
uint_fast8_t mask = 0x80;
|
||||
uint_fast8_t d = *data++;
|
||||
|
||||
// 最初の1bitの送信
|
||||
sda->write((bool)(d & mask));
|
||||
delayCycle(dc0);
|
||||
scl->writeHigh();
|
||||
delayCycle(dc1);
|
||||
// クロックストレッチの判定と待機;
|
||||
if (!scl->read())
|
||||
{ // タイムアウト時間までクロックストレッチが解除されるのを待つ;
|
||||
auto result = waitClockStretch(ac.timeout_msec);
|
||||
if (!result)
|
||||
{
|
||||
M5_LIB_LOGE("TIMEOUT");
|
||||
sda->writeHigh();
|
||||
return m5::stl::make_unexpected ( error::error_t::TIMEOUT_ERROR );
|
||||
}
|
||||
}
|
||||
|
||||
mask >>= 1;
|
||||
do
|
||||
{ // 2bit~8bit目の送信;
|
||||
scl->writeLow();
|
||||
// 最初の1bitの送信
|
||||
sda->write((bool)(d & mask));
|
||||
delayCycle(dc0);
|
||||
scl->writeHigh();
|
||||
delayCycle(dc1);
|
||||
mask >>= 1;
|
||||
} while (mask);
|
||||
|
||||
// ACK応答チェック;
|
||||
scl->writeLow(); // SCL lo
|
||||
sda->writeHigh(); // SDA hi
|
||||
delayCycle(dc1);
|
||||
scl->writeHigh(); // hi
|
||||
delayCycle(dc0);
|
||||
|
||||
// クロックストレッチの判定と待機;
|
||||
if (!scl->read())
|
||||
{ // タイムアウト時間までクロックストレッチが解除されるのを待つ;
|
||||
auto result = waitClockStretch(ac.timeout_msec);
|
||||
if (!result)
|
||||
{
|
||||
M5_LIB_LOGE("TIMEOUT2");
|
||||
return m5::stl::make_unexpected ( error::error_t::TIMEOUT_ERROR );
|
||||
// クロックストレッチの判定と待機;
|
||||
if (!scl->read()) { // タイムアウト時間までクロックストレッチが解除されるのを待つ;
|
||||
auto result = waitClockStretch(ac.timeout_msec);
|
||||
if (!result) {
|
||||
M5_LIB_LOGE("TIMEOUT");
|
||||
sda->writeHigh();
|
||||
return m5::stl::make_unexpected(error::error_t::TIMEOUT_ERROR);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (sda->read())
|
||||
{ // ToDo:ACK応答がない場合の処理;
|
||||
M5_LIB_LOGE("NO_ACK");
|
||||
{
|
||||
// re-init?
|
||||
scl->writeLow();
|
||||
sda->writeLow();
|
||||
scl->writeHigh();
|
||||
delayCycle(128);
|
||||
sda->writeHigh();
|
||||
}
|
||||
return m5::stl::make_unexpected ( error::error_t::I2C_NO_ACK );
|
||||
}
|
||||
scl->writeLow();
|
||||
|
||||
mask >>= 1;
|
||||
do { // 2bit~8bit目の送信;
|
||||
scl->writeLow();
|
||||
sda->write((bool)(d & mask));
|
||||
delayCycle(dc0);
|
||||
scl->writeHigh();
|
||||
delayCycle(dc1);
|
||||
mask >>= 1;
|
||||
} while (mask);
|
||||
|
||||
// ACK応答チェック;
|
||||
scl->writeLow(); // SCL lo
|
||||
sda->writeHigh(); // SDA hi
|
||||
delayCycle(dc1);
|
||||
scl->writeHigh(); // hi
|
||||
delayCycle(dc0);
|
||||
|
||||
// クロックストレッチの判定と待機;
|
||||
if (!scl->read()) { // タイムアウト時間までクロックストレッチが解除されるのを待つ;
|
||||
auto result = waitClockStretch(ac.timeout_msec);
|
||||
if (!result) {
|
||||
M5_LIB_LOGE("TIMEOUT2");
|
||||
return m5::stl::make_unexpected(error::error_t::TIMEOUT_ERROR);
|
||||
}
|
||||
}
|
||||
if (sda->read()) { // ToDo:ACK応答がない場合の処理;
|
||||
M5_LIB_LOGE("NO_ACK");
|
||||
{
|
||||
// re-init?
|
||||
scl->writeLow();
|
||||
sda->writeLow();
|
||||
scl->writeHigh();
|
||||
delayCycle(128);
|
||||
sda->writeHigh();
|
||||
}
|
||||
return m5::stl::make_unexpected(error::error_t::I2C_NO_ACK);
|
||||
}
|
||||
scl->writeLow();
|
||||
} while (++result < len);
|
||||
return result;
|
||||
}
|
||||
|
||||
m5::stl::expected<size_t, m5::hal::error::error_t> SoftwareI2CMasterAccessor::readWithLastNackFlag(uint8_t* data, size_t len, bool last_nack)
|
||||
m5::stl::expected<size_t, m5::hal::error::error_t> SoftwareI2CMasterAccessor::readWithLastNackFlag(uint8_t* data,
|
||||
size_t len,
|
||||
bool last_nack)
|
||||
{
|
||||
auto bc = static_cast<const I2CBusConfig&>(getBusConfig());
|
||||
auto ac = static_cast<const I2CMasterAccessConfig&>(getAccessConfig());
|
||||
@@ -268,83 +260,76 @@ m5::stl::expected<size_t, m5::hal::error::error_t> SoftwareI2CMasterAccessor::re
|
||||
auto scl = bc.pin_scl;
|
||||
auto sda = bc.pin_sda;
|
||||
|
||||
/// @TODO:ディレイサイクル数を求める仕組みを作っておくこと。
|
||||
int delay_cycle = DELAY_CYCLE;//_nop_wait_w;
|
||||
/// @TODO:ディレイサイクル数を求める仕組みを作っておくこと。
|
||||
int delay_cycle = DELAY_CYCLE; //_nop_wait_w;
|
||||
int_fast16_t dc0 = (delay_cycle) >> 1;
|
||||
int_fast16_t dc1 = delay_cycle - dc0;
|
||||
size_t result = 0;
|
||||
do
|
||||
{
|
||||
// 最初の1bitの受信
|
||||
sda->writeHigh();
|
||||
size_t result = 0;
|
||||
do {
|
||||
// 最初の1bitの受信
|
||||
sda->writeHigh();
|
||||
|
||||
delayCycle(dc0);
|
||||
scl->writeHigh();
|
||||
delayCycle(dc1);
|
||||
|
||||
// クロックストレッチの判定と待機;
|
||||
if (!scl->read())
|
||||
{ // タイムアウト時間までクロックストレッチが解除されるのを待つ;
|
||||
if (!waitClockStretch(ac.timeout_msec))
|
||||
{
|
||||
return m5::stl::make_unexpected ( error::error_t::TIMEOUT_ERROR );
|
||||
}
|
||||
}
|
||||
|
||||
uint_fast8_t mask = 0x80;
|
||||
uint_fast8_t byte = sda->read() ? mask : 0;
|
||||
mask >>= 1;
|
||||
|
||||
do
|
||||
{
|
||||
scl->writeLow();
|
||||
delayCycle(dc0);
|
||||
scl->writeHigh();
|
||||
delayCycle(dc1);
|
||||
|
||||
if (sda->read())
|
||||
{
|
||||
byte |= mask;
|
||||
// クロックストレッチの判定と待機;
|
||||
if (!scl->read()) { // タイムアウト時間までクロックストレッチが解除されるのを待つ;
|
||||
if (!waitClockStretch(ac.timeout_msec)) {
|
||||
return m5::stl::make_unexpected(error::error_t::TIMEOUT_ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
uint_fast8_t mask = 0x80;
|
||||
uint_fast8_t byte = sda->read() ? mask : 0;
|
||||
mask >>= 1;
|
||||
} while (mask);
|
||||
scl->writeLow();
|
||||
/// ACKを返す (ただし、データ末尾かつNACK指定がある場合はACKを返さない);
|
||||
if ((++result < len) || !last_nack)
|
||||
{
|
||||
sda->writeLow();
|
||||
}
|
||||
delayCycle(dc0);
|
||||
scl->writeHigh();
|
||||
delayCycle(dc1);
|
||||
scl->writeLow();
|
||||
*data++ = byte;
|
||||
|
||||
do {
|
||||
scl->writeLow();
|
||||
delayCycle(dc0);
|
||||
scl->writeHigh();
|
||||
delayCycle(dc1);
|
||||
|
||||
if (sda->read()) {
|
||||
byte |= mask;
|
||||
}
|
||||
mask >>= 1;
|
||||
} while (mask);
|
||||
scl->writeLow();
|
||||
/// ACKを返す (ただし、データ末尾かつNACK指定がある場合はACKを返さない);
|
||||
if ((++result < len) || !last_nack) {
|
||||
sda->writeLow();
|
||||
}
|
||||
delayCycle(dc0);
|
||||
scl->writeHigh();
|
||||
delayCycle(dc1);
|
||||
scl->writeLow();
|
||||
*data++ = byte;
|
||||
} while (result < len);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// I2CBus* createBus(const I2CBusConfig& config)
|
||||
// {
|
||||
// static SoftwareI2CBus i2c_bus;
|
||||
// return &i2c_bus;
|
||||
// }
|
||||
|
||||
// error::error_t SoftwareI2CMasterAccessor::init(const interface::bus::BusConfig& config) { return error::error_t::NOT_IMPLEMENTED; }
|
||||
// error::error_t SoftwareI2CMasterAccessor::release(void) { return error::error_t::NOT_IMPLEMENTED; }
|
||||
// error::error_t SoftwareI2CMasterAccessor::start(void) { return error::error_t::NOT_IMPLEMENTED; }
|
||||
// error::error_t SoftwareI2CMasterAccessor::stop(void) { return error::error_t::NOT_IMPLEMENTED; }
|
||||
// error::error_t SoftwareI2CMasterAccessor::lock(void) { return error::error_t::NOT_IMPLEMENTED; }
|
||||
// error::error_t SoftwareI2CMasterAccessor::unlock(void) { return error::error_t::NOT_IMPLEMENTED; }
|
||||
// error::error_t SoftwareI2CMasterAccessor::beginAccess(interface::bus::Accessor* Accessor) { return error::error_t::NOT_IMPLEMENTED; }
|
||||
// error::error_t SoftwareI2CMasterAccessor::endAccess(void) { return error::error_t::NOT_IMPLEMENTED; }
|
||||
// error::error_t SoftwareI2CMasterAccessor::setFrequency(uint32_t freq) { return error::error_t::NOT_IMPLEMENTED; }
|
||||
// error::error_t SoftwareI2CMasterAccessor::read(uint8_t* data, size_t len, interface::io::AsyncResult* async) { return error::error_t::NOT_IMPLEMENTED; }
|
||||
// error::error_t SoftwareI2CMasterAccessor::write(const uint8_t* data, size_t len, interface::io::AsyncResult* async) { return error::error_t::NOT_IMPLEMENTED; }
|
||||
// error::error_t SoftwareI2CMasterAccessor::init(const interface::bus::BusConfig& config) { return
|
||||
// error::error_t::NOT_IMPLEMENTED; } error::error_t SoftwareI2CMasterAccessor::release(void) { return
|
||||
// error::error_t::NOT_IMPLEMENTED; } error::error_t SoftwareI2CMasterAccessor::start(void) { return
|
||||
// error::error_t::NOT_IMPLEMENTED; } error::error_t SoftwareI2CMasterAccessor::stop(void) { return
|
||||
// error::error_t::NOT_IMPLEMENTED; } error::error_t SoftwareI2CMasterAccessor::lock(void) { return
|
||||
// error::error_t::NOT_IMPLEMENTED; } error::error_t SoftwareI2CMasterAccessor::unlock(void) { return
|
||||
// error::error_t::NOT_IMPLEMENTED; } error::error_t SoftwareI2CMasterAccessor::beginAccess(interface::bus::Accessor*
|
||||
// Accessor) { return error::error_t::NOT_IMPLEMENTED; } error::error_t SoftwareI2CMasterAccessor::endAccess(void) {
|
||||
// return error::error_t::NOT_IMPLEMENTED; } error::error_t SoftwareI2CMasterAccessor::setFrequency(uint32_t freq) {
|
||||
// return error::error_t::NOT_IMPLEMENTED; } error::error_t SoftwareI2CMasterAccessor::read(uint8_t* data, size_t len,
|
||||
// interface::io::AsyncResult* async) { return error::error_t::NOT_IMPLEMENTED; } error::error_t
|
||||
// SoftwareI2CMasterAccessor::write(const uint8_t* data, size_t len, interface::io::AsyncResult* async) { return
|
||||
// error::error_t::NOT_IMPLEMENTED; }
|
||||
|
||||
|
||||
} // namespace i2c
|
||||
} // namespace bus
|
||||
} // namespace hal
|
||||
} // namespace m5
|
||||
} // namespace i2c
|
||||
} // namespace bus
|
||||
} // namespace hal
|
||||
} // namespace m5
|
||||
|
||||
+89
-67
@@ -6,110 +6,132 @@
|
||||
namespace m5 {
|
||||
namespace hal {
|
||||
namespace bus {
|
||||
|
||||
|
||||
/// @brief SPIバスの設定
|
||||
/// @details 標準的なSPIだけでなく、QSPI,OSPIの設定も可能となっている
|
||||
struct SPIBusConfig : public BusConfig {
|
||||
virtual ~SPIBusConfig() = default;
|
||||
types::bus_type_t getBusType(void) const override { return types::bus_type_t::SPI; };
|
||||
types::bus_type_t getBusType(void) const override
|
||||
{
|
||||
return types::bus_type_t::SPI;
|
||||
};
|
||||
union {
|
||||
interface::gpio::Pin* pins[9];
|
||||
struct {
|
||||
interface::gpio::Pin* pin_clk;
|
||||
interface::gpio::Pin* pin_dc;
|
||||
interface::gpio::Pin* pin_mosi; // data0
|
||||
interface::gpio::Pin* pin_miso; // data1
|
||||
interface::gpio::Pin* pin_d2; // data2
|
||||
interface::gpio::Pin* pin_d3; // data3
|
||||
interface::gpio::Pin* pin_d4; // data4
|
||||
interface::gpio::Pin* pin_d5; // data5
|
||||
interface::gpio::Pin* pin_d6; // data6
|
||||
interface::gpio::Pin* pin_d7; // data7
|
||||
interface::gpio::Pin* pin_mosi; // data0
|
||||
interface::gpio::Pin* pin_miso; // data1
|
||||
interface::gpio::Pin* pin_d2; // data2
|
||||
interface::gpio::Pin* pin_d3; // data3
|
||||
interface::gpio::Pin* pin_d4; // data4
|
||||
interface::gpio::Pin* pin_d5; // data5
|
||||
interface::gpio::Pin* pin_d6; // data6
|
||||
interface::gpio::Pin* pin_d7; // data7
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
enum class SpiDataMode {
|
||||
spi_halfduplex, // 半二重通信
|
||||
spi_fullduplex,
|
||||
spi_halfduplex_with_dc_pin, // 半二重通信+DCピン
|
||||
spi_fullduplex_with_dc_pin, // 全二重通信+DCピン
|
||||
spi_halfduplex_with_dc_bit, // 半二重通信+DCビット(9ビットSPI)
|
||||
spi_fullduplex_with_dc_bit, // 全二重通信+DCビット(9ビットSPI)
|
||||
spi_dual_output,
|
||||
spi_dual_io,
|
||||
spi_quad_output,
|
||||
spi_quad_io,
|
||||
spi_octal_output,
|
||||
spi_octal_io,
|
||||
spi_halfduplex, // 半二重通信
|
||||
spi_fullduplex,
|
||||
spi_halfduplex_with_dc_pin, // 半二重通信+DCピン
|
||||
spi_fullduplex_with_dc_pin, // 全二重通信+DCピン
|
||||
spi_halfduplex_with_dc_bit, // 半二重通信+DCビット(9ビットSPI)
|
||||
spi_fullduplex_with_dc_bit, // 全二重通信+DCビット(9ビットSPI)
|
||||
spi_dual_output,
|
||||
spi_dual_io,
|
||||
spi_quad_output,
|
||||
spi_quad_io,
|
||||
spi_octal_output,
|
||||
spi_octal_io,
|
||||
};
|
||||
typedef SpiDataMode spi_data_mode_t;
|
||||
|
||||
struct SPIMasterAccessConfig : public AccessConfig {
|
||||
virtual ~SPIMasterAccessConfig() = default;
|
||||
types::bus_type_t getBusType(void) const override { return types::bus_type_t::SPI; };
|
||||
types::bus_type_t getBusType(void) const override
|
||||
{
|
||||
return types::bus_type_t::SPI;
|
||||
};
|
||||
interface::gpio::Pin* pin_cs;
|
||||
uint32_t freq;
|
||||
spi_data_mode_t spi_data_mode;
|
||||
struct {
|
||||
uint8_t spi_mode:2;
|
||||
uint8_t spi_order:1;
|
||||
uint8_t spi_mode : 2;
|
||||
uint8_t spi_order : 1;
|
||||
};
|
||||
uint8_t spi_command_length = 0; // コマンド部のビット長
|
||||
uint8_t spi_address_length = 0; // アドレス部のビット長
|
||||
uint8_t spi_dummy_cycle = 0; // アドレスからデータへ移る際のダミーサイクル数
|
||||
uint8_t spi_command_length = 0; // コマンド部のビット長
|
||||
uint8_t spi_address_length = 0; // アドレス部のビット長
|
||||
uint8_t spi_dummy_cycle = 0; // アドレスからデータへ移る際のダミーサイクル数
|
||||
};
|
||||
|
||||
namespace spi {
|
||||
struct SPIMasterAccessor : public Accessor
|
||||
struct SPIMasterAccessor : public Accessor {
|
||||
SPIMasterAccessor(Bus& bus, const SPIMasterAccessConfig& access_config)
|
||||
: Accessor{bus}, _access_config{access_config}
|
||||
{
|
||||
SPIMasterAccessor(Bus& bus, const SPIMasterAccessConfig& access_config) : Accessor { bus }, _access_config { access_config } {}
|
||||
types::bus_type_t getBusType(void) const override { return types::bus_type_t::SPI; };
|
||||
const AccessConfig& getAccessConfig(void) const override { return _access_config; }
|
||||
|
||||
virtual m5::stl::expected<size_t, m5::hal::error::error_t> writeCommand(const uint8_t* data, size_t len);
|
||||
virtual m5::stl::expected<size_t, m5::hal::error::error_t> writeCommandData(const uint8_t* data, size_t len);
|
||||
virtual m5::stl::expected<void, m5::hal::error::error_t> sendDummyClock(size_t count);
|
||||
virtual m5::stl::expected<void, m5::hal::error::error_t> cs_control(bool cs_level);
|
||||
protected:
|
||||
SPIMasterAccessConfig _access_config;
|
||||
};
|
||||
|
||||
class SoftwareSPIMasterAccessor : public SPIMasterAccessor
|
||||
}
|
||||
types::bus_type_t getBusType(void) const override
|
||||
{
|
||||
public:
|
||||
SoftwareSPIMasterAccessor(Bus& bus, const SPIMasterAccessConfig& access_config) : SPIMasterAccessor { bus, access_config } {}
|
||||
m5::stl::expected<size_t, m5::hal::error::error_t> read(uint8_t* data, size_t len) override;
|
||||
m5::stl::expected<size_t, m5::hal::error::error_t> write(const uint8_t* data, size_t len) override;
|
||||
return types::bus_type_t::SPI;
|
||||
};
|
||||
const AccessConfig& getAccessConfig(void) const override
|
||||
{
|
||||
return _access_config;
|
||||
}
|
||||
|
||||
virtual m5::stl::expected<size_t, m5::hal::error::error_t> writeCommand(const uint8_t* data, size_t len);
|
||||
virtual m5::stl::expected<size_t, m5::hal::error::error_t> writeCommandData(const uint8_t* data, size_t len);
|
||||
virtual m5::stl::expected<void, m5::hal::error::error_t> sendDummyClock(size_t count);
|
||||
virtual m5::stl::expected<void, m5::hal::error::error_t> cs_control(bool cs_level);
|
||||
|
||||
protected:
|
||||
SPIMasterAccessConfig _access_config;
|
||||
};
|
||||
|
||||
class SoftwareSPIMasterAccessor : public SPIMasterAccessor {
|
||||
public:
|
||||
SoftwareSPIMasterAccessor(Bus& bus, const SPIMasterAccessConfig& access_config)
|
||||
: SPIMasterAccessor{bus, access_config}
|
||||
{
|
||||
}
|
||||
m5::stl::expected<size_t, m5::hal::error::error_t> read(uint8_t* data, size_t len) override;
|
||||
m5::stl::expected<size_t, m5::hal::error::error_t> write(const uint8_t* data, size_t len) override;
|
||||
};
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
struct SPIBus : public Bus {
|
||||
types::bus_type_t getBusType(void) const override { return types::bus_type_t::SPI; };
|
||||
const BusConfig& getConfig(void) const override { return _config; }
|
||||
|
||||
// virtual SPIMasterAccessor* beginAccess(const SPIMasterAccessConfig& access_config) = 0;
|
||||
// Accessor* beginAccess(const AccessConfig& access_config) override { return beginAccess((const SPIMasterAccessConfig&)access_config); }
|
||||
protected:
|
||||
SPIBusConfig _config;
|
||||
};
|
||||
|
||||
class SoftwareSPIBus : public SPIBus
|
||||
struct SPIBus : public Bus {
|
||||
types::bus_type_t getBusType(void) const override
|
||||
{
|
||||
public:
|
||||
error::error_t init(const BusConfig& config) override;
|
||||
m5::stl::expected<Accessor*, m5::hal::error::error_t> beginAccess(const AccessConfig& access_config) override;
|
||||
// SPIMasterAccessor* beginAccess(const SPIMasterAccessConfig& access_config) override;
|
||||
return types::bus_type_t::SPI;
|
||||
};
|
||||
const BusConfig& getConfig(void) const override
|
||||
{
|
||||
return _config;
|
||||
}
|
||||
|
||||
m5::stl::expected<SPIBus*, m5::hal::error::error_t> getBus(const SPIBusConfig& config);
|
||||
// SPIBus* createBus(const SPIBusConfig& config); // { return spi::createBus(config); }
|
||||
} // namespace spi
|
||||
// virtual SPIMasterAccessor* beginAccess(const SPIMasterAccessConfig& access_config) = 0;
|
||||
// Accessor* beginAccess(const AccessConfig& access_config) override { return beginAccess((const
|
||||
// SPIMasterAccessConfig&)access_config); }
|
||||
protected:
|
||||
SPIBusConfig _config;
|
||||
};
|
||||
|
||||
class SoftwareSPIBus : public SPIBus {
|
||||
public:
|
||||
error::error_t init(const BusConfig& config) override;
|
||||
m5::stl::expected<Accessor*, m5::hal::error::error_t> beginAccess(const AccessConfig& access_config) override;
|
||||
// SPIMasterAccessor* beginAccess(const SPIMasterAccessConfig& access_config) override;
|
||||
};
|
||||
|
||||
} // namespace bus
|
||||
} // namespace hal
|
||||
} // namespace m5
|
||||
m5::stl::expected<SPIBus*, m5::hal::error::error_t> getBus(const SPIBusConfig& config);
|
||||
// SPIBus* createBus(const SPIBusConfig& config); // { return spi::createBus(config); }
|
||||
} // namespace spi
|
||||
|
||||
} // namespace bus
|
||||
} // namespace hal
|
||||
} // namespace m5
|
||||
|
||||
#endif
|
||||
|
||||
+26
-25
@@ -4,7 +4,7 @@
|
||||
namespace m5 {
|
||||
namespace hal {
|
||||
namespace bus {
|
||||
namespace spi {
|
||||
namespace spi {
|
||||
|
||||
m5::stl::expected<SPIBus*, m5::hal::error::error_t> getBus(const SPIBusConfig& config)
|
||||
{
|
||||
@@ -14,7 +14,8 @@ m5::stl::expected<SPIBus*, m5::hal::error::error_t> getBus(const SPIBusConfig& c
|
||||
return &spi_bus;
|
||||
}
|
||||
|
||||
error::error_t SoftwareSPIBus::init(const BusConfig& config) {
|
||||
error::error_t SoftwareSPIBus::init(const BusConfig& config)
|
||||
{
|
||||
if (config.getBusType() != types::bus_type_t::SPI) {
|
||||
M5_LIB_LOGE("SoftwareSPI::init: error %s", __PRETTY_FUNCTION__);
|
||||
return error::error_t::INVALID_ARGUMENT;
|
||||
@@ -56,8 +57,8 @@ m5::stl::expected<Accessor*, m5::hal::error::error_t> SoftwareSPIBus::beginAcces
|
||||
m5::stl::expected<void, m5::hal::error::error_t> SPIMasterAccessor::sendDummyClock(size_t count)
|
||||
{
|
||||
if (count) {
|
||||
auto bc = static_cast<const SPIBusConfig&>(getBusConfig());
|
||||
auto ac = static_cast<const SPIMasterAccessConfig&>(getAccessConfig());
|
||||
auto bc = static_cast<const SPIBusConfig&>(getBusConfig());
|
||||
auto ac = static_cast<const SPIMasterAccessConfig&>(getAccessConfig());
|
||||
auto cpol = (ac.spi_mode & 2);
|
||||
auto sclk = bc.pin_clk;
|
||||
do {
|
||||
@@ -70,7 +71,7 @@ m5::stl::expected<void, m5::hal::error::error_t> SPIMasterAccessor::sendDummyClo
|
||||
|
||||
m5::stl::expected<size_t, m5::hal::error::error_t> SPIMasterAccessor::writeCommand(const uint8_t* data, size_t len)
|
||||
{
|
||||
auto bc = static_cast<const SPIBusConfig&>(getBusConfig());
|
||||
auto bc = static_cast<const SPIBusConfig&>(getBusConfig());
|
||||
auto pin_dc = bc.pin_dc;
|
||||
if (pin_dc) pin_dc->write(false);
|
||||
auto res = write(data, len);
|
||||
@@ -80,9 +81,9 @@ m5::stl::expected<size_t, m5::hal::error::error_t> SPIMasterAccessor::writeComma
|
||||
|
||||
m5::stl::expected<size_t, m5::hal::error::error_t> SPIMasterAccessor::writeCommandData(const uint8_t* data, size_t len)
|
||||
{
|
||||
auto bc = static_cast<const SPIBusConfig&>(getBusConfig());
|
||||
auto pin_dc = bc.pin_dc;
|
||||
auto ac = static_cast<const SPIMasterAccessConfig&>(getAccessConfig());
|
||||
auto bc = static_cast<const SPIBusConfig&>(getBusConfig());
|
||||
auto pin_dc = bc.pin_dc;
|
||||
auto ac = static_cast<const SPIMasterAccessConfig&>(getAccessConfig());
|
||||
auto cmd_len = (ac.spi_command_length >> 3);
|
||||
if (cmd_len) {
|
||||
if (pin_dc) pin_dc->write(false);
|
||||
@@ -92,8 +93,10 @@ m5::stl::expected<size_t, m5::hal::error::error_t> SPIMasterAccessor::writeComma
|
||||
if (pin_dc) pin_dc->write(true);
|
||||
if (!res || datalen == 0) return res;
|
||||
res = write(data, datalen);
|
||||
if (!res) { return res; }
|
||||
return len;
|
||||
if (!res) {
|
||||
return res;
|
||||
}
|
||||
return len;
|
||||
}
|
||||
return write(data, len);
|
||||
}
|
||||
@@ -107,7 +110,7 @@ m5::stl::expected<void, m5::hal::error::error_t> SPIMasterAccessor::cs_control(b
|
||||
|
||||
m5::stl::expected<size_t, m5::hal::error::error_t> SoftwareSPIMasterAccessor::read(uint8_t* data, size_t len)
|
||||
{
|
||||
return m5::stl::make_unexpected ( error::error_t::NOT_IMPLEMENTED );
|
||||
return m5::stl::make_unexpected(error::error_t::NOT_IMPLEMENTED);
|
||||
}
|
||||
|
||||
m5::stl::expected<size_t, m5::hal::error::error_t> SoftwareSPIMasterAccessor::write(const uint8_t* data, size_t len)
|
||||
@@ -122,23 +125,21 @@ m5::stl::expected<size_t, m5::hal::error::error_t> SoftwareSPIMasterAccessor::wr
|
||||
auto mosi = bc.pin_mosi;
|
||||
|
||||
size_t result = 0;
|
||||
do
|
||||
{
|
||||
uint_fast8_t mask = 0x80;
|
||||
uint_fast8_t d = *data++;
|
||||
do
|
||||
{
|
||||
mosi->write(d & mask);
|
||||
sclk->write(flip);
|
||||
sclk->write(!flip);
|
||||
} while (mask >>= 1);
|
||||
do {
|
||||
uint_fast8_t mask = 0x80;
|
||||
uint_fast8_t d = *data++;
|
||||
do {
|
||||
mosi->write(d & mask);
|
||||
sclk->write(flip);
|
||||
sclk->write(!flip);
|
||||
} while (mask >>= 1);
|
||||
} while (++result < len);
|
||||
sclk->write(cpol);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
} // namespace spi
|
||||
} // namespace bus
|
||||
} // namespace hal
|
||||
} // namespace m5
|
||||
} // namespace spi
|
||||
} // namespace bus
|
||||
} // namespace hal
|
||||
} // namespace m5
|
||||
|
||||
+18
-16
@@ -9,27 +9,29 @@ namespace hal {
|
||||
namespace error {
|
||||
|
||||
enum class ErrorType : int8_t {
|
||||
ASYNC_RUNNING = 1,
|
||||
OK = 0,
|
||||
UNKNOWN_ERROR = -1,
|
||||
TIMEOUT_ERROR = -2,
|
||||
INVALID_ARGUMENT = -3,
|
||||
NOT_IMPLEMENTED = -4,
|
||||
I2C_BUS_ERROR = -5,
|
||||
I2C_NO_ACK = -6,
|
||||
// @ TODO エラーコード細分化する
|
||||
ASYNC_RUNNING = 1,
|
||||
OK = 0,
|
||||
UNKNOWN_ERROR = -1,
|
||||
TIMEOUT_ERROR = -2,
|
||||
INVALID_ARGUMENT = -3,
|
||||
NOT_IMPLEMENTED = -4,
|
||||
I2C_BUS_ERROR = -5,
|
||||
I2C_NO_ACK = -6,
|
||||
// @ TODO エラーコード細分化する
|
||||
};
|
||||
using error_t = ErrorType;
|
||||
|
||||
constexpr bool isError(const error_t e) {
|
||||
return e < error_t::OK;
|
||||
constexpr bool isError(const error_t e)
|
||||
{
|
||||
return e < error_t::OK;
|
||||
}
|
||||
constexpr bool isOk(const error_t e) {
|
||||
return e == error_t::OK;
|
||||
constexpr bool isOk(const error_t e)
|
||||
{
|
||||
return e == error_t::OK;
|
||||
}
|
||||
|
||||
} // namespace error
|
||||
} // namespace hal
|
||||
} // namespace m5
|
||||
} // namespace error
|
||||
} // namespace hal
|
||||
} // namespace m5
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,26 +1,22 @@
|
||||
#ifndef M5_HAL_FRAMEWORK_CHECKER_HPP
|
||||
#define M5_HAL_FRAMEWORK_CHECKER_HPP
|
||||
|
||||
|
||||
#if defined ( ARDUINO )
|
||||
#define M5HAL_FRAMEWORK_HAS_ARDUINO 1
|
||||
#if defined(ARDUINO)
|
||||
#define M5HAL_FRAMEWORK_HAS_ARDUINO 1
|
||||
#else
|
||||
#define M5HAL_FRAMEWORK_HAS_ARDUINO 0
|
||||
#define M5HAL_FRAMEWORK_HAS_ARDUINO 0
|
||||
#endif
|
||||
|
||||
|
||||
#if __has_include(<FreeRTOS.h>) || __has_include(<freertos/FreeRTOS.h>)
|
||||
#define M5HAL_FRAMEWORK_HAS_FREERTOS 1
|
||||
#define M5HAL_FRAMEWORK_HAS_FREERTOS 1
|
||||
#else
|
||||
#define M5HAL_FRAMEWORK_HAS_FREERTOS 0
|
||||
#define M5HAL_FRAMEWORK_HAS_FREERTOS 0
|
||||
#endif
|
||||
|
||||
|
||||
#if __has_include(<SDL2/SDL.h>) || __has_include(<SDL.h>)
|
||||
#define M5HAL_FRAMEWORK_HAS_SDL 1
|
||||
#define M5HAL_FRAMEWORK_HAS_SDL 1
|
||||
#else
|
||||
#define M5HAL_FRAMEWORK_HAS_SDL 0
|
||||
#define M5HAL_FRAMEWORK_HAS_SDL 0
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
#include <Wire.h>
|
||||
#endif
|
||||
|
||||
#if defined( ARDUINO )
|
||||
#if defined(ARDUINO)
|
||||
|
||||
namespace m5 {
|
||||
namespace hal {
|
||||
@@ -16,57 +16,63 @@ namespace frameworks {
|
||||
namespace arduino {
|
||||
namespace gpio {
|
||||
|
||||
// 単一のデジタルピンを表すインターフェイス
|
||||
class Pin : public interface::gpio::Pin {
|
||||
public:
|
||||
void write(bool value) override;
|
||||
void writeHigh(void) override;
|
||||
void writeLow(void) override;
|
||||
bool read(void) override;
|
||||
// 単一のデジタルピンを表すインターフェイス
|
||||
class Pin : public interface::gpio::Pin {
|
||||
public:
|
||||
void write(bool value) override;
|
||||
void writeHigh(void) override;
|
||||
void writeLow(void) override;
|
||||
bool read(void) override;
|
||||
|
||||
void setMode(types::gpio_mode_t mode) override;
|
||||
types::gpio_number_t getGpioNumber(void) const override { return _gpio_number; }
|
||||
void setMode(types::gpio_mode_t mode) override;
|
||||
types::gpio_number_t getGpioNumber(void) const override
|
||||
{
|
||||
return _gpio_number;
|
||||
}
|
||||
|
||||
Pin(void) = default;
|
||||
Pin(types::gpio_number_t gpio_number) : _gpio_number { gpio_number }
|
||||
{}
|
||||
protected:
|
||||
types::gpio_number_t _gpio_number;// = (int16_t)-1;
|
||||
};
|
||||
Pin(void) = default;
|
||||
Pin(types::gpio_number_t gpio_number) : _gpio_number{gpio_number}
|
||||
{
|
||||
}
|
||||
|
||||
// 複数のPinを束ねた概念を表すインターフェイス
|
||||
class Port : public interface::gpio::Port {
|
||||
public:
|
||||
interface::gpio::Pin* getPin(uint8_t pinNumber) override;
|
||||
// uint8_t getPortNumber(void) const override { return 0; }
|
||||
// void setDirection(uint8_t mask, bool isOutput);
|
||||
protected:
|
||||
};
|
||||
protected:
|
||||
types::gpio_number_t _gpio_number; // = (int16_t)-1;
|
||||
};
|
||||
|
||||
// ポートを含めてGPIO全体を表すインターフェイス
|
||||
class GPIO : public interface::gpio::GPIO {
|
||||
public:
|
||||
interface::gpio::Port* getPort(uint8_t portNumber) override;
|
||||
interface::gpio::Pin* getPin(types::gpio_number_t pinNumber) override;
|
||||
private:
|
||||
};
|
||||
// 複数のPinを束ねた概念を表すインターフェイス
|
||||
class Port : public interface::gpio::Port {
|
||||
public:
|
||||
interface::gpio::Pin* getPin(uint8_t pinNumber) override;
|
||||
// uint8_t getPortNumber(void) const override { return 0; }
|
||||
// void setDirection(uint8_t mask, bool isOutput);
|
||||
protected:
|
||||
};
|
||||
|
||||
interface::gpio::GPIO* getGPIO(void);
|
||||
interface::gpio::Pin* getPin(types::gpio_number_t pinNumber);
|
||||
// ポートを含めてGPIO全体を表すインターフェイス
|
||||
class GPIO : public interface::gpio::GPIO {
|
||||
public:
|
||||
interface::gpio::Port* getPort(uint8_t portNumber) override;
|
||||
interface::gpio::Pin* getPin(types::gpio_number_t pinNumber) override;
|
||||
|
||||
} // namespace gpio
|
||||
private:
|
||||
};
|
||||
|
||||
interface::gpio::GPIO* getGPIO(void);
|
||||
interface::gpio::Pin* getPin(types::gpio_number_t pinNumber);
|
||||
|
||||
} // namespace gpio
|
||||
|
||||
namespace bus {
|
||||
namespace i2c {
|
||||
namespace i2c {
|
||||
|
||||
// bus::I2CBus* createBus(TwoWire& _wire);
|
||||
|
||||
} // namespace i2c
|
||||
} // namespace bus
|
||||
} // namespace arduino
|
||||
} // namespace frameworks
|
||||
} // namespace hal
|
||||
} // namespace m5
|
||||
} // namespace i2c
|
||||
} // namespace bus
|
||||
} // namespace arduino
|
||||
} // namespace frameworks
|
||||
} // namespace hal
|
||||
} // namespace m5
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
#include <vector>
|
||||
#include <list>
|
||||
|
||||
#if defined( ARDUINO )
|
||||
#if defined(ARDUINO)
|
||||
|
||||
namespace m5 {
|
||||
namespace hal {
|
||||
@@ -22,14 +22,14 @@ namespace gpio {
|
||||
|
||||
interface::gpio::GPIO* getGPIO(void)
|
||||
{
|
||||
M5_LIB_LOGV("getGPIO\n");
|
||||
M5_LIB_LOGV("getGPIO\n");
|
||||
static GPIO s_gpio_instance;
|
||||
return &s_gpio_instance;
|
||||
}
|
||||
|
||||
interface::gpio::Pin* getPin(types::gpio_number_t pinNumber)
|
||||
{
|
||||
M5_LIB_LOGV("getPin %d", pinNumber);
|
||||
M5_LIB_LOGV("getPin %d", pinNumber);
|
||||
return getGPIO()->getPin(pinNumber);
|
||||
}
|
||||
|
||||
@@ -41,11 +41,12 @@ interface::gpio::Port* GPIO::getPort(uint8_t portNumber)
|
||||
|
||||
interface::gpio::Pin* GPIO::getPin(types::gpio_number_t pinNumber)
|
||||
{
|
||||
M5_LIB_LOGV("GPIO::getPin %d", pinNumber);
|
||||
M5_LIB_LOGV("GPIO::getPin %d", pinNumber);
|
||||
return getPort(0)->getPin(pinNumber);
|
||||
}
|
||||
|
||||
interface::gpio::Pin* Port::getPin(uint8_t pinNumber) {
|
||||
interface::gpio::Pin* Port::getPin(uint8_t pinNumber)
|
||||
{
|
||||
static std::vector<Pin*> s_pins_pointer;
|
||||
static std::list<Pin> s_pins_instance;
|
||||
if (s_pins_pointer.size() <= pinNumber) {
|
||||
@@ -63,12 +64,17 @@ void Pin::write(bool value)
|
||||
// M5_LIB_LOGV("Pin::write %d [pin %d]", value, _gpio_number);
|
||||
digitalWrite(_gpio_number, value);
|
||||
}
|
||||
bool Pin::read(void) { return digitalRead(_gpio_number); }
|
||||
void Pin::writeHigh(void) {
|
||||
bool Pin::read(void)
|
||||
{
|
||||
return digitalRead(_gpio_number);
|
||||
}
|
||||
void Pin::writeHigh(void)
|
||||
{
|
||||
// M5_LIB_LOGV("Pin::setHigh [pin %d]", _gpio_number);
|
||||
digitalWrite(_gpio_number, true);
|
||||
}
|
||||
void Pin::writeLow(void) {
|
||||
void Pin::writeLow(void)
|
||||
{
|
||||
// M5_LIB_LOGV("Pin::setLow [pin %d]", _gpio_number);
|
||||
digitalWrite(_gpio_number, false);
|
||||
}
|
||||
@@ -76,37 +82,37 @@ void Pin::writeLow(void) {
|
||||
void Pin::setMode(types::gpio_mode_t mode)
|
||||
{
|
||||
switch (mode) {
|
||||
case types::gpio_mode_t::Input:
|
||||
pinMode(_gpio_number, INPUT);
|
||||
break;
|
||||
case types::gpio_mode_t::Output:
|
||||
pinMode(_gpio_number, OUTPUT);
|
||||
break;
|
||||
case types::gpio_mode_t::Output_OpenDrain:
|
||||
pinMode(_gpio_number, OUTPUT_OPEN_DRAIN);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
case types::gpio_mode_t::Input:
|
||||
pinMode(_gpio_number, INPUT);
|
||||
break;
|
||||
case types::gpio_mode_t::Output:
|
||||
pinMode(_gpio_number, OUTPUT);
|
||||
break;
|
||||
case types::gpio_mode_t::Output_OpenDrain:
|
||||
pinMode(_gpio_number, OUTPUT_OPEN_DRAIN);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace gpio
|
||||
} // namespace gpio
|
||||
|
||||
namespace bus {
|
||||
namespace i2c {
|
||||
namespace i2c {
|
||||
// interface::bus::I2C* createBus(TwoWire& _wire)
|
||||
// {
|
||||
// return nullptr;
|
||||
// }
|
||||
} // namespace i2c
|
||||
} // namespace bus
|
||||
} // namespace i2c
|
||||
} // namespace bus
|
||||
|
||||
//
|
||||
|
||||
} // namespace arduino
|
||||
} // namespace frameworks
|
||||
} // namespace hal
|
||||
} // namespace m5
|
||||
} // namespace arduino
|
||||
} // namespace frameworks
|
||||
} // namespace hal
|
||||
} // namespace m5
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -10,13 +10,13 @@
|
||||
@namespace m5
|
||||
@brief Toplevel namespace of M5
|
||||
*/
|
||||
namespace m5 { namespace hal { namespace gpio {
|
||||
class GPIO {
|
||||
};
|
||||
namespace m5 {
|
||||
namespace hal {
|
||||
namespace gpio {
|
||||
class GPIO {};
|
||||
|
||||
|
||||
};
|
||||
}
|
||||
}
|
||||
}; // namespace gpio
|
||||
} // namespace hal
|
||||
} // namespace m5
|
||||
|
||||
#endif
|
||||
|
||||
@@ -9,67 +9,85 @@
|
||||
@namespace m5
|
||||
@brief Toplevel namespace of M5
|
||||
*/
|
||||
namespace m5 { namespace hal { namespace interface {
|
||||
namespace m5 {
|
||||
namespace hal {
|
||||
namespace interface {
|
||||
// 抽象化されたGPIOインターフェースを置く。これは LowLayerではなく汎用的なもの。
|
||||
// このGPIOインターフェースを継承してGPIOエキスパンダの実装を作ることもできる。
|
||||
namespace gpio {
|
||||
|
||||
// 単一のデジタルピンを表すインターフェイス
|
||||
struct Pin {
|
||||
virtual ~Pin() = default;
|
||||
virtual ~Pin() = default;
|
||||
virtual void write(bool value) = 0;
|
||||
virtual bool read(void) = 0;
|
||||
virtual void writeHigh(void) { write(true); }
|
||||
virtual void writeLow(void) { write(false); }
|
||||
virtual bool read(void) = 0;
|
||||
virtual void writeHigh(void)
|
||||
{
|
||||
write(true);
|
||||
}
|
||||
virtual void writeLow(void)
|
||||
{
|
||||
write(false);
|
||||
}
|
||||
|
||||
virtual types::gpio_number_t getGpioNumber(void) const = 0;
|
||||
virtual void setMode(types::gpio_mode_t mode) = 0;
|
||||
virtual void setMode(types::gpio_mode_t mode) = 0;
|
||||
};
|
||||
|
||||
// 複数のPinを保持する概念を表すインターフェイス
|
||||
struct Port {
|
||||
virtual ~Port() = default;
|
||||
virtual ~Port() = default;
|
||||
virtual Pin* getPin(uint8_t pinNumber) = 0;
|
||||
// virtual uint8_t getPortNumber(void) const = 0;
|
||||
};
|
||||
|
||||
// Portを複数含むGPIO全体を表すインターフェイス
|
||||
struct GPIO {
|
||||
virtual ~GPIO() = default;
|
||||
virtual Port* getPort(uint8_t portNumber) = 0;
|
||||
virtual ~GPIO() = default;
|
||||
virtual Port* getPort(uint8_t portNumber) = 0;
|
||||
virtual Pin* getPin(types::gpio_number_t gpioNumber) = 0;
|
||||
virtual void digitalWrite(types::gpio_number_t gpioNumber, bool value) {
|
||||
virtual void digitalWrite(types::gpio_number_t gpioNumber, bool value)
|
||||
{
|
||||
getPin(gpioNumber)->write(value);
|
||||
}
|
||||
virtual bool digitalRead(types::gpio_number_t gpioNumber) {
|
||||
virtual bool digitalRead(types::gpio_number_t gpioNumber)
|
||||
{
|
||||
return getPin(gpioNumber)->read();
|
||||
}
|
||||
virtual int analogRead(types::gpio_number_t gpioNumber) {
|
||||
virtual int analogRead(types::gpio_number_t gpioNumber)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// n個のピンを内包するポート (例: 2個ならGROVEコネクタ、等)
|
||||
// コンストラクタにてピンの数を指定する。生成後のサイズ変更は不可とする。
|
||||
// 暫定的に std::vector でポインタを保持するが、将来的にはメモリ効率を考慮して変更する可能性あり。
|
||||
class MultiPinPort : public Port {
|
||||
public:
|
||||
MultiPinPort(size_t size) : _pins { size, nullptr } {}
|
||||
Pin* getPin(uint8_t pinNumber) override {
|
||||
MultiPinPort(size_t size) : _pins{size, nullptr}
|
||||
{
|
||||
}
|
||||
Pin* getPin(uint8_t pinNumber) override
|
||||
{
|
||||
return _pins.size() > pinNumber ? _pins[pinNumber] : nullptr;
|
||||
}
|
||||
void setPin(uint8_t pinNumber, Pin* pin) {
|
||||
void setPin(uint8_t pinNumber, Pin* pin)
|
||||
{
|
||||
if (_pins.size() > pinNumber) _pins[pinNumber] = pin;
|
||||
}
|
||||
size_t getPinCount(void) const { return _pins.size(); }
|
||||
size_t getPinCount(void) const
|
||||
{
|
||||
return _pins.size();
|
||||
}
|
||||
|
||||
protected:
|
||||
std::vector<Pin*> _pins;
|
||||
};
|
||||
|
||||
} // namespace gpio
|
||||
} // namespace interface
|
||||
} // namespace hal
|
||||
} // namespace m5
|
||||
} // namespace gpio
|
||||
} // namespace interface
|
||||
} // namespace hal
|
||||
} // namespace m5
|
||||
|
||||
#endif
|
||||
|
||||
+22
-12
@@ -41,9 +41,12 @@ public:
|
||||
// @param len 読み込むデータの長さ
|
||||
// @return 読み込んだデータの長さ / エラー
|
||||
virtual m5::stl::expected<size_t, m5::hal::error::error_t> read(uint8_t* data, size_t len) = 0;
|
||||
// virtual std::future<m5::stl::expected<size_t, m5::hal::error::error_t> > asyncRead(uint8_t* data, size_t len, AsyncParam* async = nullptr) = 0;
|
||||
// virtual std::future<m5::stl::expected<size_t, m5::hal::error::error_t> > asyncRead(uint8_t* data, size_t len,
|
||||
// AsyncParam* async = nullptr) = 0;
|
||||
virtual m5::stl::expected<size_t, m5::hal::error::error_t> availableRead(void) const
|
||||
{ return m5::stl::make_unexpected(error::error_t::NOT_IMPLEMENTED); };
|
||||
{
|
||||
return m5::stl::make_unexpected(error::error_t::NOT_IMPLEMENTED);
|
||||
};
|
||||
};
|
||||
|
||||
struct Output {
|
||||
@@ -51,28 +54,35 @@ public:
|
||||
virtual ~Output() = default;
|
||||
|
||||
virtual m5::stl::expected<size_t, m5::hal::error::error_t> write(const uint8_t* data, size_t len) = 0;
|
||||
// virtual std::future<m5::stl::expected<size_t, m5::hal::error::error_t> > asyncWrite(const uint8_t* data, size_t len, AsyncParam* async = nullptr) = 0;
|
||||
// virtual std::future<m5::stl::expected<size_t, m5::hal::error::error_t> > asyncWrite(const uint8_t* data, size_t
|
||||
// len, AsyncParam* async = nullptr) = 0;
|
||||
virtual m5::stl::expected<size_t, m5::hal::error::error_t> availableWrite(void) const
|
||||
{ return m5::stl::make_unexpected(error::error_t::NOT_IMPLEMENTED); };
|
||||
{
|
||||
return m5::stl::make_unexpected(error::error_t::NOT_IMPLEMENTED);
|
||||
};
|
||||
};
|
||||
|
||||
// Push型の入力はデータが一定量たまったらコールバックが呼ばれ、readで取得する
|
||||
struct PushInput : public Input {
|
||||
public:
|
||||
virtual ~PushInput() = default;
|
||||
virtual m5::stl::expected<void, m5::hal::error::error_t> setCallbackRead(void(*cb)(PushInput* bus, size_t available_len, void* cb_obj)) = 0;
|
||||
virtual ~PushInput() = default;
|
||||
virtual m5::stl::expected<void, m5::hal::error::error_t> setCallbackRead(void (*cb)(PushInput* bus,
|
||||
size_t available_len,
|
||||
void* cb_obj)) = 0;
|
||||
};
|
||||
|
||||
// Push型の出力は新しいデータが必要になったらコールバックが呼ばれ、writeで書き込む
|
||||
struct PushOutput : public Output {
|
||||
public:
|
||||
virtual ~PushOutput() = default;
|
||||
virtual m5::stl::expected<void, m5::hal::error::error_t> setCallbackWrite(void(*cb)(PushOutput* bus, size_t request_len, void* cb_obj)) = 0;
|
||||
virtual ~PushOutput() = default;
|
||||
virtual m5::stl::expected<void, m5::hal::error::error_t> setCallbackWrite(void (*cb)(PushOutput* bus,
|
||||
size_t request_len,
|
||||
void* cb_obj)) = 0;
|
||||
};
|
||||
|
||||
} // namespace io
|
||||
} // namespace interface
|
||||
} // namespace hal
|
||||
} // namespace m5
|
||||
} // namespace io
|
||||
} // namespace interface
|
||||
} // namespace hal
|
||||
} // namespace m5
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,62 +1,60 @@
|
||||
#ifndef M5_HAL_PLATFORM_CHECKER_HPP
|
||||
#define M5_HAL_PLATFORM_CHECKER_HPP
|
||||
|
||||
#define M5HAL_PLATFORM_NUMBER_UNKNOWN 0
|
||||
#define M5HAL_PLATFORM_NUMBER_WINDOWS 10
|
||||
#define M5HAL_PLATFORM_NUMBER_MACOS 20
|
||||
#define M5HAL_PLATFORM_NUMBER_LINUX 30
|
||||
#define M5HAL_PLATFORM_NUMBER_UNKNOWN 0
|
||||
#define M5HAL_PLATFORM_NUMBER_WINDOWS 10
|
||||
#define M5HAL_PLATFORM_NUMBER_MACOS 20
|
||||
#define M5HAL_PLATFORM_NUMBER_LINUX 30
|
||||
|
||||
#define M5HAL_PLATFORM_NUMBER_SDL_MAX 99
|
||||
#define M5HAL_PLATFORM_NUMBER_SDL_MAX 99
|
||||
|
||||
#define M5HAL_PLATFORM_NUMBER_AVR 200
|
||||
#define M5HAL_PLATFORM_NUMBER_ESP8266 300
|
||||
#define M5HAL_PLATFORM_NUMBER_ESP32_UNKNOWN 310
|
||||
#define M5HAL_PLATFORM_NUMBER_ESP32_1st 311
|
||||
#define M5HAL_PLATFORM_NUMBER_ESP32_S2 312
|
||||
#define M5HAL_PLATFORM_NUMBER_ESP32_S3 313
|
||||
#define M5HAL_PLATFORM_NUMBER_ESP32_C3 314
|
||||
#define M5HAL_PLATFORM_NUMBER_ESP32_C6 315
|
||||
#define M5HAL_PLATFORM_NUMBER_RP2040 400
|
||||
#define M5HAL_PLATFORM_NUMBER_SAMD21 500
|
||||
#define M5HAL_PLATFORM_NUMBER_SAMD51 510
|
||||
#define M5HAL_PLATFORM_NUMBER_SPRESENSE 600
|
||||
#define M5HAL_PLATFORM_NUMBER_STM32 700
|
||||
#define M5HAL_PLATFORM_NUMBER_AVR 200
|
||||
#define M5HAL_PLATFORM_NUMBER_ESP8266 300
|
||||
#define M5HAL_PLATFORM_NUMBER_ESP32_UNKNOWN 310
|
||||
#define M5HAL_PLATFORM_NUMBER_ESP32_1st 311
|
||||
#define M5HAL_PLATFORM_NUMBER_ESP32_S2 312
|
||||
#define M5HAL_PLATFORM_NUMBER_ESP32_S3 313
|
||||
#define M5HAL_PLATFORM_NUMBER_ESP32_C3 314
|
||||
#define M5HAL_PLATFORM_NUMBER_ESP32_C6 315
|
||||
#define M5HAL_PLATFORM_NUMBER_RP2040 400
|
||||
#define M5HAL_PLATFORM_NUMBER_SAMD21 500
|
||||
#define M5HAL_PLATFORM_NUMBER_SAMD51 510
|
||||
#define M5HAL_PLATFORM_NUMBER_SPRESENSE 600
|
||||
#define M5HAL_PLATFORM_NUMBER_STM32 700
|
||||
|
||||
#define XSTR(x) STR(x)
|
||||
#define STR(x) #x
|
||||
#define STR(x) #x
|
||||
|
||||
#if defined(ESP_PLATFORM)
|
||||
#if __has_include(<sdkconfig.h>)
|
||||
#include <sdkconfig.h>
|
||||
#endif
|
||||
#if defined(CONFIG_IDF_TARGET)
|
||||
#if defined(CONFIG_IDF_TARGET_ESP32C3)
|
||||
#define M5HAL_TARGET_PLATFORM_NUMBER M5HAL_PLATFORM_NUMBER_ESP32C3
|
||||
#define M5HAL_TARGET_PLATFORM_PATH m5_hal / platforms / espressif / esp32c3
|
||||
#elif defined(CONFIG_IDF_TARGET_ESP32S3)
|
||||
#define M5HAL_TARGET_PLATFORM_NUMBER M5HAL_PLATFORM_NUMBER_ESP32S3
|
||||
#define M5HAL_TARGET_PLATFORM_PATH m5_hal / platforms / espressif / esp32s3
|
||||
#elif defined(CONFIG_IDF_TARGET_ESP32)
|
||||
#define M5HAL_TARGET_PLATFORM_NUMBER M5HAL_PLATFORM_NUMBER_ESP32_1st
|
||||
#define M5HAL_TARGET_PLATFORM_PATH m5_hal / platforms / espressif / esp32
|
||||
|
||||
#if defined ( ESP_PLATFORM )
|
||||
#if __has_include (<sdkconfig.h>)
|
||||
#include <sdkconfig.h>
|
||||
#endif
|
||||
#if defined ( CONFIG_IDF_TARGET )
|
||||
#if defined ( CONFIG_IDF_TARGET_ESP32C3 )
|
||||
#define M5HAL_TARGET_PLATFORM_NUMBER M5HAL_PLATFORM_NUMBER_ESP32C3
|
||||
#define M5HAL_TARGET_PLATFORM_PATH m5_hal/platforms/espressif/esp32c3
|
||||
#elif defined ( CONFIG_IDF_TARGET_ESP32S3 )
|
||||
#define M5HAL_TARGET_PLATFORM_NUMBER M5HAL_PLATFORM_NUMBER_ESP32S3
|
||||
#define M5HAL_TARGET_PLATFORM_PATH m5_hal/platforms/espressif/esp32s3
|
||||
#elif defined ( CONFIG_IDF_TARGET_ESP32 )
|
||||
#define M5HAL_TARGET_PLATFORM_NUMBER M5HAL_PLATFORM_NUMBER_ESP32_1st
|
||||
#define M5HAL_TARGET_PLATFORM_PATH m5_hal/platforms/espressif/esp32
|
||||
|
||||
#elif defined ( CONFIG_IDF_TARGET_ESP32C6 )
|
||||
#define M5HAL_TARGET_PLATFORM_NUMBER M5HAL_PLATFORM_NUMBER_ESP32_C6
|
||||
#define M5HAL_TARGET_PLATFORM_PATH m5_hal/platforms/espressif/esp32c6
|
||||
#else
|
||||
#define M5HAL_TARGET_PLATFORM_NUMBER M5HAL_PLATFORM_NUMBER_ESP32_UNKNOWN
|
||||
#define M5HAL_TARGET_PLATFORM_PATH m5_hal/platforms/espressif/esp32_unknown
|
||||
#endif
|
||||
#endif
|
||||
#elif defined(CONFIG_IDF_TARGET_ESP32C6)
|
||||
#define M5HAL_TARGET_PLATFORM_NUMBER M5HAL_PLATFORM_NUMBER_ESP32_C6
|
||||
#define M5HAL_TARGET_PLATFORM_PATH m5_hal / platforms / espressif / esp32c6
|
||||
#else
|
||||
#define M5HAL_TARGET_PLATFORM_NUMBER M5HAL_PLATFORM_NUMBER_ESP32_UNKNOWN
|
||||
#define M5HAL_TARGET_PLATFORM_PATH m5_hal / platforms / espressif / esp32_unknown
|
||||
#endif
|
||||
#endif
|
||||
#else
|
||||
#endif
|
||||
|
||||
#undef XSTR
|
||||
#undef STR
|
||||
|
||||
|
||||
#if !defined ( M5HAL_TARGET_PLATFORM_NUMBER )
|
||||
#if !defined(M5HAL_TARGET_PLATFORM_NUMBER)
|
||||
#define M5HAL_TARGET_PLATFORM_NUMBER M5HAL_PLATFORM_NUMBER_UNKNOWN
|
||||
#endif
|
||||
|
||||
|
||||
@@ -17,23 +17,23 @@ namespace esp32 {
|
||||
namespace types {
|
||||
|
||||
enum class PeripheralType : uint8_t {
|
||||
none = 0,
|
||||
i2c0,
|
||||
i2c1,
|
||||
spi2,
|
||||
spi3,
|
||||
none = 0,
|
||||
i2c0,
|
||||
i2c1,
|
||||
spi2,
|
||||
spi3,
|
||||
};
|
||||
using periph_t = PeripheralType;
|
||||
|
||||
} // namespace types
|
||||
} // namespace types
|
||||
|
||||
namespace gpio {
|
||||
interface::gpio::GPIO* getGPIO(void);
|
||||
} // namespace gpio
|
||||
} // namespace gpio
|
||||
|
||||
} // namespace esp32
|
||||
} // namespace platforms
|
||||
} // namespace hal
|
||||
} // namespace m5
|
||||
} // namespace esp32
|
||||
} // namespace platforms
|
||||
} // namespace hal
|
||||
} // namespace m5
|
||||
|
||||
#endif
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
#define M5_HAL_PLATFORMS_ESPRESSIF_ESP32C6_HEADER_HPP
|
||||
|
||||
#include "../../../interface/gpio.hpp"
|
||||
//#include "../../../interface/bus.hpp"
|
||||
// #include "../../../interface/bus.hpp"
|
||||
|
||||
namespace m5 {
|
||||
namespace hal {
|
||||
@@ -10,17 +10,16 @@ namespace platforms {
|
||||
namespace esp32 {
|
||||
namespace gpio {
|
||||
interface::gpio::GPIO* getGPIO(void);
|
||||
} // namespace gpio
|
||||
} // namespace gpio
|
||||
|
||||
namespace bus {
|
||||
namespace i2c {
|
||||
namespace i2c {
|
||||
|
||||
|
||||
} // namespace i2c
|
||||
} // namespace bus
|
||||
} // namespace esp32
|
||||
} // namespace platforms
|
||||
} // namespace hal
|
||||
} // namespace m5
|
||||
} // namespace i2c
|
||||
} // namespace bus
|
||||
} // namespace esp32
|
||||
} // namespace platforms
|
||||
} // namespace hal
|
||||
} // namespace m5
|
||||
|
||||
#endif
|
||||
|
||||
@@ -10,17 +10,16 @@ namespace platforms {
|
||||
namespace esp32 {
|
||||
namespace gpio {
|
||||
interface::gpio::GPIO* getGPIO(void);
|
||||
} // namespace gpio
|
||||
} // namespace gpio
|
||||
|
||||
namespace bus {
|
||||
namespace i2c {
|
||||
namespace i2c {
|
||||
|
||||
|
||||
} // namespace i2c
|
||||
} // namespace bus
|
||||
} // namespace esp32
|
||||
} // namespace platforms
|
||||
} // namespace hal
|
||||
} // namespace m5
|
||||
} // namespace i2c
|
||||
} // namespace bus
|
||||
} // namespace esp32
|
||||
} // namespace platforms
|
||||
} // namespace hal
|
||||
} // namespace m5
|
||||
|
||||
#endif
|
||||
|
||||
+15
-16
@@ -38,29 +38,28 @@ gpio_number_t の下位 5bit がピン番号、上位 10bit がポート番号
|
||||
*/
|
||||
|
||||
enum class GpioMode : uint8_t {
|
||||
Input = 0,
|
||||
Output,
|
||||
Output_OpenDrain,
|
||||
Input = 0,
|
||||
Output,
|
||||
Output_OpenDrain,
|
||||
};
|
||||
using gpio_mode_t = GpioMode;
|
||||
|
||||
|
||||
enum class BusType : uint8_t {
|
||||
UNKNOWN = 0,
|
||||
I2C,
|
||||
SPI,
|
||||
I2S,
|
||||
UART,
|
||||
UNKNOWN = 0,
|
||||
I2C,
|
||||
SPI,
|
||||
I2S,
|
||||
UART,
|
||||
|
||||
PWM,
|
||||
GPIO,
|
||||
ADC,
|
||||
DAC,
|
||||
PWM,
|
||||
GPIO,
|
||||
ADC,
|
||||
DAC,
|
||||
};
|
||||
using bus_type_t = BusType;
|
||||
|
||||
} // namespace types
|
||||
} // namespace hal
|
||||
} // namespace m5
|
||||
} // namespace types
|
||||
} // namespace hal
|
||||
} // namespace m5
|
||||
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user