Merge develop into main (#167)

- WiFi Connect app is now hidden by default, but accessible at the bottom of the WiFi Manage app when WiFi is turned on.
- WiFi service now turns on WiFi when calling connect() and WiFi is not on.
- Removed `blocking` option for `service::loader::startApp()`. This feature was unused and complex.
- Various apps: Moved private headers into Private/ folder.
- Various apps: created start() function for easy starting.
- Added documentation to all TactilityC APIs
- Refactored various `enum` into `class enum`
- Refactor M5Stack `initBoot()` (but VBus is still 0V for some reason)
This commit is contained in:
Ken Van Hoeylandt
2025-01-17 19:37:42 +01:00
committed by GitHub
parent 3ca0f8cf97
commit 3ea02d912f
147 changed files with 1538 additions and 739 deletions
+9 -9
View File
@@ -16,22 +16,22 @@ std::string Bundle::getString(const std::string& key) const {
bool Bundle::hasBool(const std::string& key) const {
auto entry = this->entries.find(key);
return entry != std::end(this->entries) && entry->second.type == TypeBool;
return entry != std::end(this->entries) && entry->second.type == Type::Bool;
}
bool Bundle::hasInt32(const std::string& key) const {
auto entry = this->entries.find(key);
return entry != std::end(this->entries) && entry->second.type == TypeInt32;
return entry != std::end(this->entries) && entry->second.type == Type::Int32;
}
bool Bundle::hasString(const std::string& key) const {
auto entry = this->entries.find(key);
return entry != std::end(this->entries) && entry->second.type == TypeString;
return entry != std::end(this->entries) && entry->second.type == Type::String;
}
bool Bundle::optBool(const std::string& key, bool& out) const {
auto entry = this->entries.find(key);
if (entry != std::end(this->entries) && entry->second.type == TypeBool) {
if (entry != std::end(this->entries) && entry->second.type == Type::Bool) {
out = entry->second.value_bool;
return true;
} else {
@@ -41,7 +41,7 @@ bool Bundle::optBool(const std::string& key, bool& out) const {
bool Bundle::optInt32(const std::string& key, int32_t& out) const {
auto entry = this->entries.find(key);
if (entry != std::end(this->entries) && entry->second.type == TypeInt32) {
if (entry != std::end(this->entries) && entry->second.type == Type::Int32) {
out = entry->second.value_int32;
return true;
} else {
@@ -51,7 +51,7 @@ bool Bundle::optInt32(const std::string& key, int32_t& out) const {
bool Bundle::optString(const std::string& key, std::string& out) const {
auto entry = this->entries.find(key);
if (entry != std::end(this->entries) && entry->second.type == TypeString) {
if (entry != std::end(this->entries) && entry->second.type == Type::String) {
out = entry->second.value_string;
return true;
} else {
@@ -61,7 +61,7 @@ bool Bundle::optString(const std::string& key, std::string& out) const {
void Bundle::putBool(const std::string& key, bool value) {
this->entries[key] = {
.type = TypeBool,
.type = Type::Bool,
.value_bool = value,
.value_string = ""
};
@@ -69,7 +69,7 @@ void Bundle::putBool(const std::string& key, bool value) {
void Bundle::putInt32(const std::string& key, int32_t value) {
this->entries[key] = {
.type = TypeInt32,
.type = Type::Int32,
.value_int32 = value,
.value_string = ""
};
@@ -77,7 +77,7 @@ void Bundle::putInt32(const std::string& key, int32_t value) {
void Bundle::putString(const std::string& key, const std::string& value) {
this->entries[key] = {
.type = TypeString,
.type = Type::String,
.value_bool = false,
.value_string = value
};
+5 -5
View File
@@ -19,11 +19,11 @@ private:
typedef uint32_t Hash;
typedef enum {
TypeBool,
TypeInt32,
TypeString,
} Type;
enum class Type {
Bool,
Int32,
String,
};
typedef struct {
Type type;
+1 -1
View File
@@ -9,7 +9,7 @@ namespace tt {
#define WAIT_FLAG 1
Dispatcher::Dispatcher() :
mutex(Mutex::TypeNormal)
mutex(Mutex::Type::Normal)
{}
Dispatcher::~Dispatcher() {
+10 -10
View File
@@ -61,15 +61,15 @@ namespace tt {
static char toPrefix(LogLevel level) {
switch (level) {
case LogLevelError:
case LogLevel::Error:
return 'E';
case LogLevelWarning:
case LogLevel::Warning:
return 'W';
case LogLevelInfo:
case LogLevel::Info:
return 'I';
case LogLevelDebug:
case LogLevel::Debug:
return 'D';
case LogLevelVerbose:
case LogLevel::Verbose:
return 'T';
default:
return '?';
@@ -78,15 +78,15 @@ static char toPrefix(LogLevel level) {
static const char* toColour(LogLevel level) {
switch (level) {
case LogLevelError:
case LogLevel::Error:
return "\033[1;31m";
case LogLevelWarning:
case LogLevel::Warning:
return "\033[33m";
case LogLevelInfo:
case LogLevel::Info:
return "\033[32m";
case LogLevelDebug:
case LogLevel::Debug:
return "\033[1;37m";
case LogLevelVerbose:
case LogLevel::Verbose:
return "\033[37m";
default:
return "";
+13 -13
View File
@@ -13,17 +13,17 @@
namespace tt {
/** Used for log output filtering */
enum LogLevel {
LogLevelNone, /*!< No log output */
LogLevelError, /*!< Critical errors, software module can not recover on its own */
LogLevelWarning, /*!< Error conditions from which recovery measures have been taken */
LogLevelInfo, /*!< Information messages which describe normal flow of events */
LogLevelDebug, /*!< Extra information which is not necessary for normal use (values, pointers, sizes, etc). */
LogLevelVerbose /*!< Bigger chunks of debugging information, or frequent messages which can potentially flood the output. */
enum class LogLevel {
None, /*!< No log output */
Error, /*!< Critical errors, software module can not recover on its own */
Warning, /*!< Error conditions from which recovery measures have been taken */
Info, /*!< Information messages which describe normal flow of events */
Debug, /*!< Extra information which is not necessary for normal use (values, pointers, sizes, etc). */
Verbose /*!< Bigger chunks of debugging information, or frequent messages which can potentially flood the output. */
};
struct LogEntry {
LogLevel level = LogLevelNone;
LogLevel level = LogLevel::None;
char message[TT_LOG_MESSAGE_SIZE] = { 0 };
};
@@ -64,14 +64,14 @@ void log(LogLevel level, const char* tag, const char* format, ...);
} // namespace
#define TT_LOG_E(tag, format, ...) \
tt::log(tt::LogLevelError, tag, format, ##__VA_ARGS__)
tt::log(tt::LogLevel::Error, tag, format, ##__VA_ARGS__)
#define TT_LOG_W(tag, format, ...) \
tt::log(tt::LogLevelWarning, tag, format, ##__VA_ARGS__)
tt::log(tt::LogLevel::Warning, tag, format, ##__VA_ARGS__)
#define TT_LOG_I(tag, format, ...) \
tt::log(tt::LogLevelInfo, tag, format, ##__VA_ARGS__)
tt::log(tt::LogLevel::Info, tag, format, ##__VA_ARGS__)
#define TT_LOG_D(tag, format, ...) \
tt::log(tt::LogLevelDebug, tag, format, ##__VA_ARGS__)
tt::log(tt::LogLevel::Debug, tag, format, ##__VA_ARGS__)
#define TT_LOG_T(tag, format, ...) \
tt::log(tt::LogLevelTrace, tag, format, ##__VA_ARGS__)
tt::log(tt::LogLevel::Trace, tag, format, ##__VA_ARGS__)
#endif // ESP_TARGET
+6 -6
View File
@@ -25,10 +25,10 @@ namespace tt {
Mutex::Mutex(Type type) : type(type) {
tt_mutex_info(data, "alloc");
switch (type) {
case TypeNormal:
case Type::Normal:
semaphore = xSemaphoreCreateMutex();
break;
case TypeRecursive:
case Type::Recursive:
semaphore = xSemaphoreCreateRecursiveMutex();
break;
default:
@@ -51,7 +51,7 @@ TtStatus Mutex::acquire(TickType_t timeout) const {
tt_mutex_info(mutex, "acquire");
switch (type) {
case TypeNormal:
case Type::Normal:
if (xSemaphoreTake(semaphore, timeout) != pdPASS) {
if (timeout != 0U) {
return TtStatusErrorTimeout;
@@ -61,7 +61,7 @@ TtStatus Mutex::acquire(TickType_t timeout) const {
} else {
return TtStatusOk;
}
case TypeRecursive:
case Type::Recursive:
if (xSemaphoreTakeRecursive(semaphore, timeout) != pdPASS) {
if (timeout != 0U) {
return TtStatusErrorTimeout;
@@ -82,14 +82,14 @@ TtStatus Mutex::release() const {
tt_mutex_info(mutex, "release");
switch (type) {
case TypeNormal: {
case Type::Normal: {
if (xSemaphoreGive(semaphore) != pdPASS) {
return TtStatusErrorResource;
} else {
return TtStatusOk;
}
}
case TypeRecursive:
case Type::Recursive:
if (xSemaphoreGiveRecursive(semaphore) != pdPASS) {
return TtStatusErrorResource;
} else {
+4 -4
View File
@@ -21,9 +21,9 @@ class Mutex : public Lockable {
public:
enum Type {
TypeNormal,
TypeRecursive,
enum class Type {
Normal,
Recursive,
};
private:
@@ -33,7 +33,7 @@ private:
public:
explicit Mutex(Type type = TypeNormal);
explicit Mutex(Type type = Type::Normal);
~Mutex() override;
/** Attempt to lock the mutex. Blocks until timeout passes or lock is acquired.
+1 -1
View File
@@ -32,7 +32,7 @@ public:
~Semaphore();
/** Acquire semaphore */
bool acquire(uint32_t timeoutTicks) const;
bool acquire(uint32_t timeout) const;
/** Release semaphore */
bool release() const;
+6 -2
View File
@@ -187,15 +187,19 @@ void Thread::start() {
tt_check(data.state == State::Stopped || data.taskHandle);
}
bool Thread::join() {
bool Thread::join(TickType_t timeout, TickType_t pollInterval) {
tt_check(thread_get_current() != this);
// !!! IMPORTANT NOTICE !!!
//
// If your thread exited, but your app stuck here: some other thread uses
// all cpu time, which delays kernel from releasing task handle
TickType_t start_ticks = kernel::getTicks();
while (data.taskHandle) {
kernel::delayMillis(10);
kernel::delayTicks(pollInterval);
if ((kernel::getTicks() - start_ticks) > timeout) {
return false;
}
}
return true;
+8 -3
View File
@@ -122,17 +122,22 @@ public:
void start();
/** Join Thread
* @warning Use this method only when CPU is not busy (Idle task receives control), otherwise it will wait forever.
* @warning make sure you manually interrupt any logic in your thread (e.g. by an EventFlag or boolean+Mutex)
* @param[in] timeout the maximum amount of time to wait
* @param[in] pollInterval the amount of ticks to wait before we check again if the thread is finished
* @return success result
*/
bool join();
bool join(TickType_t timeout = portMAX_DELAY, TickType_t pollInterval = 10);
/** Get FreeRTOS ThreadId for Thread instance
* @return ThreadId or nullptr
*/
ThreadId getId() const;
/** @return thread return code */
/**
* @warning crashes when state is not "stopped"
* @return thread return code
*/
int32_t getReturnCode() const;
private:
+1 -1
View File
@@ -21,7 +21,7 @@ Timer::Timer(Type type, Callback callback, std::shared_ptr<void> callbackContext
this->callbackContext = std::move(callbackContext);
UBaseType_t reload;
if (type == TypeOnce) {
if (type == Type::Once) {
reload = pdFALSE;
} else {
reload = pdTRUE;
+9 -9
View File
@@ -19,10 +19,15 @@ public:
Callback callback;
std::shared_ptr<void> callbackContext;
typedef enum {
TypeOnce = 0, ///< One-shot timer.
TypePeriodic = 1 ///< Repeating timer.
} Type;
enum class Type {
Once = 0, ///< One-shot timer.
Periodic = 1 ///< Repeating timer.
};
enum class Priority{
Normal, /**< Lower then other threads */
Elevated, /**< Same as other threads */
};
/**
* @param[in] type The timer type
@@ -74,11 +79,6 @@ public:
*/
bool setPendingCallback(PendingCallback callback, void* callbackContext, uint32_t callbackArg, TickType_t timeout);
enum class Priority{
Normal, /**< Lower then other threads */
Elevated, /**< Same as other threads */
};
/** Set Timer thread priority
* @param[in] priority The priority
*/