@@ -0,0 +1,144 @@
|
||||
#include <vamp_pico/display.hpp>
|
||||
#include <vamp_pico/http_client.hpp>
|
||||
#include <vamp_pico/touch.hpp>
|
||||
#include <vamp_protocol/page_control.hpp>
|
||||
|
||||
#include "pico/cyw43_arch.h"
|
||||
#include "pico/stdlib.h"
|
||||
|
||||
namespace {
|
||||
|
||||
enum class link_status {
|
||||
CONNECTING,
|
||||
RETRYING,
|
||||
CONNECTED,
|
||||
};
|
||||
|
||||
struct gesture_state {
|
||||
std::bool_t touching{};
|
||||
std::bool_t hold_sent{};
|
||||
std::bool_t pending_tap{};
|
||||
absolute_time_t down_time{};
|
||||
absolute_time_t last_up_time{};
|
||||
};
|
||||
|
||||
auto color_for(link_status status) -> vamp_style::color {
|
||||
switch (status) {
|
||||
case link_status::CONNECTING:
|
||||
return vamp_style::connecting;
|
||||
case link_status::RETRYING:
|
||||
return vamp_style::retrying;
|
||||
case link_status::CONNECTED:
|
||||
return vamp_style::connected;
|
||||
}
|
||||
return vamp_style::retrying;
|
||||
}
|
||||
|
||||
auto render(vamp_pico::display& display, link_status status, vamp_pico::remote_display_state const& remote) -> void {
|
||||
display.show_remote(color_for(status), remote.title, remote.part, remote.page, remote.pages, remote.active);
|
||||
}
|
||||
|
||||
auto connect_wifi(vamp_pico::display& display) -> std::bool_t {
|
||||
auto empty = vamp_pico::remote_display_state{};
|
||||
render(display, link_status::CONNECTING, empty);
|
||||
if (cyw43_arch_init() != 0) {
|
||||
display.show_boot("WIFI", "ERROR", vamp_style::rgb565(vamp_style::danger));
|
||||
return false;
|
||||
}
|
||||
cyw43_arch_enable_sta_mode();
|
||||
while (cyw43_arch_wifi_connect_timeout_ms(VAMP_PICO_WIFI_SSID, VAMP_PICO_WIFI_PASSPHRASE, CYW43_AUTH_WPA2_AES_PSK, 15000) != 0) {
|
||||
render(display, link_status::RETRYING, empty);
|
||||
sleep_ms(2000);
|
||||
render(display, link_status::CONNECTING, empty);
|
||||
}
|
||||
render(display, link_status::RETRYING, empty);
|
||||
return true;
|
||||
}
|
||||
|
||||
auto send_command(vamp_protocol::page_command command, link_status& status, vamp_pico::remote_display_state& remote, vamp_pico::display& display) -> void {
|
||||
if (!vamp_pico::post_remote_command(command, remote)) {
|
||||
status = link_status::RETRYING;
|
||||
render(display, status, remote);
|
||||
return;
|
||||
}
|
||||
status = link_status::CONNECTED;
|
||||
render(display, status, remote);
|
||||
}
|
||||
|
||||
auto update_gesture(gesture_state& gesture, std::bool_t touching, link_status& status, vamp_pico::remote_display_state& remote, vamp_pico::display& display) -> void {
|
||||
constexpr auto hold_us = std::int64_t{700000};
|
||||
constexpr auto double_tap_us = std::int64_t{220000};
|
||||
auto now = get_absolute_time();
|
||||
|
||||
if (touching && !gesture.touching) {
|
||||
gesture.touching = true;
|
||||
gesture.hold_sent = false;
|
||||
gesture.down_time = now;
|
||||
}
|
||||
|
||||
if (touching && !gesture.hold_sent && absolute_time_diff_us(gesture.down_time, now) >= hold_us) {
|
||||
gesture.hold_sent = true;
|
||||
gesture.pending_tap = false;
|
||||
send_command(vamp_protocol::page_command::SELECT, status, remote, display);
|
||||
}
|
||||
|
||||
if (!touching && gesture.touching) {
|
||||
gesture.touching = false;
|
||||
if (!gesture.hold_sent) {
|
||||
if (gesture.pending_tap && absolute_time_diff_us(gesture.last_up_time, now) <= double_tap_us) {
|
||||
gesture.pending_tap = false;
|
||||
send_command(vamp_protocol::page_command::PREVIOUS, status, remote, display);
|
||||
} else {
|
||||
gesture.pending_tap = true;
|
||||
gesture.last_up_time = now;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!touching && gesture.pending_tap && absolute_time_diff_us(gesture.last_up_time, now) > double_tap_us) {
|
||||
gesture.pending_tap = false;
|
||||
send_command(vamp_protocol::page_command::NEXT, status, remote, display);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
auto main() -> int {
|
||||
stdio_init_all();
|
||||
|
||||
auto display = vamp_pico::display{};
|
||||
auto touch = vamp_pico::touch_controller{};
|
||||
display.init();
|
||||
touch.init();
|
||||
|
||||
if (!connect_wifi(display)) {
|
||||
while (true) {
|
||||
sleep_ms(1000);
|
||||
}
|
||||
}
|
||||
|
||||
auto remote = vamp_pico::remote_display_state{};
|
||||
auto status = link_status::RETRYING;
|
||||
auto gesture = gesture_state{};
|
||||
auto last_poll = get_absolute_time();
|
||||
auto poll_now = true;
|
||||
render(display, status, remote);
|
||||
|
||||
while (true) {
|
||||
auto point = vamp_pico::touch_point{};
|
||||
update_gesture(gesture, touch.read(point), status, remote, display);
|
||||
|
||||
auto now = get_absolute_time();
|
||||
if (poll_now || absolute_time_diff_us(last_poll, now) >= 1000000) {
|
||||
poll_now = false;
|
||||
last_poll = now;
|
||||
if (vamp_pico::fetch_remote_display(remote)) {
|
||||
status = link_status::CONNECTED;
|
||||
} else {
|
||||
status = link_status::RETRYING;
|
||||
}
|
||||
render(display, status, remote);
|
||||
}
|
||||
sleep_ms(8);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user