mirror of
https://github.com/eried/portapack-mayhem.git
synced 2024-10-01 01:26:06 -04:00
Savestate ! RDS (only PSN) tx
This commit is contained in:
parent
14ada9e132
commit
8e0210f944
@ -160,10 +160,12 @@ CPPSRC = main.cpp \
|
||||
ui_font_fixed_8x16.cpp \
|
||||
ui_setup.cpp \
|
||||
ui_debug.cpp \
|
||||
ui_rds.cpp \
|
||||
ui_console.cpp \
|
||||
ui_receiver.cpp \
|
||||
ui_spectrum.cpp \
|
||||
receiver_model.cpp \
|
||||
transmitter_model.cpp \
|
||||
spectrum_color_lut.cpp \
|
||||
../common/utility.cpp \
|
||||
../common/debug.cpp \
|
||||
|
@ -65,6 +65,10 @@ ReceiverModel receiver_model {
|
||||
clock_manager
|
||||
};
|
||||
|
||||
TransmitterModel transmitter_model {
|
||||
clock_manager
|
||||
};
|
||||
|
||||
class Power {
|
||||
public:
|
||||
void init() {
|
||||
|
@ -22,6 +22,7 @@
|
||||
#include "portapack_io.hpp"
|
||||
|
||||
#include "receiver_model.hpp"
|
||||
#include "transmitter_model.hpp"
|
||||
|
||||
#include "spi_pp.hpp"
|
||||
#include "wm8731.hpp"
|
||||
@ -41,6 +42,7 @@ extern SPI ssp1;
|
||||
extern wolfson::wm8731::WM8731 audio_codec;
|
||||
|
||||
extern ReceiverModel receiver_model;
|
||||
extern TransmitterModel transmitter_model;
|
||||
|
||||
void init();
|
||||
void shutdown();
|
||||
|
@ -101,7 +101,7 @@ uint32_t ReceiverModel::modulation() const {
|
||||
return baseband_configuration.mode;
|
||||
}
|
||||
|
||||
void ReceiverModel::set_modulation(uint32_t v) {
|
||||
void ReceiverModel::set_modulation(int32_t v) {
|
||||
baseband_configuration.mode = v;
|
||||
update_modulation();
|
||||
}
|
||||
|
@ -64,7 +64,7 @@ public:
|
||||
void set_sampling_rate(uint32_t hz);
|
||||
|
||||
uint32_t modulation() const;
|
||||
void set_modulation(uint32_t v);
|
||||
void set_modulation(int32_t v);
|
||||
|
||||
volume_t headphone_volume() const;
|
||||
void set_headphone_volume(volume_t v);
|
||||
@ -82,7 +82,7 @@ private:
|
||||
uint32_t baseband_bandwidth_ { max2837::filter::bandwidth_minimum };
|
||||
int32_t vga_gain_db_ { 32 };
|
||||
BasebandConfiguration baseband_configuration {
|
||||
.mode = 1, /* TODO: Enum! */
|
||||
.mode = 1,
|
||||
.sampling_rate = 3072000,
|
||||
.decimation_factor = 4,
|
||||
};
|
||||
|
@ -22,6 +22,9 @@
|
||||
#include "touch.hpp"
|
||||
|
||||
namespace touch {
|
||||
|
||||
float Manager::cmx;
|
||||
float Manager::cmy;
|
||||
|
||||
struct Metrics {
|
||||
const float x;
|
||||
@ -66,6 +69,13 @@ static Metrics calculate_metrics(const Frame frame) {
|
||||
};
|
||||
}
|
||||
|
||||
ui::Point Manager::raw_point() const {
|
||||
return {
|
||||
static_cast<ui::Coord>(cmx),
|
||||
static_cast<ui::Coord>(cmy)
|
||||
};
|
||||
}
|
||||
|
||||
void Manager::feed(const Frame frame) {
|
||||
// touch_debounce.feed(touch_raw);
|
||||
const auto touch_raw = frame.touch;
|
||||
@ -81,6 +91,9 @@ void Manager::feed(const Frame frame) {
|
||||
// TODO: Add touch pressure hysteresis?
|
||||
touch_pressure = (metrics.r < r_touch_threshold);
|
||||
if( touch_pressure ) {
|
||||
cmx = metrics.x*100;
|
||||
cmy = metrics.y*100;
|
||||
|
||||
const float x = width_pixels * (metrics.x - calib_x_low) / calib_x_range;
|
||||
filter_x.feed(x);
|
||||
const float y = height_pixels * (calib_y_high - metrics.y) / calib_y_range;
|
||||
|
@ -172,6 +172,9 @@ private:
|
||||
NoTouch,
|
||||
TouchDetected,
|
||||
};
|
||||
|
||||
static float cmx;
|
||||
static float cmy;
|
||||
|
||||
static constexpr uint32_t width_pixels = 240;
|
||||
static constexpr uint32_t height_pixels = 320;
|
||||
@ -180,12 +183,12 @@ private:
|
||||
static constexpr size_t touch_count_threshold { 4 };
|
||||
static constexpr uint32_t touch_stable_bound { 4 };
|
||||
|
||||
static constexpr float calib_x_low = 0.07f;
|
||||
static constexpr float calib_x_high = 0.94f;
|
||||
static constexpr float calib_x_low = 0.15f;
|
||||
static constexpr float calib_x_high = 0.93f;
|
||||
static constexpr float calib_x_range = calib_x_high - calib_x_low;
|
||||
|
||||
static constexpr float calib_y_low = 0.04f;
|
||||
static constexpr float calib_y_high = 0.91f;
|
||||
static constexpr float calib_y_low = 0.05f;
|
||||
static constexpr float calib_y_high = 0.84f;
|
||||
static constexpr float calib_y_range = calib_y_high - calib_y_low;
|
||||
|
||||
// Ensure filter length is equal or less than touch_count_threshold,
|
||||
@ -209,6 +212,8 @@ private:
|
||||
};
|
||||
}
|
||||
|
||||
ui::Point raw_point() const ;
|
||||
|
||||
void touch_started() {
|
||||
fire_event(ui::TouchEvent::Type::Start);
|
||||
}
|
||||
@ -223,7 +228,7 @@ private:
|
||||
|
||||
void fire_event(ui::TouchEvent::Type type) {
|
||||
if( on_event ) {
|
||||
on_event({ filtered_point(), type });
|
||||
on_event({ filtered_point(), type, raw_point() });
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -23,12 +23,19 @@
|
||||
|
||||
#include "ch.h"
|
||||
|
||||
#include "ff.h"
|
||||
#include "led.hpp"
|
||||
#include "hackrf_gpio.hpp"
|
||||
#include "portapack.hpp"
|
||||
|
||||
#include "radio.hpp"
|
||||
|
||||
#include "hackrf_hal.hpp"
|
||||
using namespace hackrf::one;
|
||||
|
||||
namespace ui {
|
||||
|
||||
FRESULT fr; /* FatFs function common result code */
|
||||
|
||||
/* BasebandStatsView *****************************************************/
|
||||
|
||||
@ -154,11 +161,79 @@ void DebugRFFC5072View::focus() {
|
||||
button_done.focus();
|
||||
}
|
||||
|
||||
void DebugSDView::paint(Painter& painter) {
|
||||
const Point offset = {
|
||||
static_cast<Coord>(32),
|
||||
static_cast<Coord>(32)
|
||||
};
|
||||
|
||||
const auto text = to_string_hex(fr, 2);
|
||||
painter.draw_string(
|
||||
screen_pos() + offset,
|
||||
style(),
|
||||
text
|
||||
);
|
||||
}
|
||||
|
||||
DebugSDView::DebugSDView(NavigationView& nav) {
|
||||
add_children({ {
|
||||
&text_title,
|
||||
&button_makefile,
|
||||
&button_done
|
||||
} });
|
||||
|
||||
button_makefile.on_select = [this](Button&){
|
||||
FATFS fs; /* Work area (file system object) for logical drives */
|
||||
FIL fdst; /* File objects */
|
||||
int16_t buffer[512]; /* File copy buffer */
|
||||
UINT bw; /* File read/write count */
|
||||
|
||||
sdcConnect(&SDCD1);
|
||||
|
||||
fr = f_mount(&fs, "", 1);
|
||||
|
||||
fr = f_open(&fdst, "TST.SND", FA_OPEN_EXISTING | FA_READ);
|
||||
|
||||
if (!fr) led_rx.on();
|
||||
|
||||
/*fr = f_read(&fdst, buffer, 512*2, &bw);
|
||||
|
||||
Coord oy,ny;
|
||||
|
||||
oy = 128;
|
||||
|
||||
for (int c=0;c<512;c++) {
|
||||
ny = 128+32-(buffer[c]>>10);
|
||||
portapack::display.draw_line({static_cast<Coord>(c/3),oy},{static_cast<Coord>((c+1)/3),ny},{255,127,0});
|
||||
oy = ny;
|
||||
}*/
|
||||
|
||||
/*
|
||||
//if (fr) return;
|
||||
|
||||
fr = f_write(&fdst, buffer, br, &bw);
|
||||
//if (fr || bw < br) return;*/
|
||||
|
||||
//set_dirty();
|
||||
|
||||
f_close(&fdst);
|
||||
|
||||
f_mount(NULL, "", 0);
|
||||
|
||||
};
|
||||
|
||||
button_done.on_select = [&nav](Button&){ nav.pop(); };
|
||||
}
|
||||
|
||||
void DebugSDView::focus() {
|
||||
button_done.focus();
|
||||
}
|
||||
|
||||
DebugMenuView::DebugMenuView(NavigationView& nav) {
|
||||
add_items<7>({ {
|
||||
{ "Memory", [&nav](){ nav.push(new DebugMemoryView { nav }); } },
|
||||
{ "Radio State", [&nav](){ nav.push(new NotImplementedView { nav }); } },
|
||||
{ "SD Card", [&nav](){ nav.push(new NotImplementedView { nav }); } },
|
||||
{ "SD Card", [&nav](){ nav.push(new DebugSDView { nav }); } },
|
||||
{ "RFFC5072", [&nav](){ nav.push(new DebugRFFC5072View { nav }); } },
|
||||
{ "MAX2837", [&nav](){ nav.push(new NotImplementedView { nav }); } },
|
||||
{ "Si5351C", [&nav](){ nav.push(new NotImplementedView { nav }); } },
|
||||
|
@ -163,6 +163,31 @@ private:
|
||||
};
|
||||
};
|
||||
|
||||
class DebugSDView : public View {
|
||||
public:
|
||||
DebugSDView(NavigationView& nav);
|
||||
|
||||
void focus() override;
|
||||
|
||||
void paint(Painter& painter) override;
|
||||
|
||||
private:
|
||||
Text text_title {
|
||||
{ 32, 16, 128, 16 },
|
||||
"SD card debug",
|
||||
};
|
||||
|
||||
Button button_makefile {
|
||||
{ 72, 192, 96, 24 },
|
||||
"Play file"
|
||||
};
|
||||
|
||||
Button button_done {
|
||||
{ 72, 240, 96, 24 },
|
||||
"Done"
|
||||
};
|
||||
};
|
||||
|
||||
class DebugMenuView : public MenuView {
|
||||
public:
|
||||
DebugMenuView(NavigationView& nav);
|
||||
|
@ -22,10 +22,12 @@
|
||||
#include "ui_navigation.hpp"
|
||||
|
||||
#include "receiver_model.hpp"
|
||||
#include "transmitter_model.hpp"
|
||||
|
||||
#include "ui_setup.hpp"
|
||||
#include "ui_debug.hpp"
|
||||
#include "ui_receiver.hpp"
|
||||
#include "ui_rds.hpp"
|
||||
|
||||
#include "portapack.hpp"
|
||||
#include "m4_startup.hpp"
|
||||
@ -95,10 +97,11 @@ void NavigationView::focus() {
|
||||
/* SystemMenuView ********************************************************/
|
||||
|
||||
SystemMenuView::SystemMenuView(NavigationView& nav) {
|
||||
add_items<7>({ {
|
||||
add_items<8>({ {
|
||||
{ "Receiver", [&nav](){ nav.push(new ReceiverView { nav, receiver_model }); } },
|
||||
{ "Capture", [&nav](){ nav.push(new NotImplementedView { nav }); } },
|
||||
{ "Analyze", [&nav](){ nav.push(new NotImplementedView { nav }); } },
|
||||
{ "RDS toolbox",[&nav](){ nav.push(new RDSView { nav, transmitter_model }); } },
|
||||
{ "Setup", [&nav](){ nav.push(new SetupMenuView { nav }); } },
|
||||
{ "About", [&nav](){ nav.push(new AboutView { nav }); } },
|
||||
{ "Debug", [&nav](){ nav.push(new DebugMenuView { nav }); } },
|
||||
|
@ -524,7 +524,7 @@ void ReceiverView::on_vga_changed(int32_t v_db) {
|
||||
}
|
||||
|
||||
void ReceiverView::on_modulation_changed(int32_t modulation) {
|
||||
if( modulation == 3 ) {
|
||||
if( modulation == 4 ) {
|
||||
/* TODO: This is TERRIBLE!!! */
|
||||
receiver_model.set_sampling_rate(2457600);
|
||||
} else {
|
||||
|
@ -20,9 +20,13 @@
|
||||
*/
|
||||
|
||||
#include "ui_setup.hpp"
|
||||
#include "touch.hpp"
|
||||
|
||||
#include "portapack_persistent_memory.hpp"
|
||||
#include "lpc43xx_cpp.hpp"
|
||||
|
||||
#include <math.h>
|
||||
|
||||
using namespace lpc43xx;
|
||||
|
||||
namespace ui {
|
||||
@ -157,11 +161,34 @@ void AboutView::focus() {
|
||||
button_ok.focus();
|
||||
}
|
||||
|
||||
SetTouchCalibView::SetTouchCalibView(NavigationView& nav) {
|
||||
add_children({{
|
||||
&text_title,
|
||||
&text_debugx,
|
||||
&text_debugy,
|
||||
&button_ok
|
||||
}});
|
||||
|
||||
button_ok.on_select = [&nav](Button&){ nav.pop(); };
|
||||
}
|
||||
|
||||
void SetTouchCalibView::focus() {
|
||||
button_ok.focus();
|
||||
}
|
||||
|
||||
bool SetTouchCalibView::on_touch(const TouchEvent event) {
|
||||
if (event.type == ui::TouchEvent::Type::Start) {
|
||||
text_debugx.set(to_string_dec_uint(round(event.rawpoint.x), 4));
|
||||
text_debugy.set(to_string_dec_uint(round(event.rawpoint.y), 4));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
SetupMenuView::SetupMenuView(NavigationView& nav) {
|
||||
add_items<3>({ {
|
||||
{ "Date/Time", [&nav](){ nav.push(new SetDateTimeView { nav }); } },
|
||||
{ "Frequency Correction", [&nav](){ nav.push(new SetFrequencyCorrectionView { nav }); } },
|
||||
{ "Touch", [&nav](){ nav.push(new NotImplementedView { nav }); } },
|
||||
{ "Touch", [&nav](){ nav.push(new SetTouchCalibView { nav }); } },
|
||||
} });
|
||||
on_left = [&nav](){ nav.pop(); };
|
||||
}
|
||||
|
@ -209,6 +209,34 @@ private:
|
||||
};
|
||||
};
|
||||
|
||||
class SetTouchCalibView : public View {
|
||||
public:
|
||||
SetTouchCalibView(NavigationView& nav);
|
||||
void focus() override;
|
||||
bool on_touch(const TouchEvent event) override;
|
||||
private:
|
||||
|
||||
Text text_title {
|
||||
{ 64, 32, 40, 16 },
|
||||
"UL,UR,DL,DR !",
|
||||
};
|
||||
|
||||
Text text_debugx {
|
||||
{ 64, 64, 40, 16 },
|
||||
"X",
|
||||
};
|
||||
|
||||
Text text_debugy {
|
||||
{ 64, 80, 40, 16 },
|
||||
"Y",
|
||||
};
|
||||
|
||||
Button button_ok {
|
||||
{ 72, 192, 96, 24 },
|
||||
"OK"
|
||||
};
|
||||
};
|
||||
|
||||
class SetupMenuView : public MenuView {
|
||||
public:
|
||||
SetupMenuView(NavigationView& nav);
|
||||
|
@ -20,6 +20,7 @@
|
||||
*/
|
||||
|
||||
#include "baseband_dma.hpp"
|
||||
#include "portapack_shared_memory.hpp"
|
||||
|
||||
#include <cstdint>
|
||||
#include <cstddef>
|
||||
@ -34,6 +35,8 @@ using namespace lpc43xx;
|
||||
|
||||
namespace baseband {
|
||||
namespace dma {
|
||||
|
||||
int quitt = 0;
|
||||
|
||||
constexpr uint32_t gpdma_ahb_master_sgpio = 0;
|
||||
constexpr uint32_t gpdma_ahb_master_memory = 1;
|
||||
@ -105,8 +108,14 @@ static Semaphore semaphore;
|
||||
|
||||
static volatile const gpdma::channel::LLI* next_lli = nullptr;
|
||||
|
||||
static void transfer_complete() {
|
||||
void test() {
|
||||
quitt = 1;
|
||||
chSemSignalI(&semaphore);
|
||||
}
|
||||
|
||||
void transfer_complete() {
|
||||
next_lli = gpdma_channel_sgpio.next_lli();
|
||||
quitt = 0;
|
||||
/* TODO: Is Mailbox the proper synchronization mechanism for this? */
|
||||
//chMBPostI(&mailbox, 0);
|
||||
chSemSignalI(&semaphore);
|
||||
@ -162,6 +171,7 @@ baseband::buffer_t wait_for_rx_buffer() {
|
||||
//msg_t msg;
|
||||
//const auto status = chMBFetch(&mailbox, &msg, TIME_INFINITE);
|
||||
const auto status = chSemWait(&semaphore);
|
||||
if (quitt) return { nullptr, 0 };
|
||||
if( status == RDY_OK ) {
|
||||
const auto next = next_lli;
|
||||
if( next ) {
|
||||
@ -176,5 +186,23 @@ baseband::buffer_t wait_for_rx_buffer() {
|
||||
}
|
||||
}
|
||||
|
||||
baseband::buffer_t wait_for_tx_buffer() {
|
||||
//msg_t msg;
|
||||
//const auto status = chMBFetch(&mailbox, &msg, TIME_INFINITE);
|
||||
const auto status = chSemWait(&semaphore);
|
||||
if( status == RDY_OK ) {
|
||||
const auto next = next_lli;
|
||||
if( next ) {
|
||||
const size_t next_index = next - &lli_loop[0];
|
||||
const size_t free_index = (next_index + transfers_per_buffer - 2) & transfers_mask;
|
||||
return { reinterpret_cast<sample_t*>(lli_loop[free_index].srcaddr), transfer_samples };
|
||||
} else {
|
||||
return { nullptr, 0 };
|
||||
}
|
||||
} else {
|
||||
return { nullptr, 0 };
|
||||
}
|
||||
}
|
||||
|
||||
} /* namespace dma */
|
||||
} /* namespace baseband */
|
||||
|
@ -39,12 +39,15 @@ void configure(
|
||||
const baseband::Direction direction
|
||||
);
|
||||
|
||||
void test();
|
||||
|
||||
void enable(const baseband::Direction direction);
|
||||
bool is_enabled();
|
||||
|
||||
void disable();
|
||||
|
||||
baseband::buffer_t wait_for_rx_buffer();
|
||||
baseband::buffer_t wait_for_tx_buffer();
|
||||
|
||||
} /* namespace dma */
|
||||
} /* namespace baseband */
|
||||
|
File diff suppressed because one or more lines are too long
@ -36,6 +36,7 @@ enum class Direction {
|
||||
};
|
||||
|
||||
buffer_t wait_for_rx_buffer();
|
||||
buffer_t wait_for_tx_buffer();
|
||||
|
||||
} /* namespace baseband */
|
||||
|
||||
|
@ -28,6 +28,8 @@ using namespace portapack;
|
||||
|
||||
#include "ch.h"
|
||||
|
||||
#include <complex>
|
||||
|
||||
namespace lcd {
|
||||
|
||||
namespace {
|
||||
@ -239,6 +241,25 @@ void ILI9341::fill_rectangle(ui::Rect r, const ui::Color c) {
|
||||
}
|
||||
}
|
||||
|
||||
void ILI9341::draw_line(const ui::Point start, const ui::Point end, const ui::Color color) {
|
||||
int x0 = start.x;
|
||||
int y0 = start.y;
|
||||
int x1 = end.x;
|
||||
int y1 = end.y;
|
||||
|
||||
int dx = std::abs(x1-x0), sx = x0<x1 ? 1 : -1;
|
||||
int dy = std::abs(y1-y0), sy = y0<y1 ? 1 : -1;
|
||||
int err = (dx>dy ? dx : -dy)/2, e2;
|
||||
|
||||
for(;;){
|
||||
draw_pixel({static_cast<ui::Coord>(x0), static_cast<ui::Coord>(y0)}, color);
|
||||
if (x0==x1 && y0==y1) break;
|
||||
e2 = err;
|
||||
if (e2 >-dx) { err -= dy; x0 += sx; }
|
||||
if (e2 < dy) { err += dx; y0 += sy; }
|
||||
}
|
||||
}
|
||||
|
||||
void ILI9341::fill_circle(
|
||||
const ui::Point center,
|
||||
const ui::Dim radius,
|
||||
|
@ -45,6 +45,7 @@ public:
|
||||
void shutdown();
|
||||
|
||||
void fill_rectangle(ui::Rect r, const ui::Color c);
|
||||
void draw_line(const ui::Point start, const ui::Point end, const ui::Color color);
|
||||
void fill_circle(
|
||||
const ui::Point center,
|
||||
const ui::Dim radius,
|
||||
|
@ -164,6 +164,15 @@ public:
|
||||
AudioStatistics statistics;
|
||||
};
|
||||
|
||||
/*enum bbmode {
|
||||
RxNBAM = 1,
|
||||
RxNBFM = 2,
|
||||
RxWBFM = 3,
|
||||
RxFSK = 4,
|
||||
TxRDS = 15,
|
||||
BBOff = 255
|
||||
};*/
|
||||
|
||||
struct BasebandConfiguration {
|
||||
int32_t mode;
|
||||
uint32_t sampling_rate;
|
||||
|
@ -38,6 +38,10 @@ struct SharedMemory {
|
||||
// TODO: M0 should directly configure and control DMA channel that is
|
||||
// acquiring ADC samples.
|
||||
TouchADCFrame touch_adc_frame;
|
||||
|
||||
int test;
|
||||
|
||||
uint32_t rdsdata[16];
|
||||
};
|
||||
|
||||
extern SharedMemory& shared_memory;
|
||||
|
@ -282,6 +282,7 @@ struct TouchEvent {
|
||||
|
||||
Point point;
|
||||
Type type;
|
||||
Point rawpoint;
|
||||
};
|
||||
|
||||
} /* namespace ui */
|
||||
|
@ -356,14 +356,23 @@ void Button::set_text(const std::string value) {
|
||||
set_dirty();
|
||||
}
|
||||
|
||||
void Button::set_style(const Style* new_style) {
|
||||
if( new_style != style_ ) {
|
||||
style_ = new_style;
|
||||
set_dirty();
|
||||
}
|
||||
}
|
||||
|
||||
std::string Button::text() const {
|
||||
return text_;
|
||||
}
|
||||
|
||||
void Button::paint(Painter& painter) {
|
||||
const auto r = screen_rect();
|
||||
|
||||
if (style_ == nullptr) style_ = &style();
|
||||
|
||||
const auto paint_style = (has_focus() || flags.highlighted) ? style().invert() : style();
|
||||
const auto paint_style = (has_focus() || flags.highlighted) ? style_->invert() : *(style_);
|
||||
|
||||
painter.draw_rectangle(r, style().foreground);
|
||||
|
||||
|
@ -228,6 +228,7 @@ public:
|
||||
}
|
||||
|
||||
void set_text(const std::string value);
|
||||
void set_style(const Style* new_style);
|
||||
std::string text() const;
|
||||
|
||||
void paint(Painter& painter) override;
|
||||
@ -237,6 +238,7 @@ public:
|
||||
|
||||
private:
|
||||
std::string text_;
|
||||
const Style* style_ { nullptr };
|
||||
};
|
||||
|
||||
class OptionsField : public Widget {
|
||||
|
Loading…
Reference in New Issue
Block a user