Compare commits

..

No commits in common. "0107d3e6e74d96c4ec35d7bfa2cf091ed353cb9f" and "8d49d2d4467ad8d597f2383a4bec81ec7d149187" have entirely different histories.

6 changed files with 12 additions and 184 deletions

View File

@ -42,7 +42,7 @@ public:
Button() = delete; Button() = delete;
explicit Button(const gpio& sw) explicit Button(const gpio& sw)
: sw(sw), was_pressed_(sw.read()) : sw(sw)
{} {}
void update() void update()
@ -59,15 +59,7 @@ public:
else if (!is_pressed && was_pressed_) else if (!is_pressed && was_pressed_)
{ {
if (time_held > TIMEOUT_SHORT_PRESS && time_held <= TIMEOUT_LONG_PRESS) if (time_held > TIMEOUT_SHORT_PRESS && time_held <= TIMEOUT_LONG_PRESS)
{
new_state = ButtonPress::SHORT_PRESS; new_state = ButtonPress::SHORT_PRESS;
}
if (state_exhausted_)
{
current_state_ = ButtonPress::NOT_PRESSED;
state_exhausted_ = false;
}
time_pressed_down_ = 0; time_pressed_down_ = 0;
} }
@ -78,25 +70,13 @@ public:
} }
was_pressed_ = is_pressed; was_pressed_ = is_pressed;
if (!state_exhausted_)
current_state_ = new_state; current_state_ = new_state;
} }
[[nodiscard]] ButtonPress getState() const [[nodiscard]] ButtonPress getState() const
{ {
if (!state_exhausted_)
{
if (current_state_ != ButtonPress::NOT_PRESSED && current_state_ != ButtonPress::SHORT_PRESS)
state_exhausted_ = true;
return current_state_; return current_state_;
} }
else
{
return ButtonPress::NOT_PRESSED;
}
}
#ifdef SKULLC_WITH_CORO #ifdef SKULLC_WITH_CORO
skullc::coro::Task<ButtonPress> await_press() skullc::coro::Task<ButtonPress> await_press()
@ -116,10 +96,9 @@ public:
#endif #endif
private: private:
bool was_pressed_; bool was_pressed_ = false;
std::uint32_t time_pressed_down_ = 0; std::uint32_t time_pressed_down_ = 0;
ButtonPress current_state_ = ButtonPress::NOT_PRESSED; ButtonPress current_state_ = ButtonPress::NOT_PRESSED;
mutable bool state_exhausted_ = false;
}; };
}// namespace Peripherals }// namespace Peripherals

View File

@ -31,7 +31,7 @@ template<typename Origin>
using IsrCallbackFn = void (*)(Origin*); using IsrCallbackFn = void (*)(Origin*);
template<typename Origin, typename Handler, void (Handler::*func)(), template<typename Origin, typename Handler, void (Handler::*func)(),
typename Tag = decltype([] {})> typename Tag>
IsrCallbackFn<Origin> createCallback(Handler& h_in) IsrCallbackFn<Origin> createCallback(Handler& h_in)
{ {
static Handler* h = &h_in; static Handler* h = &h_in;
@ -200,104 +200,6 @@ struct SerialInterfaceAsync
} }
}; };
#ifdef SKULLC_WITH_CORO
template<typename T,
HAL_StatusTypeDef (*transmit_)(T*, std::uint8_t* data,
std::uint16_t data_len),
HAL_StatusTypeDef (*receive_)(T*, std::uint8_t* data,
std::uint16_t data_len)>
struct SerialInterfaceCoro
{
private:
void on_rx_complete()
{
if (rx_awaiter_)
rx_awaiter_->set_completed();
}
void on_tx_complete()
{
if (tx_awaiter_)
tx_awaiter_->set_completed();
}
std::optional<skullc::coro::ISRAwaiter> rx_awaiter_ = std::nullopt;
std::optional<skullc::coro::ISRAwaiter> tx_awaiter_ = std::nullopt;
public:
using underlying_handle_type = T;
underlying_handle_type* handle;
SerialInterfaceCoro() = delete;
template<typename = decltype([] {})>
explicit SerialInterfaceCoro(underlying_handle_type* handle)
: handle(handle)
{
handle->RxCpltCallback = createCallback<T,
std::decay_t<decltype(*this)>,
&std::decay_t<decltype(*this)>::on_rx_complete>(*this);
handle->TxCpltCallback = createCallback<T,
std::decay_t<decltype(*this)>,
&std::decay_t<decltype(*this)>::on_tx_complete>(*this);
}
skullc::coro::Task<bool> transmit(std::uint8_t* data, const std::uint32_t data_len)
{
tx_awaiter_.emplace();
const auto status = transmit_(handle, data, data_len);
if (status != HAL_StatusTypeDef::HAL_OK)
co_return false;
co_await *tx_awaiter_;
tx_awaiter_ = std::nullopt;
co_return true;
}
template<typename Td, std::size_t N>
skullc::coro::Task<bool> transmit(std::array<Td, N>& array)
{
static_assert(sizeof(Td) == sizeof(std::uint8_t), "Data is not a byte large.");
return transmit(reinterpret_cast<std::uint8_t*>(array.data()), std::uint32_t(N));
}
skullc::coro::Task<bool> receive(std::uint8_t* data, const std::uint32_t data_len)
{
rx_awaiter_.emplace();
const auto status = receive_(handle, data, data_len);
if (status != HAL_StatusTypeDef::HAL_OK)
co_return false;
co_await *rx_awaiter_;
rx_awaiter_ = std::nullopt;
co_return true;
}
template<typename Td, std::size_t N>
skullc::coro::Task<bool> receive(std::array<Td, N>& array)
{
static_assert(sizeof(Td) == sizeof(std::uint8_t), "Data is not a byte large.");
return receive(reinterpret_cast<std::uint8_t*>(array.data()), std::uint32_t(N));
}
template<std::size_t N>
skullc::coro::Task<std::array<std::uint8_t, N>> receive()
{
std::array<std::uint8_t, N> data;
data.fill(0);
co_await receive(data.data(), std::uint32_t(N));
co_return data;
}
};
#endif// SKULLC_WITH_CORO
#ifdef HAL_SPI_MODULE_ENABLED #ifdef HAL_SPI_MODULE_ENABLED
using SpiInterface = using SpiInterface =
@ -394,11 +296,6 @@ inline HAL_StatusTypeDef uartTransmitDma(UART_HandleTypeDef* huart, std::uint8_t
return HAL_UART_Transmit_DMA(huart, data, size); return HAL_UART_Transmit_DMA(huart, data, size);
} }
inline HAL_StatusTypeDef uartTransmitIt(UART_HandleTypeDef* huart, std::uint8_t* data, const std::uint16_t size)
{
return HAL_UART_Transmit_IT(huart, data, size);
}
}// namespace _Details }// namespace _Details
using UartInterface = using UartInterface =
@ -406,14 +303,6 @@ using UartInterface =
using UartInterfaceDMA = using UartInterfaceDMA =
SerialInterfaceAsync<UART_HandleTypeDef, _Details::uartTransmitDma, SerialInterfaceAsync<UART_HandleTypeDef, _Details::uartTransmitDma,
HAL_UART_Receive_DMA>; HAL_UART_Receive_DMA>;
#ifdef SKULLC_WITH_CORO
using UartInterfaceCoro =
SerialInterfaceCoro<UART_HandleTypeDef, _Details::uartTransmitIt,
HAL_UART_Receive_IT>;
using UartInterfaceCoroDma =
SerialInterfaceCoro<UART_HandleTypeDef, _Details::uartTransmitDma,
HAL_UART_Receive_DMA>;
#endif// SKULLC_WITH_CORO
#endif// HAL_UART_MODULE_ENABLED #endif// HAL_UART_MODULE_ENABLED

