Skip to content

Commit c02044c

Browse files
committed
feat(base_peripheral): Update mutex to be mutable and make all read methods const.
1 parent 3fb544c commit c02044c

File tree

1 file changed

+105
-63
lines changed

1 file changed

+105
-63
lines changed

components/base_peripheral/include/base_peripheral.hpp

Lines changed: 105 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ class BasePeripheral : public BaseComponent {
100100
/// \note If the probe function is not set, this function will return false
101101
/// and set the error code to operation_not_supported
102102
/// \note This function is only available if UseAddress is true
103-
bool probe(std::error_code &ec) requires(UseAddress) {
103+
bool probe(std::error_code &ec) const requires(UseAddress) {
104104
std::lock_guard<std::recursive_mutex> lock(base_mutex_);
105105
if (base_config_.probe) {
106106
return base_config_.probe(base_config_.address);
@@ -213,6 +213,14 @@ class BasePeripheral : public BaseComponent {
213213
base_config_ = std::move(config);
214214
}
215215

216+
/// Get the configuration for the peripheral
217+
/// \return The configuration for the peripheral
218+
const Config &config() const { return base_config_; }
219+
220+
/// Get the address of the peripheral
221+
/// \return The address of the peripheral
222+
uint8_t address() const { return base_config_.address; }
223+
216224
protected:
217225
/// Constructor
218226
/// \param config The configuration for the peripheral
@@ -223,14 +231,6 @@ class BasePeripheral : public BaseComponent {
223231
: BaseComponent(name, verbosity)
224232
, base_config_(config) {}
225233

226-
/// Get the configuration for the peripheral
227-
/// \return The configuration for the peripheral
228-
const Config &config() const { return base_config_; }
229-
230-
/// Get the address of the peripheral
231-
/// \return The address of the peripheral
232-
uint8_t address() const { return base_config_.address; }
233-
234234
/// Write data to the peripheral
235235
/// \param data The data to write
236236
/// \param length The length of the data to write
@@ -269,7 +269,7 @@ class BasePeripheral : public BaseComponent {
269269
/// \param data The buffer to read into
270270
/// \param length The length of the buffer
271271
/// \param ec The error code to set if there is an error
272-
void read(uint8_t *data, size_t length, std::error_code &ec) requires(UseAddress) {
272+
void read(uint8_t *data, size_t length, std::error_code &ec) const requires(UseAddress) {
273273
std::lock_guard<std::recursive_mutex> lock(base_mutex_);
274274
if (base_config_.read) {
275275
if (!base_config_.read(base_config_.address, data, length)) {
@@ -286,7 +286,7 @@ class BasePeripheral : public BaseComponent {
286286
/// \param data The buffer to read into
287287
/// \param length The length of the buffer
288288
/// \param ec The error code to set if there is an error
289-
void read(uint8_t *data, size_t length, std::error_code &ec) requires(!UseAddress) {
289+
void read(uint8_t *data, size_t length, std::error_code &ec) const requires(!UseAddress) {
290290
std::lock_guard<std::recursive_mutex> lock(base_mutex_);
291291
if (base_config_.read) {
292292
if (!base_config_.read(data, length)) {
@@ -305,7 +305,7 @@ class BasePeripheral : public BaseComponent {
305305
/// \param length The length of the buffer
306306
/// \param ec The error code to set if there is an error
307307
void read_register(RegisterAddressType reg_addr, uint8_t *data, size_t length,
308-
std::error_code &ec) requires(UseAddress) {
308+
std::error_code &ec) const requires(UseAddress) {
309309
std::lock_guard<std::recursive_mutex> lock(base_mutex_);
310310
if (base_config_.read_register) {
311311
if (!base_config_.read_register(base_config_.address, reg_addr, data, length)) {
@@ -314,7 +314,42 @@ class BasePeripheral : public BaseComponent {
314314
ec.clear();
315315
}
316316
} else {
317-
ec = std::make_error_code(std::errc::operation_not_supported);
317+
// use the size of the register address to determine how many bytes the
318+
// register address is
319+
static constexpr size_t reg_addr_size = sizeof(RegisterAddressType);
320+
uint8_t buffer[reg_addr_size];
321+
put_register_bytes(reg_addr, buffer);
322+
323+
// now we need to determine if we can write_then_read, or if we need to
324+
// write then read separately
325+
if (base_config_.write_then_read) {
326+
// we can use write_then_read
327+
if (!base_config_.write_then_read(base_config_.address, buffer, reg_addr_size, data,
328+
length)) {
329+
ec = std::make_error_code(std::errc::io_error);
330+
} else {
331+
ec.clear();
332+
}
333+
} else if (base_config_.write && base_config_.read) {
334+
if (!base_config_.write(base_config_.address, buffer, reg_addr_size)) {
335+
ec = std::make_error_code(std::errc::io_error);
336+
return;
337+
}
338+
if (ec) {
339+
return;
340+
}
341+
if (base_config_.separate_write_then_read_delay.count() > 0) {
342+
std::this_thread::sleep_for(base_config_.separate_write_then_read_delay);
343+
}
344+
if (!base_config_.read(base_config_.address, data, length)) {
345+
ec = std::make_error_code(std::errc::io_error);
346+
return;
347+
}
348+
} else {
349+
// we can't do anything
350+
ec = std::make_error_code(std::errc::operation_not_supported);
351+
return;
352+
}
318353
}
319354
}
320355

@@ -324,7 +359,7 @@ class BasePeripheral : public BaseComponent {
324359
/// \param length The length of the buffer
325360
/// \param ec The error code to set if there is an error
326361
void read_register(RegisterAddressType reg_addr, uint8_t *data, size_t length,
327-
std::error_code &ec) requires(!UseAddress) {
362+
std::error_code &ec) const requires(!UseAddress) {
328363
std::lock_guard<std::recursive_mutex> lock(base_mutex_);
329364
if (base_config_.read_register) {
330365
if (!base_config_.read_register(reg_addr, data, length)) {
@@ -333,7 +368,38 @@ class BasePeripheral : public BaseComponent {
333368
ec.clear();
334369
}
335370
} else {
336-
ec = std::make_error_code(std::errc::operation_not_supported);
371+
// use the size of the register address to determine how many bytes the
372+
// register address is
373+
static constexpr size_t reg_addr_size = sizeof(RegisterAddressType);
374+
uint8_t buffer[reg_addr_size];
375+
put_register_bytes(reg_addr, buffer);
376+
377+
// now we need to determine if we can write_then_read, or if we need to
378+
// write then read separately
379+
if (base_config_.write_then_read) {
380+
// we can use write_then_read
381+
if (!base_config_.write_then_read(buffer, reg_addr_size, data, length)) {
382+
ec = std::make_error_code(std::errc::io_error);
383+
} else {
384+
ec.clear();
385+
}
386+
} else if (base_config_.write && base_config_.read) {
387+
if (!base_config_.write(buffer, reg_addr_size)) {
388+
ec = std::make_error_code(std::errc::io_error);
389+
return;
390+
}
391+
if (base_config_.separate_write_then_read_delay.count() > 0) {
392+
std::this_thread::sleep_for(base_config_.separate_write_then_read_delay);
393+
}
394+
if (!base_config_.read(data, length)) {
395+
ec = std::make_error_code(std::errc::io_error);
396+
return;
397+
}
398+
} else {
399+
// we can't do anything
400+
ec = std::make_error_code(std::errc::operation_not_supported);
401+
return;
402+
}
337403
}
338404
}
339405

@@ -356,14 +422,17 @@ class BasePeripheral : public BaseComponent {
356422
}
357423
} else if (base_config_.write && base_config_.read) {
358424
logger_.debug("write {} bytes then read {} bytes", write_length, read_length);
359-
write(write_data, write_length, ec);
360-
if (ec) {
425+
if (!base_config_.write(base_config_.address, write_data, write_length)) {
426+
ec = std::make_error_code(std::errc::io_error);
361427
return;
362428
}
363429
if (base_config_.separate_write_then_read_delay.count() > 0) {
364430
std::this_thread::sleep_for(base_config_.separate_write_then_read_delay);
365431
}
366-
read(read_data, read_length, ec);
432+
if (!base_config_.read(base_config_.address, read_data, read_length)) {
433+
ec = std::make_error_code(std::errc::io_error);
434+
return;
435+
}
367436
} else {
368437
ec = std::make_error_code(std::errc::operation_not_supported);
369438
}
@@ -445,7 +514,7 @@ class BasePeripheral : public BaseComponent {
445514
/// \param data The buffer to read into
446515
/// \param length The length of the buffer
447516
/// \param ec The error code to set if there is an error
448-
void read_many(uint8_t *data, size_t length, std::error_code &ec) {
517+
void read_many(uint8_t *data, size_t length, std::error_code &ec) const {
449518
logger_.debug("read {} bytes", length);
450519
read(data, length, ec);
451520
}
@@ -456,15 +525,15 @@ class BasePeripheral : public BaseComponent {
456525
/// \note You should ensure that the buffer is the correct size before calling
457526
/// this function since the buffer size is what is used to know how many
458527
/// bytes to read
459-
void read_many(std::vector<uint8_t> &data, std::error_code &ec) {
528+
void read_many(std::vector<uint8_t> &data, std::error_code &ec) const {
460529
logger_.debug("read {} bytes", data.size());
461530
read(data.data(), data.size(), ec);
462531
}
463532

464533
/// Read a uint8_t from the peripheral
465534
/// \param ec The error code to set if there is an error
466535
/// \return The data read from the peripheral
467-
uint8_t read_u8(std::error_code &ec) {
536+
uint8_t read_u8(std::error_code &ec) const {
468537
logger_.debug("read u8");
469538
uint8_t data = 0;
470539
read(&data, 1, ec);
@@ -477,7 +546,7 @@ class BasePeripheral : public BaseComponent {
477546
/// Read a uint16_t from the peripheral
478547
/// \param ec The error code to set if there is an error
479548
/// \return The data read from the peripheral
480-
uint16_t read_u16(std::error_code &ec) {
549+
uint16_t read_u16(std::error_code &ec) const {
481550
logger_.debug("read u16");
482551
uint16_t data = 0;
483552
uint8_t buffer[2];
@@ -559,22 +628,13 @@ class BasePeripheral : public BaseComponent {
559628
/// \param register_address The address of the register to read from
560629
/// \param ec The error code to set if there is an error
561630
/// \return The data read from the peripheral
562-
uint8_t read_u8_from_register(RegisterAddressType register_address, std::error_code &ec) {
631+
uint8_t read_u8_from_register(RegisterAddressType register_address, std::error_code &ec) const {
563632
logger_.debug("read u8 from register 0x{:x}", register_address);
564633
uint8_t data = 0;
565634
std::lock_guard<std::recursive_mutex> lock(base_mutex_);
566-
if (base_config_.read_register) {
567-
read_register(register_address, &data, 1, ec);
568-
} else {
569-
// use the size of the register address to determine how many bytes the
570-
// register address is
571-
static constexpr size_t reg_addr_size = sizeof(RegisterAddressType);
572-
uint8_t buffer[reg_addr_size];
573-
put_register_bytes(register_address, buffer);
574-
write_then_read(buffer, reg_addr_size, &data, 1, ec);
575-
if (ec) {
576-
return 0;
577-
}
635+
read_register(register_address, &data, 1, ec);
636+
if (ec) {
637+
return 0;
578638
}
579639
return data;
580640
}
@@ -583,22 +643,13 @@ class BasePeripheral : public BaseComponent {
583643
/// \param register_address The address of the register to read from
584644
/// \param ec The error code to set if there is an error
585645
/// \return The data read from the peripheral
586-
uint16_t read_u16_from_register(RegisterAddressType register_address, std::error_code &ec) {
646+
uint16_t read_u16_from_register(RegisterAddressType register_address, std::error_code &ec) const {
587647
logger_.debug("read u16 from register 0x{:x}", register_address);
588648
uint8_t data[2];
589649
std::lock_guard<std::recursive_mutex> lock(base_mutex_);
590-
if (base_config_.read_register) {
591-
read_register(register_address, data, 2, ec);
592-
} else {
593-
// use the size of the register address to determine how many bytes the
594-
// register address is
595-
static constexpr size_t reg_addr_size = sizeof(RegisterAddressType);
596-
uint8_t buffer[reg_addr_size];
597-
put_register_bytes(register_address, buffer);
598-
write_then_read(buffer, reg_addr_size, (uint8_t *)&data, 2, ec);
599-
if (ec) {
600-
return 0;
601-
}
650+
read_register(register_address, data, 2, ec);
651+
if (ec) {
652+
return 0;
602653
}
603654
if constexpr (BigEndianData) {
604655
return (data[0] << 8) | data[1];
@@ -613,28 +664,19 @@ class BasePeripheral : public BaseComponent {
613664
/// \param length The length of the buffer
614665
/// \param ec The error code to set if there is an error
615666
void read_many_from_register(RegisterAddressType register_address, uint8_t *data, size_t length,
616-
std::error_code &ec) {
667+
std::error_code &ec) const {
617668
logger_.debug("read_many_from_register {} bytes from register 0x{:x}", length,
618669
register_address);
619670
std::lock_guard<std::recursive_mutex> lock(base_mutex_);
620-
if (base_config_.read_register) {
621-
read_register(register_address, data, length, ec);
622-
} else {
623-
// use the size of the register address to determine how many bytes the
624-
// register address is
625-
static constexpr size_t reg_addr_size = sizeof(RegisterAddressType);
626-
uint8_t buffer[reg_addr_size];
627-
put_register_bytes(register_address, buffer);
628-
write_then_read(buffer, reg_addr_size, data, length, ec);
629-
}
671+
read_register(register_address, data, length, ec);
630672
}
631673

632674
/// Read many bytes from a register on the peripheral
633675
/// \param register_address The address of the register to read from
634676
/// \param data The buffer to read into
635677
/// \param ec The error code to set if there is an error
636678
void read_many_from_register(RegisterAddressType register_address, std::vector<uint8_t> &data,
637-
std::error_code &ec) {
679+
std::error_code &ec) const {
638680
logger_.debug("read_many_from_register {} bytes from register 0x{:x}", data.size(),
639681
register_address);
640682
read_many_from_register(register_address, data.data(), data.size(), ec);
@@ -771,7 +813,7 @@ class BasePeripheral : public BaseComponent {
771813
}
772814

773815
// Set the bytes of the register address in the buffer
774-
void put_register_bytes(RegisterAddressType register_address, uint8_t *data) {
816+
void put_register_bytes(RegisterAddressType register_address, uint8_t *data) const {
775817
if constexpr (std::is_same_v<RegisterAddressType, uint8_t>) {
776818
data[0] = register_address;
777819
} else {
@@ -794,7 +836,7 @@ class BasePeripheral : public BaseComponent {
794836
}
795837
}
796838

797-
Config base_config_; ///< The configuration for the peripheral
798-
std::recursive_mutex base_mutex_; ///< The mutex to protect access to the peripheral
839+
Config base_config_; ///< The configuration for the peripheral
840+
mutable std::recursive_mutex base_mutex_; ///< The mutex to protect access to the peripheral
799841
};
800842
} // namespace espp

0 commit comments

Comments
 (0)