Skip to content

Commit

Permalink
Merge branch 'develop'
Browse files Browse the repository at this point in the history
  • Loading branch information
GOB52 committed Jan 20, 2025
2 parents ed0de47 + 08f9eaf commit 3b942a7
Show file tree
Hide file tree
Showing 4 changed files with 206 additions and 23 deletions.
2 changes: 1 addition & 1 deletion library.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
"M5Utility": "https://github.com/m5stack/M5Utility.git",
"M5HAL": "https://github.com/m5stack/M5HAL.git"
},
"version": "0.0.4",
"version": "0.0.5",
"frameworks": [
"arduino"
],
Expand Down
2 changes: 1 addition & 1 deletion library.properties
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
name=M5UnitUnified
version=0.0.4
version=0.0.5
author=M5Stack
maintainer=M5Stack
sentence=M5UnitUnified is a library for unified handling of various M5 units products. (Alpha version)
Expand Down
57 changes: 45 additions & 12 deletions src/M5UnitComponent.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,6 @@ bool Component::readRegister(const Reg reg, uint8_t* rbuf, const size_t len, con
}

m5::utility::delay(delayMillis);

return (readWithTransaction(rbuf, len) == m5::hal::error::error_t::OK);
}

Expand All @@ -186,12 +185,27 @@ bool Component::readRegister8(const Reg reg, uint8_t& result, const uint32_t del
template <typename Reg,
typename std::enable_if<std::is_integral<Reg>::value && std::is_unsigned<Reg>::value && sizeof(Reg) <= 2,
std::nullptr_t>::type>
bool Component::readRegister16(const Reg reg, uint16_t& result, const uint32_t delayMillis, const bool stop)
bool Component::read_register16E(const Reg reg, uint16_t& result, const uint32_t delayMillis, const bool stop,
const bool endian)
{
uint8_t tmp[2]{};
auto ret = readRegister(reg, tmp, 2, delayMillis, stop);
if (ret) {
result = (tmp[!endian] << 8) | tmp[endian];
}
return ret;
}

template <typename Reg,
typename std::enable_if<std::is_integral<Reg>::value && std::is_unsigned<Reg>::value && sizeof(Reg) <= 2,
std::nullptr_t>::type>
bool Component::read_register32E(const Reg reg, uint32_t& result, const uint32_t delayMillis, const bool stop,
const bool endian)
{
m5::types::big_uint16_t buf{};
auto ret = readRegister(reg, buf.data(), buf.size(), delayMillis, stop);
uint8_t tmp[4]{};
auto ret = readRegister(reg, tmp, 4, delayMillis, stop);
if (ret) {
result = buf.get();
result = (tmp[0 + 3 * endian] | (tmp[1 + endian] << 8) | (tmp[2 - endian] << 16)) | (tmp[3 - 3 * endian] << 24);
}
return ret;
}
Expand All @@ -217,10 +231,25 @@ bool Component::writeRegister8(const Reg reg, const uint8_t value, const bool st
template <typename Reg,
typename std::enable_if<std::is_integral<Reg>::value && std::is_unsigned<Reg>::value && sizeof(Reg) <= 2,
std::nullptr_t>::type>
bool Component::writeRegister16(const Reg reg, const uint16_t value, const bool stop)
bool Component::write_register16E(const Reg reg, const uint16_t value, const bool stop, const bool endian)
{
uint8_t tmp[2]{};
tmp[endian] = value & 0xFF;
tmp[!endian] = (value >> 8) & 0xFF;
return writeRegister(reg, tmp, 2, stop);
}

template <typename Reg,
typename std::enable_if<std::is_integral<Reg>::value && std::is_unsigned<Reg>::value && sizeof(Reg) <= 2,
std::nullptr_t>::type>
bool Component::write_register32E(const Reg reg, const uint32_t value, const bool stop, const bool endian)
{
m5::types::big_uint16_t u16{value};
return writeRegister(reg, u16.data(), u16.size(), stop);
uint8_t tmp[4]{};
tmp[0 + endian * 3] = value & 0xFF;
tmp[1 + endian] = (value >> 8) & 0xFF;
tmp[2 - endian] = (value >> 16) & 0xFF;
tmp[3 - endian * 3] = (value >> 24) & 0xFF;
return writeRegister(reg, tmp, 4, stop);
}

bool Component::generalCall(const uint8_t* data, const size_t len)
Expand Down Expand Up @@ -251,15 +280,19 @@ template bool Component::readRegister<uint8_t>(const uint8_t, uint8_t*, const si
template bool Component::readRegister<uint16_t>(const uint16_t, uint8_t*, const size_t, const uint32_t, const bool);
template bool Component::readRegister8<uint8_t>(const uint8_t, uint8_t&, const uint32_t, const bool);
template bool Component::readRegister8<uint16_t>(const uint16_t, uint8_t&, const uint32_t, const bool);
template bool Component::readRegister16<uint8_t>(const uint8_t, uint16_t&, const uint32_t, const bool);
template bool Component::readRegister16<uint16_t>(const uint16_t, uint16_t&, const uint32_t, const bool);
template bool Component::read_register16E<uint8_t>(const uint8_t, uint16_t&, const uint32_t, const bool, const bool);
template bool Component::read_register16E<uint16_t>(const uint16_t, uint16_t&, const uint32_t, const bool, const bool);
template bool Component::read_register32E<uint8_t>(const uint8_t, uint32_t&, const uint32_t, const bool, const bool);
template bool Component::read_register32E<uint16_t>(const uint16_t, uint32_t&, const uint32_t, const bool, const bool);

template bool Component::writeRegister<uint8_t>(const uint8_t, const uint8_t*, const size_t, const bool);
template bool Component::writeRegister<uint16_t>(const uint16_t, const uint8_t*, const size_t, const bool);
template bool Component::writeRegister8<uint8_t>(const uint8_t, const uint8_t, const bool);
template bool Component::writeRegister8<uint16_t>(const uint16_t, const uint8_t, const bool);
template bool Component::writeRegister16<uint8_t>(const uint8_t, const uint16_t, const bool);
template bool Component::writeRegister16<uint16_t>(const uint16_t, const uint16_t, const bool);
template bool Component::write_register16E<uint8_t>(const uint8_t, const uint16_t, const bool, const bool);
template bool Component::write_register16E<uint16_t>(const uint16_t, const uint16_t, const bool, const bool);
template bool Component::write_register32E<uint8_t>(const uint8_t, const uint32_t, const bool, const bool);
template bool Component::write_register32E<uint16_t>(const uint16_t, const uint32_t, const bool, const bool);

template m5::hal::error::error_t Component::writeWithTransaction<uint8_t>(const uint8_t reg, const uint8_t* data,
const size_t len, const bool stop);
Expand Down
168 changes: 159 additions & 9 deletions src/M5UnitComponent.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -229,7 +229,7 @@ class Component {
bool selectChannel(const uint8_t ch = 8);
///@}

///@cond
///@cond 0
template <typename T>
class iterator {
public:
Expand Down Expand Up @@ -274,10 +274,7 @@ class Component {
private:
Component* _ptr;
};
///@endcond

///@name Iterator for children
///@{
using child_iterator = iterator<Component>;
using const_child_iterator = iterator<const Component>;
inline child_iterator childBegin() noexcept
Expand All @@ -296,17 +293,17 @@ class Component {
{
return const_child_iterator();
}
///@}
///@endcond

/*! @brief General call for I2C*/
bool generalCall(const uint8_t* data, const size_t len);

//! @brief Output information for debug
virtual std::string debugInfo() const;

///@name Read/Write
///@{
///@cond 0
m5::hal::error::error_t readWithTransaction(uint8_t* data, const size_t len);

template <typename Reg,
typename std::enable_if<std::is_integral<Reg>::value && std::is_unsigned<Reg>::value && sizeof(Reg) <= 2,
std::nullptr_t>::type = nullptr>
Expand All @@ -316,29 +313,163 @@ class Component {
typename std::enable_if<std::is_integral<Reg>::value && std::is_unsigned<Reg>::value && sizeof(Reg) <= 2,
std::nullptr_t>::type = nullptr>
bool readRegister8(const Reg reg, uint8_t& result, const uint32_t delayMillis, const bool stop = true);

template <typename Reg,
typename std::enable_if<std::is_integral<Reg>::value && std::is_unsigned<Reg>::value && sizeof(Reg) <= 2,
std::nullptr_t>::type = nullptr>
inline bool readRegister16BE(const Reg reg, uint16_t& result, const uint32_t delayMillis, const bool stop = true)
{
return read_register16E(reg, result, delayMillis, stop, true);
}

template <typename Reg,
typename std::enable_if<std::is_integral<Reg>::value && std::is_unsigned<Reg>::value && sizeof(Reg) <= 2,
std::nullptr_t>::type = nullptr>
inline bool readRegister16LE(const Reg reg, uint16_t& result, const uint32_t delayMillis, const bool stop = true)
{
return read_register16E(reg, result, delayMillis, stop, false);
}

template <typename Reg,
typename std::enable_if<std::is_integral<Reg>::value && std::is_unsigned<Reg>::value && sizeof(Reg) <= 2,
std::nullptr_t>::type = nullptr>
inline bool readRegister32BE(const Reg reg, uint32_t& result, const uint32_t delayMillis, const bool stop = true)
{
return read_register32E(reg, result, delayMillis, stop, true);
}

template <typename Reg,
typename std::enable_if<std::is_integral<Reg>::value && std::is_unsigned<Reg>::value && sizeof(Reg) <= 2,
std::nullptr_t>::type = nullptr>
bool readRegister16(const Reg reg, uint16_t& result, const uint32_t delayMillis, const bool stop = true);
inline bool readRegister32LE(const Reg reg, uint32_t& result, const uint32_t delayMillis, const bool stop = true)
{
return read_register32E(reg, result, delayMillis, stop, false);
}

m5::hal::error::error_t writeWithTransaction(const uint8_t* data, const size_t len, const bool stop = true);

template <typename Reg,
typename std::enable_if<std::is_integral<Reg>::value && std::is_unsigned<Reg>::value && sizeof(Reg) <= 2,
std::nullptr_t>::type = nullptr>
m5::hal::error::error_t writeWithTransaction(const Reg reg, const uint8_t* data, const size_t len,
const bool stop = true);

template <typename Reg,
typename std::enable_if<std::is_integral<Reg>::value && std::is_unsigned<Reg>::value && sizeof(Reg) <= 2,
std::nullptr_t>::type = nullptr>
bool writeRegister(const Reg reg, const uint8_t* buf = nullptr, const size_t len = 0U, const bool stop = true);

template <typename Reg,
typename std::enable_if<std::is_integral<Reg>::value && std::is_unsigned<Reg>::value && sizeof(Reg) <= 2,
std::nullptr_t>::type = nullptr>
bool writeRegister8(const Reg reg, const uint8_t value, const bool stop = true);

template <typename Reg,
typename std::enable_if<std::is_integral<Reg>::value && std::is_unsigned<Reg>::value && sizeof(Reg) <= 2,
std::nullptr_t>::type = nullptr>
inline bool writeRegister16BE(const Reg reg, const uint16_t value, const bool stop = true)
{
return write_register16E(reg, value, stop, true);
}

template <typename Reg,
typename std::enable_if<std::is_integral<Reg>::value && std::is_unsigned<Reg>::value && sizeof(Reg) <= 2,
std::nullptr_t>::type = nullptr>
inline bool writeRegister16LE(const Reg reg, const uint16_t value, const bool stop = true)
{
return write_register16E(reg, value, stop, false);
}

template <typename Reg,
typename std::enable_if<std::is_integral<Reg>::value && std::is_unsigned<Reg>::value && sizeof(Reg) <= 2,
std::nullptr_t>::type = nullptr>
inline bool writeRegister32BE(const Reg reg, const uint32_t value, const bool stop = true)
{
return write_register32E(reg, value, stop, true);
}

template <typename Reg,
typename std::enable_if<std::is_integral<Reg>::value && std::is_unsigned<Reg>::value && sizeof(Reg) <= 2,
std::nullptr_t>::type = nullptr>
inline bool writeRegister32LE(const Reg reg, const uint32_t value, const bool stop = true)
{
return write_register32E(reg, value, stop, false);
}

// clang-format off
template <typename Reg,
typename std::enable_if<std::is_integral<Reg>::value && std::is_unsigned<Reg>::value && sizeof(Reg) <= 2,
std::nullptr_t>::type = nullptr>
bool writeRegister16(const Reg reg, const uint16_t value, const bool stop = true);
[[deprecated("Use readRegister16BE() or readRegister16LE(). To be removed in the next minor version increase")]]
inline bool readRegister16(const Reg reg, uint16_t& result, const uint32_t delayMillis, const bool stop = true)
{
return read_register16E(reg, result, delayMillis, stop, true);
}

template <typename Reg,
typename std::enable_if<std::is_integral<Reg>::value && std::is_unsigned<Reg>::value && sizeof(Reg) <= 2,
std::nullptr_t>::type = nullptr>
[[deprecated("Use writeRegister16BE() or writeRegister16LE(). To be removed in the next minor version increase")]]
inline bool writeRegister16(const Reg reg, const uint16_t value, const bool stop = true)
{
return write_register16E(reg, value, stop, true);
}
// clang-format on
///@endcond

#if defined(DOXYGEN_PROCESS)
// There is a problem with the Doxygen output of templates containing std::enable_if,
// so we need a section for Dxygen output
///@name Read/Write
///@{
//! @brief Read any data with transaction
m5::hal::error::error_t readWithTransaction(uint8_t* data, const size_t len);
//! @brief Read any data with transaction from register
template <typename Reg>
bool readRegister(const Reg reg, uint8_t* rbuf, const size_t len, const uint32_t delayMillis,
const bool stop = true);
//! @brief Read byte with transaction from register
template <typename Reg>
bool readRegister8(const Reg reg, uint8_t& result, const uint32_t delayMillis, const bool stop = true);
//! @brief Read word in big-endian order with transaction from register
template <typename Reg>
bool readRegister16BE(const Reg reg, uint16_t& result, const uint32_t delayMillis, const bool stop = true);
//! @brief Read word in little-endian order with transaction from register
template <typename Reg>
bool readRegister16LE(const Reg reg, uint16_t& result, const uint32_t delayMillis, const bool stop = true);
//! @brief Read dword in big-endian order with transaction from register
template <typename Reg>
bool readRegister32BE(const Reg reg, uint32_t& result, const uint32_t delayMillis, const bool stop = true);
//! @brief Read dword in little-endian order with transaction from register
template <typename Reg>
bool readRegister32LE(const Reg reg, uint32_t& result, const uint32_t delayMillis, const bool stop = true);

//! @brief Write any data with transaction
m5::hal::error::error_t writeWithTransaction(const uint8_t* data, const size_t len, const bool stop = true);
//! @brief Write any data with transaction to register
template <typename Reg>
m5::hal::error::error_t writeWithTransaction(const Reg reg, const uint8_t* data, const size_t len,
const bool stop = true);
//! @brief Write any data with transaction to register
template <typename Reg>
bool writeRegister(const Reg reg, const uint8_t* buf = nullptr, const size_t len = 0U, const bool stop = true);
//! @brief Write byte with transaction to register
template <typename Reg>
bool writeRegister8(const Reg reg, const uint8_t value, const bool stop = true);
//! @brief Write word in big-endian order with transaction from register
template <typename Reg>
bool writeRegister16BE(const Reg reg, const uint16_t value, const bool stop = true);
//! @brief Write word in little-endian order with transaction from register
template <typename Reg>
bool writeRegister16LE(const Reg reg, const uint16_t value, const bool stop = true);
//! @brief Write dword in big-endian order with transaction from register
template <typename Reg>
bool writeRegister32BE(const Reg reg, const uint32_t value, const bool stop = true);
//! @brief Write dword in little-endian order with transaction from register
template <typename Reg>
bool writeRegister32LE(const Reg reg, const uint32_t value, const bool stop = true);
///@}
#endif

protected:
// Proper implementation in derived classes is required
Expand Down Expand Up @@ -369,6 +500,25 @@ class Component {
bool add_child(Component* c);
bool changeAddress(const uint8_t addr); // Functions for dynamically addressable devices

template <typename Reg,
typename std::enable_if<std::is_integral<Reg>::value && std::is_unsigned<Reg>::value && sizeof(Reg) <= 2,
std::nullptr_t>::type = nullptr>
bool read_register16E(const Reg reg, uint16_t& result, const uint32_t delayMillis, const bool stop,
const bool endian);
template <typename Reg,
typename std::enable_if<std::is_integral<Reg>::value && std::is_unsigned<Reg>::value && sizeof(Reg) <= 2,
std::nullptr_t>::type = nullptr>
bool write_register16E(const Reg reg, const uint16_t value, const bool stop, const bool endifan);
template <typename Reg,
typename std::enable_if<std::is_integral<Reg>::value && std::is_unsigned<Reg>::value && sizeof(Reg) <= 2,
std::nullptr_t>::type = nullptr>
bool read_register32E(const Reg reg, uint32_t& result, const uint32_t delayMillis, const bool stop,
const bool endian);
template <typename Reg,
typename std::enable_if<std::is_integral<Reg>::value && std::is_unsigned<Reg>::value && sizeof(Reg) <= 2,
std::nullptr_t>::type = nullptr>
bool write_register32E(const Reg reg, const uint32_t value, const bool stop, const bool endifan);

protected:
// For periodic measurement
types::elapsed_time_t _latest{}, _interval{};
Expand Down

0 comments on commit 3b942a7

Please sign in to comment.