View File

@ -46,10 +46,10 @@ struct Gpio
} }
void set(const bool value) void set(const bool value)
{} { }
void toggle() void toggle()
{} { }
}; };
bool Gpio::is_set = false; bool Gpio::is_set = false;

View File

@ -6,10 +6,10 @@
#include "skullc/coro/scheduler.hpp" #include "skullc/coro/scheduler.hpp"
#include "skullc/coro/semaphore.hpp" #include "skullc/coro/semaphore.hpp"
#include "skullc/coro/signal.hpp"
#include "skullc/coro/sleep.hpp" #include "skullc/coro/sleep.hpp"
#include "skullc/coro/task.hpp" #include "skullc/coro/task.hpp"
#include "skullc/coro/this_coro.hpp" #include "skullc/coro/this_coro.hpp"
#include "skullc/coro/signal.hpp"
#include <semaphore> #include <semaphore>
@ -263,7 +263,7 @@ skullc::coro::Task<> send_signal(const int value, skullc::coro::Signal<int>* sig
co_return; co_return;
} }
}// namespace }
TEST_CASE("Signal awaiters work.", "[coro],[signal]") TEST_CASE("Signal awaiters work.", "[coro],[signal]")
{ {
@ -300,7 +300,7 @@ TEST_CASE("Signal awaiters work.", "[coro],[signal]")
REQUIRE(test_coro_called == 1); REQUIRE(test_coro_called == 1);
} }
const std::vector<int> values = {10, 11, 13}; const std::vector<int> values = { 10, 11, 13 };
SECTION("Sending multiple values.") SECTION("Sending multiple values.")
{ {

View File

@ -4,7 +4,6 @@
#pragma once #pragma once
#include <atomic>
#include <coroutine> #include <coroutine>
#include <optional> #include <optional>
@ -79,42 +78,4 @@ private:
} }
}; };
struct ISRAwaiter
{
ISRAwaiter() = default;
~ISRAwaiter()
{
if (continuation)
this_coro::scheduler().remove(continuation);
}
bool await_ready()
{
return isr_completed;
}
void await_suspend(std::coroutine_handle<> h)
{
continuation = h;
suspended = true;
}
auto await_resume()
{
continuation = {};
}
void set_completed()
{
isr_completed = true;
if (suspended == true)
this_coro::scheduler().schedule(continuation, 0);
}
std::coroutine_handle<> continuation;
std::atomic<bool> isr_completed = false;
std::atomic<bool> suspended = false;
};
}// namespace skullc::coro }// namespace skullc::coro

View File

@ -83,10 +83,9 @@ public:
return *awaiter_; return *awaiter_;
} }
private: private:
std::optional<T> data_; std::optional<T> data_;
std::optional<Awaiter> awaiter_; std::optional<Awaiter> awaiter_;
}; };
}// namespace skullc::coro }