Savestate ! RDS (only PSN) tx

This commit is contained in:
furrtek 2015-08-23 05:08:38 +02:00
parent 14ada9e132
commit 8e0210f944
24 changed files with 459 additions and 45 deletions

View File

@ -160,10 +160,12 @@ CPPSRC = main.cpp \
ui_font_fixed_8x16.cpp \ ui_font_fixed_8x16.cpp \
ui_setup.cpp \ ui_setup.cpp \
ui_debug.cpp \ ui_debug.cpp \
ui_rds.cpp \
ui_console.cpp \ ui_console.cpp \
ui_receiver.cpp \ ui_receiver.cpp \
ui_spectrum.cpp \ ui_spectrum.cpp \
receiver_model.cpp \ receiver_model.cpp \
transmitter_model.cpp \
spectrum_color_lut.cpp \ spectrum_color_lut.cpp \
../common/utility.cpp \ ../common/utility.cpp \
../common/debug.cpp \ ../common/debug.cpp \

View File

@ -65,6 +65,10 @@ ReceiverModel receiver_model {
clock_manager clock_manager
}; };
TransmitterModel transmitter_model {
clock_manager
};
class Power { class Power {
public: public:
void init() { void init() {

View File

@ -22,6 +22,7 @@
#include "portapack_io.hpp" #include "portapack_io.hpp"
#include "receiver_model.hpp" #include "receiver_model.hpp"
#include "transmitter_model.hpp"
#include "spi_pp.hpp" #include "spi_pp.hpp"
#include "wm8731.hpp" #include "wm8731.hpp"
@ -41,6 +42,7 @@ extern SPI ssp1;
extern wolfson::wm8731::WM8731 audio_codec; extern wolfson::wm8731::WM8731 audio_codec;
extern ReceiverModel receiver_model; extern ReceiverModel receiver_model;
extern TransmitterModel transmitter_model;
void init(); void init();
void shutdown(); void shutdown();

View File

@ -101,7 +101,7 @@ uint32_t ReceiverModel::modulation() const {
return baseband_configuration.mode; return baseband_configuration.mode;
} }
void ReceiverModel::set_modulation(uint32_t v) { void ReceiverModel::set_modulation(int32_t v) {
baseband_configuration.mode = v; baseband_configuration.mode = v;
update_modulation(); update_modulation();
} }

View File

@ -64,7 +64,7 @@ public:
void set_sampling_rate(uint32_t hz); void set_sampling_rate(uint32_t hz);
uint32_t modulation() const; uint32_t modulation() const;
void set_modulation(uint32_t v); void set_modulation(int32_t v);
volume_t headphone_volume() const; volume_t headphone_volume() const;
void set_headphone_volume(volume_t v); void set_headphone_volume(volume_t v);
@ -82,7 +82,7 @@ private:
uint32_t baseband_bandwidth_ { max2837::filter::bandwidth_minimum }; uint32_t baseband_bandwidth_ { max2837::filter::bandwidth_minimum };
int32_t vga_gain_db_ { 32 }; int32_t vga_gain_db_ { 32 };
BasebandConfiguration baseband_configuration { BasebandConfiguration baseband_configuration {
.mode = 1, /* TODO: Enum! */ .mode = 1,
.sampling_rate = 3072000, .sampling_rate = 3072000,
.decimation_factor = 4, .decimation_factor = 4,
}; };

View File

@ -22,6 +22,9 @@
#include "touch.hpp" #include "touch.hpp"
namespace touch { namespace touch {
float Manager::cmx;
float Manager::cmy;
struct Metrics { struct Metrics {
const float x; 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) { void Manager::feed(const Frame frame) {
// touch_debounce.feed(touch_raw); // touch_debounce.feed(touch_raw);
const auto touch_raw = frame.touch; const auto touch_raw = frame.touch;
@ -81,6 +91,9 @@ void Manager::feed(const Frame frame) {
// TODO: Add touch pressure hysteresis? // TODO: Add touch pressure hysteresis?
touch_pressure = (metrics.r < r_touch_threshold); touch_pressure = (metrics.r < r_touch_threshold);
if( touch_pressure ) { if( touch_pressure ) {
cmx = metrics.x*100;
cmy = metrics.y*100;
const float x = width_pixels * (metrics.x - calib_x_low) / calib_x_range; const float x = width_pixels * (metrics.x - calib_x_low) / calib_x_range;
filter_x.feed(x); filter_x.feed(x);
const float y = height_pixels * (calib_y_high - metrics.y) / calib_y_range; const float y = height_pixels * (calib_y_high - metrics.y) / calib_y_range;

View File

@ -172,6 +172,9 @@ private:
NoTouch, NoTouch,
TouchDetected, TouchDetected,
}; };
static float cmx;
static float cmy;
static constexpr uint32_t width_pixels = 240; static constexpr uint32_t width_pixels = 240;
static constexpr uint32_t height_pixels = 320; static constexpr uint32_t height_pixels = 320;
@ -180,12 +183,12 @@ private:
static constexpr size_t touch_count_threshold { 4 }; static constexpr size_t touch_count_threshold { 4 };
static constexpr uint32_t touch_stable_bound { 4 }; static constexpr uint32_t touch_stable_bound { 4 };
static constexpr float calib_x_low = 0.07f; static constexpr float calib_x_low = 0.15f;
static constexpr float calib_x_high = 0.94f; static constexpr float calib_x_high = 0.93f;
static constexpr float calib_x_range = calib_x_high - calib_x_low; 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_low = 0.05f;
static constexpr float calib_y_high = 0.91f; static constexpr float calib_y_high = 0.84f;
static constexpr float calib_y_range = calib_y_high - calib_y_low; static constexpr float calib_y_range = calib_y_high - calib_y_low;
// Ensure filter length is equal or less than touch_count_threshold, // Ensure filter length is equal or less than touch_count_threshold,
@ -209,6 +212,8 @@ private:
}; };
} }
ui::Point raw_point() const ;
void touch_started() { void touch_started() {
fire_event(ui::TouchEvent::Type::Start); fire_event(ui::TouchEvent::Type::Start);
} }
@ -223,7 +228,7 @@ private:
void fire_event(ui::TouchEvent::Type type) { void fire_event(ui::TouchEvent::Type type) {
if( on_event ) { if( on_event ) {
on_event({ filtered_point(), type }); on_event({ filtered_point(), type, raw_point() });
} }
} }
}; };

View File

@ -23,12 +23,19 @@
#include "ch.h" #include "ch.h"
#include "ff.h"
#include "led.hpp"
#include "hackrf_gpio.hpp"
#include "portapack.hpp"
#include "radio.hpp" #include "radio.hpp"
#include "hackrf_hal.hpp" #include "hackrf_hal.hpp"
using namespace hackrf::one; using namespace hackrf::one;
namespace ui { namespace ui {
FRESULT fr; /* FatFs function common result code */
/* BasebandStatsView *****************************************************/ /* BasebandStatsView *****************************************************/
@ -154,11 +161,79 @@ void DebugRFFC5072View::focus() {
button_done.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) { DebugMenuView::DebugMenuView(NavigationView& nav) {
add_items<7>({ { add_items<7>({ {
{ "Memory", [&nav](){ nav.push(new DebugMemoryView { nav }); } }, { "Memory", [&nav](){ nav.push(new DebugMemoryView { nav }); } },
{ "Radio State", [&nav](){ nav.push(new NotImplementedView { 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 }); } }, { "RFFC5072", [&nav](){ nav.push(new DebugRFFC5072View { nav }); } },
{ "MAX2837", [&nav](){ nav.push(new NotImplementedView { nav }); } }, { "MAX2837", [&nav](){ nav.push(new NotImplementedView { nav }); } },
{ "Si5351C", [&nav](){ nav.push(new NotImplementedView { nav }); } }, { "Si5351C", [&nav](){ nav.push(new NotImplementedView { nav }); } },

View File

@ -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 { class DebugMenuView : public MenuView {
public: public:
DebugMenuView(NavigationView& nav); DebugMenuView(NavigationView& nav);

View File

@ -22,10 +22,12 @@
#include "ui_navigation.hpp" #include "ui_navigation.hpp"
#include "receiver_model.hpp" #include "receiver_model.hpp"
#include "transmitter_model.hpp"
#include "ui_setup.hpp" #include "ui_setup.hpp"
#include "ui_debug.hpp" #include "ui_debug.hpp"
#include "ui_receiver.hpp" #include "ui_receiver.hpp"
#include "ui_rds.hpp"
#include "portapack.hpp" #include "portapack.hpp"
#include "m4_startup.hpp" #include "m4_startup.hpp"
@ -95,10 +97,11 @@ void NavigationView::focus() {
/* SystemMenuView ********************************************************/ /* SystemMenuView ********************************************************/
SystemMenuView::SystemMenuView(NavigationView& nav) { SystemMenuView::SystemMenuView(NavigationView& nav) {
add_items<7>({ { add_items<8>({ {
{ "Receiver", [&nav](){ nav.push(new ReceiverView { nav, receiver_model }); } }, { "Receiver", [&nav](){ nav.push(new ReceiverView { nav, receiver_model }); } },
{ "Capture", [&nav](){ nav.push(new NotImplementedView { nav }); } }, { "Capture", [&nav](){ nav.push(new NotImplementedView { nav }); } },
{ "Analyze", [&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 }); } }, { "Setup", [&nav](){ nav.push(new SetupMenuView { nav }); } },
{ "About", [&nav](){ nav.push(new AboutView { nav }); } }, { "About", [&nav](){ nav.push(new AboutView { nav }); } },
{ "Debug", [&nav](){ nav.push(new DebugMenuView { nav }); } }, { "Debug", [&nav](){ nav.push(new DebugMenuView { nav }); } },

View File

@ -524,7 +524,7 @@ void ReceiverView::on_vga_changed(int32_t v_db) {
} }
void ReceiverView::on_modulation_changed(int32_t modulation) { void ReceiverView::on_modulation_changed(int32_t modulation) {
if( modulation == 3 ) { if( modulation == 4 ) {
/* TODO: This is TERRIBLE!!! */ /* TODO: This is TERRIBLE!!! */
receiver_model.set_sampling_rate(2457600); receiver_model.set_sampling_rate(2457600);
} else { } else {

View File

@ -20,9 +20,13 @@
*/ */
#include "ui_setup.hpp" #include "ui_setup.hpp"
#include "touch.hpp"
#include "portapack_persistent_memory.hpp" #include "portapack_persistent_memory.hpp"
#include "lpc43xx_cpp.hpp" #include "lpc43xx_cpp.hpp"
#include <math.h>
using namespace lpc43xx; using namespace lpc43xx;
namespace ui { namespace ui {
@ -157,11 +161,34 @@ void AboutView::focus() {
button_ok.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) { SetupMenuView::SetupMenuView(NavigationView& nav) {
add_items<3>({ { add_items<3>({ {
{ "Date/Time", [&nav](){ nav.push(new SetDateTimeView { nav }); } }, { "Date/Time", [&nav](){ nav.push(new SetDateTimeView { nav }); } },
{ "Frequency Correction", [&nav](){ nav.push(new SetFrequencyCorrectionView { 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(); }; on_left = [&nav](){ nav.pop(); };
} }

View File

@ -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 { class SetupMenuView : public MenuView {
public: public:
SetupMenuView(NavigationView& nav); SetupMenuView(NavigationView& nav);

View File

@ -20,6 +20,7 @@
*/ */
#include "baseband_dma.hpp" #include "baseband_dma.hpp"
#include "portapack_shared_memory.hpp"
#include <cstdint> #include <cstdint>
#include <cstddef> #include <cstddef>
@ -34,6 +35,8 @@ using namespace lpc43xx;
namespace baseband { namespace baseband {
namespace dma { namespace dma {
int quitt = 0;
constexpr uint32_t gpdma_ahb_master_sgpio = 0; constexpr uint32_t gpdma_ahb_master_sgpio = 0;
constexpr uint32_t gpdma_ahb_master_memory = 1; 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 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(); next_lli = gpdma_channel_sgpio.next_lli();
quitt = 0;
/* TODO: Is Mailbox the proper synchronization mechanism for this? */ /* TODO: Is Mailbox the proper synchronization mechanism for this? */
//chMBPostI(&mailbox, 0); //chMBPostI(&mailbox, 0);
chSemSignalI(&semaphore); chSemSignalI(&semaphore);
@ -162,6 +171,7 @@ baseband::buffer_t wait_for_rx_buffer() {
//msg_t msg; //msg_t msg;
//const auto status = chMBFetch(&mailbox, &msg, TIME_INFINITE); //const auto status = chMBFetch(&mailbox, &msg, TIME_INFINITE);
const auto status = chSemWait(&semaphore); const auto status = chSemWait(&semaphore);
if (quitt) return { nullptr, 0 };
if( status == RDY_OK ) { if( status == RDY_OK ) {
const auto next = next_lli; const auto next = next_lli;
if( next ) { 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 dma */
} /* namespace baseband */ } /* namespace baseband */

View File

@ -39,12 +39,15 @@ void configure(
const baseband::Direction direction const baseband::Direction direction
); );
void test();
void enable(const baseband::Direction direction); void enable(const baseband::Direction direction);
bool is_enabled(); bool is_enabled();
void disable(); void disable();
baseband::buffer_t wait_for_rx_buffer(); baseband::buffer_t wait_for_rx_buffer();
baseband::buffer_t wait_for_tx_buffer();
} /* namespace dma */ } /* namespace dma */
} /* namespace baseband */ } /* namespace baseband */

File diff suppressed because one or more lines are too long

View File

@ -36,6 +36,7 @@ enum class Direction {
}; };
buffer_t wait_for_rx_buffer(); buffer_t wait_for_rx_buffer();
buffer_t wait_for_tx_buffer();
} /* namespace baseband */ } /* namespace baseband */

View File

@ -28,6 +28,8 @@ using namespace portapack;
#include "ch.h" #include "ch.h"
#include <complex>
namespace lcd { namespace lcd {
namespace { 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( void ILI9341::fill_circle(
const ui::Point center, const ui::Point center,
const ui::Dim radius, const ui::Dim radius,

View File

@ -45,6 +45,7 @@ public:
void shutdown(); void shutdown();
void fill_rectangle(ui::Rect r, const ui::Color c); 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( void fill_circle(
const ui::Point center, const ui::Point center,
const ui::Dim radius, const ui::Dim radius,

View File

@ -164,6 +164,15 @@ public:
AudioStatistics statistics; AudioStatistics statistics;
}; };
/*enum bbmode {
RxNBAM = 1,
RxNBFM = 2,
RxWBFM = 3,
RxFSK = 4,
TxRDS = 15,
BBOff = 255
};*/
struct BasebandConfiguration { struct BasebandConfiguration {
int32_t mode; int32_t mode;
uint32_t sampling_rate; uint32_t sampling_rate;

View File

@ -38,6 +38,10 @@ struct SharedMemory {
// TODO: M0 should directly configure and control DMA channel that is // TODO: M0 should directly configure and control DMA channel that is
// acquiring ADC samples. // acquiring ADC samples.
TouchADCFrame touch_adc_frame; TouchADCFrame touch_adc_frame;
int test;
uint32_t rdsdata[16];
}; };
extern SharedMemory& shared_memory; extern SharedMemory& shared_memory;

View File

@ -282,6 +282,7 @@ struct TouchEvent {
Point point; Point point;
Type type; Type type;
Point rawpoint;
}; };
} /* namespace ui */ } /* namespace ui */

View File

@ -356,14 +356,23 @@ void Button::set_text(const std::string value) {
set_dirty(); set_dirty();
} }
void Button::set_style(const Style* new_style) {
if( new_style != style_ ) {
style_ = new_style;
set_dirty();
}
}
std::string Button::text() const { std::string Button::text() const {
return text_; return text_;
} }
void Button::paint(Painter& painter) { void Button::paint(Painter& painter) {
const auto r = screen_rect(); 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); painter.draw_rectangle(r, style().foreground);

View File

@ -228,6 +228,7 @@ public:
} }
void set_text(const std::string value); void set_text(const std::string value);
void set_style(const Style* new_style);
std::string text() const; std::string text() const;
void paint(Painter& painter) override; void paint(Painter& painter) override;
@ -237,6 +238,7 @@ public:
private: private:
std::string text_; std::string text_;
const Style* style_ { nullptr };
}; };
class OptionsField : public Widget { class OptionsField : public Widget {