diff --git a/firmware/CMakeLists.txt b/firmware/CMakeLists.txt index db2f2963..ed73b622 100644 --- a/firmware/CMakeLists.txt +++ b/firmware/CMakeLists.txt @@ -28,7 +28,7 @@ set(CHIBIOS_PORTAPACK ${PROJECT_SOURCE_DIR}/chibios-portapack) set(HACKRF_FIRMWARE_FILENAME hackrf_one_usb_ram.dfu) set(HACKRF_FIRMWARE_IMAGE ${PROJECT_SOURCE_DIR}/${HACKRF_FIRMWARE_FILENAME}) -set(HACKRF_CPLD_SVF_FILENAME hackrf_cpld_portapack.svf) +set(HACKRF_CPLD_SVF_FILENAME hackrf_cpld_default.svf) set(HACKRF_CPLD_SVF_PATH ${PROJECT_SOURCE_DIR}/${HACKRF_CPLD_SVF_FILENAME}) set(EXTRACT_CPLD_DATA ${PROJECT_SOURCE_DIR}/tools/extract_cpld_data.py) diff --git a/firmware/application/main.cpp b/firmware/application/main.cpp index 582875fe..bc7832e0 100755 --- a/firmware/application/main.cpp +++ b/firmware/application/main.cpp @@ -23,8 +23,11 @@ // Color bitmaps generated with: // Gimp image > indexed colors (16), then "xxd -i *.bmp" +//BUG: Distorted audio in WFM receiver //BUG: (fixed ?) Bad console scroll init //BUG: POCSAG misses alphanum messages, cuts them off sometimes +//BUG: Check AFSK transmit end, skips last bits ? +//BUG: RDS doesn't stop baseband when stopping tx ? //TEST: Imperial in whipcalc //TEST: Numbers @@ -37,10 +40,6 @@ //TODO: IQ replay //TODO: Wav visualizer -//BUG: POCSAG RX sometimes misses the first codeword after SYNC -//BUG: Check AFSK transmit end, skips last bits ? -//BUG: RDS doesn't stop baseband when stopping tx ? - //TODO: File browser ? //TODO: Mousejack ? //TODO: Move frequencykeypad from ui_receiver to ui_widget (used everywhere) diff --git a/firmware/application/receiver_model.hpp b/firmware/application/receiver_model.hpp index 10eb5d9f..1d6d4783 100644 --- a/firmware/application/receiver_model.hpp +++ b/firmware/application/receiver_model.hpp @@ -30,27 +30,6 @@ #include "max2837.hpp" #include "volume.hpp" -struct BasebandConfiguration { - int32_t mode; - uint32_t sampling_rate; - size_t decimation_factor; - - constexpr BasebandConfiguration( - int32_t mode, - uint32_t sampling_rate, - size_t decimation_factor = 1 - ) : mode { mode }, - sampling_rate { sampling_rate }, - decimation_factor { decimation_factor } - { - } - - constexpr BasebandConfiguration( - ) : BasebandConfiguration { -1, 0, 1 } - { - } -}; - class ReceiverModel { public: enum class Mode { diff --git a/firmware/application/transmitter_model.cpp b/firmware/application/transmitter_model.cpp index f78c9d46..b0fdf032 100644 --- a/firmware/application/transmitter_model.cpp +++ b/firmware/application/transmitter_model.cpp @@ -112,8 +112,10 @@ void TransmitterModel::enable() { signal_token_tick_second = rtc_time::signal_tick_second += [this]() { this->on_tick_second(); }; - if (portapack::persistent_memory::stealth_mode()) - EventDispatcher::set_display_sleep(true); + if (portapack::persistent_memory::stealth_mode()) { + DisplaySleepMessage message; + EventDispatcher::send_message(message); + } } void TransmitterModel::disable() { diff --git a/firmware/application/ui_bht_tx.cpp b/firmware/application/ui_bht_tx.cpp index c1f04ec3..34e6534c 100644 --- a/firmware/application/ui_bht_tx.cpp +++ b/firmware/application/ui_bht_tx.cpp @@ -64,7 +64,7 @@ void BHTView::start_tx() { generate_message(); transmitter_model.set_tuning_frequency(bht_freqs[options_freq.selected_index()]); - transmitter_model.set_sampling_rate(1536000U); + transmitter_model.set_sampling_rate(1536000); transmitter_model.set_rf_amp(true); transmitter_model.set_lna(40); transmitter_model.set_vga(40); @@ -78,7 +78,7 @@ void BHTView::start_tx() { } audio::set_rate(audio::Rate::Hz_24000); - baseband::set_tones_data(field_bw.value() * 20, CCIR_SILENCE, 20, false, checkbox_speaker.value()); + baseband::set_tones_data(field_bw.value(), CCIR_SILENCE, 20, false, checkbox_speaker.value()); } void BHTView::on_tx_progress(const int progress, const bool done) { diff --git a/firmware/application/ui_nuoptix.cpp b/firmware/application/ui_nuoptix.cpp index dc445afa..e4d452f7 100644 --- a/firmware/application/ui_nuoptix.cpp +++ b/firmware/application/ui_nuoptix.cpp @@ -137,7 +137,7 @@ void NuoptixView::transmit(bool setup) { shared_memory.bb_data.tones_data.silence = NUOPTIX_TONE_LENGTH; // 49ms tone, 49ms space audio::set_rate(audio::Rate::Hz_24000); - baseband::set_tones_data(number_bw.value() * 500, 0, 6 * 2, true, true); + baseband::set_tones_data(number_bw.value(), 0, 6 * 2, true, true); timecode++; } diff --git a/firmware/application/ui_nuoptix.hpp b/firmware/application/ui_nuoptix.hpp index b7cde481..8e6fd962 100644 --- a/firmware/application/ui_nuoptix.hpp +++ b/firmware/application/ui_nuoptix.hpp @@ -97,14 +97,14 @@ private: NumberField number_bw { { 13 * 8, 4 }, - 3, - {1, 150}, + 2, + {1, 99}, 1, ' ' }; Text text_kHz { - { 16 * 8, 4, 3 * 8, 16 }, + { 15 * 8, 4, 3 * 8, 16 }, "kHz" }; diff --git a/firmware/application/ui_receiver.cpp b/firmware/application/ui_receiver.cpp index 802e7092..1142eeed 100644 --- a/firmware/application/ui_receiver.cpp +++ b/firmware/application/ui_receiver.cpp @@ -1,5 +1,6 @@ /* * Copyright (C) 2014 Jared Boone, ShareBrained Technology, Inc. + * Copyright (C) 2016 Furrtek * * This file is part of PortaPack. * diff --git a/firmware/baseband/audio_output.cpp b/firmware/baseband/audio_output.cpp index dd06d3ea..ee16322d 100644 --- a/firmware/baseband/audio_output.cpp +++ b/firmware/baseband/audio_output.cpp @@ -93,7 +93,7 @@ void AudioOutput::on_block( } } else audio_present = true; - + fill_audio_buffer(audio, audio_present); } diff --git a/firmware/baseband/audio_output.hpp b/firmware/baseband/audio_output.hpp index fac6f3e5..bd0455f6 100644 --- a/firmware/baseband/audio_output.hpp +++ b/firmware/baseband/audio_output.hpp @@ -36,9 +36,7 @@ class AudioOutput { public: - void configure( - const bool do_proc - ); + void configure(const bool do_proc); void configure( const iir_biquad_config_t& hpf_config, diff --git a/firmware/baseband/baseband_dma.cpp b/firmware/baseband/baseband_dma.cpp index 0850ed68..4fc1fdd8 100644 --- a/firmware/baseband/baseband_dma.cpp +++ b/firmware/baseband/baseband_dma.cpp @@ -115,9 +115,16 @@ static void dma_error() { void init() { gpdma_channel_sgpio.set_handlers(transfer_complete, dma_error); - - // LPC_GPDMA->SYNC |= (1 << gpdma_src_peripheral); - // LPC_GPDMA->SYNC |= (1 << gpdma_dest_peripheral); +#if defined(PORTAPACK_BASEBAND_DMA_NO_SYNC) + /* Disable synchronization logic to improve(?) DMA response time. + * SGPIO (peripheral) must be on same clock as GPDMA peripheral. + * SGPIO runs from BASE_PERIPH_CLK, which is set to PLL1 in normal + * operation, same as the M4 and M0 cores. Memory, of course, is + * running from the same clock as the cores. + */ + LPC_GPDMA->SYNC |= (1 << gpdma_src_peripheral); + LPC_GPDMA->SYNC |= (1 << gpdma_dest_peripheral); +#endif } void configure( @@ -149,7 +156,7 @@ void disable() { gpdma_channel_sgpio.disable(); } -/*baseband::buffer_t wait_for_buffer() { +baseband::buffer_t wait_for_buffer() { const auto next_index = thread_wait.sleep(); if( next_index >= 0 ) { @@ -161,28 +168,6 @@ void disable() { } else { return { }; } -}*/ - -baseband::buffer_t wait_for_rx_buffer() { - const auto next_index = thread_wait.sleep(); - - if( next_index >= 0 ) { - const size_t free_index = (next_index + transfers_per_buffer - 2) & transfers_mask; - return { reinterpret_cast(lli_loop[free_index].destaddr), transfer_samples }; - } else { - return { }; - } -} - -baseband::buffer_t wait_for_tx_buffer() { - const auto next_index = thread_wait.sleep(); - - if( next_index >= 0 ) { - const size_t free_index = (next_index + transfers_per_buffer - 2) & transfers_mask; - return { reinterpret_cast(lli_loop[free_index].srcaddr), transfer_samples }; - } else { - return { }; - } } } /* namespace dma */ diff --git a/firmware/baseband/baseband_dma.hpp b/firmware/baseband/baseband_dma.hpp index 8e67a12e..56752ddc 100644 --- a/firmware/baseband/baseband_dma.hpp +++ b/firmware/baseband/baseband_dma.hpp @@ -42,8 +42,7 @@ bool is_enabled(); void disable(); -baseband::buffer_t wait_for_rx_buffer(); -baseband::buffer_t wait_for_tx_buffer(); +baseband::buffer_t wait_for_buffer(); } /* namespace dma */ } /* namespace baseband */ diff --git a/firmware/baseband/baseband_thread.cpp b/firmware/baseband/baseband_thread.cpp index b5c6e544..7083e9f4 100644 --- a/firmware/baseband/baseband_thread.cpp +++ b/firmware/baseband/baseband_thread.cpp @@ -47,7 +47,7 @@ BasebandThread::BasebandThread( uint32_t sampling_rate, BasebandProcessor* const baseband_processor, const tprio_t priority, - const baseband::Direction direction + baseband::Direction direction ) : baseband_processor { baseband_processor }, _direction { direction }, sampling_rate { sampling_rate } @@ -78,33 +78,17 @@ void BasebandThread::run() { baseband_sgpio.configure(direction()); baseband::dma::enable(direction()); baseband_sgpio.streaming_enable(); - - if (_direction == baseband::Direction::Transmit) { - while( !chThdShouldTerminate() ) { - // TODO: Place correct sampling rate into buffer returned here: - const baseband::buffer_t buffer_tmp = baseband::dma::wait_for_tx_buffer(); - if( buffer_tmp ) { - buffer_c8_t buffer { - buffer_tmp.p, buffer_tmp.count, sampling_rate - }; - if( baseband_processor ) { - baseband_processor->execute(buffer); - } - } - } - } else { - while( !chThdShouldTerminate() ) { - // TODO: Place correct sampling rate into buffer returned here: - const baseband::buffer_t buffer_tmp = baseband::dma::wait_for_rx_buffer(); - if( buffer_tmp ) { - buffer_c8_t buffer { - buffer_tmp.p, buffer_tmp.count, sampling_rate - }; + while( !chThdShouldTerminate() ) { + // TODO: Place correct sampling rate into buffer returned here: + const auto buffer_tmp = baseband::dma::wait_for_buffer(); + if( buffer_tmp ) { + buffer_c8_t buffer { + buffer_tmp.p, buffer_tmp.count, sampling_rate + }; - if( baseband_processor ) { - baseband_processor->execute(buffer); - } + if( baseband_processor ) { + baseband_processor->execute(buffer); } } } diff --git a/firmware/baseband/baseband_thread.hpp b/firmware/baseband/baseband_thread.hpp index cbe8f013..54fa9023 100644 --- a/firmware/baseband/baseband_thread.hpp +++ b/firmware/baseband/baseband_thread.hpp @@ -51,10 +51,10 @@ public: private: static Thread* thread; - baseband::Direction _direction; BasebandProcessor* baseband_processor { nullptr }; - uint32_t sampling_rate; + baseband::Direction _direction { baseband::Direction::Receive }; + uint32_t sampling_rate { 0 }; void run() override; }; diff --git a/firmware/baseband/proc_afsk.hpp b/firmware/baseband/proc_afsk.hpp index 1db25682..fd28e35a 100644 --- a/firmware/baseband/proc_afsk.hpp +++ b/firmware/baseband/proc_afsk.hpp @@ -37,27 +37,27 @@ private: BasebandThread baseband_thread { 1536000, this, NORMALPRIO + 20, baseband::Direction::Transmit }; - 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; + uint32_t afsk_samples_per_bit { 0 }; + uint32_t afsk_phase_inc_mark { 0 }; + uint32_t afsk_phase_inc_space { 0 }; + uint8_t afsk_repeat { 0 }; + uint32_t afsk_bw { 0 }; + uint8_t afsk_format { 0 }; - uint8_t repeat_counter = 0; - int8_t re, im; - uint8_t s = 0; - uint8_t bit_pos = 0; - uint16_t byte_pos = 0; - char cur_byte = 0; - char ext_byte = 0; - uint16_t gbyte; - uint8_t cur_bit = 0; - uint32_t sample_count; - uint32_t tone_phase, phase, sphase; - int32_t tone_sample, sig, frq; + uint8_t repeat_counter { 0 }; + int8_t re { 0 }, im { 0 }; + uint8_t s { 0 }; + uint8_t bit_pos { 0 }; + uint16_t byte_pos { 0 }; + char cur_byte { 0 }; + char ext_byte { 0 }; + uint16_t gbyte { 0 }; + uint8_t cur_bit { 0 }; + uint32_t sample_count { 0 }; + uint32_t tone_phase { 0 }, phase { 0 }, sphase { 0 }; + int32_t tone_sample { 0 }, sig { 0 }, frq { 0 }; - TXDoneMessage message; + TXDoneMessage message { }; }; #endif diff --git a/firmware/baseband/proc_tones.cpp b/firmware/baseband/proc_tones.cpp index 88b816a5..59ade4be 100644 --- a/firmware/baseband/proc_tones.cpp +++ b/firmware/baseband/proc_tones.cpp @@ -82,11 +82,11 @@ void TonesProcessor::execute(const buffer_c8_t& buffer) { tone_sample = 0; } else { if (!dual_tone) { - tone_sample = (sine_table_i8[(tone_a_phase & 0x03FC0000) >> 18]); + tone_sample = (sine_table_i8[(tone_a_phase & 0x03FC0000U) >> 18]); tone_a_phase += tone_a_delta; } else { - tone_sample = sine_table_i8[(tone_a_phase & 0x03FC0000) >> 18] >> 1; - tone_sample += sine_table_i8[(tone_b_phase & 0x03FC0000) >> 18] >> 1; + tone_sample = sine_table_i8[(tone_a_phase & 0x03FC0000U) >> 18] >> 1; + tone_sample += sine_table_i8[(tone_b_phase & 0x03FC0000U) >> 18] >> 1; tone_a_phase += tone_a_delta; tone_b_phase += tone_b_delta; @@ -97,23 +97,23 @@ void TonesProcessor::execute(const buffer_c8_t& buffer) { delta = tone_sample * fm_delta; phase += delta; - sphase = phase + (64 << 18); + sphase = phase + (64 << 24); - re = (sine_table_i8[(sphase & 0x03FC0000) >> 18]); - im = (sine_table_i8[(phase & 0x03FC0000) >> 18]); + re = (sine_table_i8[(sphase & 0xFF000000U) >> 24]); + im = (sine_table_i8[(phase & 0xFF000000U) >> 24]); } // Headphone output sample generation: 1536000/24000 = 64 if (audio_out) { if (!as) { - as = 64; // 63 ? + as = 64; audio_buffer.p[ai++] = tone_sample * 128; } else { as--; } } - buffer.p[i] = {(int8_t)re, (int8_t)im}; + buffer.p[i] = {re, im}; } if (audio_out) audio_output.write(audio_buffer); @@ -128,7 +128,7 @@ void TonesProcessor::on_message(const Message* const p) { tone_durations[c] = shared_memory.bb_data.tones_data.tone_defs[c].duration; } message_length = message.tone_count; - fm_delta = message.fm_delta; + fm_delta = message.fm_delta * 32768; audio_out = message.audio_out; dual_tone = message.dual_tone; diff --git a/firmware/baseband/proc_tones.hpp b/firmware/baseband/proc_tones.hpp index 95c62a25..d298922e 100644 --- a/firmware/baseband/proc_tones.hpp +++ b/firmware/baseband/proc_tones.hpp @@ -39,7 +39,7 @@ private: BasebandThread baseband_thread { 1536000, this, NORMALPRIO + 20, baseband::Direction::Transmit }; - std::array audio; // 2048/64 + std::array audio { }; // 2048/64 const buffer_s16_t audio_buffer { (int16_t*)audio.data(), sizeof(audio) / sizeof(int16_t) @@ -48,22 +48,22 @@ private: uint32_t tone_deltas[32]; uint32_t tone_durations[32]; - bool audio_out; - bool dual_tone; - uint32_t fm_delta; - uint32_t tone_a_phase, tone_b_phase; - uint32_t tone_a_delta, tone_b_delta; - uint8_t digit_pos; - uint8_t digit; - uint32_t silence_count, sample_count; - uint32_t message_length; - uint32_t phase, sphase; - int32_t tone_sample, delta; - int8_t re, im; - uint8_t as, ai; + bool audio_out { false }; + bool dual_tone { false }; + uint32_t fm_delta { 0 }; + uint32_t tone_a_phase { 0 }, tone_b_phase { 0 }; + uint32_t tone_a_delta { 0 }, tone_b_delta { 0 }; + uint8_t digit_pos { 0 }; + uint8_t digit { 0 }; + uint32_t silence_count { 0 }, sample_count { 0 }; + uint32_t message_length { 0 }; + uint32_t phase { 0 }, sphase { 0 }; + int32_t tone_sample { 0 }, delta { 0 }; + int8_t re { 0 }, im { 0 }; + uint8_t as { 0 }, ai { 0 }; - TXDoneMessage txdone_message; - AudioOutput audio_output; + TXDoneMessage txdone_message { }; + AudioOutput audio_output { }; }; #endif diff --git a/firmware/hackrf_cpld_portapack.svf b/firmware/hackrf_cpld_portapack.svf old mode 100755 new mode 100644 diff --git a/firmware/tools/extract_svf_data_xc2c64a.py b/firmware/tools/extract_svf_data_xc2c64a.py index 1c1b8c1b..5a2656d6 100755 --- a/firmware/tools/extract_svf_data_xc2c64a.py +++ b/firmware/tools/extract_svf_data_xc2c64a.py @@ -339,3 +339,4 @@ type_name = '::cpld::xilinx::XC2C64A::verify_blocks_t' HeaderGen(header_includes, namespaces, type_name, variable_name).to_file(args.header_file_path) DataGen(data_includes, namespaces, type_name, variable_name, verify).to_file(args.data_file_path) +