mirror of
https://github.com/eried/portapack-mayhem.git
synced 2024-12-28 16:59:47 -05:00
RDS Radiotext should make receiver happier (missing end char)
String-ized text entry
This commit is contained in:
parent
62b90942ac
commit
555201b780
@ -35,7 +35,7 @@ void make_frame_mode_s(uint8_t * const adsb_frame, const uint32_t ICAO_address)
|
||||
memset(&adsb_frame[4], 0, 10);
|
||||
}
|
||||
|
||||
void generate_frame_id(uint8_t * const adsb_frame, const uint32_t ICAO_address, char * const callsign) {
|
||||
void generate_frame_id(uint8_t * const adsb_frame, const uint32_t ICAO_address, std::string & callsign) {
|
||||
std::string callsign_formatted(8, '_');
|
||||
uint64_t callsign_coded = 0;
|
||||
uint32_t c, s;
|
||||
|
@ -32,7 +32,7 @@ namespace adsb {
|
||||
|
||||
void make_frame_mode_s(uint8_t * const adsb_frame, const uint32_t ICAO_address);
|
||||
|
||||
void generate_frame_id(uint8_t * const adsb_frame, const uint32_t ICAO_address, char * const callsign);
|
||||
void generate_frame_id(uint8_t * const adsb_frame, const uint32_t ICAO_address, std::string & callsign);
|
||||
void generate_frame_pos(uint8_t * const adsb_frame, const uint32_t ICAO_address, const uint32_t altitude,
|
||||
const float latitude, const float longitude);
|
||||
void generate_frame_emergency(uint8_t * const adsb_frame, const uint32_t ICAO_address, const uint8_t code);
|
||||
|
@ -31,7 +31,7 @@
|
||||
|
||||
namespace rds {
|
||||
|
||||
uint32_t makeblock(uint32_t data, uint16_t offset) {
|
||||
uint32_t make_block(uint32_t data, uint16_t offset) {
|
||||
uint16_t CRC = 0;
|
||||
uint8_t bit;
|
||||
|
||||
@ -58,25 +58,25 @@ uint8_t b2b(const bool in) {
|
||||
}
|
||||
|
||||
// Type 0B groups are like 0A groups but without alternative frequency data
|
||||
void make_0B_group(uint32_t blocks[], const uint16_t PI_code, const bool TP, const uint8_t PTY, const bool TA,
|
||||
const bool MS, const bool DI, const uint8_t C, const char * chars) {
|
||||
blocks[0] = PI_code;
|
||||
blocks[1] = (0x0 << 12) | (1 << 11) | (b2b(TP) << 10) | ((PTY & 0x1F) << 5) | (b2b(TA) << 4) | (b2b(MS) << 3) | (b2b(DI) << 2) | (C & 3);
|
||||
blocks[2] = PI_code;
|
||||
blocks[3] = (chars[0] << 8) | chars[1];
|
||||
void make_0B_group(RDS_group * group, const uint16_t PI_code, const bool TP, const uint8_t PTY, const bool TA,
|
||||
const bool MS, const bool DI, const uint8_t C, const std::string chars) {
|
||||
group->block[0] = PI_code;
|
||||
group->block[1] = (0x0 << 12) | (1 << 11) | (b2b(TP) << 10) | ((PTY & 0x1F) << 5) | (b2b(TA) << 4) | (b2b(MS) << 3) | (b2b(DI) << 2) | (C & 3);
|
||||
group->block[2] = PI_code;
|
||||
group->block[3] = (chars[0] << 8) | chars[1];
|
||||
}
|
||||
|
||||
// For RadioText, up to 64 chars with 2A, 32 chars with 2B
|
||||
void make_2A_group(uint32_t blocks[], const uint16_t PI_code, const bool TP, const uint8_t PTY, const bool AB,
|
||||
const uint8_t segment, const char * chars) {
|
||||
blocks[0] = PI_code;
|
||||
blocks[1] = (0x2 << 12) | (0 << 11) | (b2b(TP) << 10) | ((PTY & 0x1F) << 5) | (b2b(AB) << 4) | (segment & 15);
|
||||
blocks[2] = (chars[0] << 8) | chars[1];
|
||||
blocks[3] = (chars[2] << 8) | chars[3];
|
||||
void make_2A_group(RDS_group * group, const uint16_t PI_code, const bool TP, const uint8_t PTY, const bool AB,
|
||||
const uint8_t segment, const std::string chars) {
|
||||
group->block[0] = PI_code;
|
||||
group->block[1] = (0x2 << 12) | (0 << 11) | (b2b(TP) << 10) | ((PTY & 0x1F) << 5) | (b2b(AB) << 4) | (segment & 15);
|
||||
group->block[2] = (chars[0] << 8) | chars[1];
|
||||
group->block[3] = (chars[2] << 8) | chars[3];
|
||||
}
|
||||
|
||||
// Time and date - usually one message per minute - Month: 1~12 - Day: 1~31 - Hour/Minute: 0~59 - Local offset: -12/+12 from UTC
|
||||
void make_4A_group(uint32_t blocks[], const uint16_t PI_code, const bool TP, const uint8_t PTY,
|
||||
void make_4A_group(RDS_group * group, const uint16_t PI_code, const bool TP, const uint8_t PTY,
|
||||
const uint16_t year, const uint8_t month, const uint8_t day,
|
||||
const uint8_t hour, const uint8_t minute, const int8_t local_offset) {
|
||||
uint32_t L = 0;
|
||||
@ -86,77 +86,69 @@ void make_4A_group(uint32_t blocks[], const uint16_t PI_code, const bool TP, con
|
||||
|
||||
day_code = 14956 + day + (uint32_t)((float)(year - 1900 - L) * 365.25) + uint16_t((float)((month + 1) + L * 12) * 30.6001);
|
||||
|
||||
blocks[0] = PI_code;
|
||||
blocks[1] = (0x4 << 12) | (0 << 11) | (b2b(TP) << 10) | ((PTY & 0x1F) << 5) | ((day_code & 0x18000) >> 15);
|
||||
blocks[2] = ((day_code & 0x7FFF) << 1) | (hour >> 4);
|
||||
blocks[3] = ((hour & 15) << 12) | ((minute & 0x3F) << 6) | (local_offset & 0x3F);
|
||||
group->block[0] = PI_code;
|
||||
group->block[1] = (0x4 << 12) | (0 << 11) | (b2b(TP) << 10) | ((PTY & 0x1F) << 5) | ((day_code & 0x18000) >> 15);
|
||||
group->block[2] = ((day_code & 0x7FFF) << 1) | (hour >> 4);
|
||||
group->block[3] = ((hour & 15) << 12) | ((minute & 0x3F) << 6) | (local_offset & 0x3F);
|
||||
}
|
||||
|
||||
uint16_t gen_PSN(const char * psname, const RDS_flags * rds_flags) {
|
||||
uint16_t gen_PSN(const std::string & psname, const RDS_flags * rds_flags) {
|
||||
uint8_t c;
|
||||
uint32_t group[4][4] = { 0 };
|
||||
RDS_group groups[4] = { 0 };
|
||||
|
||||
// 4 groups with 2 PSN characters in each
|
||||
for (c = 0; c < 4; c++)
|
||||
make_0B_group(&group[c][0], rds_flags->PI_code, rds_flags->TP, rds_flags->PTY, rds_flags->TA, rds_flags->MS, rds_flags->DI, c, &psname[c * 2]);
|
||||
make_0B_group(&groups[c], rds_flags->PI_code, rds_flags->TP, rds_flags->PTY, rds_flags->TA, rds_flags->MS, rds_flags->DI, c, psname.substr(c * 2, 2));
|
||||
|
||||
// Generate checkbits for each block of each group
|
||||
for (c = 0; c < 4; c++) {
|
||||
group[c][0] = makeblock(group[c][0], RDS_OFFSET_A);
|
||||
group[c][1] = makeblock(group[c][1], RDS_OFFSET_B);
|
||||
group[c][2] = makeblock(group[c][2], RDS_OFFSET_Cp); // C' !
|
||||
group[c][3] = makeblock(group[c][3], RDS_OFFSET_D);
|
||||
groups[c].block[0] = make_block(groups[c].block[0], RDS_OFFSET_A);
|
||||
groups[c].block[1] = make_block(groups[c].block[1], RDS_OFFSET_B);
|
||||
groups[c].block[2] = make_block(groups[c].block[2], RDS_OFFSET_Cp); // C' !
|
||||
groups[c].block[3] = make_block(groups[c].block[3], RDS_OFFSET_D);
|
||||
}
|
||||
|
||||
uint32_t * tx_data_u32 = (uint32_t*)shared_memory.bb_data.data;
|
||||
|
||||
// Copy to tx_data for baseband
|
||||
for (c = 0; c < 4 * 4; c++)
|
||||
tx_data_u32[c] = group[c >> 2][c & 3];
|
||||
tx_data_u32[c] = groups[c >> 2].block[c & 3];
|
||||
|
||||
return 4 * 4 * 26;
|
||||
}
|
||||
|
||||
uint16_t gen_RadioText(const char * text, const bool AB, const RDS_flags * rds_flags) {
|
||||
size_t c, i;
|
||||
uint32_t * group;
|
||||
char radiotext_buffer[65] = { 0 };
|
||||
uint8_t rtlen, groups;
|
||||
|
||||
strncpy(radiotext_buffer, text, 64);
|
||||
|
||||
rtlen = strlen(radiotext_buffer);
|
||||
|
||||
// Pad message with spaces to a multiple of 4 characters
|
||||
while (rtlen & 3)
|
||||
radiotext_buffer[rtlen++] = ' ';
|
||||
uint16_t gen_RadioText(const std::string & text, const bool AB, const RDS_flags * rds_flags) {
|
||||
size_t c;
|
||||
RDS_group * groups_ptr;
|
||||
std::string radiotext_buffer = text;
|
||||
size_t rt_length, groups;
|
||||
|
||||
// End message with Carriage Return, as required
|
||||
if (rtlen < 64) radiotext_buffer[rtlen] = 0x0D;
|
||||
radiotext_buffer += 0x0D;
|
||||
rt_length = radiotext_buffer.length();
|
||||
rt_length = (rt_length + 3) & 0xFC;
|
||||
|
||||
groups = rtlen >> 2; // 4 characters per group
|
||||
groups = rt_length >> 2; // 4 characters per group
|
||||
|
||||
group = (uint32_t*)chHeapAlloc(0, 4 * groups * sizeof(uint32_t));
|
||||
groups_ptr = (RDS_group*)chHeapAlloc(0, groups * sizeof(RDS_group));
|
||||
|
||||
for (c = 0; c < groups; c++)
|
||||
make_2A_group(&group[c * 4], rds_flags->PI_code, rds_flags->TP, rds_flags->PTY, AB, c, &radiotext_buffer[c * 4]);
|
||||
make_2A_group(&groups_ptr[c], rds_flags->PI_code, rds_flags->TP, rds_flags->PTY, AB, c, radiotext_buffer.substr(c * 4, 4));
|
||||
|
||||
// Generate checkbits for each block of each group
|
||||
for (c = 0; c < groups; c++) {
|
||||
i = c * 4;
|
||||
group[i + 0] = makeblock(group[i + 0], RDS_OFFSET_A);
|
||||
group[i + 1] = makeblock(group[i + 1], RDS_OFFSET_B);
|
||||
group[i + 2] = makeblock(group[i + 2], RDS_OFFSET_C);
|
||||
group[i + 3] = makeblock(group[i + 3], RDS_OFFSET_D);
|
||||
groups_ptr[c].block[0] = make_block(groups_ptr[c].block[0], RDS_OFFSET_A);
|
||||
groups_ptr[c].block[1] = make_block(groups_ptr[c].block[1], RDS_OFFSET_B);
|
||||
groups_ptr[c].block[2] = make_block(groups_ptr[c].block[2], RDS_OFFSET_C);
|
||||
groups_ptr[c].block[3] = make_block(groups_ptr[c].block[3], RDS_OFFSET_D);
|
||||
}
|
||||
|
||||
uint32_t * tx_data_u32 = (uint32_t*)shared_memory.bb_data.data;
|
||||
|
||||
// Copy to tx_data for baseband
|
||||
for (c = 0; c < (groups * 4); c++)
|
||||
tx_data_u32[c] = group[c];
|
||||
for (c = 0; c < groups * 4; c++)
|
||||
tx_data_u32[c] = groups_ptr[c >> 2].block[c & 3];
|
||||
|
||||
chHeapFree(group);
|
||||
chHeapFree(groups_ptr);
|
||||
|
||||
return groups * 4 * 26;
|
||||
}
|
||||
@ -165,21 +157,21 @@ uint16_t gen_ClockTime(const RDS_flags * rds_flags,
|
||||
const uint16_t year, const uint8_t month, const uint8_t day,
|
||||
const uint8_t hour, const uint8_t minute, const int8_t local_offset) {
|
||||
uint8_t c;
|
||||
uint32_t group[4] = { 0 };
|
||||
RDS_group group = { 0 };
|
||||
|
||||
make_4A_group(&group[0], rds_flags->PI_code, rds_flags->TP, rds_flags->PTY, year, month, day, hour, minute, local_offset);
|
||||
make_4A_group(&group, rds_flags->PI_code, rds_flags->TP, rds_flags->PTY, year, month, day, hour, minute, local_offset);
|
||||
|
||||
// Generate checkbits for each block
|
||||
group[0] = makeblock(group[0], RDS_OFFSET_A);
|
||||
group[1] = makeblock(group[1], RDS_OFFSET_B);
|
||||
group[2] = makeblock(group[2], RDS_OFFSET_C);
|
||||
group[3] = makeblock(group[3], RDS_OFFSET_D);
|
||||
group.block[0] = make_block(group.block[0], RDS_OFFSET_A);
|
||||
group.block[1] = make_block(group.block[1], RDS_OFFSET_B);
|
||||
group.block[2] = make_block(group.block[2], RDS_OFFSET_C);
|
||||
group.block[3] = make_block(group.block[3], RDS_OFFSET_D);
|
||||
|
||||
uint32_t * tx_data_u32 = (uint32_t*)shared_memory.bb_data.data;
|
||||
|
||||
// Copy to tx_data for baseband
|
||||
for (c = 0; c < 4; c++)
|
||||
tx_data_u32[c] = group[c];
|
||||
tx_data_u32[c] = group.block[c];
|
||||
|
||||
return 4 * 26;
|
||||
}
|
||||
|
@ -44,18 +44,23 @@ struct RDS_flags {
|
||||
bool MS;
|
||||
};
|
||||
|
||||
uint32_t makeblock(uint32_t blockdata, uint16_t offset);
|
||||
struct RDS_group {
|
||||
uint32_t block[4];
|
||||
};
|
||||
|
||||
uint32_t make_block(uint32_t blockdata, uint16_t offset);
|
||||
uint8_t b2b(const bool in);
|
||||
void make_0B_group(uint32_t group[], const uint16_t PI_code, const bool TP, const uint8_t PTY, const bool TA,
|
||||
const bool MS, const bool DI, const uint8_t C, const char * chars);
|
||||
void make_2A_group(uint32_t group[], const uint16_t PI_code, const bool TP, const uint8_t PTY, const bool AB,
|
||||
const uint8_t segment, const char * chars);
|
||||
void make_4A_group(uint32_t blocks[], const uint16_t PI_code, const bool TP, const uint8_t PTY,
|
||||
|
||||
void make_0B_group(RDS_group * group, const uint16_t PI_code, const bool TP, const uint8_t PTY, const bool TA,
|
||||
const bool MS, const bool DI, const uint8_t C, const std::string chars);
|
||||
void make_2A_group(RDS_group * group, const uint16_t PI_code, const bool TP, const uint8_t PTY, const bool AB,
|
||||
const uint8_t segment, const std::string chars);
|
||||
void make_4A_group(RDS_group * group, const uint16_t PI_code, const bool TP, const uint8_t PTY,
|
||||
const uint16_t year, const uint8_t month, const uint8_t day,
|
||||
const uint8_t hour, const uint8_t minute, const int8_t local_offset);
|
||||
|
||||
uint16_t gen_PSN(const char * psname, const RDS_flags * rds_flags);
|
||||
uint16_t gen_RadioText(const char * text, const bool AB, const RDS_flags * rds_flags);
|
||||
uint16_t gen_PSN(const std::string & psname, const RDS_flags * rds_flags);
|
||||
uint16_t gen_RadioText(const std::string & text, const bool AB, const RDS_flags * rds_flags);
|
||||
uint16_t gen_ClockTime(const RDS_flags * rds_flags,
|
||||
const uint16_t year, const uint8_t month, const uint8_t day,
|
||||
const uint8_t hour, const uint8_t minute, const int8_t local_offset);
|
||||
|
@ -141,7 +141,7 @@ ADSBTxView::ADSBTxView(NavigationView& nav) {
|
||||
generate_frame();
|
||||
};
|
||||
button_callsign.on_select = [this, &nav](Button&) {
|
||||
textentry(nav, callsign, 9);
|
||||
text_entry(nav, callsign, 9);
|
||||
};
|
||||
|
||||
field_altitude.set_value(11000);
|
||||
|
@ -53,7 +53,7 @@ private:
|
||||
|
||||
tx_modes tx_mode = IDLE;
|
||||
|
||||
char callsign[9] = "KLM1023 ";
|
||||
std::string callsign = "KLM1023 ";
|
||||
|
||||
uint8_t adsb_frame[14]; // 112 bit data block as 14 bytes
|
||||
uint8_t adsb_bin[112]; // 112 bit data block
|
||||
|
@ -38,14 +38,15 @@ void AlphanumView::paint(Painter&) {
|
||||
|
||||
AlphanumView::AlphanumView(
|
||||
NavigationView& nav,
|
||||
char txt[],
|
||||
std::string& txt,
|
||||
size_t max_length
|
||||
) : _max_length(max_length)
|
||||
{
|
||||
size_t n;
|
||||
|
||||
txtidx = strlen(txt);
|
||||
memcpy(txtinput, txt, _max_length + 1);
|
||||
txtidx = txt.length();
|
||||
txtinput = txt;
|
||||
|
||||
n = txtidx;
|
||||
while (n && (txtinput[n - 1] == ' ')) {
|
||||
txtinput[--n] = 0;
|
||||
@ -87,8 +88,8 @@ AlphanumView::AlphanumView(
|
||||
update_text();
|
||||
};
|
||||
|
||||
button_ok.on_select = [this, &nav, txt, max_length](Button&) {
|
||||
memcpy(txt, txtinput, max_length + 1);
|
||||
button_ok.on_select = [this, &nav, &txt, max_length](Button&) {
|
||||
txt = txtinput;
|
||||
if (on_changed) on_changed(this->value());
|
||||
nav.pop();
|
||||
};
|
||||
@ -140,7 +141,7 @@ void AlphanumView::focus() {
|
||||
button_ok.focus();
|
||||
}
|
||||
|
||||
char * AlphanumView::value() {
|
||||
std::string AlphanumView::value() {
|
||||
txtinput[txtidx] = 0;
|
||||
return txtinput;
|
||||
}
|
||||
@ -171,7 +172,7 @@ void AlphanumView::char_delete() {
|
||||
}
|
||||
|
||||
void AlphanumView::update_text() {
|
||||
text_input.set(std::string(txtinput) + std::string(_max_length - strlen(txtinput), ' '));
|
||||
text_input.set(std::string(txtinput) + std::string(_max_length - txtinput.length(), ' '));
|
||||
move_cursor();
|
||||
}
|
||||
|
||||
|
@ -34,9 +34,9 @@ namespace ui {
|
||||
|
||||
class AlphanumView : public View {
|
||||
public:
|
||||
std::function<void(char *)> on_changed { };
|
||||
std::function<void(std::string)> on_changed { };
|
||||
|
||||
AlphanumView(NavigationView& nav, char txt[], size_t max_length);
|
||||
AlphanumView(NavigationView& nav, std::string& txt, size_t max_length);
|
||||
|
||||
AlphanumView(const AlphanumView&) = delete;
|
||||
AlphanumView(AlphanumView&&) = delete;
|
||||
@ -47,7 +47,7 @@ public:
|
||||
void paint(Painter& painter) override;
|
||||
void focus() override;
|
||||
|
||||
char * value();
|
||||
std::string value();
|
||||
|
||||
std::string title() const override { return "Text entry"; };
|
||||
|
||||
@ -65,7 +65,7 @@ private:
|
||||
size_t _max_length { };
|
||||
uint32_t txtidx { 0 };
|
||||
uint32_t mode = 0; // Upper
|
||||
char txtinput[29] = { 0 }; // 28 chars max
|
||||
std::string txtinput { "" }; // 28 chars max
|
||||
|
||||
void char_add(const char c);
|
||||
void char_delete();
|
||||
|
@ -31,7 +31,7 @@ using namespace portapack;
|
||||
|
||||
namespace ui {
|
||||
|
||||
void FrequencySaveView::on_save_name(char * name) {
|
||||
void FrequencySaveView::on_save_name(std::string& name) {
|
||||
database.entries.push_back({ value_, "", name, (int32_t)options_category.selected_index_value() });
|
||||
nav_.pop();
|
||||
}
|
||||
@ -119,7 +119,7 @@ FrequencySaveView::FrequencySaveView(
|
||||
big_display.set(value);
|
||||
|
||||
button_save_name.on_select = [this, &nav](Button&) {
|
||||
textentry(nav, desc_buffer, 28, [this](char * buffer) {
|
||||
text_entry(nav, desc_buffer, 28, [this](std::string buffer) {
|
||||
on_save_name(buffer);
|
||||
});
|
||||
};
|
||||
@ -207,10 +207,7 @@ void FreqManView::on_edit_freq(rf::Frequency f) {
|
||||
}
|
||||
|
||||
void FreqManView::on_edit_desc(NavigationView& nav) {
|
||||
char desc_buffer[32] = { 0 };
|
||||
|
||||
strcpy(desc_buffer, database.entries[menu_view.highlighted()].description.c_str());
|
||||
textentry(nav, desc_buffer, 28, [this, &desc_buffer](char * buffer) {
|
||||
text_entry(nav, desc_buffer, 28, [this](std::string buffer) {
|
||||
database.entries[menu_view.highlighted()].description = buffer;
|
||||
//setup_list();
|
||||
});
|
||||
@ -313,6 +310,7 @@ FreqManView::FreqManView(
|
||||
};
|
||||
|
||||
button_edit_desc.on_select = [this, &nav](Button&) {
|
||||
desc_buffer = database.entries[menu_view.highlighted()].description;
|
||||
on_edit_desc(nav);
|
||||
};
|
||||
|
||||
|
@ -44,13 +44,13 @@ public:
|
||||
private:
|
||||
NavigationView& nav_;
|
||||
freqman_error error { NO_ERROR };
|
||||
char desc_buffer[32] = { 0 };
|
||||
std::string desc_buffer { "-" };
|
||||
rtc::RTC datetime { };
|
||||
rf::Frequency value_ { };
|
||||
std::string str_timestamp { };
|
||||
//int32_t category_id_ { -1 };
|
||||
|
||||
void on_save_name(char * name);
|
||||
void on_save_name(std::string& name);
|
||||
void on_save_timestamp();
|
||||
void on_tick_second();
|
||||
|
||||
@ -139,6 +139,7 @@ private:
|
||||
NavigationView& nav_;
|
||||
|
||||
freqman_error error { NO_ERROR };
|
||||
std::string desc_buffer { "-" };
|
||||
|
||||
void on_frequency_select();
|
||||
void on_edit_freq(rf::Frequency f);
|
||||
|
@ -38,7 +38,7 @@ void HandWriteView::paint(Painter& painter) {
|
||||
|
||||
HandWriteView::HandWriteView(
|
||||
NavigationView& nav,
|
||||
char txt[],
|
||||
std::string& txt,
|
||||
size_t max_length
|
||||
) : _max_length(max_length)
|
||||
{
|
||||
@ -48,8 +48,8 @@ HandWriteView::HandWriteView(
|
||||
// Handwriting alphabet definition here
|
||||
handwriting = &handwriting_unistroke;
|
||||
|
||||
txtidx = strlen(txt);
|
||||
memcpy(txtinput, txt, _max_length + 1);
|
||||
txtidx = txt.length();
|
||||
txtinput = txt;
|
||||
n = txtidx;
|
||||
while (n && (txtinput[n - 1] == ' ')) {
|
||||
txtinput[--n] = 0;
|
||||
@ -110,8 +110,8 @@ HandWriteView::HandWriteView(
|
||||
}
|
||||
};
|
||||
|
||||
button_ok.on_select = [this, &nav, txt, max_length](Button&) {
|
||||
memcpy(txt, txtinput, max_length + 1);
|
||||
button_ok.on_select = [this, &nav, &txt, max_length](Button&) {
|
||||
txt = txtinput;
|
||||
if (on_changed) on_changed(this->value());
|
||||
nav.pop();
|
||||
};
|
||||
@ -382,7 +382,7 @@ void HandWriteView::on_show() {
|
||||
clear_zone(Color::black(), false);
|
||||
}
|
||||
|
||||
char * HandWriteView::value() {
|
||||
std::string HandWriteView::value() {
|
||||
txtinput[txtidx] = 0;
|
||||
return txtinput;
|
||||
}
|
||||
|
@ -33,9 +33,9 @@ namespace ui {
|
||||
|
||||
class HandWriteView : public View {
|
||||
public:
|
||||
std::function<void(char *)> on_changed { };
|
||||
std::function<void(std::string)> on_changed { };
|
||||
|
||||
HandWriteView(NavigationView& nav, char txt[], size_t max_length);
|
||||
HandWriteView(NavigationView& nav, std::string& txt, size_t max_length);
|
||||
|
||||
HandWriteView(const HandWriteView&) = delete;
|
||||
HandWriteView(HandWriteView&&) = delete;
|
||||
@ -46,7 +46,7 @@ public:
|
||||
void on_show() override;
|
||||
bool on_touch(const TouchEvent event) override;
|
||||
|
||||
char * value();
|
||||
std::string value();
|
||||
|
||||
std::string title() const override { return "Text entry"; };
|
||||
|
||||
@ -65,7 +65,7 @@ private:
|
||||
uint8_t stroke_list[8];
|
||||
Point start_pos { }, current_pos { }, last_pos { };
|
||||
bool _lowercase = false;
|
||||
char txtinput[29] = { 0 }; // 28 chars max
|
||||
std::string txtinput { "" }; // 28 chars max
|
||||
|
||||
void sample_pen();
|
||||
void add_stroke(uint8_t dir);
|
||||
|
@ -137,7 +137,7 @@ void LCRView::on_txdone(int n) {
|
||||
transmitter_model.disable();
|
||||
// Next address
|
||||
scan_index++;
|
||||
strcpy(rgsb, &scan_list[options_scanlist.selected_index()].addresses[scan_index * 5]);
|
||||
rgsb = scan_list[options_scanlist.selected_index()].addresses[scan_index];
|
||||
scan_progress++;
|
||||
repeat_index = 1;
|
||||
update_progress();
|
||||
@ -165,7 +165,7 @@ void LCRView::start_tx(const bool scan) {
|
||||
scan_progress = 1;
|
||||
repeat_index = 1;
|
||||
tx_mode = SCAN;
|
||||
strcpy(rgsb, &scan_list[options_scanlist.selected_index()].addresses[0]);
|
||||
rgsb = scan_list[options_scanlist.selected_index()].addresses[0];
|
||||
progress.set_max(scan_count * afsk_repeats);
|
||||
update_progress();
|
||||
}
|
||||
@ -197,8 +197,6 @@ void LCRView::start_tx(const bool scan) {
|
||||
transmitter_model.set_tuning_frequency(portapack::persistent_memory::tuned_frequency());
|
||||
transmitter_model.set_sampling_rate(1536000U);
|
||||
transmitter_model.set_rf_amp(true);
|
||||
transmitter_model.set_lna(40);
|
||||
transmitter_model.set_vga(40);
|
||||
transmitter_model.set_baseband_bandwidth(1750000);
|
||||
transmitter_model.enable();
|
||||
|
||||
@ -215,7 +213,7 @@ void LCRView::start_tx(const bool scan) {
|
||||
}
|
||||
|
||||
void LCRView::on_button_setam(NavigationView& nav, Button& button) {
|
||||
textentry(nav, litteral[button.id], 7);
|
||||
text_entry(nav, litteral[button.id], 7);
|
||||
}
|
||||
|
||||
LCRView::LCRView(NavigationView& nav) {
|
||||
@ -223,7 +221,7 @@ LCRView::LCRView(NavigationView& nav) {
|
||||
|
||||
baseband::run_image(portapack::spi_flash::image_tag_afsk);
|
||||
|
||||
strcpy(rgsb, &scan_list[0].addresses[0]);
|
||||
rgsb = scan_list[0].addresses[0];
|
||||
|
||||
add_children({
|
||||
&text_recap,
|
||||
@ -294,7 +292,7 @@ LCRView::LCRView(NavigationView& nav) {
|
||||
button_scan.set_style(&style_val);
|
||||
|
||||
button_setrgsb.on_select = [this,&nav](Button&) {
|
||||
textentry(nav, rgsb, 4);
|
||||
text_entry(nav, rgsb, 4);
|
||||
};
|
||||
|
||||
button_txsetup.on_select = [&nav](Button&) {
|
||||
@ -310,7 +308,7 @@ LCRView::LCRView(NavigationView& nav) {
|
||||
};
|
||||
|
||||
button_scan.on_select = [this](Button&) {
|
||||
char str[16];
|
||||
std::string str_temp;
|
||||
|
||||
if (tx_mode == IDLE) {
|
||||
button_scan.set_style(&style_cancel);
|
||||
@ -319,9 +317,7 @@ LCRView::LCRView(NavigationView& nav) {
|
||||
} else {
|
||||
// Kill scan process
|
||||
baseband::kill_afsk();
|
||||
strcpy(str, "Abort @");
|
||||
strcat(str, rgsb);
|
||||
text_status.set(str);
|
||||
text_status.set("Abort @" + rgsb);
|
||||
progress.set_value(0);
|
||||
tx_mode = IDLE;
|
||||
button_scan.set_style(&style_val);
|
||||
@ -333,10 +329,11 @@ LCRView::LCRView(NavigationView& nav) {
|
||||
uint8_t n;
|
||||
|
||||
if (tx_mode == IDLE) {
|
||||
memset(litteral, 0, 5 * 8);
|
||||
options_ec.set_selected_index(0); // Auto
|
||||
for (n = 0; n < 5; n++)
|
||||
for (n = 0; n < 5; n++) {
|
||||
litteral[n] = " ";
|
||||
checkboxes[n].set_value(true);
|
||||
}
|
||||
set_dirty();
|
||||
start_tx(false);
|
||||
}
|
||||
|
@ -41,15 +41,15 @@ public:
|
||||
private:
|
||||
struct scan_list_t {
|
||||
uint8_t count;
|
||||
const char * addresses;
|
||||
const std::string * addresses;
|
||||
};
|
||||
|
||||
const scan_list_t scan_list[2] = {
|
||||
{ 36, &RGSB_list_Lille[0][0] },
|
||||
{ 20, &RGSB_list_Reims[0][0] }
|
||||
{ 36, &RGSB_list_Lille[0] },
|
||||
{ 20, &RGSB_list_Reims[0] }
|
||||
};
|
||||
|
||||
const char RGSB_list_Lille[36][5] = {
|
||||
const std::string RGSB_list_Lille[36] = {
|
||||
"AI10", "AI20", "AI30", "AI40",
|
||||
"AI50", "AI60", "AI70", "AJ10",
|
||||
"AJ20", "AJ30", "AJ40", "AJ50",
|
||||
@ -62,7 +62,7 @@ private:
|
||||
"EbS0"
|
||||
};
|
||||
|
||||
const char RGSB_list_Reims[20][5] = {
|
||||
const std::string RGSB_list_Reims[20] = {
|
||||
"AI10", "AI20", "AI30", "AI40",
|
||||
"AI50", "AI60", "AI70",
|
||||
"AJ10", "AJ20", "AJ30", "AJ40",
|
||||
@ -81,8 +81,8 @@ private:
|
||||
tx_modes tx_mode = IDLE;
|
||||
uint8_t scan_count { 0 }, scan_index { 0 };
|
||||
double scan_progress { 0 };
|
||||
char litteral[5][8] = { { 0 }, { 0 }, { 0 }, { 0 }, { 0 } };
|
||||
char rgsb[5] = { 0 };
|
||||
std::string litteral[5] { " " };
|
||||
std::string rgsb { " " };
|
||||
char lcr_message[512];
|
||||
char lcr_message_data[512];
|
||||
rf::Frequency f { 0 };
|
||||
|
@ -71,7 +71,7 @@ static msg_t ookthread_fn(void * arg) {
|
||||
}
|
||||
|
||||
void MorseView::on_set_text(NavigationView& nav) {
|
||||
textentry(nav, buffer, 28);
|
||||
text_entry(nav, buffer, 28);
|
||||
}
|
||||
|
||||
void MorseView::focus() {
|
||||
@ -139,7 +139,7 @@ void MorseView::on_tx_progress(const int progress, const bool done) {
|
||||
|
||||
void MorseView::set_foxhunt(size_t i) {
|
||||
message = foxhunt_codes[i];
|
||||
strncpy(buffer, message.c_str(), sizeof(buffer));
|
||||
buffer = message.c_str();
|
||||
text_message.set(message);
|
||||
update_tx_duration();
|
||||
}
|
||||
|
@ -61,7 +61,7 @@ public:
|
||||
size_t symbol_count { 0 };
|
||||
private:
|
||||
NavigationView& nav_;
|
||||
char buffer[29] = "PORTAPACK";
|
||||
std::string buffer { "PORTAPACK" };
|
||||
std::string message { };
|
||||
uint32_t time_units { 0 };
|
||||
|
||||
|
@ -124,7 +124,7 @@ void POCSAGTXView::paint(Painter&) {
|
||||
}
|
||||
|
||||
void POCSAGTXView::on_set_text(NavigationView& nav) {
|
||||
textentry(nav, buffer, 16);
|
||||
text_entry(nav, buffer, 16);
|
||||
}
|
||||
|
||||
POCSAGTXView::POCSAGTXView(
|
||||
|
@ -53,7 +53,7 @@ public:
|
||||
std::string title() const override { return "POCSAG TX"; };
|
||||
|
||||
private:
|
||||
char buffer[17] = "PORTAPACK";
|
||||
std::string buffer { "PORTAPACK" };
|
||||
std::string message { };
|
||||
NavigationView& nav_;
|
||||
|
||||
|
@ -49,8 +49,6 @@ RDSView::~RDSView() {
|
||||
void RDSView::start_tx() {
|
||||
transmitter_model.set_sampling_rate(2280000U);
|
||||
transmitter_model.set_rf_amp(true);
|
||||
transmitter_model.set_lna(40);
|
||||
transmitter_model.set_vga(40);
|
||||
transmitter_model.set_baseband_bandwidth(1750000);
|
||||
transmitter_model.enable();
|
||||
|
||||
@ -58,23 +56,16 @@ void RDSView::start_tx() {
|
||||
}
|
||||
|
||||
void RDSView::paint(Painter&) {
|
||||
char RadioTextA[17];
|
||||
|
||||
text_psn.set(PSN);
|
||||
|
||||
memcpy(RadioTextA, RadioText, 16);
|
||||
RadioTextA[16] = 0;
|
||||
text_radiotexta.set(RadioTextA);
|
||||
memcpy(RadioTextA, RadioText + 16, 8);
|
||||
RadioTextA[8] = 0;
|
||||
text_radiotextb.set(RadioTextA);
|
||||
text_radiotexta.set(RadioText.substr(0, 16));
|
||||
text_radiotextb.set(RadioText.substr(16, 16));
|
||||
}
|
||||
|
||||
RDSView::RDSView(NavigationView& nav) {
|
||||
baseband::run_image(portapack::spi_flash::image_tag_rds);
|
||||
|
||||
strcpy(PSN, "TEST1234");
|
||||
strcpy(RadioText, "Radiotext test ABCD1234");
|
||||
PSN = "TEST1234";
|
||||
RadioText = "Radiotext test ABCD1234";
|
||||
|
||||
add_children({
|
||||
&labels,
|
||||
@ -140,27 +131,16 @@ RDSView::RDSView(NavigationView& nav) {
|
||||
rds_flags.PI_code = sym_pi_code.value_hex_u64();
|
||||
};
|
||||
|
||||
options_pty.on_change = [this](size_t, int32_t v) {
|
||||
rds_flags.PTY = v;
|
||||
};
|
||||
options_pty.set_selected_index(0); // None
|
||||
|
||||
options_countrycode.on_change = [this](size_t, int32_t) {
|
||||
//rds_flags.PTY = v;
|
||||
};
|
||||
options_countrycode.set_selected_index(18); // Baguette du fromage
|
||||
|
||||
options_coverage.on_change = [this](size_t, int32_t) {
|
||||
//rds_flags.PTY = v;
|
||||
};
|
||||
options_coverage.set_selected_index(0); // Local
|
||||
|
||||
button_editpsn.on_select = [this, &nav](Button&) {
|
||||
textentry(nav, PSN, 8);
|
||||
text_entry(nav, PSN, 8);
|
||||
};
|
||||
|
||||
button_editradiotext.on_select = [this, &nav](Button&){
|
||||
textentry(nav, RadioText, 24);
|
||||
text_entry(nav, RadioText, 24);
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -45,8 +45,8 @@ public:
|
||||
std::string title() const override { return "RDS transmit"; };
|
||||
|
||||
private:
|
||||
char PSN[9] { 0 };
|
||||
char RadioText[25] { 0 };
|
||||
std::string PSN { 0 };
|
||||
std::string RadioText { 0 };
|
||||
bool txing = false;
|
||||
RDS_flags rds_flags { };
|
||||
|
||||
@ -60,8 +60,9 @@ private:
|
||||
{ { 14 * 8, 16 + 8 }, "CC:", Color::light_grey() },
|
||||
{ { 1 * 8, 32 + 8 }, "PI:", Color::light_grey() },
|
||||
{ { 13 * 8, 32 + 8 }, "Cov:", Color::light_grey() },
|
||||
{ { 2 * 8, 13 * 8 }, "PSN:", Color::light_grey() },
|
||||
{ { 2 * 8, 8 * 16 }, "RadioText:", Color::light_grey() },
|
||||
{ { 2 * 8, 14 * 16 }, "TX:", Color::light_grey() }
|
||||
{ { 2 * 8, 14 * 16 }, "TX group:", Color::light_grey() }
|
||||
};
|
||||
|
||||
OptionsField options_pty {
|
||||
@ -223,12 +224,12 @@ private:
|
||||
};
|
||||
|
||||
Button button_editpsn {
|
||||
{ 22 * 8, 5 * 16 + 12, 48, 24 },
|
||||
{ 22 * 8, 5 * 16 + 20, 48, 24 },
|
||||
"Set"
|
||||
};
|
||||
Text text_psn {
|
||||
{ 2 * 8, 6 * 16, 4 * 8, 16 },
|
||||
"PSN:"
|
||||
{ 6 * 8, 13 * 8, 4 * 8, 16 },
|
||||
""
|
||||
};
|
||||
|
||||
Text text_radiotexta {
|
||||
@ -245,7 +246,7 @@ private:
|
||||
};
|
||||
|
||||
OptionsField options_tx {
|
||||
{ 5 * 8, 14 * 16 },
|
||||
{ 11 * 8, 14 * 16 },
|
||||
11,
|
||||
{
|
||||
{ "PSN", 0 },
|
||||
|
@ -24,17 +24,17 @@
|
||||
|
||||
namespace ui {
|
||||
|
||||
bool textentry(NavigationView& nav, char * str, const size_t max_length, const std::function<void(char *)> on_done) {
|
||||
bool text_entry(NavigationView& nav, std::string& str, const size_t max_length, const std::function<void(std::string)> on_done) {
|
||||
|
||||
if (portapack::persistent_memory::ui_config_textentry() == 0) {
|
||||
auto te_view = nav.push<AlphanumView>(str, max_length);
|
||||
te_view->on_changed = [str, max_length, on_done](char * value) {
|
||||
te_view->on_changed = [str, max_length, on_done](std::string value) {
|
||||
//memcpy(str, value, max_length + 1);
|
||||
if (on_done) on_done(value);
|
||||
};
|
||||
} else {
|
||||
auto te_view = nav.push<HandWriteView>(str, max_length);
|
||||
te_view->on_changed = [str, max_length, on_done](char * value) {
|
||||
te_view->on_changed = [str, max_length, on_done](std::string value) {
|
||||
//memcpy(str, value, max_length + 1);
|
||||
if (on_done) on_done(value);
|
||||
};
|
||||
|
@ -29,11 +29,9 @@
|
||||
#include "ui_alphanum.hpp"
|
||||
#include "portapack_persistent_memory.hpp"
|
||||
|
||||
// TODO: Make class
|
||||
|
||||
namespace ui {
|
||||
|
||||
bool textentry(NavigationView& nav, char * str, size_t max_length, const std::function<void(char *)> on_done = nullptr);
|
||||
bool text_entry(NavigationView& nav, std::string& str, size_t max_length, const std::function<void(std::string)> on_done = nullptr);
|
||||
|
||||
} /* namespace ui */
|
||||
|
||||
|
@ -40,7 +40,7 @@ void RDSProcessor::execute(const buffer_c8_t& buffer) {
|
||||
cur_output = 0;
|
||||
}
|
||||
|
||||
cur_bit = (rdsdata[(bit_pos / 26) & 15] >> (25 - (bit_pos % 26))) & 1;
|
||||
cur_bit = (rdsdata[(bit_pos / 26) & 127] >> (25 - (bit_pos % 26))) & 1;
|
||||
prev_output = cur_output;
|
||||
cur_output = prev_output ^ cur_bit;
|
||||
|
||||
|
Binary file not shown.
Loading…
Reference in New Issue
Block a user