mirror of
https://github.com/esphome/esphome.git
synced 2024-11-22 23:18:10 +01:00
Introduce byteswap helpers (#2661)
* Backport std::byteswap() in helpers.h * Introduce convert_big_endian() function * Use convert_big_endian() in i2c byte swap functions
This commit is contained in:
parent
8aa72f4c1e
commit
c422b2fb0b
2 changed files with 28 additions and 10 deletions
|
@ -1,6 +1,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "i2c_bus.h"
|
#include "i2c_bus.h"
|
||||||
|
#include "esphome/core/helpers.h"
|
||||||
#include "esphome/core/optional.h"
|
#include "esphome/core/optional.h"
|
||||||
#include <array>
|
#include <array>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
@ -32,16 +33,8 @@ class I2CRegister {
|
||||||
|
|
||||||
// like ntohs/htons but without including networking headers.
|
// like ntohs/htons but without including networking headers.
|
||||||
// ("i2c" byte order is big-endian)
|
// ("i2c" byte order is big-endian)
|
||||||
inline uint16_t i2ctohs(uint16_t i2cshort) {
|
inline uint16_t i2ctohs(uint16_t i2cshort) { return convert_big_endian(i2cshort); }
|
||||||
union {
|
inline uint16_t htoi2cs(uint16_t hostshort) { return convert_big_endian(hostshort); }
|
||||||
uint16_t x;
|
|
||||||
uint8_t y[2];
|
|
||||||
} conv;
|
|
||||||
conv.x = i2cshort;
|
|
||||||
return ((uint16_t) conv.y[0] << 8) | ((uint16_t) conv.y[1] << 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline uint16_t htoi2cs(uint16_t hostshort) { return i2ctohs(hostshort); }
|
|
||||||
|
|
||||||
class I2CDevice {
|
class I2CDevice {
|
||||||
public:
|
public:
|
||||||
|
|
|
@ -306,6 +306,31 @@ template<typename T> T *new_buffer(size_t length) {
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
/// @name STL backports
|
||||||
|
///@{
|
||||||
|
|
||||||
|
// std::byteswap is from C++23 and technically should be a template, but this will do for now.
|
||||||
|
constexpr uint8_t byteswap(uint8_t n) { return n; }
|
||||||
|
constexpr uint16_t byteswap(uint16_t n) { return __builtin_bswap16(n); }
|
||||||
|
constexpr uint32_t byteswap(uint32_t n) { return __builtin_bswap32(n); }
|
||||||
|
constexpr uint64_t byteswap(uint64_t n) { return __builtin_bswap64(n); }
|
||||||
|
|
||||||
|
///@}
|
||||||
|
|
||||||
|
/// @name Bit manipulation
|
||||||
|
///@{
|
||||||
|
|
||||||
|
/// Convert a value between host byte order and big endian (most significant byte first) order.
|
||||||
|
template<typename T, enable_if_t<std::is_unsigned<T>::value, int> = 0> constexpr T convert_big_endian(T val) {
|
||||||
|
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
|
||||||
|
return byteswap(val);
|
||||||
|
#else
|
||||||
|
return val;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
///@}
|
||||||
|
|
||||||
/// @name Parsing & formatting
|
/// @name Parsing & formatting
|
||||||
///@{
|
///@{
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue