diff --git a/firmware/application/analog_audio_app.cpp b/firmware/application/analog_audio_app.cpp index cb8684cd2..d68556b18 100644 --- a/firmware/application/analog_audio_app.cpp +++ b/firmware/application/analog_audio_app.cpp @@ -322,7 +322,7 @@ void AnalogAudioView::record_start() { return; } - capture_thread = std::make_unique(filename); + capture_thread = std::make_unique(filename, 12, 2); button_record.set_bitmap(&bitmap_stop); } diff --git a/firmware/application/capture_app.cpp b/firmware/application/capture_app.cpp index 478dcedd3..d5df1ee22 100644 --- a/firmware/application/capture_app.cpp +++ b/firmware/application/capture_app.cpp @@ -112,7 +112,7 @@ void CaptureAppView::on_record() { return; } - capture_thread = std::make_unique(filename); + capture_thread = std::make_unique(filename, 14, 1); button_record.set_bitmap(&bitmap_stop); } } diff --git a/firmware/application/capture_thread.cpp b/firmware/application/capture_thread.cpp index a441350a2..e39d63121 100644 --- a/firmware/application/capture_thread.cpp +++ b/firmware/application/capture_thread.cpp @@ -21,4 +21,5 @@ #include "capture_thread.hpp" +FIFO* StreamOutput::fifo = nullptr; Thread* CaptureThread::thread = nullptr; diff --git a/firmware/application/capture_thread.hpp b/firmware/application/capture_thread.hpp index 68806f588..e43fbcfa4 100644 --- a/firmware/application/capture_thread.hpp +++ b/firmware/application/capture_thread.hpp @@ -37,13 +37,19 @@ using namespace hackrf::one; class StreamOutput { public: - StreamOutput() { + StreamOutput( + const size_t write_size_log2, + const size_t buffer_count_log2 + ) : config { write_size_log2, buffer_count_log2 } + { shared_memory.baseband_queue.push_and_wait( CaptureConfigMessage { &config } ); + fifo = config.fifo; } ~StreamOutput() { + fifo = nullptr; shared_memory.baseband_queue.push_and_wait( CaptureConfigMessage { nullptr } ); @@ -57,6 +63,8 @@ public: return config.fifo->out(reinterpret_cast(data), length); } + static FIFO* fifo; + private: CaptureConfig config; }; @@ -64,9 +72,13 @@ private: class CaptureThread { public: CaptureThread( - std::string file_path - ) : file_path { std::move(file_path) }, - write_buffer { std::make_unique>() } + std::string file_path, + size_t write_size_log2, + size_t buffer_count_log2 + ) : write_size_log2 { write_size_log2 }, + write_size { 1U << write_size_log2 }, + buffer_count_log2 { buffer_count_log2 }, + file_path { std::move(file_path) } { // Need significant stack for FATFS thread = chThdCreateFromHeap(NULL, 1024, NORMALPRIO + 10, CaptureThread::static_fn, this); @@ -90,16 +102,17 @@ public: static void check_fifo_isr() { // TODO: Prevent over-signalling by transmitting a set of // flags from the baseband core. - if( thread ) { + const auto fifo = StreamOutput::fifo; + if( fifo ) { chEvtSignalI(thread, EVT_MASK_CAPTURE_THREAD); } } private: - static constexpr size_t write_size = 16384; - + const size_t write_size_log2; + const size_t write_size; + const size_t buffer_count_log2; const std::string file_path; - std::unique_ptr> write_buffer; File file; static Thread* thread; @@ -113,12 +126,17 @@ private: return false; } - StreamOutput stream; + const auto write_buffer = std::make_unique(write_size); + if( !write_buffer ) { + return false; + } + + StreamOutput stream { write_size_log2, buffer_count_log2 }; while( !chThdShouldTerminate() ) { chEvtWaitAny(EVT_MASK_CAPTURE_THREAD); - while( stream.available() >= write_buffer->size() ) { + while( stream.available() >= write_size ) { if( !transfer(stream, write_buffer.get()) ) { return false; } @@ -128,14 +146,14 @@ private: return true; } - bool transfer(StreamOutput& stream, std::array* const write_buffer) { + bool transfer(StreamOutput& stream, uint8_t* const write_buffer) { bool success = false; led_usb.on(); - const auto bytes_to_write = stream.read(write_buffer->data(), write_buffer->size()); - if( bytes_to_write == write_buffer->size() ) { - if( file.write(write_buffer->data(), write_buffer->size()) ) { + const auto bytes_to_write = stream.read(write_buffer, write_size); + if( bytes_to_write == write_size ) { + if( file.write(write_buffer, write_size) ) { success = true; } } diff --git a/firmware/application/event_m0.cpp b/firmware/application/event_m0.cpp index 1b34f44fb..e82faa3b1 100644 --- a/firmware/application/event_m0.cpp +++ b/firmware/application/event_m0.cpp @@ -22,7 +22,6 @@ #include "event_m0.hpp" #include "portapack.hpp" -#include "portapack_shared_memory.hpp" #include "sd_card.hpp" @@ -47,7 +46,7 @@ CH_IRQ_HANDLER(M4Core_IRQHandler) { chSysLockFromIsr(); CaptureThread::check_fifo_isr(); - EventDispatcher::events_flag_isr(EVT_MASK_APPLICATION); + EventDispatcher::check_fifo_isr(); chSysUnlockFromIsr(); creg::m4txevent::clear(); diff --git a/firmware/application/event_m0.hpp b/firmware/application/event_m0.hpp index 34b988e89..f793eaf79 100644 --- a/firmware/application/event_m0.hpp +++ b/firmware/application/event_m0.hpp @@ -28,6 +28,7 @@ #include "ui_painter.hpp" #include "portapack.hpp" +#include "portapack_shared_memory.hpp" #include "message.hpp" @@ -58,6 +59,12 @@ public: void set_display_sleep(const bool sleep); + static inline void check_fifo_isr() { + if( !shared_memory.application_queue.is_empty() ) { + events_flag_isr(EVT_MASK_APPLICATION); + } + } + static inline void events_flag(const eventmask_t events) { if( thread_event_loop ) { chEvtSignal(thread_event_loop, events); diff --git a/firmware/baseband/proc_am_audio.cpp b/firmware/baseband/proc_am_audio.cpp index 9af3295e5..865ea260f 100644 --- a/firmware/baseband/proc_am_audio.cpp +++ b/firmware/baseband/proc_am_audio.cpp @@ -100,7 +100,7 @@ void NarrowbandAMAudio::configure(const AMConfigureMessage& message) { void NarrowbandAMAudio::capture_config(const CaptureConfigMessage& message) { if( message.config ) { - audio_output.set_stream(std::make_unique(14, *message.config)); + audio_output.set_stream(std::make_unique(*message.config)); } else { audio_output.set_stream(nullptr); } diff --git a/firmware/baseband/proc_capture.cpp b/firmware/baseband/proc_capture.cpp index e0b0455ab..bcb30dd92 100644 --- a/firmware/baseband/proc_capture.cpp +++ b/firmware/baseband/proc_capture.cpp @@ -85,7 +85,7 @@ void CaptureProcessor::on_message(const Message* const message) { void CaptureProcessor::capture_config(const CaptureConfigMessage& message) { if( message.config ) { - stream = std::make_unique(15, *message.config); + stream = std::make_unique(*message.config); } else { stream.reset(); } diff --git a/firmware/baseband/proc_nfm_audio.cpp b/firmware/baseband/proc_nfm_audio.cpp index bdf4421a8..190ed4b08 100644 --- a/firmware/baseband/proc_nfm_audio.cpp +++ b/firmware/baseband/proc_nfm_audio.cpp @@ -88,7 +88,7 @@ void NarrowbandFMAudio::configure(const NBFMConfigureMessage& message) { void NarrowbandFMAudio::capture_config(const CaptureConfigMessage& message) { if( message.config ) { - audio_output.set_stream(std::make_unique(14, *message.config)); + audio_output.set_stream(std::make_unique(*message.config)); } else { audio_output.set_stream(nullptr); } diff --git a/firmware/baseband/proc_wfm_audio.cpp b/firmware/baseband/proc_wfm_audio.cpp index c6f1e1165..1db24b4cd 100644 --- a/firmware/baseband/proc_wfm_audio.cpp +++ b/firmware/baseband/proc_wfm_audio.cpp @@ -117,7 +117,7 @@ void WidebandFMAudio::configure(const WFMConfigureMessage& message) { void WidebandFMAudio::capture_config(const CaptureConfigMessage& message) { if( message.config ) { - audio_output.set_stream(std::make_unique(15, *message.config)); + audio_output.set_stream(std::make_unique(*message.config)); } else { audio_output.set_stream(nullptr); } diff --git a/firmware/baseband/stream_input.hpp b/firmware/baseband/stream_input.hpp index e82214776..db5f353d1 100644 --- a/firmware/baseband/stream_input.hpp +++ b/firmware/baseband/stream_input.hpp @@ -22,18 +22,21 @@ #ifndef __STREAM_INPUT_H__ #define __STREAM_INPUT_H__ -#include "portapack_shared_memory.hpp" - +#include "message.hpp" #include "fifo.hpp" +#include "lpc43xx_cpp.hpp" +using namespace lpc43xx; + #include #include #include class StreamInput { public: - StreamInput(const size_t K, CaptureConfig& config) : - K { K }, + StreamInput(CaptureConfig& config) : + K { config.write_size_log2 + config.buffer_count_log2 }, + event_bytes_mask { (1UL << config.write_size_log2) - 1 }, data { std::make_unique(1UL << K) }, fifo { data.get(), K } { @@ -58,7 +61,7 @@ public: private: const size_t K; - const uint64_t event_bytes_mask = (1ULL << (K - 2)) - 1; + const uint64_t event_bytes_mask; uint64_t bytes_written = 0; std::unique_ptr data; FIFO fifo; diff --git a/firmware/common/message.hpp b/firmware/common/message.hpp index 44d0e5cf9..1c906c611 100644 --- a/firmware/common/message.hpp +++ b/firmware/common/message.hpp @@ -411,7 +411,18 @@ public: }; struct CaptureConfig { - FIFO* fifo { nullptr }; + const size_t write_size_log2; + const size_t buffer_count_log2; + FIFO* 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 }, + fifo { nullptr } + { + } }; class CaptureConfigMessage : public Message { diff --git a/firmware/common/message_queue.hpp b/firmware/common/message_queue.hpp index cd2bacd78..3e0a1cbb4 100644 --- a/firmware/common/message_queue.hpp +++ b/firmware/common/message_queue.hpp @@ -70,6 +70,10 @@ public: } } + bool is_empty() const { + return fifo.is_empty(); + } + private: FIFO fifo; Mutex mutex_write; @@ -92,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);