Compare commits
No commits in common. "b1ae5dcd489e2d58005cce85504f8f80f6f6b93c" and "f098154b8d0b0adc9147070a90ad49f2f90cff07" have entirely different histories.
b1ae5dcd48
...
f098154b8d
3
.gitmodules
vendored
3
.gitmodules
vendored
@ -4,6 +4,3 @@
|
|||||||
[submodule "firmware/components/etlcpp/etl"]
|
[submodule "firmware/components/etlcpp/etl"]
|
||||||
path = firmware/components/etlcpp/etl
|
path = firmware/components/etlcpp/etl
|
||||||
url = https://github.com/ETLCPP/etl.git
|
url = https://github.com/ETLCPP/etl.git
|
||||||
[submodule "firmware/components/skullc/skullc-peripherals"]
|
|
||||||
path = firmware/components/skullc/skullc-peripherals
|
|
||||||
url = https://git.skullnet.me/erki/skullc-peripherals.git
|
|
||||||
|
|||||||
@ -1,6 +0,0 @@
|
|||||||
idf_component_register(INCLUDE_DIRS
|
|
||||||
"skullc-peripherals/Peripherals/Inc"
|
|
||||||
"skullc-peripherals/Utility/Inc"
|
|
||||||
SRC_DIRS
|
|
||||||
"skullc-peripherals/Utility/Src"
|
|
||||||
REQUIRES etlcpp driver)
|
|
||||||
@ -1 +0,0 @@
|
|||||||
Subproject commit 470ad7537695229e57f2332fdd54a96fed3e556a
|
|
||||||
@ -1,11 +1,6 @@
|
|||||||
idf_component_register(
|
idf_component_register(
|
||||||
SRCS "main.cpp" "wifi_provisioner.cpp" "clock_core.cpp"
|
SRCS "main.cpp" "wifi_provisioner.cpp" "clock_core.cpp"
|
||||||
INCLUDE_DIRS ""
|
INCLUDE_DIRS ""
|
||||||
REQUIRES nvs_flash esp_wifi esp_http_server etlcpp json skullc
|
REQUIRES nvs_flash esp_wifi esp_http_server etlcpp json
|
||||||
EMBED_FILES "${CMAKE_CURRENT_LIST_DIR}/static/index.html"
|
EMBED_FILES "${CMAKE_CURRENT_LIST_DIR}/static/index.html"
|
||||||
)
|
)
|
||||||
|
|
||||||
component_compile_definitions(
|
|
||||||
SKULLC_WITH_HAL
|
|
||||||
SKULLC_USE_HAL_ESP
|
|
||||||
)
|
|
||||||
|
|||||||
@ -5,12 +5,9 @@
|
|||||||
#include "clock_core.hpp"
|
#include "clock_core.hpp"
|
||||||
|
|
||||||
#include "esp_expected.hpp"
|
#include "esp_expected.hpp"
|
||||||
#include "clock_core_event.hpp"
|
|
||||||
#include "string_helpers.hpp"
|
|
||||||
|
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <ctime>
|
#include <ctime>
|
||||||
#include <etl/string.h>
|
|
||||||
|
|
||||||
#include <esp_event.h>
|
#include <esp_event.h>
|
||||||
#include <esp_log.h>
|
#include <esp_log.h>
|
||||||
@ -18,37 +15,21 @@
|
|||||||
#include <esp_netif_sntp.h>
|
#include <esp_netif_sntp.h>
|
||||||
#include <esp_wifi.h>
|
#include <esp_wifi.h>
|
||||||
|
|
||||||
#include <peripherals_hal_esp.hpp>
|
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
|
|
||||||
const char* TAG = "clock_core";
|
const char* TAG = "clock_core";
|
||||||
|
|
||||||
struct Context
|
constexpr EventBits_t WIFI_FAIL_BIT = BIT0;
|
||||||
{
|
constexpr EventBits_t WIFI_CONNECTED_BIT = BIT1;
|
||||||
clock_core::EventGroup* events = nullptr;
|
constexpr EventBits_t SNTP_SYNCED_BIT = BIT2;
|
||||||
|
constexpr EventBits_t CLOCK_UPDATE_BIT = BIT3;
|
||||||
Context(const Context&) = delete;
|
EventGroupHandle_t clock_core_event_group_;
|
||||||
Context(Context&&) = delete;
|
|
||||||
Context& operator=(const Context&) = delete;
|
|
||||||
Context& operator=(Context&&) = delete;
|
|
||||||
|
|
||||||
static Context* getContext()
|
|
||||||
{
|
|
||||||
static Context ctx;
|
|
||||||
return &ctx;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
Context() = default;
|
|
||||||
};
|
|
||||||
|
|
||||||
void wifiEventHandler(void* arg, esp_event_base_t event_base,
|
void wifiEventHandler(void* arg, esp_event_base_t event_base,
|
||||||
int32_t event_id, void* event_data)
|
int32_t event_id, void* event_data)
|
||||||
{
|
{
|
||||||
static int retry_num = 0;
|
static int retry_num = 0;
|
||||||
auto* ctx = Context::getContext();
|
|
||||||
|
|
||||||
if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_START)
|
if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_START)
|
||||||
{
|
{
|
||||||
@ -64,7 +45,7 @@ void wifiEventHandler(void* arg, esp_event_base_t event_base,
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
ctx->events->setEvent(clock_core::EventGroup::WIFI_FAILED);
|
xEventGroupSetBits(clock_core_event_group_, WIFI_FAIL_BIT);
|
||||||
}
|
}
|
||||||
ESP_LOGW(TAG, "Connection to AP failed.");
|
ESP_LOGW(TAG, "Connection to AP failed.");
|
||||||
}
|
}
|
||||||
@ -73,20 +54,19 @@ void wifiEventHandler(void* arg, esp_event_base_t event_base,
|
|||||||
auto* event = static_cast<ip_event_got_ip_t*>(event_data);
|
auto* event = static_cast<ip_event_got_ip_t*>(event_data);
|
||||||
ESP_LOGI(TAG, "Connected to AP. Got IP: " IPSTR, IP2STR(&event->ip_info.ip));
|
ESP_LOGI(TAG, "Connected to AP. Got IP: " IPSTR, IP2STR(&event->ip_info.ip));
|
||||||
retry_num = 0;
|
retry_num = 0;
|
||||||
ESP_LOGI(TAG, "FOLLOW: Events: %p, context: %p", ctx->events, ctx);
|
|
||||||
ctx->events->setEvent(clock_core::EventGroup::WIFI_CONNECTED);
|
xEventGroupSetBits(clock_core_event_group_, WIFI_CONNECTED_BIT);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void sntpEventHandler(struct timeval*)
|
void sntpEventHandler(struct timeval*)
|
||||||
{
|
{
|
||||||
Context::getContext()->events->setEvent(clock_core::EventGroup::SNTP_SYNCED);
|
xEventGroupSetBits(clock_core_event_group_, SNTP_SYNCED_BIT);
|
||||||
}
|
}
|
||||||
|
|
||||||
void timerEventHandler(TimerHandle_t timer)
|
void timerEventHandler(TimerHandle_t)
|
||||||
{
|
{
|
||||||
auto context = static_cast<Context*>(pvTimerGetTimerID(timer));
|
xEventGroupSetBits(clock_core_event_group_, CLOCK_UPDATE_BIT);
|
||||||
context->events->setEvent(clock_core::EventGroup::CLOCK_UPDATE);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
esp_err_t sntpInitialize()
|
esp_err_t sntpInitialize()
|
||||||
@ -118,12 +98,12 @@ std::expected<void, esp_err_t> wifiInitialize(const char* wifi_ssid, const char*
|
|||||||
TRY_ESP(esp_event_handler_instance_register(WIFI_EVENT,
|
TRY_ESP(esp_event_handler_instance_register(WIFI_EVENT,
|
||||||
ESP_EVENT_ANY_ID,
|
ESP_EVENT_ANY_ID,
|
||||||
&wifiEventHandler,
|
&wifiEventHandler,
|
||||||
Context::getContext(),
|
nullptr,
|
||||||
&instance_any_id));
|
&instance_any_id));
|
||||||
TRY_ESP(esp_event_handler_instance_register(IP_EVENT,
|
TRY_ESP(esp_event_handler_instance_register(IP_EVENT,
|
||||||
IP_EVENT_STA_GOT_IP,
|
IP_EVENT_STA_GOT_IP,
|
||||||
&wifiEventHandler,
|
&wifiEventHandler,
|
||||||
Context::getContext(),
|
nullptr,
|
||||||
&instance_got_ip));
|
&instance_got_ip));
|
||||||
|
|
||||||
wifi_sta_config_t sta_config;
|
wifi_sta_config_t sta_config;
|
||||||
@ -141,22 +121,6 @@ std::expected<void, esp_err_t> wifiInitialize(const char* wifi_ssid, const char*
|
|||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
etl::string<6> getCurrentTimeString()
|
|
||||||
{
|
|
||||||
std::time_t time_now;
|
|
||||||
std::tm time_info{};
|
|
||||||
std::time(&time_now);
|
|
||||||
localtime_r(&time_now, &time_info);
|
|
||||||
|
|
||||||
etl::string<6> buffer;
|
|
||||||
wrapUnsafeStringOps(buffer, [&time_info](char* string, const int available)
|
|
||||||
{
|
|
||||||
std::strftime(string, available, "%H:%M", &time_info);
|
|
||||||
});
|
|
||||||
|
|
||||||
return buffer;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace clock_core
|
namespace clock_core
|
||||||
@ -164,14 +128,11 @@ namespace clock_core
|
|||||||
|
|
||||||
void run(const char* wifi_ssid, const char* wifi_password)
|
void run(const char* wifi_ssid, const char* wifi_password)
|
||||||
{
|
{
|
||||||
EventGroup events;
|
clock_core_event_group_ = xEventGroupCreate();
|
||||||
Context::getContext()->events = &events;
|
|
||||||
ESP_LOGI(TAG, "INITIAL: Events: %p, context: %p", &events, Context::getContext());
|
|
||||||
|
|
||||||
auto clock_timer = xTimerCreate("clock_core",
|
auto clock_timer = xTimerCreate("clock_core",
|
||||||
pdMS_TO_TICKS(60'000),
|
pdMS_TO_TICKS(60'000),
|
||||||
pdTRUE,
|
pdTRUE,
|
||||||
Context::getContext(),
|
nullptr,
|
||||||
timerEventHandler);
|
timerEventHandler);
|
||||||
|
|
||||||
if (const auto res = wifiInitialize(wifi_ssid, wifi_password);
|
if (const auto res = wifiInitialize(wifi_ssid, wifi_password);
|
||||||
@ -183,9 +144,13 @@ void run(const char* wifi_ssid, const char* wifi_password)
|
|||||||
|
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
const EventBits_t bits = events.waitForEvent();
|
const EventBits_t bits = xEventGroupWaitBits(clock_core_event_group_,
|
||||||
|
WIFI_CONNECTED_BIT | WIFI_FAIL_BIT | SNTP_SYNCED_BIT | CLOCK_UPDATE_BIT,
|
||||||
|
pdTRUE,
|
||||||
|
pdFALSE,
|
||||||
|
portMAX_DELAY);
|
||||||
|
|
||||||
if (bits & EventGroup::WIFI_CONNECTED)
|
if (bits & WIFI_CONNECTED_BIT)
|
||||||
{
|
{
|
||||||
ESP_LOGI(TAG, "WiFi setup in clock_core::run successful.");
|
ESP_LOGI(TAG, "WiFi setup in clock_core::run successful.");
|
||||||
if (const auto res = esp_netif_sntp_start();
|
if (const auto res = esp_netif_sntp_start();
|
||||||
@ -197,18 +162,24 @@ void run(const char* wifi_ssid, const char* wifi_password)
|
|||||||
|
|
||||||
xTimerStart(clock_timer, pdMS_TO_TICKS(10));
|
xTimerStart(clock_timer, pdMS_TO_TICKS(10));
|
||||||
}
|
}
|
||||||
else if (bits & EventGroup::WIFI_FAILED)
|
else if (bits & WIFI_FAIL_BIT)
|
||||||
{
|
{
|
||||||
ESP_LOGE(TAG, "WiFi setup in clock_core::run failed.");
|
ESP_LOGE(TAG, "WiFi setup in clock_core::run failed.");
|
||||||
}
|
}
|
||||||
else if (bits & EventGroup::SNTP_SYNCED)
|
else if (bits & SNTP_SYNCED_BIT)
|
||||||
{
|
{
|
||||||
ESP_LOGI(TAG, "SNTP sync successful.");
|
ESP_LOGI(TAG, "SNTP sync successful.");
|
||||||
}
|
}
|
||||||
else if (bits & EventGroup::CLOCK_UPDATE)
|
else if (bits & CLOCK_UPDATE_BIT)
|
||||||
{
|
{
|
||||||
const auto time = getCurrentTimeString();
|
char time_buf[64];
|
||||||
ESP_LOGI(TAG, "Current time: %s", time.c_str());
|
std::time_t time_now;
|
||||||
|
std::tm time_info;
|
||||||
|
std::time(&time_now);
|
||||||
|
localtime_r(&time_now, &time_info);
|
||||||
|
|
||||||
|
std::strftime(time_buf, sizeof(time_buf), "%c", &time_info);
|
||||||
|
ESP_LOGI(TAG, "Current time: %s", time_buf);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|||||||
@ -1,45 +0,0 @@
|
|||||||
//
|
|
||||||
// Created by erki on 11/02/24.
|
|
||||||
//
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <freertos/FreeRTOS.h>
|
|
||||||
|
|
||||||
namespace clock_core
|
|
||||||
{
|
|
||||||
|
|
||||||
struct EventGroup
|
|
||||||
{
|
|
||||||
static constexpr EventBits_t WIFI_FAILED = BIT0;
|
|
||||||
static constexpr EventBits_t WIFI_CONNECTED = BIT1;
|
|
||||||
static constexpr EventBits_t SNTP_SYNCED = BIT2;
|
|
||||||
static constexpr EventBits_t CLOCK_UPDATE = BIT3;
|
|
||||||
static constexpr EventBits_t ALL_EVENTS = WIFI_FAILED | WIFI_CONNECTED | SNTP_SYNCED | CLOCK_UPDATE;
|
|
||||||
|
|
||||||
EventGroupHandle_t rtos_event_group = nullptr;
|
|
||||||
|
|
||||||
EventGroup()
|
|
||||||
: rtos_event_group(xEventGroupCreate())
|
|
||||||
{ }
|
|
||||||
EventGroup(const EventGroup&) = delete;
|
|
||||||
EventGroup(EventGroup&&) = delete;
|
|
||||||
EventGroup& operator=(const EventGroup&) = delete;
|
|
||||||
EventGroup& operator=(EventGroup&&) = delete;
|
|
||||||
|
|
||||||
void setEvent(const EventBits_t& bits)
|
|
||||||
{
|
|
||||||
xEventGroupSetBits(rtos_event_group, bits);
|
|
||||||
}
|
|
||||||
|
|
||||||
EventBits_t waitForEvent()
|
|
||||||
{
|
|
||||||
return xEventGroupWaitBits(rtos_event_group,
|
|
||||||
ALL_EVENTS,
|
|
||||||
pdTRUE,
|
|
||||||
pdFALSE,
|
|
||||||
portMAX_DELAY);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
@ -1,16 +0,0 @@
|
|||||||
//
|
|
||||||
// Created by erki on 16/02/24.
|
|
||||||
//
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
template<typename T, typename F>
|
|
||||||
auto wrapUnsafeStringOps(T& string, F&& operation)
|
|
||||||
{
|
|
||||||
string.initialize_free_space();
|
|
||||||
|
|
||||||
operation(string.data_end(), string.available());
|
|
||||||
|
|
||||||
string.trim_to_terminator();
|
|
||||||
return string;
|
|
||||||
}
|
|
||||||
@ -88,8 +88,7 @@ esp_err_t rootPostHandler_(httpd_req_t* req)
|
|||||||
};
|
};
|
||||||
|
|
||||||
etl::string<100> content_type;
|
etl::string<100> content_type;
|
||||||
content_type.initialize_free_space();
|
if (const auto err = httpd_req_get_hdr_value_str(req, "Content-Type", content_type.data(), content_type.max_size() - 1);
|
||||||
if (const auto err = httpd_req_get_hdr_value_str(req, "Content-Type", content_type.data_end(), content_type.available() - 1);
|
|
||||||
err != ESP_OK)
|
err != ESP_OK)
|
||||||
{
|
{
|
||||||
dispatch_error("Cannot parse header.");
|
dispatch_error("Cannot parse header.");
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user