configuration.cpp 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. #include <FFat.h>
  2. #include "pb_decode.h"
  3. #include "pb_encode.h"
  4. #include "proto_gen/smartknob.pb.h"
  5. #include "semaphore_guard.h"
  6. #include "configuration.h"
  7. static const char* CONFIG_PATH = "/config.pb";
  8. Configuration::Configuration() {
  9. mutex_ = xSemaphoreCreateMutex();
  10. assert(mutex_ != NULL);
  11. }
  12. Configuration::~Configuration() {
  13. vSemaphoreDelete(mutex_);
  14. }
  15. bool Configuration::loadFromDisk() {
  16. SemaphoreGuard lock(mutex_);
  17. FatGuard fatGuard(logger_);
  18. if (!fatGuard.mounted_) {
  19. return false;
  20. }
  21. File f = FFat.open(CONFIG_PATH);
  22. if (!f) {
  23. log("Failed to read config file");
  24. return false;
  25. }
  26. size_t read = f.readBytes((char*)buffer_, sizeof(buffer_));
  27. f.close();
  28. pb_istream_t stream = pb_istream_from_buffer(buffer_, read);
  29. if (!pb_decode(&stream, PB_PersistentConfiguration_fields, &pb_buffer_)) {
  30. char buf[200];
  31. snprintf(buf, sizeof(buf), "Decoding failed: %s", PB_GET_ERROR(&stream));
  32. log(buf);
  33. pb_buffer_ = {};
  34. return false;
  35. }
  36. if (pb_buffer_.version != PERSISTENT_CONFIGURATION_VERSION) {
  37. char buf[200];
  38. snprintf(buf, sizeof(buf), "Invalid config version. Expected %u, received %u", PERSISTENT_CONFIGURATION_VERSION, pb_buffer_.version);
  39. log(buf);
  40. pb_buffer_ = {};
  41. return false;
  42. }
  43. loaded_ = true;
  44. char buf[200];
  45. snprintf(
  46. buf,
  47. sizeof(buf),
  48. "Motor calibration: calib=%u, pole_pairs=%u, zero_offset=%.2f, cw=%u",
  49. pb_buffer_.motor.calibrated,
  50. pb_buffer_.motor.pole_pairs,
  51. pb_buffer_.motor.zero_electrical_offset,
  52. pb_buffer_.motor.direction_cw
  53. );
  54. log(buf);
  55. return true;
  56. }
  57. bool Configuration::saveToDisk() {
  58. SemaphoreGuard lock(mutex_);
  59. pb_ostream_t stream = pb_ostream_from_buffer(buffer_, sizeof(buffer_));
  60. pb_buffer_.version = PERSISTENT_CONFIGURATION_VERSION;
  61. if (!pb_encode(&stream, PB_PersistentConfiguration_fields, &pb_buffer_)) {
  62. char buf[200];
  63. snprintf(buf, sizeof(buf), "Encoding failed: %s", PB_GET_ERROR(&stream));
  64. log(buf);
  65. return false;
  66. }
  67. FatGuard fatGuard(logger_);
  68. if (!fatGuard.mounted_) {
  69. return false;
  70. }
  71. File f = FFat.open(CONFIG_PATH, FILE_WRITE);
  72. if (!f) {
  73. log("Failed to read config file");
  74. return false;
  75. }
  76. size_t written = f.write(buffer_, stream.bytes_written);
  77. f.close();
  78. char buf[20];
  79. snprintf(buf, sizeof(buf), "Wrote %d bytes", written);
  80. log(buf);
  81. if (written != stream.bytes_written) {
  82. log("Failed to write all bytes to file");
  83. return false;
  84. }
  85. return true;
  86. }
  87. PB_PersistentConfiguration Configuration::get() {
  88. SemaphoreGuard lock(mutex_);
  89. if (!loaded_) {
  90. return PB_PersistentConfiguration();
  91. }
  92. return pb_buffer_;
  93. }
  94. bool Configuration::setMotorCalibrationAndSave(PB_MotorCalibration& motor_calibration) {
  95. {
  96. SemaphoreGuard lock(mutex_);
  97. pb_buffer_.motor = motor_calibration;
  98. pb_buffer_.has_motor = true;
  99. }
  100. return saveToDisk();
  101. }
  102. bool Configuration::setStrainCalibrationAndSave(PB_StrainCalibration& strain_calibration) {
  103. {
  104. SemaphoreGuard lock(mutex_);
  105. pb_buffer_.strain = strain_calibration;
  106. pb_buffer_.has_strain = true;
  107. }
  108. return saveToDisk();
  109. }
  110. void Configuration::setLogger(Logger* logger) {
  111. logger_ = logger;
  112. }
  113. void Configuration::log(const char* msg) {
  114. if (logger_ != nullptr) {
  115. logger_->log(msg);
  116. }
  117. }