10#ifndef M5_UNIT_RS485_UNIT_SP485_HPP
11#define M5_UNIT_RS485_UNIT_SP485_HPP
13#include <M5UnitComponent.hpp>
14#include <m5_utility/stl/byteswap.hpp>
15#include <m5_utility/stl/endianness.hpp>
28 M5_UNIT_COMPONENT_HPP_BUILDER(
UnitSP485, 0x00 );
33 virtual ~ISerial() =
default;
34 virtual int available() = 0;
35 virtual int availableForWrite() = 0;
36 virtual int peek() = 0;
37 virtual int read() = 0;
38 virtual size_t read(uint8_t *buf,
const size_t len) = 0;
39 virtual size_t readBytes(uint8_t *buf,
const size_t len) = 0;
40 virtual void flush() = 0;
41 virtual void flush(
const bool txOnly) = 0;
42 virtual size_t write(
const uint8_t *buf,
const size_t len) = 0;
43 virtual size_t write(uint8_t b) = 0;
44 virtual uint32_t baudRate()
const = 0;
59 virtual bool begin()
override;
93 inline operator bool()
const
95 return isRegistered();
103 return _serial->available();
111 return _serial->availableForWrite();
119 return _serial->peek();
127 return _serial->read();
135 inline size_t read(uint8_t *buffer,
const size_t size)
137 return _serial->read(buffer, size);
145 inline size_t read(
char *buffer,
const size_t size)
147 return read(
reinterpret_cast<uint8_t *
>(buffer), size);
157 return _serial->readBytes(buffer, length);
165 inline size_t readBytes(
char *buffer,
const size_t length)
167 return readBytes(
reinterpret_cast<uint8_t *
>(buffer), length);
180 inline void flush(
const bool txOnly)
182 _serial->flush(txOnly);
191 size_t write(
const uint8_t d,
const bool flush =
true);
199 size_t write(
const uint8_t *buffer,
const size_t size,
const bool flush =
true);
207 size_t write(
const char *buffer,
const size_t size,
const bool flush =
true);
214 size_t write(
const char *s,
const bool flush =
true);
226 template <
typename T,
bool LittleEndian = true>
229 static_assert(std::is_trivially_copyable<T>::value && std::is_standard_layout<T>::value,
230 "readValue requires trivially copyable, standard-layout types only");
232 uint8_t buf[
sizeof(T)]{};
233 size_t got = _serial->readBytes(buf,
sizeof(T));
234 if (got !=
sizeof(T)) {
237 std::memcpy(&value, buf,
sizeof(T));
238 if (LittleEndian != m5::endian::little) {
239 value = byteswap_if_needed(value);
250 template <
typename T,
bool LittleEndian = true>
253 static_assert(std::is_trivially_copyable<T>::value && std::is_standard_layout<T>::value,
254 "writeValue requires trivially copyable, standard-layout types only");
256 if (LittleEndian != m5::endian::little) {
257 tmp = byteswap_if_needed(tmp);
259 uint8_t buf[
sizeof(T)]{};
260 std::memcpy(buf, &tmp,
sizeof(T));
261 return write(buf,
sizeof(T),
true) ==
sizeof(T);
266 inline ISerial *iserial()
268 return _serial.get();
271 template <
typename T>
272 static T byteswap_if_needed(T v)
274 return byteswap_if_needed_impl(v, std::integral_constant <
bool,
275 std::is_integral<T>::value || std::is_enum<T>::value > {});
278 template <
typename T>
279 static T byteswap_if_needed_impl(T v, std::true_type)
281 return m5::stl::byteswap(v);
284 template <
typename T>
285 static T byteswap_if_needed_impl(T v, std::false_type)
291 std::unique_ptr<ISerial> _serial{};
RS-485 unit using SP485 transceiver.
Definition unit_SP485.hpp:27
virtual ~UnitSP485()=default
Destructor.
virtual bool begin() override
Begin using the registered UART adapter.
Definition unit_SP485.cpp:130
size_t readBytes(uint8_t *buffer, const size_t length)
Reads bytes with timeout defined by underlying Serial.
Definition unit_SP485.hpp:155
void flush(const bool txOnly)
Flushes the serial port.
Definition unit_SP485.hpp:180
int availableForWrite()
Returns the number of bytes that can be written without blocking.
Definition unit_SP485.hpp:109
size_t readBytes(char *buffer, const size_t length)
Reads bytes with timeout defined by underlying Serial.
Definition unit_SP485.hpp:165
size_t write(const uint8_t d, const bool flush=true)
Writes one byte.
Definition unit_SP485.cpp:149
bool writeValue(const T value)
Write the any number value.
Definition unit_SP485.hpp:251
void flush()
Flushes the serial port.
Definition unit_SP485.hpp:172
int read()
Reads one byte.
Definition unit_SP485.hpp:125
size_t read(uint8_t *buffer, const size_t size)
Reads up to size bytes into buffer.
Definition unit_SP485.hpp:135
UnitSP485()
Constructor.
Definition unit_SP485.cpp:125
config_t config()
Gets the configuration.
Definition unit_SP485.hpp:75
int peek()
Peeks the next incoming byte without removing it.
Definition unit_SP485.hpp:117
int available()
Returns the number of available bytes to read.
Definition unit_SP485.hpp:101
bool readValue(T &value)
Read the any number value.
Definition unit_SP485.hpp:227
void config(const config_t &cfg)
Sets the configuration.
Definition unit_SP485.hpp:83
size_t read(char *buffer, const size_t size)
Reads up to size bytes into buffer.
Definition unit_SP485.hpp:145
Top level namespace of M5stack.
Settings for begin.
Definition unit_SP485.hpp:65
bool flushRX
Flush RX buffer on begin?
Definition unit_SP485.hpp:66