mirror of
https://github.com/portapack-mayhem/mayhem-firmware.git
synced 2025-12-02 19:01:48 +00:00
Merge
This commit is contained in:
@@ -26,6 +26,7 @@
|
||||
#include <cstddef>
|
||||
#include <array>
|
||||
#include <functional>
|
||||
#include <algorithm>
|
||||
|
||||
#include "baseband_packet.hpp"
|
||||
#include "ert_packet.hpp"
|
||||
@@ -61,13 +62,15 @@ public:
|
||||
ChannelSpectrumConfig = 14,
|
||||
SpectrumStreamingConfig = 15,
|
||||
DisplaySleep = 16,
|
||||
TXDone = 17,
|
||||
Retune = 18,
|
||||
ReadyForSwitch = 19,
|
||||
AFSKData = 20,
|
||||
ModuleID = 21,
|
||||
FIFOSignal = 22,
|
||||
FIFOData = 23,
|
||||
CaptureConfig = 17,
|
||||
|
||||
TXDone = 20,
|
||||
Retune = 21,
|
||||
ReadyForSwitch = 22,
|
||||
AFSKData = 23,
|
||||
ModuleID = 24,
|
||||
FIFOSignal = 25,
|
||||
FIFOData = 26,
|
||||
MAX
|
||||
};
|
||||
|
||||
@@ -416,6 +419,46 @@ public:
|
||||
const iir_biquad_config_t audio_hpf_config;
|
||||
};
|
||||
|
||||
struct CaptureConfig {
|
||||
const size_t write_size_log2;
|
||||
const size_t buffer_count_log2;
|
||||
uint64_t baseband_bytes_received;
|
||||
uint64_t baseband_bytes_dropped;
|
||||
FIFO<uint8_t>* fifo;
|
||||
|
||||
constexpr CaptureConfig(
|
||||
const size_t write_size_log2,
|
||||
const size_t buffer_count_log2
|
||||
) : write_size_log2 { write_size_log2 },
|
||||
buffer_count_log2 { buffer_count_log2 },
|
||||
baseband_bytes_received { 0 },
|
||||
baseband_bytes_dropped { 0 },
|
||||
fifo { nullptr }
|
||||
{
|
||||
}
|
||||
|
||||
size_t dropped_percent() const {
|
||||
if( baseband_bytes_dropped == 0 ) {
|
||||
return 0;
|
||||
} else {
|
||||
const size_t percent = baseband_bytes_dropped * 100U / baseband_bytes_received;
|
||||
return std::max(1U, percent);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
class CaptureConfigMessage : public Message {
|
||||
public:
|
||||
constexpr CaptureConfigMessage(
|
||||
CaptureConfig* const config
|
||||
) : Message { ID::CaptureConfig },
|
||||
config { config }
|
||||
{
|
||||
}
|
||||
|
||||
CaptureConfig* const config;
|
||||
};
|
||||
|
||||
class TXDoneMessage : public Message {
|
||||
public:
|
||||
TXDoneMessage(
|
||||
|
||||
@@ -20,3 +20,18 @@
|
||||
*/
|
||||
|
||||
#include "message_queue.hpp"
|
||||
|
||||
#include "lpc43xx_cpp.hpp"
|
||||
using namespace lpc43xx;
|
||||
|
||||
#if defined(LPC43XX_M0)
|
||||
void MessageQueue::signal() {
|
||||
creg::m0apptxevent::assert();
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(LPC43XX_M4)
|
||||
void MessageQueue::signal() {
|
||||
creg::m4txevent::assert();
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -27,9 +27,6 @@
|
||||
#include "message.hpp"
|
||||
#include "fifo.hpp"
|
||||
|
||||
#include "lpc43xx_cpp.hpp"
|
||||
using namespace lpc43xx;
|
||||
|
||||
#include <ch.h>
|
||||
|
||||
class MessageQueue {
|
||||
@@ -73,6 +70,10 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
bool is_empty() const {
|
||||
return fifo.is_empty();
|
||||
}
|
||||
|
||||
private:
|
||||
FIFO<uint8_t> fifo;
|
||||
Mutex mutex_write;
|
||||
@@ -95,10 +96,6 @@ private:
|
||||
return fifo.len();
|
||||
}
|
||||
|
||||
bool is_empty() const {
|
||||
return fifo.is_empty();
|
||||
}
|
||||
|
||||
bool push(const void* const buf, const size_t len) {
|
||||
chMtxLock(&mutex_write);
|
||||
const auto result = fifo.in_r(buf, len);
|
||||
@@ -111,18 +108,7 @@ private:
|
||||
return success;
|
||||
}
|
||||
|
||||
|
||||
#if defined(LPC43XX_M0)
|
||||
void signal() {
|
||||
creg::m0apptxevent::assert();
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(LPC43XX_M4)
|
||||
void signal() {
|
||||
creg::m4txevent::assert();
|
||||
}
|
||||
#endif
|
||||
void signal();
|
||||
};
|
||||
|
||||
#endif/*__MESSAGE_QUEUE_H__*/
|
||||
|
||||
@@ -51,9 +51,8 @@ static constexpr std::array<uint8_t, 12> png_iend { {
|
||||
|
||||
PNGWriter::PNGWriter(
|
||||
const std::string& filename
|
||||
)
|
||||
) : file { filename, File::openmode::out | File::openmode::binary | File::openmode::trunc }
|
||||
{
|
||||
file.open_for_writing(filename);
|
||||
file.write(png_file_header);
|
||||
file.write(png_ihdr_screen_capture);
|
||||
|
||||
|
||||
@@ -47,7 +47,6 @@ struct SharedMemory {
|
||||
uint8_t baseband_queue_data[1 << baseband_queue_k];
|
||||
MessageQueue application_queue;
|
||||
uint8_t application_queue_data[1 << application_queue_k];
|
||||
void* FIFO_HACK;
|
||||
|
||||
// TODO: M0 should directly configure and control DMA channel that is
|
||||
// acquiring ADC samples.
|
||||
|
||||
@@ -85,67 +85,78 @@ static void widget_collect_visible(Widget* const w, TestFn test, test_collection
|
||||
}
|
||||
}
|
||||
|
||||
static int32_t rect_distances(
|
||||
const KeyEvent direction,
|
||||
const Rect& rect_start,
|
||||
const Rect& rect_end
|
||||
) {
|
||||
Coord on_axis_max, on_axis_min;
|
||||
|
||||
switch(direction) {
|
||||
case KeyEvent::Right:
|
||||
on_axis_max = rect_end.left();
|
||||
on_axis_min = rect_start.right();
|
||||
break;
|
||||
|
||||
case KeyEvent::Left:
|
||||
on_axis_max = rect_start.left();
|
||||
on_axis_min = rect_end.right();
|
||||
break;
|
||||
|
||||
case KeyEvent::Down:
|
||||
on_axis_max = rect_end.top();
|
||||
on_axis_min = rect_start.bottom();
|
||||
break;
|
||||
|
||||
case KeyEvent::Up:
|
||||
on_axis_max = rect_start.top();
|
||||
on_axis_min = rect_end.bottom();
|
||||
break;
|
||||
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
|
||||
Coord on_axis_distance = on_axis_max - on_axis_min;
|
||||
if( on_axis_distance < 0 ) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
Coord perpendicular_axis_start, perpendicular_axis_end;
|
||||
|
||||
switch(direction) {
|
||||
case KeyEvent::Right:
|
||||
case KeyEvent::Left:
|
||||
perpendicular_axis_start = rect_start.center().y;
|
||||
perpendicular_axis_end = rect_end.center().y;
|
||||
break;
|
||||
|
||||
case KeyEvent::Up:
|
||||
case KeyEvent::Down:
|
||||
perpendicular_axis_start = rect_start.center().x;
|
||||
perpendicular_axis_end = rect_end.center().x;
|
||||
break;
|
||||
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
|
||||
return (std::abs(perpendicular_axis_end - perpendicular_axis_start) + 1) * (on_axis_distance + 1);
|
||||
}
|
||||
|
||||
void FocusManager::update(
|
||||
Widget* const top_widget,
|
||||
const KeyEvent event
|
||||
) {
|
||||
if( focus_widget() ) {
|
||||
const auto focus_screen_rect = focus_widget()->screen_rect();
|
||||
const auto center = focus_screen_rect.center();
|
||||
|
||||
const auto test_fn = [¢er, event](ui::Widget* const w) -> test_result_t {
|
||||
const auto test_fn = [&focus_screen_rect, event](ui::Widget* const w) -> test_result_t {
|
||||
// if( w->visible() && w->focusable() ) {
|
||||
if( w->focusable() ) {
|
||||
const Point delta = w->screen_rect().center() - center;
|
||||
|
||||
/* Heuristic to compute closeness. */
|
||||
/* TODO: Look at metric involving overlap of current
|
||||
* widget rectangle in the direction of movement, with
|
||||
* all the prospective widgets.
|
||||
*/
|
||||
switch(event) {
|
||||
case KeyEvent::Right:
|
||||
if( delta.x > 0 ) {
|
||||
if( delta.y == 0 ) {
|
||||
return { w, delta.x };
|
||||
} else {
|
||||
return { w, delta.x * abs(delta.y) + 1000 };
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case KeyEvent::Left:
|
||||
if( delta.x < 0 ) {
|
||||
if( delta.y == 0 ) {
|
||||
return { w, -delta.x };
|
||||
} else {
|
||||
return { w, -delta.x * abs(delta.y) + 1000 };
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case KeyEvent::Down:
|
||||
if( delta.y > 0 ) {
|
||||
if( delta.x == 0 ) {
|
||||
return { w, delta.y };
|
||||
} else {
|
||||
return { w, delta.y * abs(delta.x) + 1000 };
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case KeyEvent::Up:
|
||||
if( delta.y < 0 ) {
|
||||
if( delta.x == 0 ) {
|
||||
return { w, -delta.y };
|
||||
} else {
|
||||
return { w, -delta.y * abs(delta.x) + 1000 };
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
const auto distance = rect_distances(event, focus_screen_rect, w->screen_rect());
|
||||
if( distance >= 0 ) {
|
||||
return { w, distance };
|
||||
}
|
||||
}
|
||||
|
||||
@@ -167,34 +178,5 @@ void FocusManager::update(
|
||||
}
|
||||
}
|
||||
}
|
||||
#if 0
|
||||
void FocusManager::update(
|
||||
Widget* const top_widget,
|
||||
const TouchEvent event
|
||||
) {
|
||||
const auto test_fn = [event](Widget* const w) -> test_result_t {
|
||||
if( w->focusable() ) {
|
||||
const auto r = w->screen_rect();
|
||||
if( r.contains(event) ) {
|
||||
return { w, 0 };
|
||||
}
|
||||
}
|
||||
|
||||
return { nullptr, { } };
|
||||
};
|
||||
|
||||
test_collection_t collection;
|
||||
widget_collect_visible(
|
||||
top_widget, test_fn,
|
||||
collection
|
||||
);
|
||||
|
||||
if( !collection.empty() ) {
|
||||
// Take the last object in the collection, it will be rendered last,
|
||||
// therefore appear "on top".
|
||||
const auto touched = collection.back().first;
|
||||
touched->on_touch(event);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
} /* namespace ui */
|
||||
|
||||
@@ -38,7 +38,7 @@ Size Widget::size() const {
|
||||
return parent_rect.size;
|
||||
}
|
||||
|
||||
Rect Widget::screen_rect() {
|
||||
Rect Widget::screen_rect() const {
|
||||
return parent() ? (parent_rect + parent()->screen_pos()) : parent_rect;
|
||||
}
|
||||
|
||||
|
||||
@@ -51,12 +51,12 @@ private:
|
||||
|
||||
class Widget {
|
||||
public:
|
||||
constexpr Widget(
|
||||
Widget(
|
||||
) : parent_rect { }
|
||||
{
|
||||
}
|
||||
|
||||
constexpr Widget(
|
||||
Widget(
|
||||
Rect parent_rect
|
||||
) : parent_rect { parent_rect }
|
||||
{
|
||||
@@ -69,7 +69,7 @@ public:
|
||||
|
||||
Point screen_pos();
|
||||
Size size() const;
|
||||
Rect screen_rect();
|
||||
Rect screen_rect() const;
|
||||
virtual void set_parent_rect(const Rect new_parent_rect);
|
||||
|
||||
Widget* parent() const;
|
||||
|
||||
Reference in New Issue
Block a user