mirror of
https://github.com/portapack-mayhem/mayhem-firmware.git
synced 2025-08-25 05:47:44 +00:00
OOK transmit is mostly working, bit durations are wrong
Simplified messages carrying data (uses shared_memory instead) Added SymField widget (bitfield, symbol field...) Added some space for baseband code BMP palette loading bugfix
This commit is contained in:
@@ -291,7 +291,7 @@ void ILI9341::render_box(const ui::Point p, const ui::Size s, const ui::Color* l
|
||||
|
||||
// RLE_4 BMP loader (delta not implemented)
|
||||
void ILI9341::drawBMP(const ui::Point p, const uint8_t * bitmap, const bool transparency) {
|
||||
const bmp_t * bmp_header = (const bmp_t *)bitmap;
|
||||
const bmp_header_t * bmp_header = (const bmp_header_t *)bitmap;
|
||||
uint32_t data_idx;
|
||||
uint8_t by, c, count, transp_idx = 0;
|
||||
ui::Color line_buffer[240];
|
||||
@@ -303,13 +303,14 @@ void ILI9341::drawBMP(const ui::Point p, const uint8_t * bitmap, const bool tran
|
||||
(bmp_header->compression != 2)) return;
|
||||
|
||||
data_idx = bmp_header->image_data;
|
||||
const bmp_palette_t * bmp_palette = (const bmp_palette_t *)&bitmap[bmp_header->BIH_size + 14];
|
||||
|
||||
// Convert palette and find pure magenta index (alpha color key)
|
||||
for (c = 0; c < 16; c++) {
|
||||
palette[c] = ui::Color(bmp_header->palette[c].R, bmp_header->palette[c].G, bmp_header->palette[c].B);
|
||||
if ((bmp_header->palette[c].R == 0xFF) &&
|
||||
(bmp_header->palette[c].G == 0x00) &&
|
||||
(bmp_header->palette[c].B == 0xFF)) transp_idx = c;
|
||||
palette[c] = ui::Color(bmp_palette->color[c].R, bmp_palette->color[c].G, bmp_palette->color[c].B);
|
||||
if ((bmp_palette->color[c].R == 0xFF) &&
|
||||
(bmp_palette->color[c].G == 0x00) &&
|
||||
(bmp_palette->color[c].B == 0xFF)) transp_idx = c;
|
||||
}
|
||||
|
||||
if (!transparency) {
|
||||
|
@@ -111,7 +111,7 @@ private:
|
||||
};
|
||||
|
||||
#pragma pack(push, 1)
|
||||
struct bmp_t {
|
||||
struct bmp_header_t {
|
||||
uint16_t signature;
|
||||
uint32_t size;
|
||||
uint16_t reserved_1;
|
||||
@@ -128,15 +128,20 @@ private:
|
||||
uint32_t v_res;
|
||||
uint32_t colors_count;
|
||||
uint32_t icolors_count;
|
||||
struct palette {
|
||||
};
|
||||
#pragma pack(pop)
|
||||
|
||||
#pragma pack(push, 1)
|
||||
struct bmp_palette_t {
|
||||
struct color_t {
|
||||
uint8_t B;
|
||||
uint8_t G;
|
||||
uint8_t R;
|
||||
uint8_t A;
|
||||
} palette[16];
|
||||
} color[16];
|
||||
};
|
||||
#pragma pack(pop)
|
||||
|
||||
|
||||
scroll_t scroll_state;
|
||||
|
||||
void draw_pixels(const ui::Rect r, const ui::Color* const colors, const size_t count);
|
||||
|
@@ -67,7 +67,7 @@ public:
|
||||
|
||||
TXDone = 20,
|
||||
Retune = 21,
|
||||
XylosConfigure = 22,
|
||||
CCIRConfigure = 22,
|
||||
AFSKConfigure = 23,
|
||||
PWMRSSIConfigure = 24,
|
||||
OOKConfigure = 25,
|
||||
@@ -473,7 +473,7 @@ public:
|
||||
|
||||
class TXDoneMessage : public Message {
|
||||
public:
|
||||
TXDoneMessage(
|
||||
constexpr TXDoneMessage(
|
||||
) : Message { ID::TXDone }
|
||||
{
|
||||
}
|
||||
@@ -485,7 +485,7 @@ public:
|
||||
|
||||
class PWMRSSIConfigureMessage : public Message {
|
||||
public:
|
||||
PWMRSSIConfigureMessage(
|
||||
constexpr PWMRSSIConfigureMessage(
|
||||
const bool enabled,
|
||||
const uint32_t freq,
|
||||
const int32_t avg
|
||||
@@ -501,93 +501,96 @@ public:
|
||||
const int32_t avg;
|
||||
};
|
||||
|
||||
class XylosConfigureMessage : public Message {
|
||||
class CCIRConfigureMessage : public Message {
|
||||
public:
|
||||
XylosConfigureMessage(
|
||||
const char data[]
|
||||
) : Message { ID::XylosConfigure }
|
||||
constexpr CCIRConfigureMessage(
|
||||
const uint32_t samples_per_tone,
|
||||
const uint16_t tone_count
|
||||
) : Message { ID::CCIRConfigure },
|
||||
samples_per_tone(samples_per_tone),
|
||||
tone_count(tone_count)
|
||||
{
|
||||
memcpy(ccir_message, data, 21);
|
||||
}
|
||||
|
||||
char ccir_message[21];
|
||||
};
|
||||
|
||||
class OOKConfigureMessage : public Message {
|
||||
public:
|
||||
OOKConfigureMessage(
|
||||
const char data[],
|
||||
const uint32_t stream_length,
|
||||
const uint32_t samples_per_bit,
|
||||
const uint8_t repeat
|
||||
) : Message { ID::OOKConfigure },
|
||||
stream_length(stream_length),
|
||||
samples_per_bit(samples_per_bit),
|
||||
repeat(repeat)
|
||||
{
|
||||
memcpy(ook_bitstream, data, 64);
|
||||
}
|
||||
|
||||
char ook_bitstream[64];
|
||||
uint32_t stream_length;
|
||||
uint32_t samples_per_bit;
|
||||
uint8_t repeat;
|
||||
const uint32_t samples_per_tone;
|
||||
const uint16_t tone_count;
|
||||
};
|
||||
|
||||
class RetuneMessage : public Message {
|
||||
public:
|
||||
RetuneMessage(
|
||||
) : Message { ID::Retune }
|
||||
constexpr RetuneMessage(
|
||||
const int64_t freq
|
||||
) : Message { ID::Retune },
|
||||
freq(freq)
|
||||
{
|
||||
}
|
||||
|
||||
int64_t freq = 0;
|
||||
const int64_t freq = 0;
|
||||
};
|
||||
|
||||
class AFSKConfigureMessage : public Message {
|
||||
public:
|
||||
AFSKConfigureMessage(
|
||||
const char data[],
|
||||
const uint32_t afsk_samples_per_bit,
|
||||
const uint32_t afsk_phase_inc_mark,
|
||||
const uint32_t afsk_phase_inc_space,
|
||||
const uint8_t afsk_repeat,
|
||||
const uint32_t afsk_bw,
|
||||
const uint8_t afsk_format
|
||||
constexpr AFSKConfigureMessage(
|
||||
const uint32_t samples_per_bit,
|
||||
const uint32_t phase_inc_mark,
|
||||
const uint32_t phase_inc_space,
|
||||
const uint8_t repeat,
|
||||
const uint32_t bw,
|
||||
const uint8_t format
|
||||
) : Message { ID::AFSKConfigure },
|
||||
afsk_samples_per_bit(afsk_samples_per_bit),
|
||||
afsk_phase_inc_mark(afsk_phase_inc_mark),
|
||||
afsk_phase_inc_space(afsk_phase_inc_space),
|
||||
afsk_repeat(afsk_repeat),
|
||||
afsk_bw(afsk_bw),
|
||||
afsk_format(afsk_format)
|
||||
samples_per_bit(samples_per_bit),
|
||||
phase_inc_mark(phase_inc_mark),
|
||||
phase_inc_space(phase_inc_space),
|
||||
repeat(repeat),
|
||||
bw(bw),
|
||||
format(format)
|
||||
{
|
||||
memcpy(message_data, data, 512);
|
||||
}
|
||||
|
||||
uint32_t afsk_samples_per_bit;
|
||||
uint32_t afsk_phase_inc_mark;
|
||||
uint32_t afsk_phase_inc_space;
|
||||
uint8_t afsk_repeat;
|
||||
uint32_t afsk_bw;
|
||||
uint8_t afsk_format;
|
||||
char message_data[512];
|
||||
const uint32_t samples_per_bit;
|
||||
const uint32_t phase_inc_mark;
|
||||
const uint32_t phase_inc_space;
|
||||
const uint8_t repeat;
|
||||
const uint32_t bw;
|
||||
const uint8_t format;
|
||||
};
|
||||
|
||||
class OOKConfigureMessage : public Message {
|
||||
public:
|
||||
constexpr OOKConfigureMessage(
|
||||
const uint32_t stream_length,
|
||||
const uint32_t samples_per_bit,
|
||||
const uint8_t repeat,
|
||||
const uint32_t pause_symbols
|
||||
) : Message { ID::OOKConfigure },
|
||||
stream_length(stream_length),
|
||||
samples_per_bit(samples_per_bit),
|
||||
repeat(repeat),
|
||||
pause_symbols(pause_symbols)
|
||||
{
|
||||
}
|
||||
|
||||
const uint32_t stream_length;
|
||||
const uint32_t samples_per_bit;
|
||||
const uint8_t repeat;
|
||||
const uint32_t pause_symbols;
|
||||
};
|
||||
|
||||
class FIFOSignalMessage : public Message {
|
||||
public:
|
||||
FIFOSignalMessage(
|
||||
constexpr FIFOSignalMessage(
|
||||
) : Message { ID::FIFOSignal }
|
||||
{
|
||||
}
|
||||
|
||||
char signaltype = 0;
|
||||
const char signaltype = 0;
|
||||
};
|
||||
|
||||
class FIFODataMessage : public Message {
|
||||
public:
|
||||
FIFODataMessage(
|
||||
) : Message { ID::FIFOData }
|
||||
constexpr FIFODataMessage(
|
||||
) : Message { ID::FIFOData },
|
||||
data ( nullptr )
|
||||
{
|
||||
}
|
||||
|
||||
|
@@ -51,8 +51,7 @@ struct SharedMemory {
|
||||
|
||||
JammerRange jammer_ranges[16];
|
||||
|
||||
char epardata[13];
|
||||
int32_t excursion;
|
||||
char tx_data[512] { 0 };
|
||||
};
|
||||
|
||||
extern SharedMemory& shared_memory;
|
||||
|
@@ -103,16 +103,16 @@ struct region_t {
|
||||
|
||||
constexpr region_t bootstrap {
|
||||
.offset = 0x00000,
|
||||
.size = 0x8000,
|
||||
.size = 0x10000,
|
||||
};
|
||||
|
||||
constexpr region_t images {
|
||||
.offset = 0x8000,
|
||||
.size = 0x38000,
|
||||
.offset = 0x10000,
|
||||
.size = 0x40000,
|
||||
};
|
||||
|
||||
constexpr region_t application {
|
||||
.offset = 0x40000,
|
||||
.offset = 0x80000,
|
||||
.size = 0x40000,
|
||||
};
|
||||
|
||||
|
@@ -1,3 +1,25 @@
|
||||
/*
|
||||
* Copyright (C) 2014 Jared Boone, ShareBrained Technology, Inc.
|
||||
* Copyright (C) 2016 Furrtek
|
||||
*
|
||||
* This file is part of PortaPack.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, Inc., 51 Franklin Street,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#include "ui_widget.hpp"
|
||||
#include "ui_painter.hpp"
|
||||
#include "portapack.hpp"
|
||||
@@ -1026,10 +1048,6 @@ void NumberField::set_value(int32_t new_value, bool trigger_change) {
|
||||
}
|
||||
}
|
||||
|
||||
void NumberField::set_value(int32_t new_value) {
|
||||
set_value(new_value, true);
|
||||
}
|
||||
|
||||
void NumberField::set_range(const int32_t min, const int32_t max) {
|
||||
range.first = min;
|
||||
range.second = max;
|
||||
@@ -1081,4 +1099,129 @@ int32_t NumberField::clip_value(int32_t value) {
|
||||
return value;
|
||||
}
|
||||
|
||||
/* SymField **************************************************************/
|
||||
|
||||
SymField::SymField(
|
||||
Point parent_pos,
|
||||
size_t length,
|
||||
range_t range
|
||||
) : Widget { { parent_pos, { static_cast<ui::Dim>(8 * length), 16 } } },
|
||||
range { range },
|
||||
length_ { length }
|
||||
{
|
||||
set_focusable(true);
|
||||
}
|
||||
|
||||
uint32_t SymField::value(const uint32_t index) {
|
||||
return values_[index];
|
||||
}
|
||||
|
||||
void SymField::set_value(const uint32_t index, int32_t new_value) {
|
||||
new_value = clip_value(new_value);
|
||||
|
||||
if( new_value != values_[index] ) {
|
||||
values_[index] = new_value;
|
||||
if( on_change ) {
|
||||
on_change();
|
||||
}
|
||||
set_dirty();
|
||||
}
|
||||
}
|
||||
|
||||
void SymField::set_length(const uint32_t new_length) {
|
||||
if (new_length <= 30) {
|
||||
prev_length_ = length_;
|
||||
length_ = new_length;
|
||||
erase_prev_ = true;
|
||||
set_dirty();
|
||||
}
|
||||
}
|
||||
|
||||
void SymField::set_range(const int32_t min, const int32_t max) {
|
||||
size_t n;
|
||||
|
||||
range.first = min;
|
||||
range.second = max;
|
||||
for (n = 0; n < length_; n++)
|
||||
set_value(n, values_[n]);
|
||||
}
|
||||
|
||||
void SymField::paint(Painter& painter) {
|
||||
size_t n;
|
||||
Point pt_draw = screen_pos();
|
||||
|
||||
if (erase_prev_) {
|
||||
painter.fill_rectangle( { pt_draw, { prev_length_ * 8, 16 } }, Color::black() );
|
||||
erase_prev_ = false;
|
||||
}
|
||||
|
||||
for (n = 0; n < length_; n++) {
|
||||
const auto text = to_string_dec_uint(values_[n], 1);
|
||||
|
||||
const auto paint_style = (has_focus() && (n == selected_)) ? style().invert() : style();
|
||||
|
||||
painter.draw_string(
|
||||
pt_draw,
|
||||
paint_style,
|
||||
text
|
||||
);
|
||||
|
||||
pt_draw.x += 8;
|
||||
}
|
||||
}
|
||||
|
||||
bool SymField::on_key(const KeyEvent key) {
|
||||
switch (key) {
|
||||
case KeyEvent::Select:
|
||||
if( on_select ) {
|
||||
on_select(*this);
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
|
||||
case KeyEvent::Left:
|
||||
if (selected_ > 0) {
|
||||
selected_--;
|
||||
set_dirty();
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
|
||||
case KeyEvent::Right:
|
||||
if (selected_ < (length_ - 1)) {
|
||||
selected_++;
|
||||
set_dirty();
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool SymField::on_encoder(const EncoderEvent delta) {
|
||||
set_value(selected_, values_[selected_] + delta);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SymField::on_touch(const TouchEvent event) {
|
||||
if( event.type == TouchEvent::Type::Start ) {
|
||||
focus();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
int32_t SymField::clip_value(int32_t value) {
|
||||
if( value > range.second ) {
|
||||
value = range.second;
|
||||
}
|
||||
if( value < range.first ) {
|
||||
value = range.first;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
} /* namespace ui */
|
||||
|
@@ -1,5 +1,6 @@
|
||||
/*
|
||||
* Copyright (C) 2014 Jared Boone, ShareBrained Technology, Inc.
|
||||
* Copyright (C) 2016 Furrtek
|
||||
*
|
||||
* This file is part of PortaPack.
|
||||
*
|
||||
@@ -411,7 +412,7 @@ public:
|
||||
|
||||
NumberField(Point parent_pos, size_t length, range_t range, int32_t step, char fill_char);
|
||||
NumberField(
|
||||
) : NumberField { { }, 1, { 0, 1 }, 1, ' ' }
|
||||
) : NumberField { { 0, 0 }, 1, { 0, 1 }, 1, ' ' }
|
||||
{
|
||||
}
|
||||
|
||||
@@ -419,8 +420,7 @@ public:
|
||||
NumberField(NumberField&&) = delete;
|
||||
|
||||
int32_t value() const;
|
||||
void set_value(int32_t new_value);
|
||||
void set_value(int32_t new_value, bool trigger_change);
|
||||
void set_value(int32_t new_value, bool trigger_change = true);
|
||||
void set_range(const int32_t min, const int32_t max);
|
||||
|
||||
void paint(Painter& painter) override;
|
||||
@@ -439,6 +439,39 @@ private:
|
||||
int32_t clip_value(int32_t value);
|
||||
};
|
||||
|
||||
class SymField : public Widget {
|
||||
public:
|
||||
std::function<void(SymField&)> on_select;
|
||||
std::function<void()> on_change;
|
||||
|
||||
using range_t = std::pair<int32_t, int32_t>;
|
||||
|
||||
SymField(Point parent_pos, size_t length, range_t range);
|
||||
|
||||
SymField(const SymField&) = delete;
|
||||
SymField(SymField&&) = delete;
|
||||
|
||||
uint32_t value(const uint32_t index);
|
||||
void set_value(const uint32_t index, int32_t new_value);
|
||||
void set_length(const uint32_t new_length);
|
||||
void set_range(const int32_t min, const int32_t max);
|
||||
|
||||
void paint(Painter& painter) override;
|
||||
|
||||
bool on_key(const KeyEvent key) override;
|
||||
bool on_encoder(const EncoderEvent delta) override;
|
||||
bool on_touch(const TouchEvent event) override;
|
||||
|
||||
private:
|
||||
range_t range;
|
||||
int32_t values_[30] = { 0 };
|
||||
uint32_t selected_ = 0;
|
||||
size_t length_, prev_length_;
|
||||
bool erase_prev_ = false;
|
||||
|
||||
int32_t clip_value(int32_t value);
|
||||
};
|
||||
|
||||
} /* namespace ui */
|
||||
|
||||
#endif/*__UI_WIDGET_H__*/
|
||||
|
Reference in New Issue
Block a user