Compare commits

...

91 Commits

Author SHA1 Message Date
GullCode 8ec69d7c95 Merge pull request #727 from Brumi-2021/adding_in_RX_WFM_to_Mic_App
Add WFM mode in Mic App (in tx and rx)
2022-10-16 20:47:50 +02:00
Brumi-2021 efe8d82fae Add WFM mode in Mic App (in tx and rx) 2022-10-16 19:01:05 +02:00
GullCode 32697d1c73 Merge pull request #723 from GullCode/recon-freqman-steps-band-update
Recon freqman steps band update
2022-10-11 12:52:23 +02:00
GullCode 11558b9843 Merge pull request #722 from GullCode/scanner-freqman-update-max_files-steps
Scanner freqman update max files steps
2022-10-11 12:52:10 +02:00
GullCode e5d1308560 Added FM bands files 2022-10-11 12:49:32 +02:00
GullCode 62968e6009 Added default RECON.TXT file 2022-10-11 12:49:15 +02:00
GullCode a9b4abc07e Indenting some comments 2022-10-11 12:48:42 +02:00
GullCode 05f3793213 Added 30Khz steps and removed quoted code 2022-10-11 12:46:12 +02:00
GullCode ae8633c569 Use FREQMAN_MAX_PER_FILE instead of MAX_DB_ENTRY 2022-10-11 12:40:49 +02:00
GullCode 480f492740 Removed MAX_DB_ENTRY definition 2022-10-11 12:40:31 +02:00
GullCode dd2e23f901 Updated FREQMAN_MAX_PER_FILE value 2022-10-11 12:40:08 +02:00
GullCode 3ca57f634c Merge pull request #721 from eried/hackrf_update
Update hackrf
2022-10-11 12:10:26 +02:00
GullCode 29ac3192cb Update hackrf 2022-10-11 12:03:25 +02:00
GullCode e76faf6edd Merge pull request #717 from Brumi-2021/Recovered_ALC_AK4953_Mic_App_feature_solving_WM8731_side_effects
Adding Mic Control gain in both platforms : mic Auto volume Level Control  (AK4951) and mic Boost control (WM8731)
2022-10-09 21:50:43 +02:00
GullCode 5474487751 Merge pull request #696 from andrej-mk/ook
Increase max OOK clock
2022-10-09 18:23:33 +02:00
GullCode e6cf04e511 Update ui_encoders.hpp
Proper indentation
2022-10-09 18:22:23 +02:00
GullCode 1d521819ff Merge pull request #711 from GullCode/recon-app
Recon app
2022-10-08 13:46:50 +02:00
GullCode 83f7c9ae63 Merge pull request #707 from Brumi-2021/try_to_solve_RX_ghost_signal_issue_#637
Solve previous regression fw 1.3.1 -->fw 1.4.0 onwards , about RX ghost signal issue #637
2022-10-07 22:17:10 +02:00
igolyudov 310fbd53ec Update docker file (#719)
Pin base image ubuntu LTS version. add installation python3 with python3-yaml package. create python link in PATH for build hackrf dependency,
2022-10-04 08:56:04 +13:00
Brumi-2021 6b75249b0a Finalised all Mic Boost(WM) and Mic ALC(AK) 2022-10-02 00:51:12 +02:00
Brumi-2021 745574d3c4 Ak4951-ALC_base adding WM8731-boost OFF options 2022-09-28 22:42:33 +02:00
Jimi Sanchez c80595db7e Merge pull request #535 from jimilinuxguy/jimi-merging-conflicts
Playlist replay application
2022-09-19 17:48:11 -04:00
Jimi Sanchez 040dded2a6 Merges latest firmware into feature branch 2022-09-19 17:35:28 -04:00
Jimi Sanchez 958c9a1bfa Merge pull request #4 from jimilinuxguy/replayapp
Replayapp
2022-09-19 13:13:21 -04:00
Jimi Sanchez 76a137924c Merge pull request #3 from eried/master
Master
2022-09-19 13:12:31 -04:00
Jimi Sanchez 861db600e8 Merge branch 'replayapp' into master 2022-09-19 13:12:15 -04:00
Erwin Ried 4993a6abcb Update README.md 2022-09-16 09:28:32 +02:00
GullCode 9086f32a63 Added Recon app persistent settings 2022-09-13 23:58:03 +02:00
GullCode 9d59c07855 Added Recon app under 'Receive' menu 2022-09-13 23:58:03 +02:00
GullCode 0d18aa47f3 Added Recon files to CMake list 2022-09-13 23:58:03 +02:00
GullCode cf40f5eb14 Added ButtonWithEncoder 2022-09-13 23:58:03 +02:00
GullCode fe4bc7902f Added access to min/med/max values 2022-09-13 23:58:03 +02:00
GullCode 5d5865eefb Added tone to string and string to tone 2022-09-13 23:58:03 +02:00
GullCode a7370ee95d Added new file format funcs 2022-09-13 23:58:03 +02:00
GullCode 223cd7c20d added Recon files 2022-09-13 23:58:03 +02:00
Erwin Ried 1be3167748 Merge pull request #710 from Brumi-2021/Increase_freq_step_resolution
Very minor change , add 10 & 50Hz freq. steps , SSB  in HF and Qo-100_sat_#669
2022-09-12 09:24:25 +02:00
Brumi-2021 1bbd889005 Very minor change , add 10/50Hz freq. step #669 2022-09-06 21:01:09 +02:00
Erwin Ried d87e9853a1 Merge pull request #705 from Brumi-2021/Bias_DC_Voltage_not_working_in_TPMS_&_ERT_#700
Adding Bias dc voltage not working in tpms & ert (previous issue #700)
2022-09-05 10:14:47 +02:00
Erwin Ried 36109964a7 Merge pull request #701 from arneluehrs/ais-fix
AIS Class B decoding and display
2022-09-05 10:13:54 +02:00
Brumi-2021 6087c658e9 Applied ghost-signal c/m to all remaining TX Apps 2022-08-27 17:47:24 +02:00
Brumi-2021 08a108d3e4 First test, ghost-singal c/m to only Mic_App 2022-08-26 18:34:30 +02:00
GullCode c78659db38 RECON sdcard dir and empty config 2022-08-24 17:36:58 +02:00
Brumi-2021 5021a03572 Minor change radio,disable-->receiver.disable 2022-08-23 00:04:48 +02:00
Brumi-2021 961a4c4588 Addition_bias_DC_ERP_TPMS 2022-08-21 19:59:15 +02:00
Arne Luehrs a89d418202 AIS Decoding, destination text display fix
Remove trailing null characters '@' from display of destination field
2022-08-15 14:41:07 +08:00
Arne Luehrs 1dcc80ba59 Merge remote-tracking branch 'refs/remotes/origin/ais-fix' into ais-fix 2022-08-15 14:04:40 +08:00
Arne Luehrs 1e14ca4df1 Enable AIS-B decoding and display
Implement decoding for AIS messages 18 and 24A 24B
clean up display of text messages by removing the trailing null
character '@'
2022-08-15 13:56:40 +08:00
Arne Luehrs 5096f91986 Add AIS Class B Decoding 2022-08-15 00:12:24 +08:00
Arne Luehrs 65be02c5b1 Add AIS Class B Decoding 2022-08-14 23:48:04 +08:00
Arne Luehrs f5a604a0a5 Merge pull request #3 from eried/next
Sync with upstream
2022-08-12 15:17:29 +08:00
andrej 87418703e0 Make clk and frame duration steps in OOK configurable 2022-08-01 08:40:26 +02:00
andrej e33c98cbc7 Increase maximum OOK clock to 1000 kHz 2022-08-01 08:40:16 +02:00
Brumi-2021 823c69eb42 Merge branch 'eried:next' into next 2022-06-14 21:55:36 +02:00
Brumi-2021 a26ee84ff8 Merge branch 'eried:next' into next 2022-06-06 15:33:20 +02:00
Brumi-2021 379ad6dbf0 Recovered_ALC_Mic_Feature_AK4953_OK_WM8731 2022-05-28 22:29:10 +02:00
Brumi-2021 840da4c685 Merge branch 'eried:next' into next 2022-05-22 16:41:48 +02:00
jLynx c389ce7c0e Merge pull request #653 from eried/next
v1.5.3
2022-05-21 12:06:39 +12:00
Brumi-2021 dda543f7f3 Merge branch 'eried:next' into next 2022-05-08 12:39:27 +02:00
Brumi-2021 92844a7528 Merge branch 'eried:next' into next 2022-05-06 21:55:27 +02:00
Brumi-2021 ef52339b1d Merge branch 'eried:next' into next 2022-05-02 20:05:42 +02:00
Brumi-2021 5e0780839c Merge branch 'eried:next' into next 2022-04-30 16:22:45 +02:00
Jimi Sanchez 85602d145a Update create_nightly_release.yml 2022-04-28 17:15:03 -04:00
Jimi Sanchez 2efab19bf6 Merge branch 'next' of https://github.com/jimilinuxguy/portapack-mayhem into next 2022-04-28 17:06:50 -04:00
Jimi Sanchez 4562228b55 Fixing spelling of Wav Viewer 2022-04-28 17:06:45 -04:00
Jimi Sanchez b56acb0c9d Merge pull request #2 from jimilinuxguy/jimi-merging-conflicts
Jimi merging conflicts
2022-04-28 17:03:37 -04:00
Jimi Sanchez 6af0d4e751 Merge branch 'next' into jimi-merging-conflicts 2022-04-28 17:03:24 -04:00
Jimi Sanchez 0fed174a80 Adding back wipe sd 2022-04-28 16:58:44 -04:00
Jimi Sanchez d71c759480 Merge branch 'next' into jimi-merging-conflicts 2022-04-28 13:55:44 -04:00
Jimi Sanchez c1e568f62c Removing wipe sd 2022-04-28 13:54:17 -04:00
Jimi Sanchez db1b7ffddf Merge branch 'next' of https://github.com/jimilinuxguy/portapack-mayhem into next 2022-04-28 13:52:55 -04:00
Jimi Sanchez f48980e381 Adding playlist to CMakeLists 2022-04-28 13:52:47 -04:00
Jimi Sanchez cdaa6683ae Adding playlist to CMakeLists 2022-04-28 13:49:36 -04:00
Arne Luehrs d2dbad73c7 Merge branch 'eried:next' into next 2022-04-27 10:16:26 +02:00
jLynx 9412dd8bec Merge pull request #546 from eried/next
V1.5.0
2022-04-07 20:42:05 +12:00
Jimi Sanchez d624b92e85 Adding helper header for playlist file 2022-04-03 19:42:48 -04:00
Jimi Sanchez 584c46af64 Initial commit of playlist app for replaying capture files sequentially 2022-04-03 19:38:06 -04:00
Brumi-2021 1976c3648b Merge branch 'eried:next' into next 2022-04-02 13:23:43 +02:00
Jimi Sanchez c4eb02422b Merge pull request #1 from eried/next
Merging changes
2022-04-02 05:10:41 -04:00
Brumi-2021 95ac4a2d1e Merge branch 'eried:next' into next 2022-03-28 18:13:24 +02:00
Brumi-2021 a7c7495428 Merge branch 'eried:next' into next 2022-03-26 21:56:38 +01:00
Arne Luehrs 8f311ea1f2 Merge pull request #1 from eried/next
Sync with upstream
2022-02-25 15:00:45 +01:00
Brumi-2021 d0643421a8 Merge branch 'eried:next' into next 2022-02-04 20:13:04 +01:00
Brumi-2021 adb0cdf8fb Merge branch 'eried:next' into next 2022-02-01 23:20:00 +01:00
Brumi-2021 1b93a042a3 Merge branch 'next' of https://github.com/Brumi-2021/portapack-mayhem into next 2022-01-29 12:19:06 +01:00
Brumi-2021 52c6d0e4ed Merge branch 'next' of https://github.com/Brumi-2021/portapack-mayhem into next 2021-11-24 21:10:08 +01:00
Brumi-2021 22a5ca7df7 Merge branch 'next' of https://github.com/Brumi-2021/portapack-mayhem into next 2021-10-25 20:47:33 +02:00
Brumi-2021 d0b356a7ef Revert "Solving Compile error on gcc10 . Keeping same safety protection about the size of the array ,but with slightly different sintax."
This reverts commit f4db4e2b53.
2021-10-24 01:59:25 +02:00
Brumi-2021 28ee69baae Revert "Update spectrum_collector.cpp"
This reverts commit 35cece1cb0.
2021-10-24 01:58:58 +02:00
Brumi-2021 bfd614b51f Revert "Update spectrum_collector.cpp"
This reverts commit 4a6fc35384.
2021-10-24 01:58:06 +02:00
Brumi-2021 4a6fc35384 Update spectrum_collector.cpp
Description changed , better explanation.
2021-10-24 01:47:42 +02:00
Brumi-2021 35cece1cb0 Update spectrum_collector.cpp
lower case correction
2021-10-24 01:40:08 +02:00
67 changed files with 4762 additions and 411 deletions
+1 -1
View File
@@ -1,6 +1,6 @@
# PortaPack Mayhem
[![Build Status](https://travis-ci.com/eried/portapack-mayhem.svg?branch=master)](https://travis-ci.com/eried/portapack-mayhem) [![CodeScene Code Health](https://codescene.io/projects/8381/status-badges/code-health)](https://codescene.io/projects/8381) [![GitHub All Releases](https://img.shields.io/github/downloads/eried/portapack-mayhem/total)](https://github.com/eried/portapack-mayhem/releases) [![GitHub Releases](https://img.shields.io/github/downloads/eried/portapack-mayhem/latest/total)](https://github.com/eried/portapack-mayhem/releases/latest) [![Docker Hub Pulls](https://img.shields.io/docker/pulls/eried/portapack.svg)](https://hub.docker.com/r/eried/portapack) [![Discord Chat](https://img.shields.io/discord/719669764804444213.svg)](https://discord.gg/tuwVMv3) [![Check bounties!](https://img.shields.io/bountysource/team/portapack-mayhem/activity?color=%2333ccff&label=bountysource%20%28USD%29&style=plastic)](https://www.bountysource.com/teams/portapack-mayhem/issues)
[![Build Status](https://travis-ci.com/eried/portapack-mayhem.svg?branch=master)](https://travis-ci.com/eried/portapack-mayhem) [![Nightly Release](https://github.com/eried/portapack-mayhem/actions/workflows/create_nightly_release.yml/badge.svg?branch=next)](https://github.com/eried/portapack-mayhem/actions/workflows/create_nightly_release.yml) [![CodeScene Code Health](https://codescene.io/projects/8381/status-badges/code-health)](https://codescene.io/projects/8381) [![GitHub All Releases](https://img.shields.io/github/downloads/eried/portapack-mayhem/total)](https://github.com/eried/portapack-mayhem/releases) [![GitHub Releases](https://img.shields.io/github/downloads/eried/portapack-mayhem/latest/total)](https://github.com/eried/portapack-mayhem/releases/latest) [![Docker Hub Pulls](https://img.shields.io/docker/pulls/eried/portapack.svg)](https://hub.docker.com/r/eried/portapack) [![Discord Chat](https://img.shields.io/discord/719669764804444213.svg)](https://discord.gg/tuwVMv3) [![Check bounties!](https://img.shields.io/bountysource/team/portapack-mayhem/activity?color=%2333ccff&label=bountysource%20%28USD%29&style=plastic)](https://www.bountysource.com/teams/portapack-mayhem/issues)
This is a fork of the [Havoc](https://github.com/furrtek/portapack-havoc/) firmware, which itself was a fork of the [PortaPack](https://github.com/sharebrained/portapack-hackrf) firmware, an add-on for the [HackRF](http://greatscottgadgets.com/hackrf/). A fork is a derivate, in this case one that has extra features and fixes when compared to the older versions.
+12 -9
View File
@@ -1,6 +1,6 @@
#Download base image.
#The ubuntu:latest tag points to the "latest LTS"
FROM ubuntu:latest
#The ubuntu:20.04 tag points to the "20.04 LTS"
FROM ubuntu:20.04
#Set location to download ARM toolkit from.
# This will need to be changed over time or replaced with a static link to the latest release.
@@ -14,16 +14,18 @@ COPY ./ /havocsrc
#Fetch dependencies from APT
RUN apt-get update && \
apt-get install -y tar wget dfu-util cmake python bzip2 curl && \
apt-get -qy autoremove
apt-get install -y tar wget dfu-util cmake python bzip2 curl python3 python3-yaml && \
apt-get -qy autoremove
#Install current pip from PyPa
RUN curl https://bootstrap.pypa.io/pip/3.4/get-pip.py -o get-pip.py && \
python get-pip.py
python get-pip.py
#Fetch additional dependencies from Python 2.x pip
RUN pip install pyyaml
RUN ln -s /usr/bin/python3 /usr/bin/python && \
RUN rm -rf /usr/bin/python && \
rm -rf /usr/bin/pip && \
ln -s /usr/bin/python3 /usr/bin/python && \
ln -s /usr/bin/pip3 /usr/bin/pip
ENV LANG C.UTF-8
@@ -32,9 +34,9 @@ ENV LC_ALL C.UTF-8
#Grab the GNU ARM toolchain from arm.com
#Then extract contents to /opt/build/armbin/
RUN mkdir /opt/build && cd /opt/build && \
wget -O gcc-arm-none-eabi $ARMBINURL && \
mkdir armbin && \
tar --strip=1 -xjvf gcc-arm-none-eabi -C armbin
wget -O gcc-arm-none-eabi $ARMBINURL && \
mkdir armbin && \
tar --strip=1 -xjvf gcc-arm-none-eabi -C armbin
#Set environment variable so compiler knows where the toolchain lives
ENV PATH=$PATH:/opt/build/armbin/bin
@@ -43,3 +45,4 @@ CMD cd /havocsrc && \
mkdir build && cd build && \
cmake .. && make firmware && \
cp /portapack-havoc/firmware/portapack-h1-havoc.bin /havocbin
+4
View File
@@ -267,8 +267,12 @@ set(CPPSRC
apps/lge_app.cpp
apps/pocsag_app.cpp
apps/replay_app.cpp
apps/ui_playlist.cpp
apps/gps_sim_app.cpp
apps/soundboard_app.cpp
apps/ui_recon.cpp
apps/ui_recon_settings.cpp
apps/tpms_app.cpp
apps/tpms_app.cpp
protocols/aprs.cpp
protocols/ax25.cpp
+43 -11
View File
@@ -76,12 +76,18 @@ static std::string mid(
mid_code = to_string_dec_uint(mmsi, 9, ' ').substr(0, 3);
return_code = db.retrieve_mid_record(&mid_record, mid_code);
switch(return_code) {
case DATABASE_RECORD_FOUND: return mid_record.country;
case DATABASE_RECORD_FOUND: return mid_record.country;
case DATABASE_NOT_FOUND: return "No mids.db file";
default: return "";
}
}
static std::string text(const std::string &text) {
size_t end = text.find_last_not_of("@");
return (end == std::string::npos) ? "" : text.substr(0, end + 1);
}
static std::string navigational_status(const unsigned int value) {
switch(value) {
case 0: return "under way w/engine";
@@ -164,7 +170,7 @@ void AISLogger::on_packet(const ais::Packet& packet) {
}
log_file.write_entry(packet.received_at(), entry);
}
}
void AISRecentEntry::update(const ais::Packet& packet) {
received_count++;
@@ -195,6 +201,15 @@ void AISRecentEntry::update(const ais::Packet& packet) {
destination = packet.text(302, 20);
break;
case 18:
last_position.timestamp = packet.received_at();
last_position.speed_over_ground = packet.read(46, 10);
last_position.latitude = packet.latitude(85);
last_position.longitude = packet.longitude(57);
last_position.course_over_ground = packet.read(112, 12);
last_position.true_heading = packet.read(124, 9);
break;
case 21:
name = packet.text(43, 20);
last_position.timestamp = packet.received_at();
@@ -202,6 +217,23 @@ void AISRecentEntry::update(const ais::Packet& packet) {
last_position.longitude = packet.longitude(164);
break;
case 24:
switch (packet.read(38, 2))
{
case 0:
name = packet.text(40, 20);
break;
case 1:
call_sign = packet.text(90, 7);
break;
default:
break;
}
break;
default:
break;
}
@@ -218,9 +250,9 @@ void RecentEntriesTable<AISRecentEntries>::draw(
) {
std::string line = ais::format::mmsi(entry.mmsi) + " ";
if( !entry.name.empty() ) {
line += entry.name;
line += ais::format::text(entry.name);
} else {
line += entry.call_sign;
line += ais::format::text(entry.call_sign);
}
line.resize(target_rect.width() / 8, ' ');
@@ -241,7 +273,7 @@ AISRecentEntryDetailView::AISRecentEntryDetailView(NavigationView& nav) {
button_see_map.on_select = [this, &nav](Button&) {
geomap_view = nav.push<GeoMapView>(
entry_.name,
ais::format::text(entry_.name),
0,
GeoPos::alt_unit::METERS,
ais::format::latlon_float(entry_.last_position.latitude.normalized()),
@@ -252,7 +284,7 @@ AISRecentEntryDetailView::AISRecentEntryDetailView(NavigationView& nav) {
});
send_updates = true;
};
}
@@ -262,7 +294,7 @@ AISRecentEntryDetailView::AISRecentEntryDetailView(const AISRecentEntryDetailVie
(void)Entry;
}
AISRecentEntryDetailView & AISRecentEntryDetailView::operator=(const AISRecentEntryDetailView&Entry)
AISRecentEntryDetailView & AISRecentEntryDetailView::operator=(const AISRecentEntryDetailView&Entry)
{
(void)Entry;
return *this;
@@ -302,9 +334,9 @@ void AISRecentEntryDetailView::paint(Painter& painter) {
field_rect = draw_field(painter, field_rect, s, "MMSI", ais::format::mmsi(entry_.mmsi));
field_rect = draw_field(painter, field_rect, s, "Ctry", ais::format::mid(entry_.mmsi));
field_rect = draw_field(painter, field_rect, s, "Name", entry_.name);
field_rect = draw_field(painter, field_rect, s, "Call", entry_.call_sign);
field_rect = draw_field(painter, field_rect, s, "Dest", entry_.destination);
field_rect = draw_field(painter, field_rect, s, "Name", ais::format::text(entry_.name));
field_rect = draw_field(painter, field_rect, s, "Call", ais::format::text(entry_.call_sign));
field_rect = draw_field(painter, field_rect, s, "Dest", ais::format::text(entry_.destination));
field_rect = draw_field(painter, field_rect, s, "Last", to_string_datetime(entry_.last_position.timestamp));
field_rect = draw_field(painter, field_rect, s, "Pos ", ais::format::latlon(entry_.last_position.latitude, entry_.last_position.longitude));
field_rect = draw_field(painter, field_rect, s, "Stat", ais::format::navigational_status(entry_.navigational_status));
@@ -352,7 +384,7 @@ AISAppView::AISAppView(NavigationView& nav) : nav_ { nav } {
receiver_model.set_sampling_rate(sampling_rate);
receiver_model.set_baseband_bandwidth(baseband_bandwidth);
receiver_model.enable(); // Before using radio::enable(), but not updating Ant.DC-Bias.
options_channel.on_change = [this](size_t, OptionsField::value_t v) {
this->on_frequency_changed(v);
};
+7 -3
View File
@@ -113,8 +113,12 @@ ERTAppView::ERTAppView(NavigationView&) {
field_rf_amp.set_value(app_settings.rx_amp);
}
receiver_model.set_tuning_frequency(initial_target_frequency);
receiver_model.set_sampling_rate(sampling_rate);
receiver_model.set_baseband_bandwidth(baseband_bandwidth);
receiver_model.enable(); // Before using radio::enable(), but not updating Ant.DC-Bias.
radio::enable({
/* radio::enable({
initial_target_frequency,
sampling_rate,
baseband_bandwidth,
@@ -122,7 +126,7 @@ ERTAppView::ERTAppView(NavigationView&) {
receiver_model.rf_amp(),
static_cast<int8_t>(receiver_model.lna()),
static_cast<int8_t>(receiver_model.vga()),
});
}); */
logger = std::make_unique<ERTLogger>();
if( logger ) {
@@ -135,7 +139,7 @@ ERTAppView::~ERTAppView() {
// save app settings
settings.save("rx_ert", &app_settings);
radio::disable();
receiver_model.disable(); // to switch off all, including DC bias and change flag enabled_
baseband::shutdown();
}
+3 -1
View File
@@ -29,6 +29,7 @@
#include "baseband_api.hpp"
#include "portapack.hpp"
#include "cpld_update.hpp"
#include "portapack_persistent_memory.hpp"
using namespace portapack;
@@ -242,7 +243,8 @@ GpsSimAppView::GpsSimAppView(
GpsSimAppView::~GpsSimAppView() {
radio::disable();
baseband::shutdown();
hackrf::cpld::load_sram_no_verify(); // to leave all RX ok, without ghost signal problem at the exit .
baseband::shutdown(); // better this function at the end, not load_sram() that sometimes produces hang up.
}
void GpsSimAppView::on_hide() {
+3 -1
View File
@@ -27,6 +27,7 @@
#include "lge_app.hpp"
#include "baseband_api.hpp"
#include "cpld_update.hpp"
#include "ui_textentry.hpp"
#include "string_format.hpp"
@@ -48,7 +49,8 @@ LGEView::~LGEView() {
settings.save("tx_lge", &app_settings);
transmitter_model.disable();
baseband::shutdown();
hackrf::cpld::load_sram_no_verify(); // to leave all RX ok, without ghost signal problem at the exit .
baseband::shutdown();// better this function at the end, not load_sram() that sometimes produces hang up.
}
void LGEView::generate_lge_frame(const uint8_t command, const uint16_t address_a, const uint16_t address_b, std::vector<uint8_t>& data) {
+4 -1
View File
@@ -25,6 +25,7 @@
#include "soundboard_app.hpp"
#include "string_format.hpp"
#include "tonesets.hpp"
#include "cpld_update.hpp"
using namespace tonekey;
using namespace portapack;
@@ -110,6 +111,7 @@ void SoundBoardView::start_tx(const uint32_t id) {
1536000 / 20, // Update vu-meter at 20Hz
transmitter_model.channel_bandwidth(),
0, // Gain is unused
8, // shift_bits_s16, default 8 bits, but also unused
TONES_F2D(tone_key_frequency(tone_key_index), 1536000),
0, //AM
0, //DSB
@@ -295,7 +297,8 @@ SoundBoardView::~SoundBoardView() {
stop();
transmitter_model.disable();
baseband::shutdown();
hackrf::cpld::load_sram_no_verify(); // to leave all RX ok, without ghost signal problem at the exit.
baseband::shutdown(); // better this function at the end, not load_sram() that sometimes produces hang up.
}
}
+8 -3
View File
@@ -161,7 +161,12 @@ TPMSAppView::TPMSAppView(NavigationView&) {
}
else options_band.set_by_value(receiver_model.tuning_frequency());
radio::enable({
receiver_model.set_tuning_frequency(tuning_frequency());
receiver_model.set_sampling_rate(sampling_rate);
receiver_model.set_baseband_bandwidth(baseband_bandwidth);
receiver_model.enable(); // Before using radio::enable(), but not updating Ant.DC-Bias.
/* radio::enable({
tuning_frequency(),
sampling_rate,
baseband_bandwidth,
@@ -169,7 +174,7 @@ TPMSAppView::TPMSAppView(NavigationView&) {
receiver_model.rf_amp(),
static_cast<int8_t>(receiver_model.lna()),
static_cast<int8_t>(receiver_model.vga()),
});
}); */
options_band.on_change = [this](size_t, OptionsField::value_t v) {
this->on_band_changed(v);
@@ -200,7 +205,7 @@ TPMSAppView::~TPMSAppView() {
app_settings.rx_frequency = target_frequency_;
settings.save("rx_tpms", &app_settings);
radio::disable();
receiver_model.disable(); // to switch off all, including DC bias and change flag enabled_
baseband::shutdown();
}
+4 -2
View File
@@ -26,6 +26,7 @@
#include "manchester.hpp"
#include "string_format.hpp"
#include "portapack.hpp"
#include "cpld_update.hpp"
#include "baseband_api.hpp"
#include <cstring>
@@ -290,8 +291,9 @@ ADSBTxView::~ADSBTxView() {
settings.save("tx_adsb", &app_settings);
transmitter_model.disable();
baseband::shutdown();
}
hackrf::cpld::load_sram_no_verify(); // to leave all RX ok, withouth ghost signal problem at the exit .
baseband::shutdown(); // better this function at the end, not load_sram() that sometimes produces hang up.
}
void ADSBTxView::generate_frames() {
const uint32_t ICAO_address = sym_icao.value_hex_u64();
+3 -1
View File
@@ -26,6 +26,7 @@
#include "aprs.hpp"
#include "string_format.hpp"
#include "portapack.hpp"
#include "cpld_update.hpp"
#include "baseband_api.hpp"
#include "portapack_shared_memory.hpp"
#include "portapack_persistent_memory.hpp"
@@ -48,7 +49,8 @@ APRSTXView::~APRSTXView() {
settings.save("tx_aprs", &app_settings);
transmitter_model.disable();
baseband::shutdown();
hackrf::cpld::load_sram_no_verify(); // to leave all RX ok, without ghost signal problem at the exit.
baseband::shutdown(); // better this function at the end, not load_sram() that sometimes produces hang up.
}
void APRSTXView::start_tx() {
+3
View File
@@ -24,6 +24,7 @@
#include "string_format.hpp"
#include "baseband_api.hpp"
#include "cpld_update.hpp"
#include "portapack_persistent_memory.hpp"
using namespace portapack;
@@ -145,6 +146,8 @@ BHTView::~BHTView() {
settings.save("tx_bht", &app_settings);
transmitter_model.disable();
hackrf::cpld::load_sram_no_verify(); // to leave all RX ok, without ghost signal problem at the exit .
baseband::shutdown(); // better this function at the end, not load_sram() that sometimes produces hang up.
}
BHTView::BHTView(NavigationView& nav) {
+3 -1
View File
@@ -23,6 +23,7 @@
#include "ui_coasterp.hpp"
#include "baseband_api.hpp"
#include "cpld_update.hpp"
#include "portapack_persistent_memory.hpp"
#include <cstring>
@@ -42,7 +43,8 @@ CoasterPagerView::~CoasterPagerView() {
settings.save("tx_coaster", &app_settings);
transmitter_model.disable();
baseband::shutdown();
hackrf::cpld::load_sram_no_verify(); // to leave all RX ok, without ghost signal problem at the exit .
baseband::shutdown(); // better this function at the end, not load_sram() that sometimes produces hang up.
}
void CoasterPagerView::generate_frame() {
+13 -1
View File
@@ -24,6 +24,7 @@
#include "baseband_api.hpp"
#include "string_format.hpp"
#include "cpld_update.hpp"
using namespace portapack;
@@ -46,7 +47,9 @@ EncodersConfigView::EncodersConfigView(
&labels,
&options_enctype,
&field_clk,
&field_clk_step,
&field_frameduration,
&field_frameduration_step,
&symfield_word,
&text_format,
&waveform
@@ -74,6 +77,10 @@ EncodersConfigView::EncodersConfigView(
if (new_value != field_frameduration.value())
field_frameduration.set_value(new_value * encoder_def->word_length, false);
};
field_clk_step.on_change = [this](size_t, int32_t value) {
field_clk.set_step(value);
};
// Selecting word duration changes input clock and symbol duration
field_frameduration.on_change = [this](int32_t value) {
@@ -82,6 +89,10 @@ EncodersConfigView::EncodersConfigView(
if (new_value != field_clk.value())
field_clk.set_value(1000000 / new_value, false);
};
field_frameduration_step.on_change = [this](size_t, int32_t value) {
field_frameduration.set_step(value);
};
}
void EncodersConfigView::focus() {
@@ -208,7 +219,8 @@ EncodersView::~EncodersView() {
settings.save("tx_ook", &app_settings);
transmitter_model.disable();
baseband::shutdown();
hackrf::cpld::load_sram_no_verify(); // ghost signal c/m to the problem at the exit .
baseband::shutdown(); // better this function after load_sram()
}
void EncodersView::update_progress() {
+36 -13
View File
@@ -66,12 +66,14 @@ private:
Labels labels {
{ { 1 * 8, 0 }, "Type:", Color::light_grey() },
{ { 16 * 8, 0 }, "Clk:", Color::light_grey() },
{ { 24 * 8, 0 }, "kHz", Color::light_grey() },
{ { 14 * 8, 2 * 8 }, "Frame:", Color::light_grey() },
{ { 26 * 8, 2 * 8 }, "us", Color::light_grey() },
{ { 2 * 8, 4 * 8 }, "Symbols:", Color::light_grey() },
{ { 1 * 8, 11 * 8 }, "Waveform:", Color::light_grey() }
{ { 1 * 8, 2 * 8 }, "Clk:", Color::light_grey() },
{ { 10 * 8, 2 * 8 }, "kHz", Color::light_grey() },
{ { 17 * 8, 2 * 8 }, "Step:", Color::light_grey() },
{ { 1 * 8, 4 * 8 }, "Frame:", Color::light_grey() },
{ { 13 * 8, 4 * 8 }, "us", Color::light_grey() },
{ { 17 * 8, 4 * 8 }, "Step", Color::light_grey() },
{ { 2 * 8, 7 * 8 }, "Symbols:", Color::light_grey() },
{ { 1 * 8, 14 * 8 }, "Waveform:", Color::light_grey() }
};
OptionsField options_enctype { // Options are loaded at runtime
@@ -82,34 +84,55 @@ private:
};
NumberField field_clk {
{ 21 * 8, 0 },
3,
{ 1, 500 },
{ 5 * 8, 2 * 8 },
4,
{ 1, 1000 },
1,
' '
};
OptionsField field_clk_step {
{ 22 * 8, 2 * 8 },
7,
{
{ "1", 1 },
{ "10", 10 },
{ "100", 100 }
}
};
NumberField field_frameduration {
{ 21 * 8, 2 * 8 },
{ 7 * 8, 4 * 8 },
5,
{ 300, 99999 },
100,
' '
};
OptionsField field_frameduration_step {
{ 22 * 8, 4 * 8 },
7,
{
{ "1", 1 },
{ "10", 10 },
{ "100", 100 },
{ "1000", 1000 }
}
};
SymField symfield_word {
{ 2 * 8, 6 * 8 },
{ 2 * 8, 9 * 8 },
20,
SymField::SYMFIELD_DEF
};
Text text_format {
{ 2 * 8, 8 * 8, 24 * 8, 16 },
{ 2 * 8, 11 * 8, 24 * 8, 16 },
""
};
Waveform waveform {
{ 0, 14 * 8, 240, 32 },
{ 0, 17 * 8, 240, 32 },
waveform_buffer,
0,
0,
+3 -1
View File
@@ -25,6 +25,7 @@
#include "ui_freqman.hpp"
#include "baseband_api.hpp"
#include "cpld_update.hpp"
#include "string_format.hpp"
using namespace portapack;
@@ -183,7 +184,8 @@ void JammerView::focus() {
JammerView::~JammerView() {
transmitter_model.disable();
baseband::shutdown();
hackrf::cpld::load_sram_no_verify(); // to leave all RX ok, without ghost signal problem at the exit .
baseband::shutdown(); // better this function at the end, not load_sram() that sometimes produces hang up.
}
void JammerView::on_retune(const rf::Frequency freq, const uint32_t range) {
+3 -1
View File
@@ -23,6 +23,7 @@
#include "ui_keyfob.hpp"
#include "baseband_api.hpp"
#include "cpld_update.hpp"
#include "string_format.hpp"
using namespace portapack;
@@ -140,7 +141,8 @@ KeyfobView::~KeyfobView() {
settings.save("tx_keyfob", &app_settings);
transmitter_model.disable();
baseband::shutdown();
hackrf::cpld::load_sram_no_verify(); // to leave all RX ok, without ghost signal problem at the exit .
baseband::shutdown(); // better this function at the end, not load_sram() that sometimes produces hang up.
}
void KeyfobView::update_progress(const uint32_t progress) {
+3 -1
View File
@@ -27,6 +27,7 @@
#include "modems.hpp"
#include "baseband_api.hpp"
#include "string_format.hpp"
#include "cpld_update.hpp"
#include "serializer.hpp"
@@ -44,7 +45,8 @@ LCRView::~LCRView() {
settings.save("tx_lcr", &app_settings);
transmitter_model.disable();
baseband::shutdown();
hackrf::cpld::load_sram_no_verify(); // to leave all RX ok, without ghost signal problem at the exit.
baseband::shutdown(); // better this function at the end, not load_sram() that sometimes produces hang up.
}
/*
+119 -40
View File
@@ -30,6 +30,7 @@ using wolfson::wm8731::WM8731;
#include "tonesets.hpp"
#include "portapack_hal.hpp"
#include "cpld_update.hpp"
#include "string_format.hpp"
#include "irq_controls.hpp"
@@ -73,6 +74,7 @@ void MicTXView::configure_baseband() {
sampling_rate / 20, // Update vu-meter at 20Hz
transmitting ? transmitter_model.channel_bandwidth() : 0,
mic_gain,
shift_bits_s16, // to be used in dsp_modulate
TONES_F2D(tone_key_frequency(tone_key_index), sampling_rate),
enable_am,
enable_dsb,
@@ -160,16 +162,23 @@ void MicTXView::rxaudio(bool is_on) {
if (enable_am || enable_usb || enable_lsb || enable_dsb) {
baseband::run_image(portapack::spi_flash::image_tag_am_audio);
receiver_model.set_modulation(ReceiverModel::Mode::AMAudio);
if (options_mode.selected_index() < 4)
receiver_model.set_am_configuration(options_mode.selected_index() - 1);
else
receiver_model.set_am_configuration(0);
if (options_mode.selected_index() < 5) // We will called here, 2,3,4,5 , and we are excluding DSB case (5) , "NFM/FM",0 ," WFM ",1 , " AM ",2, " USB ", 3, " LSB ",4, " DSB ", 5
receiver_model.set_am_configuration(options_mode.selected_index() - 2); // selecting proper filter. 2-2=0=>6k(0) , 3-2=1=>usb(1), 4-2=2lsb(2),
else
receiver_model.set_am_configuration(0); // DSB case (5) , same BW as AM config(5)
}
else {
baseband::run_image(portapack::spi_flash::image_tag_nfm_audio);
receiver_model.set_modulation(ReceiverModel::Mode::NarrowbandFMAudio);
else { // We are in NFM/FM or WFM (NFM BW:8k5 or 11k / FM BW 16k / WFM BW:200k)
}
if (enable_wfm) { // WFM , BW 200Khz aprox ,
baseband::run_image(portapack::spi_flash::image_tag_wfm_audio);
receiver_model.set_modulation(ReceiverModel::Mode::WidebandFMAudio);
receiver_model.set_wfm_configuration(0); // there are only 1 x config filters 200k WFM . (not like 8k5/11k/16k)
} else { // NFM BW:8k5 or 11k / FM BW 16k
baseband::run_image(portapack::spi_flash::image_tag_nfm_audio);
receiver_model.set_modulation(ReceiverModel::Mode::NarrowbandFMAudio); //
// receiver_model.set_nbfm_configuration(n); is called above , depending 8k5, 11k, 16k
}
}
receiver_model.set_sampling_rate(3072000);
receiver_model.set_baseband_bandwidth(1750000);
// receiver_model.set_tuning_frequency(field_frequency.value()); //probably this too can be commented out.
@@ -178,6 +187,7 @@ void MicTXView::rxaudio(bool is_on) {
receiver_model.set_vga(rx_vga);
receiver_model.set_rf_amp(rx_amp);
receiver_model.enable();
hackrf::cpld::load_sram_no_verify(); // to have a good RX without any ghost inside Mic App
audio::output::start();
} else { //These incredibly convoluted steps are required for the vumeter to reappear when stopping RX.
receiver_model.set_modulation(ReceiverModel::Mode::NarrowbandFMAudio); //This fixes something with AM RX...
@@ -186,7 +196,7 @@ void MicTXView::rxaudio(bool is_on) {
baseband::run_image(portapack::spi_flash::image_tag_mic_tx);
audio::output::stop();
audio::input::start(); // set up audio input = mic config of any audio coded AK4951/WM8731, (in WM8731 parameter will be ignored)
audio::input::start(ak4951_alc_and_wm8731_boost_GUI); // When detected AK4951 => set up ALC mode; when detected WM8731 => set up mic_boost ON/OFF.
portapack::pin_i2s0_rx_sda.mode(3);
configure_baseband();
}
@@ -211,12 +221,12 @@ MicTXView::MicTXView(
baseband::run_image(portapack::spi_flash::image_tag_mic_tx);
if (true ) { // Temporary , disabling ALC feature , (pending to solve -No Audio in Mic app ,in some H2/H2+ WM /QFP100 CPLS users- if ( audio_codec_wm8731.detected() ) {
if (audio::debug::codec_name() =="WM8731" ) {
add_children({
&labels_WM8731, // we have audio codec WM8731, same MIC menu as original.
&vumeter,
&options_gain, // MIC GAIN float factor on the GUI.
&options_wm8731_boost_mode,
// &check_va,
&field_va,
&field_va_level,
@@ -281,13 +291,43 @@ MicTXView::MicTXView(
mic_gain = v / 10.0;
configure_baseband();
};
options_gain.set_selected_index(1); // x1.0
options_gain.set_selected_index(1); // x1.0 preselected default.
if (audio::debug::codec_name() =="WM8731") {
options_wm8731_boost_mode.on_change = [this](size_t, int8_t v) {
switch(v) {
case 0: // +12 dBs respect reference level orig fw 1.5.x fw FM : when +20dB's boost ON) and shift bits (>>8),
shift_bits_s16 = 6; // now mic-boost on (+20dBs) and shift bits (>>6), +20+12=32 dBs (orig fw +20 dBs+ 0dBs)=> +12dB's respect ref.
break;
case 1: // +06 dBs reference level , (when +20dB's boost ON)
shift_bits_s16 = 7; // now mic-boost on (+20dBs) and shift bits (>>7), +20+06=26 dBs (orig fw +20 dBs+ 0dBs) => +06dB's respect ref.
break;
case 2:
shift_bits_s16 = 4; // +04 dBs respect ref level , (when +20dB's boost OFF)
break; // now mic-boost off (+00dBs) shift bits (4) (+0+24dB's)=24 dBs => +04dB's respect ref.
case 3:
shift_bits_s16 = 5; // -02 dBs respect ref level , (when +20dB's boost OFF)
break; // now mic-boost off (+00dBs) shift bits (5) (+0+18dB's)=18 dBs => -02dB's respect ref.
case 4:
shift_bits_s16 = 6; // -08 dBs respect ref level , (when +20dB's boost OFF)
break; // now mic-boost off (+00dBs) shift bits (6) (+0+12dB's)=12 dBs => -08dB's respect ref.
}
ak4951_alc_and_wm8731_boost_GUI = v; // 0,..4 WM8731_boost dB's options, (combination boost on/off , and effective gain in captured data >>x)
audio::input::start(ak4951_alc_and_wm8731_boost_GUI); // Detected (WM8731) , set up the proper wm_boost on/off , 0..4 (0,1) boost_on , (2,3,4) boost_0ff
configure_baseband(); // to update in real timme,sending msg , var-parameters >>shift_bits FM msg ,to audio_tx from M0 to M4 Proc -
};
options_wm8731_boost_mode.set_selected_index(3); // preset GUI index 3 as default WM -> -02 dB's .
} else {
shift_bits_s16 = 8; // Initialized default fixed >>8_FM for FM tx mod , shift audio data for AK4951 ,using top 8 bits s16 data (>>8)
options_ak4951_alc_mode.on_change = [this](size_t, int8_t v) {
ak4951_alc_and_wm8731_boost_GUI = v; // 0,..11, AK4951 Mic -Automatic volume Level Control options,
audio::input::start(ak4951_alc_and_wm8731_boost_GUI); // Detected (AK4951) ==> Set up proper ALC mode from 0..11 options
configure_baseband(); // sending fixed >>8_FM , var-parameters msg , to audiotx from this M0 to M4 process.
};
}
options_ak4951_alc_mode.on_change = [this](size_t, int8_t v) {
ak4951_alc_GUI_selected = v;
audio::input::start();
};
// options_ak4951_alc_mode.set_selected_index(0);
// options_ak4951_alc_mode.set_selected_index(0);
tx_frequency = transmitter_model.tuning_frequency();
field_frequency.set_value(transmitter_model.tuning_frequency());
@@ -313,7 +353,8 @@ MicTXView::MicTXView(
field_bw.on_change = [this](uint32_t v) {
transmitter_model.set_channel_bandwidth(v * 1000);
};
field_bw.set_value(10);
field_bw.set_value(10); // pre-default first time, TX deviation FM for NFM / FM
tx_gain = transmitter_model.tx_gain();
field_rfgain.on_change = [this](int32_t v) {
@@ -328,47 +369,80 @@ MicTXView::MicTXView(
};
field_rfamp.set_value(rf_amp ? 14 : 0);
options_mode.on_change = [this](size_t, int32_t v) {
enable_am = false;
options_mode.on_change = [this](size_t, int32_t v) { //{ "FM", 0 },{ "AM", 1 },{ "USB", 2 },{ "LSB", 3 },{ "DSB", 4 }
enable_am = false;
enable_usb = false;
enable_lsb = false;
enable_dsb = false;
enable_wfm = false;
using option_t = std::pair<std::string, int32_t>;
using options_t = std::vector<option_t>;
options_t rxbw; // Aux structure to change dynamically field_rxbw contents,
switch(v) {
case 0:
enable_am = false;
case 0: //{ "FM", 0 }
enable_am = false;
enable_usb = false;
enable_lsb = false;
enable_dsb = false;
field_bw.set_value(transmitter_model.channel_bandwidth() / 1000);
field_bw.set_value(10); // pre-default deviation FM for WFM
// field_bw.set_value(transmitter_model.channel_bandwidth() / 1000);
//if (rx_enabled)
rxaudio(rx_enabled); //Update now if we have RX audio on
options_tone_key.hidden(0); // we are in FM mode , we should have active the Key-tones & CTCSS option.
rxbw.emplace_back("8k5-NFM ", 0); // restore the original dynamic field_rxbw value.
rxbw.emplace_back("11k-NFM ", 1);
rxbw.emplace_back("16k-FM ", 2);
field_rxbw.set_options(rxbw); // store that aux GUI option to the field_rxbw.
field_rxbw.hidden(0); // we are in FM mode, we need to allow the user set up of the RX NFM BW selection (8K5, 11K, 16K)
field_bw.hidden(0); // we are in FM mode, we need to allow FM deviation parameter , in non FM mode.
break;
case 1:
case 1: //{ "WFM", 1 }
enable_am = false;
enable_usb = false;
enable_lsb = false;
enable_dsb = false;
enable_wfm = true;
field_bw.set_value(75); // pre-default deviation FM for WFM
// field_bw.set_value(transmitter_model.channel_bandwidth() / 1000);
//if (rx_enabled)
rxaudio(rx_enabled); //Update now if we have RX audio on
options_tone_key.hidden(0); // we are in WFM mode , we should have active the Key-tones & CTCSS option.
rxbw.emplace_back("200K-WFM", 0); // locked a fixed option , to display it .
field_rxbw.set_options(rxbw); // store that aux GUI option to the field_rxbw.
field_rxbw.hidden(0); // we are in WFM mode, we need to show to the user the selected BW WFM filer .
field_bw.hidden(0); // we are in WFM mode, we need to allow WFM deviation parameter , in non FM mode.
break;
case 2: //{ "AM", 2 }
enable_am = true;
rxaudio(rx_enabled); //Update now if we have RX audio on
options_tone_key.set_selected_index(0); // we are NOT in FM mode , we reset the possible previous key-tones &CTCSS selection.
set_dirty(); // Refresh display
options_tone_key.hidden(1); // we hide that Key-tones & CTCSS input selecction, (no meaning in AM/DSB/SSB).
field_rxbw.hidden(1); // we hide the NFM BW selection in other modes non_FM (no meaning in AM/DSB/SSB)
check_rogerbeep.hidden(0); // make visible again the "rogerbeep" selection.
field_bw.hidden(1); // we hide the FM deviation parameter , in non FM mode.
check_rogerbeep.hidden(0); // make visible again the "rogerbeep" selection.
break;
case 2:
case 3: //{ "USB", 3 }
enable_usb = true;
rxaudio(rx_enabled); //Update now if we have RX audio on
check_rogerbeep.set_value(false); // reset the possible activation of roger beep, because it is not compatible with SSB , by now.
check_rogerbeep.hidden(1); // hide that roger beep selection.
set_dirty(); // Refresh display
break;
case 3:
case 4: //{ "LSB", 4 }
enable_lsb = true;
rxaudio(rx_enabled); //Update now if we have RX audio on
check_rogerbeep.set_value(false); // reset the possible activation of roger beep, because it is not compatible with SSB , by now.
check_rogerbeep.hidden(1); // hide that roger beep selection.
set_dirty(); // Refresh display
break;
case 4:
case 5: //{ "DSB", 5 }
enable_dsb = true;
rxaudio(rx_enabled); //Update now if we have RX audio on
check_rogerbeep.hidden(0); // make visible again the "rogerbeep" selection.
@@ -447,20 +521,24 @@ MicTXView::MicTXView(
field_volume.set_value((receiver_model.headphone_volume() - audio::headphone::volume_range().max).decibel() + 99);
field_volume.on_change = [this](int32_t v) { this->on_headphone_volume_changed(v); };
field_rxbw.on_change = [this](size_t, int32_t v) {
switch(v) {
// In Previous fw versions, that nbfm_configuration(n) was done in any mode (FM/AM/SSB/DSB)...strictly speaking only need it in NFM-FM .
if (!(enable_am || enable_usb || enable_lsb || enable_dsb || enable_wfm )) {
//we are in NFM/FM case, here it has meaning to set the selected NFM/FM mode.
field_rxbw.on_change = [this](size_t, int32_t v) {
switch(v) {
case 0:
receiver_model.set_nbfm_configuration(0);
receiver_model.set_nbfm_configuration(0); // NFM BW 8K5
break;
case 1:
receiver_model.set_nbfm_configuration(1);
receiver_model.set_nbfm_configuration(1); // NFM BW 11K
break;
case 2:
receiver_model.set_nbfm_configuration(2);
receiver_model.set_nbfm_configuration(2); // FM BW 16K
break;
}
};
field_rxbw.set_selected_index(2);
}
};
field_rxbw.set_selected_index(2); // preselected FM BW 16K
}
field_squelch.on_change = [this](int32_t v) {
receiver_model.set_squelch_level(100 - v);
@@ -537,9 +615,9 @@ MicTXView::MicTXView(
transmitter_model.set_baseband_bandwidth(1750000);
set_tx(false);
audio::set_rate(audio::Rate::Hz_24000);
audio::input::start(); // originally , audio::input::start(); (we added parameter)
audio::set_rate(audio::Rate::Hz_24000);
audio::input::start(ak4951_alc_and_wm8731_boost_GUI); // When detected AK4951 => set up ALC mode; when detected WM8731 => set up mic_boost ON/OFF.
}
MicTXView::~MicTXView() {
@@ -548,7 +626,8 @@ MicTXView::~MicTXView() {
transmitter_model.disable();
if (rx_enabled) //Also turn off audio rx if enabled
rxaudio(false);
baseband::shutdown();
hackrf::cpld::load_sram_no_verify(); // to leave all RX ok, without ghost signal problem at the exit .
baseband::shutdown(); // better this function at the end, not load_sram() that sometimes produces hang up.
}
}
+35 -19
View File
@@ -83,7 +83,7 @@ private:
bool rx_enabled { false };
uint32_t tone_key_index { };
float mic_gain { 1.0 };
uint8_t ak4951_alc_GUI_selected { 0 };
uint8_t ak4951_alc_and_wm8731_boost_GUI { 0 };
uint32_t audio_level { 0 };
uint32_t va_level { };
uint32_t attack_ms { };
@@ -99,18 +99,21 @@ private:
rf::Frequency rx_frequency { 0 };
int32_t focused_ui { 2 };
bool button_touch { false };
uint8_t shift_bits_s16 {4} ; // shift bits factor to the captured ADC S16 audio sample.
//AM TX Stuff
bool enable_am { false };
bool enable_dsb { false };
bool enable_usb { false };
bool enable_lsb { false };
bool enable_wfm { false }; // added to distinguish in the FM mode , RX BW : NFM (8K5, 11K), FM (16K), WFM(200K)
Labels labels_WM8731 {
{ { 3 * 8, 1 * 8 }, "MIC-GAIN:", Color::light_grey() },
{ { 17 * 8, 1 * 8 }, "Boost", Color::light_grey() },
{ { 3 * 8, 3 * 8 }, "F:", Color::light_grey() },
{ { 15 * 8, 3 * 8 }, "BW: FM kHz", Color::light_grey() },
{ { 15 * 8, 3 * 8 }, "FM TXBW: kHz", Color::light_grey() }, // to be more symetric and consistent to the below FM RXBW
{ { 3 * 8, 5 * 8 }, "GAIN:", Color::light_grey() },
{ {11 * 8, 5 * 8 }, "Amp:", Color::light_grey() },
{ { 18 * 8, (5 * 8) }, "Mode:", Color::light_grey() },
@@ -120,7 +123,7 @@ private:
{ {20 * 8, 10 * 8 }, "DEC:", Color::light_grey() },
{ { 4 * 8, ( 13 * 8 ) - 2 }, "TONE KEY:", Color::light_grey() },
{ { 7 * 8, 23 * 8 }, "VOL:", Color::light_grey() },
{ {15 * 8, 23 * 8 }, "FM RXBW:", Color::light_grey() },
{ {14 * 8, 23 * 8 }, "FM RXBW:", Color::light_grey() },
{ {17 * 8, 25 * 8 }, "SQ:", Color::light_grey() },
{ { 5 * 8, 25 * 8 }, "F:", Color::light_grey() },
{ { 5 * 8, 27 * 8 }, "LNA:", Color::light_grey()},
@@ -131,7 +134,7 @@ private:
{ { 3 * 8, 1 * 8 }, "MIC-GAIN:", Color::light_grey() },
{ { 17 * 8, 1 * 8 }, "ALC", Color::light_grey() },
{ { 3 * 8, 3 * 8 }, "F:", Color::light_grey() },
{ { 15 * 8, 3 * 8 }, "BW: FM kHz", Color::light_grey() },
{ { 15 * 8, 3 * 8 }, "FM TXBW: kHz", Color::light_grey() },
{ { 3 * 8, 5 * 8 }, "GAIN:", Color::light_grey() },
{ {11 * 8, 5 * 8 }, "Amp:", Color::light_grey() },
{ { 18 * 8, (5 * 8) }, "Mode:", Color::light_grey() },
@@ -140,8 +143,8 @@ private:
{ {12 * 8, 10 * 8 }, "ATT:", Color::light_grey() },
{ {20 * 8, 10 * 8 }, "DEC:", Color::light_grey() },
{ { 4 * 8, ( 13 * 8 ) - 2 }, "TONE KEY:", Color::light_grey() },
{ { 7 * 8, 23 * 8 }, "VOL:", Color::light_grey() },
{ {15 * 8, 23 * 8 }, "FM RXBW:", Color::light_grey() },
{ { (6 * 8)+4, 23 * 8 }, "VOL:", Color::light_grey() },
{ {14 * 8, 23 * 8 }, "FM RXBW:", Color::light_grey() },
{ {17 * 8, 25 * 8 }, "SQ:", Color::light_grey() },
{ { 5 * 8, 25 * 8 }, "F:", Color::light_grey() },
{ { 5 * 8, 27 * 8 }, "LNA:", Color::light_grey()},
@@ -171,7 +174,7 @@ private:
{ 20 * 8, 1 * 8 }, // Coordinates are: int:x (px), int:y (px)
11,
{
{ " OFF-20kHz", 0 }, // Nothing changed from ORIGINAL,keeping ALL programm. AK4951 Dig. block->OFF)
{ " OFF-12kHz", 0 }, // Nothing changed from ORIGINAL,keeping ALL programmable AK4951 Digital Block->OFF, sampling 24Khz)
{ "+12dB-6kHz", 1 }, // ALC-> on, (+12dB's) Auto Vol max + Wind Noise cancel + LPF 6kHz + Pre-amp Mic (+21dB=original)
{ "+09dB-6kHz", 2 }, // ALC-> on, (+09dB's) Auto Vol max + Wind Noise cancel + LPF 6kHz + Pre-amp Mic (+21dB=original)
{ "+06dB-6kHz", 3 }, // ALC-> on, (+06dB's) Auto Vol max + Wind Noise cancel + LPF 6kHz + Pre-amp Mic (+21dB=original)
@@ -186,11 +189,23 @@ private:
}
};
OptionsField options_wm8731_boost_mode {
{ 22 * 8, 1 * 8 }, // Coordinates are: int:x (px), int:y (px)
5,
{
{ "ON +12dB", 0 }, // WM8731 Mic Boost ON ,original+12dBs condition, easy to saturate ADC sat in high voice ,relative G = +12 dB's respect ref level
{ "ON +06dB", 1 }, // WM8731 Mic Boost ON ,original+6 dBs condition, easy to saturate ADC sat in high voice ,relative G = +06 dB's respect ref level
{ "OFF+04dB", 2 }, // WM8731 Mic Boost OFF to avoid ADC sat in high voice ,relative G = +04 dB's (respect ref level) , always effective sampling 24khz
{ "OFF-02dB", 3 }, // WM8731 Mic Boost OFF to avoid ADC sat in high voice ,relative G = -02 dB's (respect ref level)
{ "OFF-08dB", 4 }, // WM8731 Mic Boost OFF to avoid ADC sat in high voice ,relative G = -12 dB's (respect ref level)
}
};
FrequencyField field_frequency {
{ 5 * 8, 3 * 8 },
};
NumberField field_bw {
{ 18 * 8, 3 * 8 },
{ 23 * 8, 3 * 8 },
3,
{ 0, 150 },
1,
@@ -214,13 +229,14 @@ private:
OptionsField options_mode {
{ 24 * 8, 5 * 8 },
3,
4,
{
{ "FM", 0 },
{ "AM", 1 },
{ "USB", 2 },
{ "LSB", 3 },
{ "DSB", 4 }
{ "NFM/FM", 0 },
{ " WFM ", 1 },
{ " AM ", 2 },
{ " USB ", 3 },
{ " LSB ", 4 },
{ " DSB ", 5 }
}
};
/*
@@ -293,13 +309,13 @@ private:
};
OptionsField field_rxbw {
{ 23* 8, 23 * 8},
{ 22* 8, 23 * 8},
3,
{
{"8k5", 0},
{"11k", 1},
{"16k", 2}
}
{"8k5-NFM", 0},
{"11k-NFM", 1},
{"16k-FM ", 2},
}
};
NumberField field_squelch {
+3 -1
View File
@@ -26,6 +26,7 @@
#include "baseband_api.hpp"
#include "hackrf_gpio.hpp"
#include "portapack_shared_memory.hpp"
#include "cpld_update.hpp"
#include "ui_textentry.hpp"
#include "string_format.hpp"
@@ -102,7 +103,8 @@ MorseView::~MorseView() {
settings.save("tx_morse", &app_settings);
transmitter_model.disable();
baseband::shutdown();
hackrf::cpld::load_sram_no_verify(); // to leave all RX ok, without ghost signal problem at the exit .
baseband::shutdown(); // better this function at the end, not load_sram() that sometimes produces hang up.
}
void MorseView::paint(Painter&) {
+328
View File
@@ -0,0 +1,328 @@
/*
* Copyright (C) 2016 Jared Boone, ShareBrained Technology, Inc.
* Copyright (C) 2016 Furrtek
* Copyleft (ↄ) 2022 NotPike
*
* This file is part of PortaPack.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street,
* Boston, MA 02110-1301, USA.
*/
#include "ui_playlist.hpp"
#include "string_format.hpp"
#include "ui_fileman.hpp"
#include "io_file.hpp"
#include "baseband_api.hpp"
#include "portapack.hpp"
#include "portapack_persistent_memory.hpp"
#include <unistd.h>
using namespace portapack;
namespace ui {
void PlaylistView::set_ready() {
ready_signal = true;
}
void PlaylistView::load_file(std::filesystem::path playlist_path) {
File playlist_file;
auto error = playlist_file.open(playlist_path.string());
if (!error.is_valid()) {
std::string line;
char one_char[1];
for (size_t pointer =0 ; pointer < playlist_file.size(); pointer++) {
playlist_file.seek(pointer);
playlist_file.read(one_char, 1);
if ((int) one_char[0] >= ' ') {
line += one_char[0];
} else if (one_char[0] == '\n') {
txtline_process(line);
line.clear();
}
}
if (line.length() > 0) {
txtline_process(line);
}
}
playlist_masterdb = playlist_db;
return ;
}
void PlaylistView::txtline_process(std::string &line) {
playlist_entry new_item;
rf::Frequency f;
size_t previous = 0;
size_t current = line.find(',');
std::string freqs = line.substr(0, current);
previous = current +1;
current = line.find(',', previous);
std::string file = line.substr(previous, current - previous);
previous = current +1;
current = line.find(',', previous);
uint32_t sample_rate = strtoll(line.substr(previous).c_str(), nullptr, 10);
f = strtoll(freqs.c_str(), nullptr, 0);
new_item.replay_frequency = f;
new_item.replay_file = "/" + file;
new_item.sample_rate = sample_rate;
new_item.next_delay = 0;
playlist_db.push_back(std::move(new_item));
}
void PlaylistView::on_file_changed(std::filesystem::path new_file_path, rf::Frequency replay_frequency, uint32_t replay_sample_rate) {
File data_file;
// Get file size
auto data_open_error = data_file.open("/" + new_file_path.string());
if (data_open_error.is_valid()) {
file_error();
return;
}
file_path = new_file_path;
field_frequency.set_value(replay_frequency);
sample_rate = replay_sample_rate;
text_sample_rate.set(unit_auto_scale(sample_rate, 3, 0) + "Hz");
auto file_size = data_file.size();
auto duration = (file_size * 1000) / (2 * 2 * sample_rate);
progressbar.set_max(file_size);
text_filename.set(file_path.filename().string().substr(0, 12));
text_duration.set(to_string_time_ms(duration));
button_play.focus();
}
void PlaylistView::on_tx_progress(const uint32_t progress) {
progressbar.set_value(progress);
}
void PlaylistView::focus() {
button_open.focus();
}
void PlaylistView::file_error() {
nav_.display_modal("Error", "File "+file_path.string() +" read error. " +file_path.string());
}
bool PlaylistView::is_active() const {
return (bool)replay_thread;
}
bool PlaylistView::loop() const {
return (bool) playlist_db.size();
}
void PlaylistView::toggle() {
if( is_active() ) {
stop(false);
} else {
start();
}
}
void PlaylistView::start() {
stop(false);
playlist_entry item = playlist_db.front();
playlist_db.pop_front();
// playlist_entry item = playlist_db[0];
// for (playlist_entry item : playlist_db) {
// file_path = item.replay_file;
// rf::Frequency replay_frequency = strtoll(item.replay_frequency.c_str(),nullptr,10);
on_file_changed(item.replay_file, item.replay_frequency, item.sample_rate);
on_target_frequency_changed(item.replay_frequency);
std::unique_ptr<stream::Reader> reader;
auto p = std::make_unique<FileReader>();
auto open_error = p->open(file_path);
if( open_error.is_valid() ) {
file_error();
return; // Fixes TX bug if there's a file error
} else {
reader = std::move(p);
}
if( reader ) {
button_play.set_bitmap(&bitmap_stop);
baseband::set_sample_rate(sample_rate * 8);
replay_thread = std::make_unique<ReplayThread>(
std::move(reader),
read_size, buffer_count,
&ready_signal,
[](uint32_t return_code) {
ReplayThreadDoneMessage message { return_code };
EventDispatcher::send_message(message);
}
);
}
field_rfgain.on_change = [this](int32_t v) {
tx_gain = v;
};
field_rfgain.set_value(tx_gain);
receiver_model.set_tx_gain(tx_gain);
field_rfamp.on_change = [this](int32_t v) {
rf_amp = (bool)v;
};
field_rfamp.set_value(rf_amp ? 14 : 0);
//Enable Bias Tee if selected
radio::set_antenna_bias(portapack::get_antenna_bias());
radio::enable({
receiver_model.tuning_frequency(),
sample_rate * 8,
baseband_bandwidth,
rf::Direction::Transmit,
rf_amp, // previous code line : "receiver_model.rf_amp()," was passing the same rf_amp of all Receiver Apps
static_cast<int8_t>(receiver_model.lna()),
static_cast<int8_t>(receiver_model.vga())
});
// }
}
void PlaylistView::stop(const bool do_loop) {
if( is_active() ) {
replay_thread.reset();
}
if (do_loop) {
if (playlist_db.size() > 0 ) {
start();
} else {
playlist_db = playlist_masterdb;
start();
}
} else {
radio::set_antenna_bias(false); //Turn off Bias Tee
radio::disable();
button_play.set_bitmap(&bitmap_play);
}
ready_signal = false;
}
void PlaylistView::handle_replay_thread_done(const uint32_t return_code) {
if (return_code == ReplayThread::END_OF_FILE) {
stop(true);
} else if (return_code == ReplayThread::READ_ERROR) {
stop(false);
file_error();
}
progressbar.set_value(0);
}
PlaylistView::PlaylistView(
NavigationView& nav
) : nav_ (nav)
{
tx_gain = 35;field_rfgain.set_value(tx_gain); // Initial default value (-12 dB's max ).
field_rfamp.set_value(rf_amp ? 14 : 0); // Initial default value True. (TX RF amp on , +14dB's)
baseband::run_image(portapack::spi_flash::image_tag_replay);
add_children({
&labels,
&button_open,
&text_filename,
&text_sample_rate,
&text_duration,
&progressbar,
&field_frequency,
&field_rfgain,
&field_rfamp, // let's not use common rf_amp
&check_loop,
&button_play,
&waterfall,
});
field_frequency.set_value(target_frequency());
field_frequency.set_step(receiver_model.frequency_step());
field_frequency.on_change = [this](rf::Frequency f) {
this->on_target_frequency_changed(f);
};
field_frequency.on_edit = [this, &nav]() {
// TODO: Provide separate modal method/scheme?
auto new_view = nav.push<FrequencyKeypadView>(this->target_frequency());
new_view->on_changed = [this](rf::Frequency f) {
this->on_target_frequency_changed(f);
this->field_frequency.set_value(f);
};
};
field_frequency.set_step(5000);
button_play.on_select = [this](ImageButton&) {
this->toggle();
};
button_open.on_select = [this, &nav](Button&) {
auto open_view = nav.push<FileLoadView>(".TXT");
open_view->on_changed = [this](std::filesystem::path new_file_path) {
load_file(new_file_path);
};
};
}
PlaylistView::~PlaylistView() {
radio::disable();
baseband::shutdown();
}
void PlaylistView::on_hide() {
stop(false);
// TODO: Terrible kludge because widget system doesn't notify Waterfall that
// it's being shown or hidden.
waterfall.on_hide();
View::on_hide();
}
void PlaylistView::set_parent_rect(const Rect new_parent_rect) {
View::set_parent_rect(new_parent_rect);
const ui::Rect waterfall_rect { 0, header_height, new_parent_rect.width(), new_parent_rect.height() - header_height };
waterfall.set_parent_rect(waterfall_rect);
}
void PlaylistView::on_target_frequency_changed(rf::Frequency f) {
set_target_frequency(f);
}
void PlaylistView::set_target_frequency(const rf::Frequency new_value) {
persistent_memory::set_tuned_frequency(new_value);;
}
rf::Frequency PlaylistView::target_frequency() const {
return persistent_memory::tuned_frequency();
}
} /* namespace ui */
+176
View File
@@ -0,0 +1,176 @@
/*
* Copyright (C) 2016 Jared Boone, ShareBrained Technology, Inc.
* Copyright (C) 2016 Furrtek
*
* This file is part of PortaPack.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street,
* Boston, MA 02110-1301, USA.
*/
#include "ui_widget.hpp"
#include "ui_navigation.hpp"
#include "ui_receiver.hpp"
#include "replay_thread.hpp"
#include "ui_spectrum.hpp"
#include <string>
#include <memory>
#include <deque>
namespace ui {
class PlaylistView : public View {
public:
PlaylistView(NavigationView& nav);
~PlaylistView();
void on_hide() override;
void set_parent_rect(const Rect new_parent_rect) override;
void focus() override;
std::string title() const override { return "Playlist"; };
private:
NavigationView& nav_;
static constexpr ui::Dim header_height = 3 * 16;
struct playlist_entry {
rf::Frequency replay_frequency { 0 };
std::string replay_file{};
uint32_t sample_rate{};
uint32_t next_delay{};
};
std::deque<playlist_entry> playlist_db{};
std::deque<playlist_entry> playlist_masterdb{};
uint32_t sample_rate = 0;
int32_t tx_gain { 47 };
bool rf_amp { true }; // aux private var to store temporal, Replay App rf_amp user selection.
static constexpr uint32_t baseband_bandwidth = 2500000;
const size_t read_size { 16384 };
const size_t buffer_count { 3 };
void load_file(std::filesystem::path playlist_path);
void txtline_process(std::string &);
void on_file_changed(std::filesystem::path new_file_path, rf::Frequency replay_frequency, uint32_t replay_sample_rate);
void on_target_frequency_changed(rf::Frequency f);
void on_tx_progress(const uint32_t progress);
void set_target_frequency(const rf::Frequency new_value);
rf::Frequency target_frequency() const;
void toggle();
void start();
void stop(const bool do_loop);
bool is_active() const;
bool loop() const;
void set_ready();
void handle_replay_thread_done(const uint32_t return_code);
void file_error();
std::filesystem::path file_path { };
std::unique_ptr<ReplayThread> replay_thread { };
bool ready_signal { false };
Labels labels {
{ { 10 * 8, 2 * 16 }, "GAIN A:", Color::light_grey() }
};
Button button_open {
{ 0 * 8, 0 * 16, 10 * 8, 2 * 16 },
"Open file"
};
Text text_filename {
{ 11 * 8, 0 * 16, 12 * 8, 16 },
"-"
};
Text text_sample_rate {
{ 24 * 8, 0 * 16, 6 * 8, 16 },
"-"
};
Text text_duration {
{ 11 * 8, 1 * 16, 6 * 8, 16 },
"-"
};
ProgressBar progressbar {
{ 18 * 8, 1 * 16, 12 * 8, 16 }
};
FrequencyField field_frequency {
{ 0 * 8, 2 * 16 },
};
NumberField field_rfgain {
{ 14 * 8, 2 * 16 },
2,
{ 0, 47 },
1,
' '
};
NumberField field_rfamp { // previously I was using "RFAmpField field_rf_amp" but that is general Receiver amp setting.
{ 19 * 8, 2 * 16 },
2,
{ 0, 14 }, // this time we will display GUI , 0 or 14 dBs same as Mic App
14,
' '
};
Checkbox check_loop {
{ 21 * 8, 2 * 16 },
4,
"Loop",
true
};
ImageButton button_play {
{ 28 * 8, 2 * 16, 2 * 8, 1 * 16 },
&bitmap_play,
Color::green(),
Color::black()
};
spectrum::WaterfallWidget waterfall { };
MessageHandlerRegistration message_handler_replay_thread_error {
Message::ID::ReplayThreadDone,
[this](const Message* const p) {
const auto message = *reinterpret_cast<const ReplayThreadDoneMessage*>(p);
this->handle_replay_thread_done(message.return_code);
}
};
MessageHandlerRegistration message_handler_fifo_signal {
Message::ID::RequestSignal,
[this](const Message* const p) {
const auto message = static_cast<const RequestSignalMessage*>(p);
if (message->signal == RequestSignalMessage::Signal::FillRequest) {
this->set_ready();
}
}
};
MessageHandlerRegistration message_handler_tx_progress {
Message::ID::TXProgress,
[this](const Message* const p) {
const auto message = *reinterpret_cast<const TXProgressMessage*>(p);
this->on_tx_progress(message.progress);
}
};
};
} /* namespace ui */
+3 -1
View File
@@ -23,6 +23,7 @@
#include "ui_pocsag_tx.hpp"
#include "baseband_api.hpp"
#include "cpld_update.hpp"
#include "string_format.hpp"
#include "ui_textentry.hpp"
@@ -43,7 +44,8 @@ POCSAGTXView::~POCSAGTXView() {
settings.save("tx_pocsag", &app_settings);
transmitter_model.disable();
baseband::shutdown();
hackrf::cpld::load_sram_no_verify(); // to leave all RX ok, without ghost signal problem at the exit
baseband::shutdown(); // better this function at the end, not load_sram() that sometimes produces hang up.
}
void POCSAGTXView::on_tx_progress(const uint32_t progress, const bool done) {
+3 -1
View File
@@ -24,6 +24,7 @@
#include "portapack.hpp"
#include "baseband_api.hpp"
#include "cpld_update.hpp"
#include "portapack_shared_memory.hpp"
#include <cstring>
@@ -180,7 +181,8 @@ RDSView::~RDSView() {
settings.save("tx_rds", &app_settings);
transmitter_model.disable();
baseband::shutdown();
hackrf::cpld::load_sram_no_verify(); // to leave all RX ok, without ghost signal problem at the exit.
baseband::shutdown(); // better this function at the end, not load_sram() that sometimes produces hang up.
}
void RDSView::start_tx() {
File diff suppressed because it is too large Load Diff
+403
View File
@@ -0,0 +1,403 @@
/*
* Copyright (C) 2015 Jared Boone, ShareBrained Technology, Inc.
* Copyright (C) 2018 Furrtek
*
* This file is part of PortaPack.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street,
* Boston, MA 02110-1301, USA.
*/
#ifndef _UI_RECON
#define _UI_RECON
#include "ui.hpp"
#include "receiver_model.hpp"
#include "ui_receiver.hpp"
#include "ui_font_fixed_8x16.hpp"
#include "freqman.hpp"
#include "analog_audio_app.hpp"
#include "audio.hpp"
#include "ui_mictx.hpp"
#include "portapack_persistent_memory.hpp"
#include "baseband_api.hpp"
#include "string_format.hpp"
#include "file.hpp"
#include "app_settings.hpp"
namespace ui {
class ReconThread {
public:
ReconThread(freqman_db *database );
~ReconThread();
void set_recon(const bool v);
void set_freq_delete(const bool v);
bool is_recon();
void set_lock_duration( const uint32_t v );
uint32_t get_lock_duration();
void set_lock_nb_match( const uint32_t v );
void set_match_mode( const uint32_t v );
uint32_t get_lock_nb_match();
void set_freq_lock(const uint32_t v);
uint32_t is_freq_lock();
int64_t get_current_freq();
void set_stepper(const int64_t v);
void change_recon_direction();
bool get_recon_direction();
void set_recon_direction( const bool v);
void set_continuous(const bool v);
void set_default_modulation( freqman_index_t index );
freqman_index_t get_current_modulation();
void set_default_bandwidth( freqman_index_t index );
freqman_index_t get_current_bandwidth();
void set_default_step( freqman_index_t index );
void set_freq_index( int16_t index );
int16_t get_freq_index();
void run();
void stop();
ReconThread(const ReconThread&) = delete;
ReconThread(ReconThread&&) = delete;
ReconThread& operator=(const ReconThread&) = delete;
ReconThread& operator=(ReconThread&&) = delete;
private:
freqman_db &frequency_list_ ;
Thread* thread { nullptr };
int64_t freq = 0 ;
uint32_t step = 0 ;
freqman_index_t def_modulation = 0 ;
freqman_index_t def_bandwidth = 0 ;
freqman_index_t def_step = 0 ;
tone_index tone = 0 ;
freqman_entry last_entry = { } ;
int16_t frequency_index = 0 ;
bool _recon { true };
bool _freq_delete { false };
bool _fwd { true };
bool _continuous { true };
int64_t _stepper { 0 };
int32_t _freq_lock { 0 };
uint32_t _lock_duration { 50 };
uint32_t _lock_nb_match { 10 };
static msg_t static_fn(void* arg);
};
class ReconView : public View {
public:
ReconView(NavigationView& nav);
~ReconView();
void focus() override;
void big_display_freq( int64_t f );
const Style style_grey { // recon
.font = font::fixed_8x16,
.background = Color::black(),
.foreground = Color::grey(),
};
const Style style_white { // recon
.font = font::fixed_8x16,
.background = Color::black(),
.foreground = Color::white(),
};
const Style style_yellow { //Found signal
.font = font::fixed_8x16,
.background = Color::black(),
.foreground = Color::yellow(),
};
const Style style_green { //Found signal
.font = font::fixed_8x16,
.background = Color::black(),
.foreground = Color::green(),
};
const Style style_red { //erasing freq
.font = font::fixed_8x16,
.background = Color::black(),
.foreground = Color::red(),
};
const Style style_blue { // quick recon, wait == 0
.font = font::fixed_8x16,
.background = Color::black(),
.foreground = Color::blue(),
};
std::string title() const override { return "Recon"; };
//void set_parent_rect(const Rect new_parent_rect) override;
private:
NavigationView& nav_;
void start_recon_thread();
size_t change_mode( freqman_index_t mod_type);
void show_max( bool refresh_display = false );
void recon_pause();
void recon_resume();
void user_pause();
void user_resume();
void frequency_file_load( bool stop_all_before = false);
void on_statistics_update(const ChannelStatistics& statistics);
void on_headphone_volume_changed(int32_t v);
void set_display_freq( int64_t freq );
void handle_retune( int64_t freq , uint32_t index );
bool check_sd_card();
jammer::jammer_range_t frequency_range { false, 0, 0 }; //perfect for manual recon task too...
int32_t squelch { 0 };
int32_t db { 0 };
int32_t timer { 0 };
int32_t wait { 5000 }; // in msec. if > 0 wait duration after a lock, if < 0 duration is set to 'wait' unless there is no more activity
uint32_t lock_wait { 500 }; // in msec. Represent the maximum amount of time we will wait for a lock to complete before switching to next
int32_t def_step { 0 };
freqman_db frequency_list = { };
uint32_t current_index { 0 };
bool userpause { false };
bool continuous_lock { false };
std::string input_file = { "RECON" };
std::string output_file = { "RECON_RESULTS" };
bool autosave = { true };
bool autostart = { true };
bool continuous = { true };
bool filedelete = { true };
bool load_freqs = { true };
bool load_ranges = { true };
bool load_hamradios = { true };
bool update_ranges = { true };
bool fwd = { true };
// maximum usable freq
long long int MAX_UFREQ = { 7200000000 };
uint32_t recon_lock_nb_match = { 10 };
uint32_t recon_lock_duration = { 50 };
uint32_t recon_match_mode = { 0 };
bool scanner_mode { false };
bool manual_mode { false };
bool sd_card_mounted = false ;
int32_t volume = 40 ;
Labels labels
{
{ { 0 * 8 , 0 * 16 }, "LNA: VGA: AMP: VOL: ", Color::light_grey() },
{ { 0 * 8 , 1 * 16 }, "BW : SQ: W,L: , ", Color::light_grey() },
{ { 3 * 8 , 10 * 16 }, "START END MANUAL", Color::light_grey() },
{ { 0 * 8 , (26 * 8) + 4 }, "MODE:", Color::light_grey() },
{ { 11 * 8 , (26 * 8) + 4 }, "STEP:", Color::light_grey() },
};
LNAGainField field_lna {
{ 4 * 8, 0 * 16 }
};
VGAGainField field_vga {
{ 11 * 8, 0 * 16 }
};
RFAmpField field_rf_amp {
{ 18 * 8, 0 * 16 }
};
NumberField field_volume {
{ 24 * 8, 0 * 16 },
2,
{ 0, 99 },
1,
' ',
};
OptionsField field_bw {
{ 3 * 8, 1 * 16 },
4,
{ }
};
NumberField field_squelch {
{ 10 * 8, 1 * 16 },
3,
{ -90, 20 },
1,
' ',
};
NumberField field_wait {
{ 18 * 8, 1 * 16 },
5,
{ -9000, 9000 },
100,
' ',
};
NumberField field_lock_wait {
{ 24 * 8, 1 * 16 },
4,
{ 100 , 9000 },
100,
' ',
};
RSSI rssi {
{ 0 * 16, 2 * 16, 15 * 16, 8 },
};
Text text_cycle {
{ 0, 3 * 16, 3 * 8, 16 },
};
Text text_max {
{ 3 * 8, 3 * 16, 20 * 8 , 16 },
};
Text desc_cycle {
{0, 4 * 16, 240, 16 },
};
/* BigFrequency big_display { //Show frequency in glamour
{ 4, 7 * 16 - 8 , 28 * 8, 52 },
0
}; */
Text big_display { //Show frequency in text mode
{ 0, 5 * 16 , 28 * 8, 16 },
};
Text freq_stats { //Show frequency stats in text mode
{ 0, 6 * 16 , 28 * 8, 16 },
};
Text text_timer { //Show frequency stats in text mode
{ 0, 7 * 16 , 28 * 8, 16 },
};
Button button_recon_setup {
{ 25 * 8 , 2 * 16 + 8 , 4 * 8, 28 },
"OPT"
};
Button button_scanner_mode {
{ 21 * 8 , 8 * 16 , 9 * 8, 28 },
"RECON"
};
Text file_name { //Show file used
{ 0 , 8 * 16 + 4 , 20 * 8, 16 },
};
ButtonWithEncoder button_manual_start {
{ 0 * 8, 11 * 16, 11 * 8, 28 },
""
};
ButtonWithEncoder button_manual_end {
{ 12 * 8 - 6, 11 * 16, 11 * 8, 28 },
""
};
Button button_manual_recon {
{ 23 * 8 - 3, 11 * 16, 7 * 8 , 28 },
"SEARCH"
};
OptionsField field_mode {
{ 5 * 8, (26 * 8) + 4 },
6,
{
}
};
OptionsField step_mode {
{ 17 * 8, (26 * 8) + 4 },
12,
{
}
};
ButtonWithEncoder button_pause {
{ 0, (15 * 16) - 4, 72, 28 },
"PAUSE"
};
Button button_audio_app {
{ 84, (15 * 16) - 4, 72, 28 },
"AUDIO"
};
ButtonWithEncoder button_add {
{ 168, (15 * 16) - 4, 72, 28 },
"<STORE>"
};
Button button_dir {
{ 0, (35 * 8) - 4, 34, 28 },
"FW>"
};
Button button_restart {
{ 38, (35 * 8) - 4, 34, 28 },
"RST"
};
Button button_mic_app {
{ 84, (35 * 8) - 4, 72, 28 },
"MIC TX"
};
ButtonWithEncoder button_remove {
{ 168, (35 * 8) - 4, 72, 28 },
"<REMOVE>"
};
std::unique_ptr<ReconThread> recon_thread { };
MessageHandlerRegistration message_handler_retune {
Message::ID::Retune,
[this](const Message* const p) {
const auto message = *reinterpret_cast<const RetuneMessage*>(p);
this->handle_retune(message.freq,message.range);
}
};
MessageHandlerRegistration message_handler_stats {
Message::ID::ChannelStatistics,
[this](const Message* const p) {
this->on_statistics_update(static_cast<const ChannelStatisticsMessage*>(p)->statistics);
}
};
// app save settings
std::app_settings settings { };
std::app_settings::AppSettings app_settings { };
};
} /* namespace ui */
#endif
@@ -0,0 +1,301 @@
/*
* Copyright (C) 2015 Jared Boone, ShareBrained Technology, Inc.
* Copyright (C) 2016 Furrtek
*
* This file is part of PortaPack.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street,
* Boston, MA 02110-1301, USA.
*/
#include "ui_recon_settings.hpp"
#include "ui_navigation.hpp"
#include "ui_fileman.hpp"
#include "ui_textentry.hpp"
#include "file.hpp"
#include "portapack.hpp"
#include "portapack_persistent_memory.hpp"
using namespace std;
using namespace portapack;
namespace ui {
bool ReconSetupLoadStrings( std::string source, std::string &input_file , std::string &output_file , uint32_t &recon_lock_duration , uint32_t &recon_lock_nb_match , int32_t &recon_squelch_level , uint32_t &recon_match_mode , int32_t &wait , uint32_t &lock_wait , int32_t &volume )
{
File settings_file;
size_t length, file_position = 0;
char * pos;
char * line_start;
char * line_end;
char file_data[257];
uint32_t it = 0 ;
uint32_t nb_params = 9 ;
std::string params[ 9 ];
bool check_sd_card = (sd_card::status() == sd_card::Status::Mounted) ? true : false ;
if( check_sd_card )
{
auto result = settings_file.open( source );
if( !result.is_valid() )
{
while( it < nb_params )
{
// Read a 256 bytes block from file
settings_file.seek(file_position);
memset(file_data, 0, 257);
auto read_size = settings_file.read(file_data, 256);
if (read_size.is_error())
break ;
file_position += 256;
// Reset line_start to beginning of buffer
line_start = file_data;
pos=line_start;
while ((line_end = strstr(line_start, "\x0A"))) {
length = line_end - line_start - 1 ;
params[ it ] = string( pos , length );
it ++ ;
line_start = line_end + 1;
pos=line_start ;
if (line_start - file_data >= 256)
break;
if( it >= nb_params )
break ;
}
if (read_size.value() != 256)
break; // End of file
// Restart at beginning of last incomplete line
file_position -= (file_data + 256 - line_start);
}
}
}
if( it > 0 )
input_file = params[ 0 ];
else
input_file = "RECON" ;
if( it > 1 )
output_file= params[ 1 ];
else
output_file = "RECON_RESULTS" ;
if( it > 2 )
recon_lock_duration = strtoll( params[ 2 ].c_str() , nullptr , 10 );
else
recon_lock_duration = 50 ;
if( it > 3 )
recon_lock_nb_match = strtoll( params[ 3 ].c_str() , nullptr , 10 );
else
recon_lock_nb_match = 10 ;
if( it > 4 )
recon_squelch_level = strtoll( params[ 4 ].c_str() , nullptr , 10 );
else
recon_squelch_level = -14 ;
if( it > 5 )
recon_match_mode = strtoll( params[ 5 ].c_str() , nullptr , 10 );
else
recon_match_mode = 0 ;
if( it > 6 )
wait = strtoll( params[ 6 ].c_str() , nullptr , 10 );
else
wait = 5000 ;
if( it > 7 )
lock_wait = strtoll( params[ 7 ].c_str() , nullptr , 10 );
else
lock_wait = 1000 ;
if( it > 8 )
volume = strtoll( params[ 8 ].c_str() , nullptr , 10 );
else
volume = 40 ;
if( it < nb_params )
{
/* bad number of params, signal defaults */
return false ;
}
return true ;
}
bool ReconSetupSaveStrings( std::string dest, std::string input_file , std::string output_file , uint32_t recon_lock_duration , uint32_t recon_lock_nb_match , int32_t recon_squelch_level , uint32_t recon_match_mode , int32_t wait , uint32_t lock_wait , int32_t volume )
{
File settings_file;
auto result = settings_file.create( dest );
if( result.is_valid() )
return false ;
settings_file.write_line( input_file );
settings_file.write_line( output_file );
settings_file.write_line( to_string_dec_uint( recon_lock_duration ) );
settings_file.write_line( to_string_dec_uint( recon_lock_nb_match ) );
settings_file.write_line( to_string_dec_int( recon_squelch_level ) );
settings_file.write_line( to_string_dec_uint( recon_match_mode ) );
settings_file.write_line( to_string_dec_int( wait ) );
settings_file.write_line( to_string_dec_uint( lock_wait ) );
settings_file.write_line( to_string_dec_int( volume ) );
return true ;
}
ReconSetupViewMain::ReconSetupViewMain( NavigationView &nav , Rect parent_rect , std::string input_file , std::string output_file ) : View( parent_rect ) , _input_file { input_file } , _output_file { output_file }
{
hidden(true);
add_children({
&button_load_freqs,
&text_input_file,
&button_save_freqs,
&button_output_file,
&checkbox_autosave_freqs,
&checkbox_autostart_recon,
&checkbox_continuous,
&checkbox_clear_output
});
checkbox_autosave_freqs.set_value( persistent_memory::recon_autosave_freqs() );
checkbox_autostart_recon.set_value( persistent_memory::recon_autostart_recon() );
checkbox_continuous.set_value( persistent_memory::recon_continuous() );
checkbox_clear_output.set_value( persistent_memory::recon_clear_output() );
text_input_file.set( _input_file );
button_output_file.set_text( _output_file );
button_load_freqs.on_select = [this, &nav](Button&) {
auto open_view = nav.push<FileLoadView>(".TXT");
open_view->on_changed = [this,&nav](std::filesystem::path new_file_path) {
std::string dir_filter = "FREQMAN/";
std::string str_file_path = new_file_path.string();
if (str_file_path.find(dir_filter) != string::npos) { // assert file from the FREQMAN folder
// get the filename without txt extension so we can use load_freqman_file fcn
_input_file = new_file_path.stem().string();
text_input_file.set( _input_file );
} else {
nav.display_modal("LOAD ERROR", "A valid file from\nFREQMAN directory is\nrequired.");
}
};
};
button_save_freqs.on_select = [this, &nav](Button&) {
auto open_view = nav.push<FileLoadView>(".TXT");
open_view->on_changed = [this,&nav](std::filesystem::path new_file_path) {
std::string dir_filter = "FREQMAN/";
std::string str_file_path = new_file_path.string();
if (str_file_path.find(dir_filter) != string::npos) { // assert file from the FREQMAN folder
_output_file = new_file_path.stem().string();
button_output_file.set_text( _output_file );
} else {
nav.display_modal("LOAD ERROR", "A valid file from\nFREQMAN directory is\nrequired.");
}
};
};
button_output_file.on_select =[this, &nav](Button&) {
text_prompt( nav, _output_file , 28 ,
[this](std::string& buffer) {
_output_file = buffer ;
button_output_file.set_text( _output_file );
} );
};
};
void ReconSetupViewMain::Save( std::string &input_file , std::string &output_file ) {
persistent_memory::set_recon_autosave_freqs(checkbox_autosave_freqs.value());
persistent_memory::set_recon_autostart_recon(checkbox_autostart_recon.value());
persistent_memory::set_recon_continuous(checkbox_continuous.value());
persistent_memory::set_recon_clear_output(checkbox_clear_output.value());
input_file=_input_file ;
output_file=_output_file ;
};
void ReconSetupViewMore::Save( uint32_t &recon_lock_duration , uint32_t &recon_lock_nb_match , uint32_t &recon_match_mode ) {
persistent_memory::set_recon_load_freqs(checkbox_load_freqs.value());
persistent_memory::set_recon_load_ranges(checkbox_load_ranges.value());
persistent_memory::set_recon_load_hamradios(checkbox_load_hamradios.value());
persistent_memory::set_recon_update_ranges_when_recon(checkbox_update_ranges_when_recon.value());
recon_lock_duration = field_recon_lock_duration.value();
recon_lock_nb_match = field_recon_lock_nb_match.value();
recon_match_mode = field_recon_match_mode . selected_index_value() ;
};
void ReconSetupViewMain::focus() {
button_load_freqs.focus();
}
ReconSetupViewMore::ReconSetupViewMore( NavigationView &nav , Rect parent_rect , uint32_t recon_lock_duration , uint32_t recon_lock_nb_match , uint32_t recon_match_mode ) : View( parent_rect ), _recon_lock_duration { recon_lock_duration } , _recon_lock_nb_match { recon_lock_nb_match } , _recon_match_mode { recon_match_mode }
{
(void)nav;
hidden(true);
add_children({
&checkbox_load_freqs,
&checkbox_load_ranges,
&checkbox_load_hamradios,
&checkbox_update_ranges_when_recon,
&text_recon_lock_duration,
&field_recon_lock_duration,
&text_recon_lock_nb,
&field_recon_lock_nb_match,
&field_recon_match_mode,
});
checkbox_load_freqs.set_value( persistent_memory::recon_load_freqs() );
checkbox_load_ranges.set_value( persistent_memory::recon_load_ranges() );
checkbox_load_hamradios.set_value( persistent_memory::recon_load_hamradios() );
checkbox_update_ranges_when_recon.set_value( persistent_memory::recon_update_ranges_when_recon() );
field_recon_lock_duration.set_value( _recon_lock_duration );
field_recon_lock_nb_match.set_value( _recon_lock_nb_match );
field_recon_match_mode.set_by_value( _recon_match_mode );
};
void ReconSetupViewMore::focus() {
checkbox_load_freqs.focus();
}
void ReconSetupView::focus() {
viewMain.focus();
}
ReconSetupView::ReconSetupView(
NavigationView& nav , std::string _input_file , std::string _output_file , uint32_t _recon_lock_duration , uint32_t _recon_lock_nb_match , uint32_t _recon_match_mode ) : nav_ { nav } , input_file { _input_file } , output_file { _output_file } , recon_lock_duration { _recon_lock_duration } , recon_lock_nb_match { _recon_lock_nb_match } , recon_match_mode { _recon_match_mode }
{
add_children({
&tab_view,
&viewMain,
&viewMore,
&button_save
});
button_save.on_select = [this,&nav](Button&) {
viewMain.Save( input_file , output_file );
viewMore.Save( recon_lock_duration , recon_lock_nb_match , recon_match_mode );
std::vector<std::string> messages ;
messages.push_back( input_file );
messages.push_back( output_file );
messages.push_back( to_string_dec_uint( recon_lock_duration ) );
messages.push_back( to_string_dec_uint( recon_lock_nb_match ) );
messages.push_back( to_string_dec_uint( recon_match_mode ) );
on_changed( messages );
nav.pop();
};
}
} /* namespace ui */
@@ -0,0 +1,194 @@
/*
* Copyright (C) 2014 Jared Boone, ShareBrained Technology, Inc.
* Copyright (C) 2016 Furrtek
*
* This file is part of PortaPack.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street,
* Boston, MA 02110-1301, USA.
*/
#include "serializer.hpp"
#include "ui.hpp"
#include "ui_widget.hpp"
#include "ui_tabview.hpp"
#include "ui_navigation.hpp"
#include "string_format.hpp"
namespace ui {
bool ReconSetupLoadStrings( std::string source, std::string &input_file , std::string &output_file , uint32_t &recon_lock_duration , uint32_t &recon_lock_nb_match , int32_t &recon_squelch_level , uint32_t &recon_match_mode , int32_t &wait , uint32_t &lock_wait , int32_t &volume );
bool ReconSetupSaveStrings( std::string dest, const std::string input_file , const std::string output_file , const uint32_t recon_lock_duration , const uint32_t recon_lock_nb_match , int32_t recon_squelch_level , uint32_t recon_match_mode , int32_t wait , uint32_t lock_wait , int32_t volume );
class ReconSetupViewMain : public View {
public:
ReconSetupViewMain( NavigationView& nav, Rect parent_rect , std::string input_file , std::string output_file );
void Save( std::string &input_file , std::string &output_file );
void focus() override;
private:
std::string _input_file = { "RECON" };
std::string _output_file = { "RECON_RESULTS" };
Button button_load_freqs {
{ 1 * 8 , 12 , 18 * 8 , 22 },
"select input file"
};
Text text_input_file {
{ 1 * 8 , 4 + 2 * 16, 18 * 8, 22 },
"RECON"
};
Button button_save_freqs {
{ 1 * 8 , 4 * 16 - 8 , 18 * 8 , 22 },
"select output file"
};
Button button_output_file {
{ 1 * 8 , 5 * 16 - 2, 18 * 8, 22 },
"RECON_RESULTS"
};
Checkbox checkbox_autosave_freqs {
{ 1 * 8, 7 * 16 - 4 },
3,
"autosave freqs"
};
Checkbox checkbox_autostart_recon {
{ 1 * 8, 9 * 16 - 4 },
3,
"autostart recon"
};
Checkbox checkbox_continuous {
{ 1 * 8, 11 * 16 - 4 },
3,
"continuous"
};
Checkbox checkbox_clear_output {
{ 1 * 8, 13 * 16 - 4 },
3,
"clear output at start"
};
};
class ReconSetupViewMore : public View {
public:
ReconSetupViewMore( NavigationView& nav, Rect parent_rect , const uint32_t _recon_lock_duration , const uint32_t _recon_lock_nb_match , const uint32_t _recon_match_mode );
void Save( uint32_t &recon_lock_duration , uint32_t &recon_lock_nb_match , uint32_t &recon_match_mode );
void focus() override;
private:
const uint32_t _recon_lock_duration = 50 ;
const uint32_t _recon_lock_nb_match = 10 ;
const uint32_t _recon_match_mode = 0 ;
Checkbox checkbox_load_freqs {
{ 1 * 8, 12 },
3,
"input: load freqs"
};
Checkbox checkbox_load_ranges {
{ 1 * 8, 42 },
3,
"input: load ranges"
};
Checkbox checkbox_load_hamradios {
{ 1 * 8, 72 },
3,
"input: load hamradios"
};
Checkbox checkbox_update_ranges_when_recon {
{ 1 * 8, 102 },
3,
"auto update m-ranges"
};
Text text_recon_lock_duration {
{ 1 * 8 , 132 , 22 * 8 , 22 },
" ms (lock duration)"
};
NumberField field_recon_lock_duration {
{ 1 * 8, 132 }, // position X , Y
4, // number of displayed digits (even empty)
{ 50 , 990 }, // range of number
10, // rotary encoder increment
' ', // filling character
false // can loop
};
Text text_recon_lock_nb {
{ 1 * 8 , 162 , 25 * 8 , 22 },
" x (nb lock to match freq)"
};
NumberField field_recon_lock_nb_match {
{ 1 * 8, 162 },
4,
{ 1, 99 },
1,
' ',
false
};
OptionsField field_recon_match_mode {
{ 1 * 8, 192 },
20, // CONTINUOUS MATCH MODE / SPARSE TIMED MATCH MODE
{
{ "SQL MATCH: CONTINOUS" , 0 },
{ "SQL MATCH: SPARSE" , 1 }
}
};
};
class ReconSetupView : public View {
public:
ReconSetupView( NavigationView& nav , std::string _input_file , std::string _output_file , const uint32_t _recon_lock_duration , const uint32_t _recon_lock_nb_match , const uint32_t _recon_match_mode );
std::function<void( std::vector<std::string> messages )> on_changed { };
void focus() override;
std::string title() const override { return "Recon setup"; };
private:
NavigationView& nav_ ;
std::string input_file = { "RECON" };
std::string output_file = { "RECON_RESULTS" };
uint32_t recon_lock_duration = 50 ;
uint32_t recon_lock_nb_match = 10 ;
uint32_t recon_match_mode = 0 ;
Rect view_rect = { 0, 3 * 8, 240, 230 };
ReconSetupViewMain viewMain{ nav_ , view_rect , input_file , output_file };
ReconSetupViewMore viewMore{ nav_ , view_rect , recon_lock_duration , recon_lock_nb_match , recon_match_mode };
TabView tab_view {
{ "Main", Color::cyan() , &viewMain },
{ "More", Color::green(), &viewMore }
};
Button button_save {
{ 9 * 8, 255, 14 * 8 , 40 },
"SAVE"
};
};
} /* namespace ui */
+5 -5
View File
@@ -160,9 +160,9 @@ ScannerView::~ScannerView() {
}
void ScannerView::show_max() { //show total number of freqs to scan
if (frequency_list.size() == MAX_DB_ENTRY) {
if (frequency_list.size() == FREQMAN_MAX_PER_FILE ) {
text_max.set_style(&style_red);
text_max.set( "/ " + to_string_dec_uint(MAX_DB_ENTRY) + " (DB MAX!)");
text_max.set( "/ " + to_string_dec_uint(FREQMAN_MAX_PER_FILE ) + " (DB MAX!)");
}
else {
text_max.set_style(&style_grey);
@@ -304,7 +304,7 @@ ScannerView::ScannerView(
);
rf::Frequency frequency = frequency_range.min;
while (frequency_list.size() < MAX_DB_ENTRY && frequency <= frequency_range.max) { //add manual range
while (frequency_list.size() < FREQMAN_MAX_PER_FILE && frequency <= frequency_range.max) { //add manual range
frequency_list.push_back(frequency);
description_list.push_back(""); //If empty, will keep showing the last description
frequency+=def_step;
@@ -398,7 +398,7 @@ void ScannerView::frequency_file_load(std::string file_name, bool stop_all_befor
if ( load_freqman_file(file_name, database) ) {
loaded_file_name = file_name; // keep loaded filename in memory
for(auto& entry : database) { // READ LINE PER LINE
if (frequency_list.size() < MAX_DB_ENTRY) { //We got space!
if (frequency_list.size() < FREQMAN_MAX_PER_FILE ) { //We got space!
if (entry.type == RANGE) { //RANGE
switch (entry.step) {
case AM_US: def_step = 10000; break ;
@@ -421,7 +421,7 @@ void ScannerView::frequency_file_load(std::string file_name, bool stop_all_befor
+ ">" + to_string_short_freq(entry.frequency_b)
+ " S" + to_string_short_freq(def_step).erase(0,1) //euquiq: lame kludge to reduce spacing in step freq
);
while (frequency_list.size() < MAX_DB_ENTRY && entry.frequency_a <= entry.frequency_b) { //add the rest of the range
while (frequency_list.size() < FREQMAN_MAX_PER_FILE && entry.frequency_a <= entry.frequency_b) { //add the rest of the range
entry.frequency_a+=def_step;
frequency_list.push_back(entry.frequency_a);
description_list.push_back(""); //Token (keep showing the last description)
-1
View File
@@ -34,7 +34,6 @@
#include "file.hpp"
#define MAX_DB_ENTRY 500
#define MAX_FREQ_LOCK 10 //50ms cycles scanner locks into freq when signal detected, to verify signal is not spureous
namespace ui {
+3 -1
View File
@@ -25,6 +25,7 @@
#include "portapack.hpp"
#include "hackrf_hal.hpp"
#include "cpld_update.hpp"
#include <cstring>
#include <stdio.h>
@@ -93,7 +94,8 @@ SSTVTXView::~SSTVTXView() {
settings.save("tx_sstv", &app_settings);
transmitter_model.disable();
baseband::shutdown();
hackrf::cpld::load_sram_no_verify(); // to leave all RX ok, without ghost signal problem at the exit.
baseband::shutdown(); // better this function at the end, not load_sram() that sometimes produces hang up.
}
void SSTVTXView::on_tuning_frequency_changed(rf::Frequency f) {
+3 -1
View File
@@ -26,6 +26,7 @@
#include "baseband_api.hpp"
#include "string_format.hpp"
#include "cpld_update.hpp"
using namespace portapack;
@@ -39,7 +40,8 @@ void TouchTunesView::focus() {
TouchTunesView::~TouchTunesView() {
transmitter_model.disable();
baseband::shutdown();
hackrf::cpld::load_sram_no_verify(); // to leave all RX ok, without ghost signal problem at the exit.
baseband::shutdown(); // better this function at the end, not load_sram() that sometimes produces hang up.
}
void TouchTunesView::stop_tx() {
+2 -2
View File
@@ -168,8 +168,8 @@ void speaker_mute() {
namespace input {
void start() {
audio_codec->microphone_enable();
void start(int8_t alc_mode) {
audio_codec->microphone_enable(alc_mode); // added user-GUI selection for AK4951, ALC mode parameter.
i2s::i2s0::rx_start();
}
+3 -3
View File
@@ -49,7 +49,7 @@ public:
virtual volume_range_t headphone_gain_range() const = 0;
virtual void set_headphone_volume(const volume_t volume) = 0;
virtual void microphone_enable() = 0;
virtual void microphone_enable(int8_t alc_mode) = 0; // added user-GUI AK4951 ,selected ALC mode.
virtual void microphone_disable() = 0;
virtual size_t reg_count() const = 0;
@@ -59,7 +59,7 @@ public:
namespace output {
void start();
void start(); // this other start(),no changed. ,in namespace output , used to config audio playback mode,
void stop();
void mute();
@@ -72,7 +72,7 @@ void speaker_unmute();
namespace input {
void start();
void start(int8_t alc_mode); // added parameter user-GUI select AK4951-ALC mode for config mic path,(recording mode in datasheet),
void stop();
} /* namespace input */
+3 -2
View File
@@ -183,12 +183,13 @@ void kill_afsk() {
}
void set_audiotx_config(const uint32_t divider, const float deviation_hz, const float audio_gain,
const uint32_t tone_key_delta, const bool am_enabled, const bool dsb_enabled,
const bool usb_enabled, const bool lsb_enabled) {
uint8_t audio_shift_bits_s16, const uint32_t tone_key_delta, const bool am_enabled,
const bool dsb_enabled, const bool usb_enabled, const bool lsb_enabled) {
const AudioTXConfigMessage message {
divider,
deviation_hz,
audio_gain,
audio_shift_bits_s16,
tone_key_delta,
(float)persistent_memory::tone_mix() / 100.0f,
am_enabled,
+2 -2
View File
@@ -61,8 +61,8 @@ void set_tones_config(const uint32_t bw, const uint32_t pre_silence, const uint1
void kill_tone();
void set_sstv_data(const uint8_t vis_code, const uint32_t pixel_duration);
void set_audiotx_config(const uint32_t divider, const float deviation_hz, const float audio_gain,
const uint32_t tone_key_delta, const bool am_enabled, const bool dsb_enabled,
const bool usb_enabled, const bool lsb_enabled);
uint8_t audio_shift_bits_s16, const uint32_t tone_key_delta, const bool am_enabled,
const bool dsb_enabled, const bool usb_enabled, const bool lsb_enabled);
void set_fifo_data(const int8_t * data);
void set_pitch_rssi(int32_t avg, bool enabled);
void set_afsk_data(const uint32_t afsk_samples_per_bit, const uint32_t afsk_phase_inc_mark, const uint32_t afsk_phase_inc_space,
+473 -148
View File
@@ -23,166 +23,491 @@
#include "freqman.hpp"
#include <algorithm>
using option_t = std::pair<std::string, int32_t>;
using options_t = std::vector<option_t>;
options_t freqman_entry_modulations = {
{ "AM", 0 },
{ "NFM", 1 },
{ "WFM", 2 }
};
options_t freqman_entry_bandwidths[ 4 ] = {
{ //AM
{ "DSB", 0 },
{ "USB", 1 },
{ "LSB", 2 },
{ "CW" , 3 }
},
{ //NFM
{ "8k5" , 0 },
{ "11k" , 1 },
{ "16k" , 2 }
},
{ //WFM
{ "16k" , 0 },
}
};
options_t freqman_entry_steps = {
{ "5KHz (SA AM)" , 5000 },
{ "6.25KHz(NFM)" , 6250 },
{ "8.33KHz(AIR)" , 8330 },
{ "9KHz (EU AM)" , 9000 },
{ "10KHz(US AM)" , 10000 },
{ "12.5KHz(NFM)" , 12500 },
{ "15KHz (HFM)" , 15000 },
{ "25KHz (N1)" , 25000 },
{ "30KHz (OIRT)" , 30000 },
{ "50KHz (FM1)" , 50000 },
{ "100KHz (FM2)" , 100000 },
{ "250KHz (N2)" , 250000 },
{ "500KHz " , 500000 },
{ "1MHz " , 1000000 }
};
options_t freqman_entry_steps_short = {
{ "5KHz" , 5000 },
{ "6.25KHz" , 6250 },
{ "8.33KHz" , 8330 },
{ "9KHz" , 9000 },
{ "10KHz" , 10000 },
{ "12.5KHz" , 12500 },
{ "15KHz" , 15000 },
{ "25KHz" , 25000 },
{ "30KHz" , 30000 },
{ "50KHz" , 50000 },
{ "100KHz" , 100000 },
{ "250KHz" , 250000 },
{ "500KHz" , 500000 },
{ "1MHz" , 1000000 }
};
std::vector<std::string> get_freqman_files() {
std::vector<std::string> file_list;
auto files = scan_root_files(u"FREQMAN", u"*.TXT");
for (auto file : files) {
std::string file_name = file.stem().string();
// don't propose tmp / hidden files in freqman's list
if (file_name.length() && file_name[0] != '.') {
file_list.emplace_back(file_name);
}
}
return file_list;
std::vector<std::string> file_list;
auto files = scan_root_files(u"FREQMAN", u"*.TXT");
for (auto file : files) {
std::string file_name = file.stem().string();
// don't propose tmp / hidden files in freqman's list
if (file_name.length() && file_name[0] != '.') {
file_list.emplace_back(file_name);
}
}
return file_list;
};
bool load_freqman_file(std::string& file_stem, freqman_db &db) {
File freqman_file;
size_t length, n = 0, file_position = 0;
char * pos;
char * line_start;
char * line_end;
std::string description;
rf::Frequency frequency_a, frequency_b;
char file_data[257];
freqman_entry_type type;
db.clear();
auto result = freqman_file.open("FREQMAN/" + file_stem + ".TXT");
if (result.is_valid())
return false;
while (1) {
// Read a 256 bytes block from file
freqman_file.seek(file_position);
memset(file_data, 0, 257);
auto read_size = freqman_file.read(file_data, 256);
if (read_size.is_error())
return false; // Read error
file_position += 256;
// Reset line_start to beginning of buffer
line_start = file_data;
if (!strstr(file_data, "f=") && !strstr(file_data, "a="))
break;
// Look for complete lines in buffer
while ((line_end = strstr(line_start, "\x0A"))) {
// Read frequency
pos = strstr(line_start, "f=");
frequency_b = 0;
type = SINGLE;
if (pos) {
pos += 2;
frequency_a = strtoll(pos, nullptr, 10);
} else {
// ...or range
pos = strstr(line_start, "a=");
if (pos) {
pos += 2;
frequency_a = strtoll(pos, nullptr, 10);
type = RANGE;
pos = strstr(line_start, "b=");
if (pos) {
pos += 2;
frequency_b = strtoll(pos, nullptr, 10);
} else
frequency_b = 0;
} else
frequency_a = 0;
}
// Read description until , or LF
pos = strstr(line_start, "d=");
if (pos) {
pos += 2;
length = std::min(strcspn(pos, ",\x0A"), (size_t)FREQMAN_DESC_MAX_LEN);
description = string(pos, length);
} else
description = "-";
db.push_back({ frequency_a, frequency_b, description, type });
n++;
if (n >= FREQMAN_MAX_PER_FILE) return true;
line_start = line_end + 1;
if (line_start - file_data >= 256) break;
}
if (read_size.value() != 256)
break; // End of file
// Restart at beginning of last incomplete line
file_position -= (file_data + 256 - line_start);
}
return true;
return load_freqman_file_ex( file_stem , db , true , true , true );
}
bool save_freqman_file(std::string& file_stem, freqman_db &db) {
File freqman_file;
std::string item_string;
rf::Frequency frequency_a, frequency_b;
if (!create_freqman_file(file_stem, freqman_file))
return false;
for (size_t n = 0; n < db.size(); n++) {
auto& entry = db[n];
bool load_freqman_file_ex(std::string& file_stem, freqman_db& db, bool load_freqs , bool load_ranges , bool load_hamradios ) {
File freqman_file;
size_t length, n = 0, file_position = 0;
char * pos;
char * line_start;
char * line_end;
std::string description;
rf::Frequency frequency_a, frequency_b;
char file_data[257];
freqman_entry_type type;
freqman_index_t modulation = 0 ;
freqman_index_t bandwidth = 0 ;
freqman_index_t step = 0 ;
freqman_index_t tone = 0 ;
frequency_a = entry.frequency_a;
if (entry.type == SINGLE) {
// Single
// TODO: Make to_string_dec_uint be able to return uint64_t's
// Please forgive me...
item_string = "f=" + to_string_dec_uint(frequency_a / 1000) + to_string_dec_uint(frequency_a % 1000UL, 3, '0');
} else {
// Range
frequency_b = entry.frequency_b;
item_string = "a=" + to_string_dec_uint(frequency_a / 1000) + to_string_dec_uint(frequency_a % 1000UL, 3, '0');
item_string += ",b=" + to_string_dec_uint(frequency_b / 1000) + to_string_dec_uint(frequency_b % 1000UL, 3, '0');
}
if (entry.description.size())
item_string += ",d=" + entry.description;
freqman_file.write_line(item_string);
}
return true;
db.clear();
auto result = freqman_file.open("FREQMAN/" + file_stem + ".TXT");
if (result.is_valid())
return false;
while (1) {
// Read a 256 bytes block from file
freqman_file.seek(file_position);
memset(file_data, 0, 257);
auto read_size = freqman_file.read(file_data, 256);
if (read_size.is_error())
return false; // Read error
file_position += 256;
// Reset line_start to beginning of buffer
line_start = file_data;
if (!strstr(file_data, "f=") && !strstr(file_data, "a=") && !strstr(file_data, "r=") )
break;
// Look for complete lines in buffer
while ((line_end = strstr(line_start, "\x0A"))) {
modulation = -1 ;
bandwidth = -1 ;
step = -1 ;
tone = -1 ;
type=SINGLE ;
frequency_a = frequency_b = 0;
// Read frequency
pos = strstr(line_start, "f=");
if(pos) {
pos += 2;
frequency_a = strtoll(pos, nullptr, 10);
} else {
// ...or range
pos = strstr(line_start, "a=");
if (pos) {
pos += 2;
frequency_a = strtoll(pos, nullptr, 10);
type = RANGE;
pos = strstr(line_start, "b=");
if (pos) {
pos += 2;
frequency_b = strtoll(pos, nullptr, 10);
} else
frequency_b = 0;
}else {
// ... or hamradio
pos = strstr(line_start, "r=");
if (pos) {
pos += 2;
frequency_a = strtoll(pos, nullptr, 10);
type = HAMRADIO;
pos = strstr(line_start, "t=");
if (pos) {
pos += 2;
frequency_b = strtoll(pos, nullptr, 10);
} else
frequency_b = frequency_a ;
} else
frequency_a = 0;
}
}
// modulation if any
pos = strstr(line_start, "m=");
if (pos) {
pos += 2;
modulation = freqman_entry_get_modulation_from_str( pos );
}
// bandwidth if any
pos = strstr(line_start, "bw=");
if (pos) {
pos += 3;
bandwidth = freqman_entry_get_bandwidth_from_str( modulation , pos );
}
// step if any
pos = strstr(line_start, "s=");
if (pos) {
pos += 2;
step = freqman_entry_get_step_from_str_short( pos );
}
// ctcss tone if any
/* disabled until better form
pos = strstr(line_start, "c=");
if (pos) {
pos += 2;
tone = tone_key_index_by_value( strtoll( pos , nullptr , 10 ) );
} */
// Read description until , or LF
pos = strstr(line_start, "d=");
if (pos) {
pos += 2;
length = std::min(strcspn(pos, ",\x0A"), (size_t)FREQMAN_DESC_MAX_LEN);
description = string(pos, length);
} else
description = "-";
if( (type == SINGLE && load_freqs) || (type == RANGE && load_ranges) || (type == HAMRADIO && load_hamradios) )
{
db.push_back({ frequency_a, frequency_b, description, type , modulation , bandwidth , step , tone });
n++;
if (n >= FREQMAN_MAX_PER_FILE) return true;
}
line_start = line_end + 1;
if (line_start - file_data >= 256) break;
}
if (read_size.value() != 256)
break; // End of file
// Restart at beginning of last incomplete line
file_position -= (file_data + 256 - line_start);
}
/* populate implicitly specified modulation / bandwidth */
if( db.size() > 2 )
{
modulation = db[ 0 ] . modulation;
bandwidth = db[ 0 ] . bandwidth;
for( unsigned int it = 1 ; it < db.size() ; it ++ )
{
if( db[ it ] . modulation < 0 )
{
db[ it ] . modulation = modulation ;
}
else
{
modulation = db[ it ] . modulation ;
}
if( db[ it ] . bandwidth < 0 )
{
db[ it ] . bandwidth = bandwidth ;
}
else
{
modulation = db[ it ] . bandwidth ;
}
}
}
return true;
}
bool get_freq_string( freqman_entry &entry , std::string &item_string )
{
rf::Frequency frequency_a, frequency_b;
frequency_a = entry.frequency_a;
if (entry.type == SINGLE) {
// Single
item_string = "f=" + to_string_dec_uint(frequency_a / 1000) + to_string_dec_uint(frequency_a % 1000UL, 3, '0');
} else if( entry.type == RANGE ) {
// Range
frequency_b = entry.frequency_b;
item_string = "a=" + to_string_dec_uint(frequency_a / 1000) + to_string_dec_uint(frequency_a % 1000UL, 3, '0');
item_string += ",b=" + to_string_dec_uint(frequency_b / 1000) + to_string_dec_uint(frequency_b % 1000UL, 3, '0');
if( entry.step >= 0 )
{
item_string += ",s=" + freqman_entry_get_step_string_short( entry.step );
}
} else if( entry.type == HAMRADIO ) {
frequency_b = entry.frequency_b;
item_string = "r=" + to_string_dec_uint(frequency_a / 1000) + to_string_dec_uint(frequency_a % 1000UL, 3, '0');
item_string += ",t=" + to_string_dec_uint(frequency_b / 1000) + to_string_dec_uint(frequency_b % 1000UL, 3, '0');
if( entry.tone >= 0 )
{
item_string += ",c=" + tone_key_string( entry.tone );
}
}
if( entry.modulation >= 0 && (unsigned)entry.modulation < freqman_entry_modulations . size() )
{
item_string += ",m=" + freqman_entry_get_modulation_string( entry.modulation );
if( entry.bandwidth >= 0 && (unsigned)entry.bandwidth < freqman_entry_bandwidths[ entry.modulation ] . size() )
{
item_string += ",bw=" + freqman_entry_get_bandwidth_string( entry.modulation , entry.bandwidth );
}
}
if (entry.description.size())
item_string += ",d=" + entry.description;
return true ;
}
bool save_freqman_file(std::string &file_stem, freqman_db &db) {
File freqman_file;
std::string freq_file_path = "FREQMAN/" + file_stem + ".TXT";
std::string tmp_freq_file_path = "FREQMAN/" + file_stem + ".TXT.TMP";
if( !db.size() )
{
delete_file( "FREQMAN/"+file_stem+".TXT" );
return true ;
}
delete_file( tmp_freq_file_path );
auto result = freqman_file.open( tmp_freq_file_path );
if ( !result.is_valid() ) {
for (size_t n = 0; n < db.size(); n++) {
std::string item_string;
auto& entry = db[n];
get_freq_string( entry , item_string );
freqman_file.write_line( item_string );
delete &item_string;
}
delete_file( freq_file_path );
rename_file( tmp_freq_file_path , freq_file_path );
return true;
}
return false ;
}
bool create_freqman_file(std::string& file_stem, File& freqman_file) {
auto result = freqman_file.create("FREQMAN/" + file_stem + ".TXT");
if (result.is_valid())
return false;
return true;
auto result = freqman_file.create( "FREQMAN/" + file_stem + ".TXT" );
if (result.is_valid())
return false;
return true;
}
std::string freqman_item_string(freqman_entry &entry, size_t max_length) {
std::string item_string;
std::string item_string;
if (entry.type == SINGLE) {
item_string = to_string_short_freq(entry.frequency_a) + "M: " + entry.description;
} else {
item_string = "Range: " + entry.description;
}
if (item_string.size() > max_length)
return item_string.substr(0, max_length - 3) + "...";
return item_string;
switch( entry.type ){
case SINGLE:
item_string = to_string_short_freq(entry.frequency_a) + "M: " + entry.description;
break;
case RANGE:
item_string = "R: " + entry.description;
break;
case HAMRADIO:
item_string = "H: " + entry.description;
break;
default:
item_string = "!UNKNOW TYPE " + entry.description;
break;
}
if (item_string.size() > max_length)
return item_string.substr(0, max_length - 3) + "...";
return item_string;
}
void freqman_set_modulation_option( OptionsField &option )
{
option.set_options( freqman_entry_modulations );
}
void freqman_set_bandwidth_option( freqman_index_t modulation , OptionsField &option )
{
option.set_options( freqman_entry_bandwidths[ modulation ] );
}
void freqman_set_step_option( OptionsField &option )
{
option.set_options( freqman_entry_steps );
}
void freqman_set_step_option_short( OptionsField &option )
{
option.set_options( freqman_entry_steps_short );
}
std::string freqman_entry_get_modulation_string( freqman_index_t modulation )
{
if( modulation < 0 || (unsigned)modulation >= freqman_entry_modulations . size() )
{
return std::string( "" ); // unknown modulation
}
return freqman_entry_modulations[ modulation ] . first ;
}
std::string freqman_entry_get_bandwidth_string( freqman_index_t modulation , freqman_index_t bandwidth )
{
if( modulation < 0 || (unsigned)modulation >= freqman_entry_modulations . size() )
{
return std::string( "" ); // unknown modulation
}
if( bandwidth < 0 || (unsigned)bandwidth > freqman_entry_bandwidths[ modulation ] . size() )
{
return std::string( "" ); // unknown modulation
}
return freqman_entry_bandwidths[ modulation ][ bandwidth ] . first ;
}
std::string freqman_entry_get_step_string( freqman_index_t step )
{
if( step < 0 || (unsigned)step >= freqman_entry_steps . size() )
{
return std::string( "" ); // unknown modulation
}
return freqman_entry_steps[ step ] . first ;
}
std::string freqman_entry_get_step_string_short( freqman_index_t step )
{
if( step < 0 || (unsigned)step >= freqman_entry_steps_short . size() )
{
return std::string( "" ); // unknown modulation
}
return freqman_entry_steps_short[ step ] . first ;
}
int32_t freqman_entry_get_modulation_value( freqman_index_t modulation )
{
if( modulation < 0 || (unsigned)modulation >= freqman_entry_modulations . size() )
{
return -1 ; // unknown modulation
}
return freqman_entry_modulations[ modulation ] . second ;
}
int32_t freqman_entry_get_bandwidth_value( freqman_index_t modulation , freqman_index_t bandwidth )
{
if( modulation < 0 || (unsigned)modulation >= freqman_entry_modulations . size() )
{
return -1 ; // unknown modulation
}
if( bandwidth < 0 || (unsigned)bandwidth > freqman_entry_bandwidths[ modulation ] . size() )
{
return -1 ; // unknown bandwidth for modulation
}
return freqman_entry_bandwidths[ modulation ][ bandwidth ] . second ;
}
int32_t freqman_entry_get_step_value( freqman_index_t step )
{
if( step < 0 || (unsigned)step >= freqman_entry_steps . size() )
{
return -1 ; // unknown modulation
}
return freqman_entry_steps[ step ] . second ;
}
freqman_index_t freqman_entry_get_modulation_from_str( char *str )
{
if( !str )
return -1 ;
for( freqman_index_t index = 0 ; (unsigned)index < freqman_entry_modulations . size() ; index ++ )
{
if( strncmp( freqman_entry_modulations[ index ] . first . c_str() , str , freqman_entry_modulations[ index ] . first . size() ) == 0 )
return index ;
}
return -1 ;
}
freqman_index_t freqman_entry_get_bandwidth_from_str( freqman_index_t modulation , char *str )
{
if( !str )
return -1 ;
if( modulation < 0 || (unsigned)modulation >= freqman_entry_modulations . size() )
return -1 ;
for( freqman_index_t index = 0 ; (unsigned)index < freqman_entry_bandwidths[ modulation ] . size() ; index ++ )
{
if( strncmp( freqman_entry_bandwidths[ modulation ][ index ] . first . c_str() , str , freqman_entry_bandwidths[ modulation ][ index ] . first . size() ) == 0 )
return index ;
}
return -1 ;
}
freqman_index_t freqman_entry_get_step_from_str( char *str )
{
if( !str )
return -1 ;
for( freqman_index_t index = 0 ; (unsigned)index < freqman_entry_steps . size() ; index ++ )
{
if( strncmp( freqman_entry_steps[ index ] . first . c_str() , str , freqman_entry_steps[ index ] . first . size() ) == 0 )
return index ;
}
return -1 ;
}
freqman_index_t freqman_entry_get_step_from_str_short( char *str )
{
if( !str )
return -1 ;
for( freqman_index_t index = 0 ; (unsigned)index < freqman_entry_steps_short . size() ; index ++ )
{
if( strncmp( freqman_entry_steps_short[ index ] . first . c_str() , str , freqman_entry_steps_short[ index ] . first . size() ) == 0 )
return index ;
}
return -1 ;
}
+55 -14
View File
@@ -20,21 +20,27 @@
* Boston, MA 02110-1301, USA.
*/
#ifndef __FREQMAN_H__
#define __FREQMAN_H__
#include <cstring>
#include <string>
#include "file.hpp"
#include "ui_receiver.hpp"
#include "tone_key.hpp"
#include "string_format.hpp"
#ifndef __FREQMAN_H__
#define __FREQMAN_H__
#include "ui_widget.hpp"
#define FREQMAN_DESC_MAX_LEN 30
#define FREQMAN_MAX_PER_FILE 99
#define FREQMAN_MAX_PER_FILE_STR "99"
#define FREQMAN_MAX_PER_FILE 500 /* MAX PER FILES */
#define FREQMAN_MAX_PER_FILE_STR "500" /*STRING OF FREQMAN_MAX_PER_FILE */
using namespace ui;
using namespace std;
using namespace tonekey;
// needs to be signed as -1 means not set
typedef int8_t freqman_index_t ;
enum freqman_error {
NO_ERROR = 0,
@@ -44,13 +50,23 @@ enum freqman_error {
};
enum freqman_entry_type {
SINGLE = 0,
RANGE
SINGLE = 0, //f=
RANGE, //a=,b=
HAMRADIO, //r=,t=
ERROR_TYPE
};
enum freqman_entry_modulation {
AM_MODULATION = 0 ,
NFM_MODULATION ,
WFM_MODULATION ,
MODULATION_DEF ,
ERROR_MODULATION
};
//Entry step placed for AlainD freqman version (or any other enhanced version)
enum freqman_entry_step {
STEP_DEF = 0, // default
STEP_DEF = -1, // default
AM_US, // 10 kHz AM/CB
AM_EUR, // 9 kHz LW/MW
NFM_1, // 12,5 kHz (Analogic PMR 446)
@@ -63,21 +79,46 @@ enum freqman_entry_step {
ERROR_STEP
};
// freqman_entry_step step added, as above, to provide compatibility / future enhancement.
struct freqman_entry {
rf::Frequency frequency_a { 0 };
rf::Frequency frequency_b { 0 };
std::string description { };
freqman_entry_type type { };
freqman_entry_step step { };
rf::Frequency frequency_a { 0 }; // 'f=freq' or 'a=freq_start' or 'r=recv_freq'
rf::Frequency frequency_b { 0 }; // 'b=freq_end' or 't=tx_freq'
std::string description { }; // 'd=desc'
freqman_entry_type type { }; // SINGLE,RANGE,HAMRADIO
freqman_index_t modulation { }; // AM,NFM,WFM
freqman_index_t bandwidth { }; // AM_DSB, ...
freqman_index_t step { }; // 5Khz (SA AM,...
tone_index tone { }; // 0XZ, 11 1ZB,...
};
using freqman_db = std::vector<freqman_entry>;
std::vector<std::string> get_freqman_files();
bool load_freqman_file(std::string& file_stem, freqman_db& db);
bool load_freqman_file_ex(std::string& file_stem, freqman_db& db, bool load_freqs , bool load_ranges , bool load_hamradios );
bool get_freq_string( freqman_entry &entry , std::string &item_string );
bool save_freqman_file(std::string& file_stem, freqman_db& db);
bool create_freqman_file(std::string& file_stem, File& freqman_file);
std::string freqman_item_string(freqman_entry &item, size_t max_length);
void freqman_set_bandwidth_option( freqman_index_t modulation , OptionsField &option );
void freqman_set_modulation_option( OptionsField &option );
void freqman_set_step_option( OptionsField &option );
void freqman_set_step_option_short( OptionsField &option );
void freqman_set_tone_option( OptionsField &option );
std::string freqman_entry_get_modulation_string( freqman_index_t modulation );
std::string freqman_entry_get_bandwidth_string( freqman_index_t modulation , freqman_index_t bandwidth );
std::string freqman_entry_get_step_string( freqman_index_t step );
std::string freqman_entry_get_step_string_short( freqman_index_t step );
int32_t freqman_entry_get_modulation_value( freqman_index_t modulation );
int32_t freqman_entry_get_bandwidth_value( freqman_index_t modulation , freqman_index_t bandwidth );
int32_t freqman_entry_get_step_value( freqman_index_t step );
freqman_index_t freqman_entry_get_modulation_from_str( char *str );
freqman_index_t freqman_entry_get_bandwidth_from_str( freqman_index_t modulation , char *str );
freqman_index_t freqman_entry_get_step_from_str( char *str );
freqman_index_t freqman_entry_get_step_from_str_short( char *str );
#endif/*__FREQMAN_H__*/
+23 -1
View File
@@ -104,8 +104,30 @@ void tone_keys_populate(OptionsField& field) {
field.set_options(tone_key_options);
}
float tone_key_frequency(const uint32_t index) {
float tone_key_frequency(const tone_index index) {
return tone_keys[index].second;
}
std::string tone_key_string( tone_index index ) {
if( index < 0 || (unsigned)index >= tone_keys . size() )
return std::string( "" );
return tone_keys[ index ] .first ;
}
tone_index tone_key_index_by_string( char *str ) {
if( !str )
return -1 ;
for( tone_index index = 0 ; (unsigned)index < tone_keys . size() ; index ++ )
{
if( tone_keys[ index ] . first . compare( str ) >= 0 )
return index ;
}
return -1 ;
}
/* tone_index tone_key_index_by_value( int32_t freq )
{
return -1 ;
} */
}
+7 -1
View File
@@ -30,12 +30,18 @@ using namespace ui;
namespace tonekey {
typedef int16_t tone_index ;
using tone_key_t = std::vector<std::pair<std::string, float>>;
extern const tone_key_t tone_keys;
void tone_keys_populate(OptionsField& field);
float tone_key_frequency(const uint32_t index);
float tone_key_frequency(const tone_index index);
std::string tone_key_string( const tone_index index );
tone_index tone_key_index_by_string( char *str );
// tone_index tone_key_index_by_value( int32_t freq );
}
+2
View File
@@ -247,6 +247,8 @@ public:
parent_pos,
5,
{
{ " 10", 10 }, /* Fine tuning SSB voice pitch,in HF and QO-100 sat #669 */
{ " 50", 50 }, /* added 50Hz/10Hz,but we do not increase GUI digit decimal */
{ " 100", 100 },
{ " 1k ", 1000 },
{ " 3k ", 3000 }, /* Approximate SSB bandwidth */
+15
View File
@@ -80,6 +80,21 @@ void RSSI::paint(Painter& painter) {
}
}
int32_t RSSI::get_min()
{
return min_ ;
}
int32_t RSSI::get_avg()
{
return avg_ ;
}
int32_t RSSI::get_max()
{
return max_ ;
}
void RSSI::set_pitch_rssi(bool enabled) {
pitch_rssi_enabled = enabled;
if (!enabled) baseband::set_pitch_rssi(0, false);
+3
View File
@@ -46,6 +46,9 @@ public:
}
void paint(Painter& painter) override;
int32_t get_min();
int32_t get_avg();
int32_t get_max();
private:
int32_t min_;
+8 -2
View File
@@ -57,6 +57,7 @@
#include "ui_remote.hpp"
#include "ui_scanner.hpp"
#include "ui_search.hpp"
#include "ui_recon.hpp"
#include "ui_sd_wipe.hpp"
#include "ui_settings.hpp"
#include "ui_siggen.hpp"
@@ -65,6 +66,7 @@
//#include "ui_test.hpp"
#include "ui_tone_search.hpp"
#include "ui_touchtunes.hpp"
#include "ui_playlist.hpp"
#include "ui_view_wav.hpp"
#include "ui_whipcalc.hpp"
@@ -481,6 +483,7 @@ ReceiversMenuView::ReceiversMenuView(NavigationView& nav) {
{ "POCSAG", ui::Color::green(), &bitmap_icon_pocsag, [&nav](){ nav.push<POCSAGAppView>(); } },
{ "Radiosnde", ui::Color::green(), &bitmap_icon_sonde, [&nav](){ nav.push<SondeView>(); } },
{ "TPMS Cars", ui::Color::green(), &bitmap_icon_tpms, [&nav](){ nav.push<TPMSAppView>(); } },
{ "Recon", ui::Color::green(), &bitmap_icon_scanner, [&nav](){ nav.push<ReconView>(); } },
{ "APRS", ui::Color::green(), &bitmap_icon_aprs, [&nav](){ nav.push<APRSRXView>(); } }
/*
{ "DMR", ui::Color::dark_grey(), &bitmap_icon_dmr, [&nav](){ nav.push<NotImplementedView>(); } },
@@ -518,6 +521,8 @@ TransmittersMenuView::TransmittersMenuView(NavigationView& nav) {
{ "SSTV", ui::Color::green(), &bitmap_icon_sstv, [&nav](){ nav.push<SSTVTXView>(); } },
{ "TEDI/LCR", ui::Color::yellow(), &bitmap_icon_lcr, [&nav](){ nav.push<LCRView>(); } },
{ "TouchTune", ui::Color::yellow(), &bitmap_icon_remote, [&nav](){ nav.push<TouchTunesView>(); } },
{ "Playlist", ui::Color::yellow(), &bitmap_icon_remote, [&nav](){ nav.push<PlaylistView>(); } },
//{ "Remote", ui::Color::dark_grey(), &bitmap_icon_remote, [&nav](){ nav.push<RemoteView>(); } },
});
}
@@ -536,9 +541,10 @@ UtilitiesMenuView::UtilitiesMenuView(NavigationView& nav) {
//{ "Notepad", ui::Color::dark_grey(), &bitmap_icon_notepad, [&nav](){ nav.push<NotImplementedView>(); } },
{ "Signal gen", ui::Color::green(), &bitmap_icon_cwgen, [&nav](){ nav.push<SigGenView>(); } },
//{ "Tone search", ui::Color::dark_grey(), nullptr, [&nav](){ nav.push<ToneSearchView>(); } },
{ "WAV viewer", ui::Color::yellow(), &bitmap_icon_soundboard, [&nav](){ nav.push<ViewWavView>(); } },
{ "Wav viewer", ui::Color::yellow(), &bitmap_icon_soundboard, [&nav](){ nav.push<ViewWavView>(); } },
{ "Antenna length", ui::Color::green(), &bitmap_icon_tools_antenna, [&nav](){ nav.push<WhipCalcView>(); } },
{ "Wipe SD Card", ui::Color::red(), &bitmap_icon_tools_wipesd, [&nav](){ nav.push<WipeSDView>(); } },
{ "Wipe SD card", ui::Color::red(), &bitmap_icon_tools_wipesd, [&nav](){ nav.push<WipeSDView>(); } },
});
set_max_rows(2); // allow wider buttons
}
+12 -6
View File
@@ -42,10 +42,16 @@ void Modulator::set_over(uint32_t new_over) {
over = new_over;
}
void Modulator::set_gain_vumeter_beep(float new_audio_gain , bool new_play_beep ) {
audio_gain = new_audio_gain ;
void Modulator::set_gain_shiftbits_vumeter_beep(float new_audio_gain ,uint8_t new_audio_shift_bits_s16, bool new_play_beep ) {
//new_audio_shift_bits_s16 are the direct shift bits (FM mod >>x) , and it is fixed to >>8_FM (AK) or 4,5,6, (WM boost OFF) or 6,7 (WM boost ON)
audio_gain = new_audio_gain ;
audio_shift_bits_s16_FM = new_audio_shift_bits_s16; //FM : >>8(AK) fixed , >>4,5,6 (WM boost OFF)
if (new_audio_shift_bits_s16==8) { //FM : we are in AK codec IC => for AM-SSB-DSB we were using >>2 fixed (wm boost ON) .
audio_shift_bits_s16_AM_DSB_SSB = 2; //AM-DSB-SSB: >>2(AK) fixed , >>0,1,2 (WM boost OFF)
} else {
audio_shift_bits_s16_AM_DSB_SSB = (new_audio_shift_bits_s16-4) ; //AM-DSB-SSB: >>0,1,2 (WM boost OFF), >>2,3 (WM boost ON)
}
play_beep = new_play_beep;
}
int32_t Modulator::apply_beep(int32_t sample_in, bool& configured_in, uint32_t& new_beep_index, uint32_t& new_beep_timer, TXProgressMessage& new_txprogress_message ) {
@@ -85,7 +91,7 @@ void SSB::execute(const buffer_s16_t& audio, const buffer_c8_t& buffer, bool& co
if (counter % 128 == 0) {
float i = 0.0, q = 0.0;
sample = audio.p[counter / over] >> 2;
sample = audio.p[counter / over] >> audio_shift_bits_s16_AM_DSB_SSB; // originally fixed >> 2, now >>2 for AK, 0,1,2,3 for WM (boost off)
sample *= audio_gain; // Apply GAIN Scale factor to the audio TX modulation.
//switch (mode) {
@@ -145,7 +151,7 @@ void FM::execute(const buffer_s16_t& audio, const buffer_c8_t& buffer, bool& con
for (size_t counter = 0; counter < buffer.count; counter++) {
sample = audio.p[counter>>6] >> 8; // sample = audio.p[counter / over] >> 8; (not enough efficient running code, over = 1536000/240000= 64 )
sample = audio.p[counter>>6] >> audio_shift_bits_s16_FM ; // Orig. >>8 , sample = audio.p[counter / over] >> 8; (not enough efficient running code, over = 1536000/240000= 64 )
sample *= audio_gain; // Apply GAIN Scale factor to the audio TX modulation.
if (play_beep) {
@@ -190,7 +196,7 @@ void AM::execute(const buffer_s16_t& audio, const buffer_c8_t& buffer, bool& con
for (size_t counter = 0; counter < buffer.count; counter++) {
if (counter % 128 == 0) {
sample = audio.p[counter / over] >> 2;
sample = audio.p[counter / over] >> audio_shift_bits_s16_AM_DSB_SSB; // originally fixed >> 2, now >>2 for AK, 0,1,2,3 for WM (boost off)
sample *= audio_gain; // Apply GAIN Scale factor to the audio TX modulation.
}
+3 -1
View File
@@ -50,9 +50,11 @@ public:
void set_mode(Mode new_mode);
void set_over(uint32_t new_over);
void set_gain_vumeter_beep(float new_audio_gain , bool new_play_beep );
void set_gain_shiftbits_vumeter_beep(float new_audio_gain ,uint8_t new_audio_shift_bits_s16, bool new_play_beep );
int32_t apply_beep(int32_t sample_in, bool& configured_in, uint32_t& new_beep_index, uint32_t& new_beep_timer, TXProgressMessage& new_txprogress_message );
float audio_gain { };
uint8_t audio_shift_bits_s16_FM { }; // shift bits factor to the captured ADC S16 audio sample.
uint8_t audio_shift_bits_s16_AM_DSB_SSB { };
bool play_beep { false };
uint32_t power_acc_count { 0 }; // this var it is initialized from Proc_mictx.cpp
uint32_t divider { }; // this var it is initialized from Proc_mictx.cpp
+2 -1
View File
@@ -35,7 +35,7 @@ void MicTXProcessor::execute(const buffer_c8_t& buffer){
if (!configured) return;
audio_input.read_audio_buffer(audio_buffer);
modulator->set_gain_vumeter_beep(audio_gain, play_beep ) ;
modulator->set_gain_shiftbits_vumeter_beep(audio_gain, audio_shift_bits_s16, play_beep ) ;
modulator->execute(audio_buffer, buffer, configured, beep_index, beep_timer, txprogress_message, level_message, power_acc_count, divider ); // Now "Key Tones & CTCSS" baseband additon inside FM mod. dsp_modulate.cpp"
/* Original fw 1.3.1 good reference, beep and vu-meter
@@ -141,6 +141,7 @@ void MicTXProcessor::on_message(const Message* const msg) {
}
audio_gain = config_message.audio_gain;
audio_shift_bits_s16 = config_message.audio_shift_bits_s16;
divider = config_message.divider;
power_acc_count = 0;
+2
View File
@@ -61,6 +61,8 @@ private:
uint32_t divider { };
float audio_gain { };
uint8_t audio_shift_bits_s16 { } ; // shift bits factor to the captured ADC S16 audio sample.
uint64_t power_acc { 0 };
uint32_t power_acc_count { 0 };
bool play_beep { false };
+323 -66
View File
@@ -216,90 +216,347 @@ void AK4951::speaker_disable() {
set_speaker_power(false);
}
void AK4951::microphone_enable() {
// map.r.digital_mic.DMIC = 0;
// update(Register::DigitalMic);
void AK4951::microphone_enable(int8_t alc_mode) {
// alc_mode =0 = (OFF =same as original code = NOT using AK4951 Programmable digital filter block),
// alc_mode >1 (with DIGITAL FILTER BLOCK , example : 1:(+12dB) , 2:(+9dB)", 3:(+6dB), ...)
// map.r.digital_mic.DMIC = 0; // originally commented code
// update(Register::DigitalMic); // originally commented code
uint_fast8_t mgain =0b0111; // Pre-amp mic (Original code, =0b0111 (+21dB's=7x3dBs),(Max is NOT 0b1111!, it is 0b1010=+30dBs=10x3dBs)
map.r.signal_select_2.INL = 0b01; // Lch input signal = LIN2 , our ext. MONO MIC is connected here LIN2 in Portapack.
map.r.signal_select_2.INR = 0b01; // Rch input signal = RIN2 , Not used ,not connected ,but no problem.
map.r.signal_select_2.MICL = 0; // MPWR = 2.4V (it has two possible settings , 2.4V or 2.0V) , (majority smarthphones around 2V , range 1V-5V)
update(Register::SignalSelect2);
// ------Common code part, = original setting conditions, it is fine for all user-GUI alc_modes: OFF , and ALC modes .*/
map.r.digital_filter_select_1.HPFAD = 1; // HPF1 ON (after ADC);page 40 datasheet, HPFAD bit controls the ON/OFF of the HPF1 (HPF ON is recommended).
map.r.digital_filter_select_1.HPFC = 0b11; // HPF Cut off frequency of high pass filter from 236.8 Hz @fs=48k ("00":3.7Hz, "01":14,8Hz, "10":118,4Hz)
update(Register::DigitalFilterSelect1);
// map.r.r_ch_mic_gain_setting.MGR = 0x80; // Microphone sensitivity correction = 0dB., (not used by now , original code cond.)
// update(Register::RchMicGainSetting); // (those two lines , not activated, same as original)
// pre-load 4 byes LPF coefficicients (.lpf_coefficient_0,1,2,3), FSA 14..0, FSB 14..0 , (fcut initial 6kHz, fs 48Khz).
// it will be default pre-loading coeff. for al ALC modes, LPF bit is activated down, for all ALC digital modes.
map.r.lpf_coefficient_0.l = 0x5F; // Pre-loading here LPF 6kHz, 1st Order from digital Block , Fc=6000 Hz, fs = 48khz
map.r.lpf_coefficient_1.h = 0x09; // LPF bit is activated down, for all ALC digital modes.
map.r.lpf_coefficient_2.l = 0xBF; // Writting reg to AK4951, with "update", following instructions.
map.r.lpf_coefficient_3.h = 0x32;
update(Register::LPFCoefficient0); // Writing pre-loaded 4 bytes LPF CoefFiecients 14 bits (FSA13..0, FSB13..0
update(Register::LPFCoefficient1); // In this case , LPF 6KHz , when we activate the LPF block.
update(Register::LPFCoefficient2);
update(Register::LPFCoefficient3);
// Reset , setting OFF all 5 x Digital Equalizer filters
map.r.digital_filter_select_3.EQ1 = 0; // EQ1 Coeffic Setting , (0: Disable-default, audio data passes EQ1 block by 0dB gain). When EQ1="1”, the settings of E1A15-0, E1B15-0 and E1C15-0 bits are enabled
map.r.digital_filter_select_3.EQ2 = 0; // EQ2 Coeffic Setting , (0: Disable-default, audio data passes EQ2 block by 0dB gain). When EQ2="1”, the settings of E2A15-0, E2B15-0 and E2C15-0 bits are enabled
map.r.digital_filter_select_3.EQ3 = 0; // EQ3 Coeffic Setting , (0: Disable-default, audio data passes EQ3 block by 0dB gain). When EQ3="1”, the settings of E3A15-0, E3B15-0 and E3C15-0 bits are enabled
map.r.digital_filter_select_3.EQ4 = 0; // EQ4 Coeffic Setting , (0: Disable-default, audio data passes EQ4 block by 0dB gain). When EQ4="1”, the settings of E4A15-0, E4B15-0 and E4C15-0 bits are enabled
map.r.digital_filter_select_3.EQ5 = 0; // EQ5 Coeffic Setting , (0: Disable-default, audio data passes EQ5 block by 0dB gain). When EQ5="1”, the settings of E5A15-0, E5B15-0 and E5C15-0 bits are enabled
update(Register::DigitalFilterSelect3); // A,B,C EQ1 Coefficients are already pre-loaded in ak4951.hpp
if (alc_mode==0) { // Programmable Digital Filter OFF, same as original condition., no Digital ALC, nor Wind Noise Filter, LPF , EQ
map.r.digital_filter_select_2.LPF = 0; // LPF-Block, Coeffic Setting Enable (OFF-Default), When LPF bit is “0”, audio data passes the LPF block by 0dB gain.
update(Register::DigitalFilterSelect2);
// Pre-loading AUDIO PATH with all DIGITAL BLOCK by pased, see, audio path block diagramm AK4951 datasheet + Table Playback mode -Recording mode.
// Digital filter block PATH is BY PASSED (we can swith off DIG. BLOCK power , PMPFIL=0) .The Path in Recording Mode 2 & Playback Mode 2 (NO DIG FILTER BLOCK AT ALL, not for MIC recording, nor for Playback)
map.r.digital_filter_mode.ADCPF = 1; // ADCPF bit swith ("0" Mic after ADC Output connected (recording mode) to the DIGITAL FILTER BLOCK. ("1" Playback mode)
map.r.digital_filter_mode.PFSDO = 0; // ADC bit switch ("0" : 1st order HPF) connectedto the Output. By bass DIGITAL block .
map.r.digital_filter_mode.PFDAC = 0b00; // (Input selector for DAC (not used in MIC), SDTI= Audio Serial Data Input Pin)
update(Register::DigitalFilterMode); // Writing the Audio Path : NO DIGITAL BLOCK or DIG BLOCK FOR MIC , Audio mode path : Playback mode /-Recording mode.
map.r.power_management_1.PMADL = 1; // ADC Lch = Lch input signal. Mic Amp Lch and ADC Lch Power Management
map.r.power_management_1.PMADR = 1; // ADC Rch = Rch input signal. Mic Amp Rch and ADC Rch Power Management
map.r.power_management_1.PMPFIL = 0; // Pre-loading , Programmable Dig. filter OFF ,filter unused, routed around.(original value = 0 )
update(Register::PowerManagement1); // Activating the Power management of the used blocks . (Mic ADC always + Dig Block filter , when used )
// 1059/fs, 22ms @ 48kHz
chThdSleepMilliseconds(22);
} else { // ( alc_mode !=0)
switch(alc_mode) { // Pre-loading register values depending on user-GUI selection (they will be sended below, with "update(Register_name::xxx )".
case 1: // ALC-> on, (+12dB's) Auto Vol max + Wind Noise cancel + LPF 6kHz + Pre-amp Mic (+21dB=original)
map.r.alc_mode_control_2.REF = 0xC0; // REF7-0 bits,max gain at ALC recovery operation,(FFH +36dBs , D0H +18dBs, A0H 0dBs, C0H=+12dBs)
map.r.l_ch_input_volume_control.IV = 0xC0; // Left, Input Digital Volume Setting, (FFH +36dBs , D0H +18dBs, A0H 0dBs, 70H=-18dBs)
map.r.r_ch_input_volume_control.IV = 0xC0; // Right Input Dig Vol Setting, same comment as above , The value of IVOL should be <= than REFs
// Already Pre-loaded, "map.r.lpf_coefficient", 6Khz - LPF 1st Order from digital Block,Fc=6000Hz,fs = 48khz
// LPF bit is activated down, for all ALC digital modes.
break;
case 2: // ALC-> on, (+09dB's) Auto Vol max + Wind Noise cancel + LPF 6kHz + Pre-amp Mic (+21dB=original)
map.r.alc_mode_control_2.REF = 0xB8; // REF7-0 bits,max gain at ALC recoveryoperation,(FFH +36dBs , D0H +18dBs, A0H 0dBs, B8H= +9dBs)
map.r.l_ch_input_volume_control.IV = 0xB8; // Left, Input Digital Volume Setting, (FFH +36dBs , D0H +18dBs, A0H 0dBs, 70H=-18dBs)
map.r.r_ch_input_volume_control.IV = 0xB8; // Right Input Dig Vol Setting, same comment as above , The value of IVOL should be <= than REFs
// Already Pre-loaded, "map.r.lpf_coefficient", 6Khz - LPF 1st Order from digital Block,Fc=6000Hz,fs = 48khz
// LPF bit is activated down, for all ALC digital modes.
break;
case 3: // ALC-> on, (+06dB's) Auto Vol max + Wind Noise cancel + LPF 6kHz + Pre-amp Mic (+21dB=original)
map.r.alc_mode_control_2.REF = 0xB0; // 0xB8 , REF7-0 bits,max gain at ALC recoveryoperation,(FFH +36dBs , D0H +18dBs, A0H 0dBs, B0H= +6dBs)
map.r.l_ch_input_volume_control.IV = 0xB0; // Left, Input Digital Volume Setting, (FFH +36dBs , D0H +18dBs, A0H 0dBs, 70H=-18dBs)
map.r.r_ch_input_volume_control.IV = 0xB0; // Right Input Dig Vol Setting, same comment as above , Then value of IVOL should be <= than REFs
// Already Pre-loaded, "map.r.lpf_coefficient", 6Khz - LPF 1st Order from digital Block,Fc=6000Hz,fs = 48khz
// LPF bit is activated down, for all ALC digital modes.
break;
case 4: // ALC-> on, (+03dB's) Auto Vol max + Wind Noise cancel + Pre-amp Mic (+21dB=original)
// + EQ boosting ~<2kHz (f0:1,1k, fb:1,7K, k=1,8) && + LPF 3,5k
map.r.alc_mode_control_2.REF = 0xA8; // 0xA8 , REF7-0 bits,max gain at ALC recoveryoperation,(FFH +36dBs , D0H +18dBs, A0H 0dBs, A8H= +3dBs)
map.r.l_ch_input_volume_control.IV = 0xA8; // Left, Input Digital Volume Setting, (FFH +36dBs , D0H +18dBs, A0H 0dBs, 70H=-18dBs)
map.r.r_ch_input_volume_control.IV = 0xA8; // Right Input Dig Vol Setting, same comment as above , Then value of IVOL should be <= than REFs
//The EQn (n=1, 2, 3, 4 or 5) coefficient must be set when EQn bit = “0” or PMPFIL bit = “0”.
map.r.digital_filter_select_3.EQ1 = 1; // EQ1 Coeffic Setting , (0: Disable-default, audio data passes EQ1 block by 0dB gain). When EQ1="1”, the settings of E1A15-0, E1B15-0 and E1C15-0 bits are enabled
update(Register::DigitalFilterSelect3); // A,B,C EQ1 Coefficients are already pre-loaded in ak4951.hpp
map.r.lpf_coefficient_0.l = 0x0D; // Pre-loading here LPF 3,5k , 1st Order from digital Block , Fc=3.500 Hz, fs = 48khz
map.r.lpf_coefficient_1.h = 0x06; // LPF bit is activated down, for all ALC digital modes.
map.r.lpf_coefficient_2.l = 0x1A; // Writting reg to AK4951 , down with update....
map.r.lpf_coefficient_3.h = 0x2C;
// LPF bit is activated down, for all ALC digital modes.
break;
case 5: // ALC-> on, (+03dB's) Auto Vol max + Wind Noise cancel + Pre-amp Mic (+21dB=original)
// + EQ boosting ~<3kHz (f0~1k4,fb~2,4k,k=1,8) && LPF 4kHz
map.r.alc_mode_control_2.REF = 0xA8; // 0xA0 , REF7-0 bits,max gain at ALC recoveryoperation,(FFH +36dBs , D0H +18dBs, A0H 0dBs, A8H= +3dBs)
map.r.l_ch_input_volume_control.IV = 0xA8; // Left, Input Digital Volume Setting, (FFH +36dBs , D0H +18dBs, A0H 0dBs, 70H=-18dBs)
map.r.r_ch_input_volume_control.IV = 0xA8; // Right Input Dig Vol Setting, same comment as above , Then value of IVOL should be <= than REFs
map.r.digital_filter_select_3.EQ2 = 1; // EQ2 Coeffic Setting , (0: Disable-default, audio data passes EQ2 block by 0dB gain). When EQ2="1”, the settings of E2A15-0, E2B15-0 and E2C15-0 bits are enabled
update(Register::DigitalFilterSelect3);
map.r.lpf_coefficient_0.l = 0xC3; // Pre-loading here LPF 4k , 1st Order from digital Block , Fc=4000 Hz, fs = 48khz
map.r.lpf_coefficient_1.h = 0x06; // LPF bit is activated down, for all ALC digital modes.
map.r.lpf_coefficient_2.l = 0x86; // Writting reg to AK4951 , down with update....
map.r.lpf_coefficient_3.h = 0x2D;
// LPF bit is activated down, for all ALC digital modes.
break;
case 6: // ALC-> on, (+03dB's) Auto Vol max + Wind Noise cancel + LPF 6kHz + Pre-amp Mic (+21dB=original)
map.r.alc_mode_control_2.REF = 0xA8; // REF7-0 bits,max gain at ALC recoveryoperation,(FFH +36dBs , D0H +18dBs, A0H 0dBs, A0H= 0dBs)
map.r.l_ch_input_volume_control.IV = 0xA8; // Left, Input Digital Volume Setting, (FFH +36dBs , D0H +18dBs, A0H 0dBs, 70H=-18dBs)
map.r.r_ch_input_volume_control.IV = 0xA8; // Right Input Dig Vol Setting, same comment as above , Then value of IVOL should be <= than REFs
// Already Pre-loaded, "map.r.lpf_coefficient", 6Khz - LPF 1st Order from digital Block,Fc=6000Hz,fs = 48khz
// LPF bit is activated down, for all ALC digital modes.
break;
case 7: // ALC-> on, (+00dB's) Auto Vol max + Wind Noise cancel + LPF 6kHz + Pre-amp Mic (+21dB=original)
map.r.alc_mode_control_2.REF = 0xA0; // REF7-0 bits,max gain at ALC recoveryoperation,(FFH +36dBs , D0H +18dBs, A0H 0dBs, A0H= 0dBs)
map.r.l_ch_input_volume_control.IV = 0xA0; // Left, Input Digital Volume Setting, (FFH +36dBs , D0H +18dBs, A0H 0dBs, 70H=-18dBs)
map.r.r_ch_input_volume_control.IV = 0xA0; // Right Input Dig Vol Setting, same comment as above , Then value of IVOL should be <= than REFs
// Already Pre-loaded, "map.r.lpf_coefficient", 6Khz - LPF 1st Order from digital Block,Fc=6000Hz,fs = 48khz
// LPF bit is activated down, for all ALC digital modes.
break;
case 8: // ALC-> on, (-03dB's) Auto Vol max + Wind Noise cancel + LPF 6kHz + Pre-amp Mic (+21dB=original)
map.r.alc_mode_control_2.REF = 0x98; //REF7-0 bits,max gain at ALC recovery operation,(FFH +36dBs , D0H +18dBs, A0H 0dBs, 98H=-03dBs)
map.r.l_ch_input_volume_control.IV = 0x98; // Left, Input Digital Volume Setting, (FFH +36dBs , D0H +18dBs, A0H 0dBs, 70H=-18dBs)
map.r.r_ch_input_volume_control.IV = 0x98; // Right Input Dig Vol Setting, same comment as above , Then value of IVOL should be <= than REFs
const uint_fast8_t mgain = 0b0111;
map.r.signal_select_1.MGAIN20 = mgain & 7;
map.r.signal_select_1.PMMP = 1;
map.r.signal_select_1.MPSEL = 1; // MPWR2 pin
map.r.signal_select_1.MGAIN3 = (mgain >> 3) & 1;
update(Register::SignalSelect1);
// Already Pre-loaded, "map.r.lpf_coefficient", 6Khz - LPF 1st Order from digital Block,Fc=6000Hz,fs = 48khz
// LPF bit is activated down, for all ALC digital modes.
break;
map.r.signal_select_2.INL = 0b01; // Lch input signal = LIN2
map.r.signal_select_2.INR = 0b01; // Rch input signal = RIN2
map.r.signal_select_2.MICL = 0; // MPWR = 2.4V
update(Register::SignalSelect2);
case 9: // ALC-> on, (-06dB's) Auto Vol max + Wind Noise cancel + LPF 6kHz + Pre-amp Mic (+21dB=original)
map.r.alc_mode_control_2.REF = 0x90; // REF7-0 bits,max gain at ALC recovery operation,(FFH +36dBs , D0H +18dBs, A0H 0dBs, 90H=-06dBs)
map.r.l_ch_input_volume_control.IV = 0x90; // Left, Input Digital Volume Setting, (FFH +36dBs , D0H +18dBs, A0H 0dBs, 70H=-18dBs)
map.r.r_ch_input_volume_control.IV = 0x90; // Right Input Dig Vol Setting, same comment as above , Then value of IVOL should be <= than REFs
// map.r.r_ch_mic_gain_setting.MGR = 0x80; // Microphone sensitivity correction = 0dB.
// update(Register::RchMicGainSetting);
/*
map.r.timer_select.FRN = ?;
map.r.timer_select.FRATT = ?;
map.r.timer_select.ADRST = 0b??;
update(Register::TimerSelect);
// Already Pre-loaded, "map.r.lpf_coefficient", 6Khz - LPF 1st Order from digital Block,Fc=6000Hz,fs = 48khz
// LPF bit is activated down, for all ALC digital modes.
break;
map.r.alc_timer_select. = ?;
update(Register::ALCTimerSelect);
map.r.alc_mode_control_1. = ?;
map.r.alc_mode_control_1.ALC = 1;
case 10: // ALC-> on, (-09dB's) Auto Vol max + Wind Noise cancel + LPF 6kHz - Pre-amp MIC -3dB (18dB's)
// Reduce also Pre-amp Mic -3dB's (+18dB's)
mgain = 0b0110; // Pre-amp mic Mic Gain Pre-amp (+18dB), Original=0b0111 (+21dB's =7x3dBs),
map.r.alc_mode_control_2.REF = 0x88; // REF7-0 bits,max gain at ALC recovery operation,(FFH +36dBs , D0H +18dBs, A0H 0dBs, 88H=-09dBs)
map.r.l_ch_input_volume_control.IV = 0x88; // Left, Input Digital Volume Setting, (FFH +36dBs , D0H +18dBs, A0H 0dBs, 70H=-18dBs)
map.r.r_ch_input_volume_control.IV = 0x88; // Right Input Dig Vol Setting, same comment as above , Then value of IVOL should be <= than REFs
// Already Pre-loaded, "map.r.lpf_coefficient", 6Khz - LPF 1st Order from digital Block,Fc=6000Hz,fs = 48khz
// LPF bit is activated down, for all ALC digital modes.
break;
case 11: // ALC-> on, (-12dB's) Auto Vol max + Wind Noise cancel + LPF 6kHz - Pre-amp MIC -6dB (15dB's)
// Reduce also Pre-amp Mic -6dB's (+15dB's)
mgain = 0b0101; // Pre-amp mic Mic Gain Pre-amp (+15dB), (Original=0b0111 (+21dB's= 7x3dBs),
map.r.alc_mode_control_2.REF = 0x80; // REF7-0 bits,max gain at ALC recovery operation,(FFH +36dBs , D0H +18dBs, A0H 0dBs, 80H=-12dBs)
map.r.l_ch_input_volume_control.IV = 0x80; // Left, Input Digital Volume Setting, (FFH +36dBs , D0H +18dBs, A0H 0dBs, 70H=-18dBs)
map.r.r_ch_input_volume_control.IV = 0x80; // Right Input Dig Vol Setting, same comment as above , Then value of IVOL should be <= than REFs
// Already Pre-loaded, "map.r.lpf_coefficient", 6Khz - LPF 1st Order from digital Block,Fc=6000Hz,fs = 48khz
// LPF bit is activated down, for all ALC digital modes.
break;
}
//-------------------------------DIGITAL ALC (Automatic Level Control ) --- --------
map.r.alc_mode_control_1.ALC = 0; // LMTH2-0, WTM1-0, RGAIN2-0, REF7-0, RFST1-0, EQFC1-0, FRATT, FRN and ALCEQN bits (needs to be set up with ALC disable = 0)
update(Register::ALCModeControl1);
map.r.alc_mode_control_2.REF = ?;
map.r.timer_select.FRN = 0; // (FRN= 0 Fast Recovery mode , enable )
map.r.timer_select.FRATT = 0; // Fast Recovery Ref. Volume Atten. Amount -0,00106dB's, timing 4/fs (default)
map.r.timer_select.ADRST = 0b00; // initial offset ADC cycles , 22ms @fs=48Khz.
update(Register::TimerSelect);
map.r.alc_timer_select.RFST = 0b00; // RFST1-0: ALC Fast Recovery Speed Default: “00” (0.0032dB)
map.r.alc_timer_select.WTM = 0b00; // ALC Recovery Operation Waiting Period 128/fs = 2,7 mseg (min=default)
map.r.alc_timer_select.EQFC = 0b10; // Selecting default, fs 48Khz , ALCEQ: First order zero pole high pass filter fc2=100Hz, fc1=150Hz
map.r.alc_timer_select.IVTM = 0; // IVTM bit set the vol transition time ,236/fs = 4,9msecs (min) (default was 19,7msegs.)
update(Register::ALCTimerSelect);
map.r.alc_mode_control_1.LMTH10 = 0b11; // ALC Limiter Detec Level/ Recovery Counter Reset; lower 2 bits (Ob111=-8,4dbs), (default 0b000=-2,5dBs)
map.r.alc_mode_control_1.RGAIN = 0b000; // ALC Recovery Gain Step, max step , max speed. Default: “000” (0.00424dB)
map.r.alc_mode_control_1.ALC = 1; // ALC Enable . (we are now, NOT in MANUAL volume mode, only becomes manual when (ALC=“0” while ADCPF=“1”. )
map.r.alc_mode_control_1.LMTH2 = 1; // ALC Limiter Detection Level/ Recovery Counter Reset Level,Upper bit,default 0b000
map.r.alc_mode_control_1.ALCEQN = 1; // ALC EQ Off =1 not used by now, 0: ALC EQ On (default)
update(Register::ALCModeControl1);
// map.r.alc_mode_control_2.REF = 0x??; // Pre-loaded in top part. Maximum gain at ALC recovery operation,.(FFH +36dBs , D0H +18dBs, A0H 0dBs, 70H=-18dBs)
update(Register::ALCModeControl2);
*/
// map.r.l_ch_input_volume_control.IV = 0xe1;
// update(Register::LchInputVolumeControl);
// map.r.r_ch_input_volume_control.IV = 0xe1;
// update(Register::RchInputVolumeControl);
/*
map.r.auto_hpf_control.STG = 0b00;
map.r.auto_hpf_control.SENC = 0b011;
map.r.auto_hpf_control.AHPF = 0;
update(Register::AutoHPFControl);
*/
map.r.digital_filter_select_1.HPFAD = 1; // HPF1 (after ADC) = on
map.r.digital_filter_select_1.HPFC = 0b11; // 2336.8 Hz @ fs=48k
update(Register::DigitalFilterSelect1);
/*
map.r.digital_filter_select_2.HPF = 0;
map.r.digital_filter_select_2.LPF = 0;
map.r.digital_filter_select_2.FIL3 = 0;
map.r.digital_filter_select_2.EQ0 = 0;
map.r.digital_filter_select_2.GN = 0b00;
// map.r.l_ch_input_volume_control.IV = 0x??; // Pre-loaded in top part. Left, Input Digital Volume Setting, (FFH +36dBs , D0H +18dBs, A0H 0dBs, 70H=-18dBs)
update(Register::LchInputVolumeControl);
// map.r.r_ch_input_volume_control.IV = 0x??; // Pre-loaded in top part. Right,Input Digital Volume Setting, (FFH +36dBs , D0H +18dBs, A0H 0dBs, 70H=-18dBs)
update(Register::RchInputVolumeControl);
//---------------Switch ON, Digital Automatic Wind Noise Filter reduction -------------------
// Difficult to realise that Dynamic HPF Wind noise filter benefit, maybe because we have another fixed HPF 236.8 Hz .
// Anyway , we propose to activate it , with default setting conditions.
map.r.power_management_1.PMPFIL = 0; // (*1) To programm SENC, STG , we need PMPFIL = 0 . (but this disconnect Digital block power supply.
update(Register::PowerManagement1); // Updated PMPFIL to 0 . (*1)
map.r.auto_hpf_control.STG = 0b00; // (00=LOW ATTENUATION Level), lets put 11 (HIGH ATTENUATION Level) (default 00)
map.r.auto_hpf_control.SENC = 0b011; // (000=LOW sensitivity detection)… 111((MAX sensitivity detection) (default 011)
map.r.auto_hpf_control.AHPF = 1; // Autom. Wind noise filter ON (AHPF bit=“1”).It atten. wind noise when detecting ,and adjusts the atten. level dynamically.
update(Register::AutoHPFControl);
// We are in Digital Block ON , (Wind Noise Filter+ALC+LPF+EQ),==> needs at the end , PMPFIL=1 , Program. Dig.filter ON
// map.r.power_management_1.PMPFIL = 1; // that instruction is at the end , we can skp pre-loading Programmable Dig. filter ON (*1)
//---------------------------------------------------------------------
// Writing AUDIO PATH diagramm, Changing Audio mode path : Playback mode1 /-Recording mode2. (Figure 37 AK4951 datasheet, Table 27. Recording Playback Mode)
// When changing those modes, PMPFIL bit must be “0”, it is OK (*1)
map.r.digital_filter_mode.ADCPF = 1; // ADCPF bit swith ("0" Mic after ADC Output connected (recording mode) to the DIGITAL FILTER BLOCK. ("1" Playback mode)
map.r.digital_filter_mode.PFSDO = 1; // ADC (+ 1st order HPF) Output
map.r.digital_filter_mode.PFDAC = 0b00; // (Input selector for DAC (not used in MIC), SDTI= Audio Serial Data Input Pin)
update(Register::DigitalFilterMode); // Writing the Audio Path : NO DIGITAL BLOCK or DIG BLOCK FOR MIC , Audio mode path : Playback mode /-Recording mode.
// The EQn (n=1, 2, 3, 4 or 5) coefficient must be set when EQn bit = “0” or PMPFIL bit = “0”., but we are already (*1)
// map.r.power_management_1.PMPFIL = 0; // In the previous Wind Noise Filter , we already set up PPFIL = 0
// update(Register::PowerManagement1); // Activating the Power management of the used blocks . (Mic ADC always + Dig Block filter , when used )
// ... Set EQ & LPF coefficients ---------------------------------
// writting to the IC ak4951 reg. settings defined in Ak4951.hpp , the 30 bytes , EQ coefficient = 5 (EQ1,2,3,4,5) x 3 (A,B,C coefficients) x 2 bytes (16 bits)
update(Register::E1Coefficient0); // we could pre-load here,ex ,"map.r.e1_coefficient_0.l = 0x50;" , EQ1 Coefficient A : A7...A0, but already done in ak4951.hpp
update(Register::E1Coefficient1); // we could pre-load here,ex ,"map.r.e1_coefficient_1.h = 0xFE;" , EQ1 Coefficient A : A15..A8, " "
update(Register::E1Coefficient2); // we could pre-load here,ex ,"map.r.e1_coefficient_2.l = 0x29;" , EQ1 Coefficient B : B7...B0, " "
update(Register::E1Coefficient3); // we could pre-load here,ex ,"map.r.e1_coefficient_3.h = 0xC5;" , EQ1 Coefficient B : B15..B8, " "
update(Register::E1Coefficient4); // we could pre-load here,ex ,"map.r.e1_coefficient_4.l = 0xA0;" , EQ1 Coefficient C : C7...C0, " "
update(Register::E1Coefficient5); // we could pre-load here,ex ,"map.r.e1_coefficient_5.h = 0x1C;" , EQ1 Coefficient C : C15..C8, " "
update(Register::E2Coefficient0); // writing pre-loaded EQ2 coefficcients
update(Register::E2Coefficient1);
update(Register::E2Coefficient2);
update(Register::E2Coefficient3);
update(Register::E2Coefficient4);
update(Register::E2Coefficient5);
// Already pre-loaded LPF coefficients to 6k, 3,5k or 4k ,(LPF 6Khz all digital alc modes top , except when 3k5 , 4k)
update(Register::LPFCoefficient0); // Writing pre-loaded 4 bytes LPF CoefFiecients 14 bits (FSA13..0, FSB13..0
update(Register::LPFCoefficient1);
update(Register::LPFCoefficient2);
update(Register::LPFCoefficient3);
// Activating LPF block , (and re-configuring the rest of bits of the same register)
map.r.digital_filter_select_2.HPF = 0; // HPF2-Block, Coeffic Setting Enable (OFF-Default), When HPF bit is “0”, audio data passes the HPF2 block by is 0dB gain.
map.r.digital_filter_select_2.LPF = 1; // LPF-Block, Coeffic Setting Enable (OFF-Default), When LPF bit is “0”, audio data passes the LPF block by 0dB gain.
map.r.digital_filter_select_2.FIL3 = 0; // Stereo_Emphasis_Filter-Block,(OFF-Default) Coefficient Setting Enable , OFF , Disable.
map.r.digital_filter_select_2.EQ0 = 0; // Gain Compensation-Block, (OFF-Default) Coeffic Setting Enable, When EQ0 bit = “0” audio data passes the EQ0 block by 0dB gain.
map.r.digital_filter_select_2.GN = 0b00; // Gain Setting of the Gain Compensation Block Default: “00”-Default (0dB)
update(Register::DigitalFilterSelect2);
map.r.digital_filter_select_3.EQ1 = 0;
map.r.digital_filter_select_3.EQ2 = 0;
map.r.digital_filter_select_3.EQ3 = 0;
map.r.digital_filter_select_3.EQ4 = 0;
map.r.digital_filter_select_3.EQ5 = 0;
update(Register::DigitalFilterSelect3);
*/
map.r.digital_filter_mode.PFSDO = 0; // ADC (+ 1st order HPF) Output
map.r.digital_filter_mode.ADCPF = 1; // ADC Output (default)
update(Register::DigitalFilterMode);
// ... Set coefficients ...
map.r.power_management_1.PMADL = 1; // ADC Lch = Lch input signal
map.r.power_management_1.PMADR = 1; // ADC Rch = Rch input signal
map.r.power_management_1.PMPFIL = 0; // Programmable filter unused, routed around.
update(Register::PowerManagement1);
// Acitivating digital block , power supply
map.r.power_management_1.PMADL = 1; // ADC Lch = Lch input signal. Mic Amp Lch and ADC Lch Power Management
map.r.power_management_1.PMADR = 1; // ADC Rch = Rch input signal. Mic Amp Rch and ADC Rch Power Management
map.r.power_management_1.PMPFIL = 1; // Pre-loaded in top part. Orig value=0, Programmable Digital filter unused (not power up), routed around.
update(Register::PowerManagement1); // Activating the Power management of the used blocks . (Mic ADC always + Dig Block filter , when used )
// 1059/fs, 22ms @ 48kHz
chThdSleepMilliseconds(22);
}
// Common part for all alc_mode , --------------------------
// const uint_fast8_t mgain = 0b0111; // Already pre-loaded , in above switch case .
map.r.signal_select_1.MGAIN20 = mgain & 7; // writing 3 lower bits of mgain , (pre-amp mic gain).
map.r.signal_select_1.PMMP = 1; // Activating DC Mic Power supply through 2kohms res., similar majority smartphones headphone+mic jack, "plug-in-power"
map.r.signal_select_1.MPSEL = 1; // MPWR2 pin ,selecting output voltage to MPWR2 pin, that we are using in portapack ext. MIC)
map.r.signal_select_1.MGAIN3 = (mgain >> 3) & 1; // writing 4th upper bit of mgain (pre-amp mic gain).
update(Register::SignalSelect1);
}
void AK4951::microphone_disable() {
map.r.power_management_1.PMADL = 0;
map.r.power_management_1.PMADR = 0;
map.r.power_management_1.PMPFIL = 0;
map.r.power_management_1.PMADL = 0; // original code , disable Power managem.Mic ADC L
map.r.power_management_1.PMADR = 0; // original code , disable Power managem.Mic ADC R
map.r.power_management_1.PMPFIL = 0; // original code , disable Power managem. all Programmable Dig. block
update(Register::PowerManagement1);
map.r.alc_mode_control_1.ALC = 0;
map.r.alc_mode_control_1.ALC = 0; // original code , Restore , disable ALC block.
update(Register::ALCModeControl1);
map.r.auto_hpf_control.AHPF = 0; //----------- new code addition , Restore disable Wind noise filter OFF (AHPF bit=“0”).
update(Register::AutoHPFControl);
//Restore original AUDIO PATH , condition, (Digital filter block PATH is BY PASSED) (we can also swith off DIG. BLOCK power , PMPFIL=0)
// The Path in Recording Mode 2 & Playback Mode 2 , (NO DIG FILTER BLOCK AT ALL, not for MIC recording, nor for Playback)
map.r.digital_filter_mode.ADCPF = 1; // new code addition , ADCPF bit swith ("0" Mic after ADC Output connected (recording mode) to the DIGITAL FILTER BLOCK. ("1" Playback mode)
map.r.digital_filter_mode.PFSDO = 0; // new code addition , ADC bit switch ("0" : 1st order HPF) connectedto the Output. By bass DIGITAL block .
map.r.digital_filter_mode.PFDAC = 0b00; // new code addition , (Input selector for DAC (not used in MIC), SDTI= Audio Serial Data Input Pin)
update(Register::DigitalFilterMode); // Writing the Audio Path : NO DIGITAL BLOCK or DIG BLOCK FOR MIC , Audio mode path : Playback mode /-Recording mode.
// Restore original condition , LPF , OFF . same as when not using DIGITAL Programmable block
map.r.digital_filter_select_2.LPF = 0; // LPF-Block, Coeffic Setting Enable (OFF-Default), When LPF bit is “0”, audio data passes the LPF block by 0dB gain.
update(Register::DigitalFilterSelect2);
map.r.lpf_coefficient_0.l = 0x00; // Pre-loading here LPF 6k , 1st Order from digital Block , Fc=6000 Hz, fs = 48khz
map.r.lpf_coefficient_1.h = 0x00; // LPF bit is activated down, for all ALC digital modes.
map.r.lpf_coefficient_2.l = 0x00; // Writting reg to AK4951 , down with update....
map.r.lpf_coefficient_3.h = 0x00;
update(Register::LPFCoefficient0); // Writing pre-loaded 4 bytes LPF CoefFiecients 14 bits (FSA13..0, FSB13..0
update(Register::LPFCoefficient1);
update(Register::LPFCoefficient2);
update(Register::LPFCoefficient3);
// Switch off all EQ 1,2,3,4,5
map.r.digital_filter_select_3.EQ1 = 0; // EQ1 Coeffic Setting , (0: Disable-default, audio data passes EQ1 block by 0dB gain). When EQ1="1”, the settings of E1A15-0, E1B15-0 and E1C15-0 bits are enabled
map.r.digital_filter_select_3.EQ2 = 0; // EQ2 Coeffic Setting , (0: Disable-default, audio data passes EQ2 block by 0dB gain). When EQ2="1”, the settings of E2A15-0, E2B15-0 and E2C15-0 bits are enabled
map.r.digital_filter_select_3.EQ3 = 0; // EQ3 Coeffic Setting , (0: Disable-default, audio data passes EQ3 block by 0dB gain). When EQ3="1”, the settings of E3A15-0, E3B15-0 and E3C15-0 bits are enabled
map.r.digital_filter_select_3.EQ4 = 0; // EQ4 Coeffic Setting , (0: Disable-default, audio data passes EQ4 block by 0dB gain). When EQ4="1”, the settings of E4A15-0, E4B15-0 and E4C15-0 bits are enabled
map.r.digital_filter_select_3.EQ5 = 0; // EQ5 Coeffic Setting , (0: Disable-default, audio data passes EQ5 block by 0dB gain). When EQ5="1”, the settings of E5A15-0, E5B15-0 and E5C15-0 bits are enabled
update(Register::DigitalFilterSelect3);
}
reg_t AK4951::read(const address_t reg_address) {
+32 -31
View File
@@ -773,40 +773,41 @@ constexpr RegisterMap default_after_reset { Register_Type {
.REV = 0b1100,
},
.e1_coefficient_0 = { .l = 0x00 },
.e1_coefficient_1 = { .h = 0x00 },
.e1_coefficient_2 = { .l = 0x00 },
.e1_coefficient_3 = { .h = 0x00 },
.e1_coefficient_4 = { .l = 0x00 },
.e1_coefficient_5 = { .h = 0x00 },
// just pre-loading into memory, 30 bytes = EQ 1,2,3,4,5 x A,B,C (2 x bytes) coefficients, but it will be written from ak4951.cpp
.e1_coefficient_0 = { .l = 0xCA }, //EQ1 Coefficient A : A7...A0, BW : 300Hz - 1700Hz (fo = 1150Hz , fb= 1700Hz) , k=1,8 peaking
.e1_coefficient_1 = { .h = 0x05 }, //EQ1 Coefficient A : A15..A8
.e1_coefficient_2 = { .l = 0xEB }, //EQ1 Coefficient B : B7...B0
.e1_coefficient_3 = { .h = 0x38 }, //EQ1 Coefficient B : B15...B8
.e1_coefficient_4 = { .l = 0x6F }, //EQ1 Coefficient C : C7...C0
.e1_coefficient_5 = { .h = 0xE6 }, //EQ1 Coefficient C : C15..C8
.e2_coefficient_0 = { .l = 0x00 },
.e2_coefficient_1 = { .h = 0x00 },
.e2_coefficient_2 = { .l = 0x00 },
.e2_coefficient_3 = { .h = 0x00 },
.e2_coefficient_4 = { .l = 0x00 },
.e2_coefficient_5 = { .h = 0x00 },
.e2_coefficient_0 = { .l = 0x05 }, //EQ2 Coefficient A : A7...A0, BW : 250Hz - 2700Hz (fo = 1475Hz , fb= 2450Hz) , k=1,8 peaking
.e2_coefficient_1 = { .h = 0x08 }, //EQ2 Coefficient A : A15..A8
.e2_coefficient_2 = { .l = 0x11 }, //EQ2 Coefficient B : B7...B0
.e2_coefficient_3 = { .h = 0x36 }, //EQ2 Coefficient B : B15...B8
.e2_coefficient_4 = { .l = 0xE9 }, //EQ2 Coefficient C : C7...C0
.e2_coefficient_5 = { .h = 0xE8 }, //EQ2 Coefficient C : C15..C8
.e3_coefficient_0 = { .l = 0x00 },
.e3_coefficient_1 = { .h = 0x00 },
.e3_coefficient_2 = { .l = 0x00 },
.e3_coefficient_3 = { .h = 0x00 },
.e3_coefficient_4 = { .l = 0x00 },
.e3_coefficient_5 = { .h = 0x00 },
.e3_coefficient_0 = { .l = 0x00 }, //EQ3 Coefficient A : A7...A0, not used currently
.e3_coefficient_1 = { .h = 0x00 }, //EQ3 Coefficient A : A15..A8
.e3_coefficient_2 = { .l = 0x00 }, //EQ3 Coefficient B : B7...B0
.e3_coefficient_3 = { .h = 0x00 }, //EQ3 Coefficient B : B15...B8
.e3_coefficient_4 = { .l = 0x00 }, //EQ3 Coefficient C : C7...C0
.e3_coefficient_5 = { .h = 0x00 }, //EQ3 Coefficient C : C15..C8
.e4_coefficient_0 = { .l = 0x00 },
.e4_coefficient_1 = { .h = 0x00 },
.e4_coefficient_2 = { .l = 0x00 },
.e4_coefficient_3 = { .h = 0x00 },
.e4_coefficient_4 = { .l = 0x00 },
.e4_coefficient_5 = { .h = 0x00 },
.e4_coefficient_0 = { .l = 0x00 }, //EQ4 Coefficient A : A7...A0, not used currently
.e4_coefficient_1 = { .h = 0x00 }, //EQ4 Coefficient A : A15..A8
.e4_coefficient_2 = { .l = 0x00 }, //EQ4 Coefficient B : B7...B0
.e4_coefficient_3 = { .h = 0x00 }, //EQ4 Coefficient B : B15...B8
.e4_coefficient_4 = { .l = 0x00 }, //EQ4 Coefficient C : C7...C0
.e4_coefficient_5 = { .h = 0x00 }, //EQ4 Coefficient C : C15..C8
.e5_coefficient_0 = { .l = 0x00 },
.e5_coefficient_1 = { .h = 0x00 },
.e5_coefficient_2 = { .l = 0x00 },
.e5_coefficient_3 = { .h = 0x00 },
.e5_coefficient_4 = { .l = 0x00 },
.e5_coefficient_5 = { .h = 0x00 },
.e5_coefficient_0 = { .l = 0x00 }, //EQ5 Coefficient A : A7...A0, not used currently
.e5_coefficient_1 = { .h = 0x00 }, //EQ5 Coefficient A : A15..A8
.e5_coefficient_2 = { .l = 0x00 }, //EQ5 Coefficient B : B7...B0
.e5_coefficient_3 = { .h = 0x00 }, //EQ5 Coefficient B : B15...B8
.e5_coefficient_4 = { .l = 0x00 }, //EQ5 Coefficient C : C7...C0
.e5_coefficient_5 = { .h = 0x00 }, //EQ5 Coefficient C : C15..C8
} };
class AK4951 : public audio::Codec {
@@ -841,7 +842,7 @@ public:
void set_headphone_volume(const volume_t volume) override;
void headphone_mute();
void microphone_enable();
void microphone_enable(int8_t alc_mode); // added user GUI parameter , to set up AK4951 ALC mode.
void microphone_disable();
size_t reg_count() const override {
+14
View File
@@ -114,6 +114,20 @@ bool load_sram() {
return ok;
}
void load_sram_no_verify() {
// CoolRunner II family has Hybrid memory CPLD arquitecture (SRAM+NVM)
// It seems that after using TX App somehow , I do not why , the CPLD_SRAM part needs to be re_loaded to solve #637 ghost beat
// load_sram() it is already called at each boot in portapack.cpp ,including verify CPLD part.
// Here we skipped CPLD verify part,just to be quicker (in case any CPLD problem it will be detected in the boot process).
auto jtag_target_hackrf_cpld = jtag_target_hackrf();
hackrf::one::cpld::CPLD hackrf_cpld { jtag_target_hackrf_cpld };
hackrf_cpld.write_sram(hackrf::one::cpld::verify_blocks);
return;
}
bool verify_eeprom() {
auto jtag_target_hackrf_cpld = jtag_target_hackrf();
hackrf::one::cpld::CPLD hackrf_cpld { jtag_target_hackrf_cpld };
+1
View File
@@ -38,6 +38,7 @@ namespace hackrf {
namespace cpld {
bool load_sram();
void load_sram_no_verify(); // added to solve issue #637 , "ghost" signal at RX , after using any TX App
bool verify_eeprom();
void init_from_eeprom();
+3
View File
@@ -868,6 +868,7 @@ public:
const uint32_t divider,
const float deviation_hz,
const float audio_gain,
const uint8_t audio_shift_bits_s16,
const uint32_t tone_key_delta,
const float tone_key_mix_weight,
const bool am_enabled,
@@ -878,6 +879,7 @@ public:
divider(divider),
deviation_hz(deviation_hz),
audio_gain(audio_gain),
audio_shift_bits_s16(audio_shift_bits_s16),
tone_key_delta(tone_key_delta),
tone_key_mix_weight(tone_key_mix_weight),
am_enabled(am_enabled),
@@ -890,6 +892,7 @@ public:
const uint32_t divider;
const float deviation_hz;
const float audio_gain;
const uint8_t audio_shift_bits_s16;
const uint32_t tone_key_delta;
const float tone_key_mix_weight;
const bool am_enabled;
@@ -285,6 +285,9 @@ struct data_t {
// Hardware
uint32_t hardware_config;
// Recon App
uint64_t recon_config;
constexpr data_t() :
structure_version(data_structure_version_enum::VERSION_CURRENT),
tuned_frequency(tuned_frequency_reset_value),
@@ -311,7 +314,8 @@ struct data_t {
tone_mix(tone_mix_reset_value),
hardware_config(0)
hardware_config(0),
recon_config(0)
{
}
};
@@ -663,6 +667,61 @@ void set_clkout_freq(uint32_t freq) {
data->ui_config.set_clkout_freq(freq);
}
bool recon_autosave_freqs() {
return (data->recon_config & 0x80000000UL) ? true : false;
}
bool recon_autostart_recon() {
return (data->recon_config & 0x40000000UL) ? true : false;
}
bool recon_continuous() {
return (data->recon_config & 0x20000000UL) ? true : false;
}
bool recon_clear_output() {
return (data->recon_config & 0x10000000UL) ? true : false;
}
bool recon_load_freqs() {
return (data->recon_config & 0x08000000UL) ? true : false;
}
bool recon_load_ranges() {
return (data->recon_config & 0x04000000UL) ? true : false;
}
bool recon_update_ranges_when_recon() {
return (data->recon_config & 0x02000000UL) ? true : false;
}
bool recon_load_hamradios() {
return (data->recon_config & 0x01000000UL) ? true : false;
}
bool recon_match_mode() {
return (data->recon_config & 0x00800000UL) ? true : false;
}
void set_recon_autosave_freqs(const bool v ){
data->recon_config = (data->recon_config & ~0x80000000UL) | (v << 31);
}
void set_recon_autostart_recon(const bool v ){
data->recon_config = (data->recon_config & ~0x40000000UL) | (v << 30);
}
void set_recon_continuous(const bool v ){
data->recon_config = (data->recon_config & ~0x20000000UL) | (v << 29);
}
void set_recon_clear_output(const bool v ){
data->recon_config = (data->recon_config & ~0x10000000UL) | (v << 28);
}
void set_recon_load_freqs(const bool v ){
data->recon_config = (data->recon_config & ~0x08000000UL) | (v << 27);
}
void set_recon_load_ranges(const bool v ){
data->recon_config = (data->recon_config & ~0x04000000UL) | (v << 26);
}
void set_recon_update_ranges_when_recon(const bool v ){
data->recon_config = (data->recon_config & ~0x02000000UL) | (v << 25);
}
void set_recon_load_hamradios(const bool v ){
data->recon_config = (data->recon_config & ~0x01000000UL) | (v << 24);
}
void set_recon_match_mode(const bool v ) {
data->recon_config = (data->recon_config & ~0x00800000UL) | (v << 23);
}
} /* namespace persistent_memory */
} /* namespace portapack */
@@ -188,6 +188,26 @@ void set_clkout_enabled(bool v);
uint32_t clkout_freq();
void set_clkout_freq(uint32_t freq);
/* Recon app */
bool recon_autosave_freqs();
bool recon_autostart_recon();
bool recon_continuous();
bool recon_clear_output();
bool recon_load_freqs();
bool recon_load_ranges();
bool recon_update_ranges_when_recon();
bool recon_load_hamradios();
bool recon_match_mode();
void set_recon_autosave_freqs(const bool v);
void set_recon_autostart_recon(const bool v);
void set_recon_continuous(const bool v);
void set_recon_clear_output(const bool v);
void set_recon_load_freqs(const bool v);
void set_recon_load_ranges(const bool v);
void set_recon_update_ranges_when_recon(const bool v);
void set_recon_load_hamradios(const bool v );
void set_recon_match_mode( const bool v );
} /* namespace persistent_memory */
} /* namespace portapack */
+153
View File
@@ -984,6 +984,159 @@ bool Button::on_touch(const TouchEvent event) {
#endif
}
/* ButtonWithEncoder ****************************************************************/
ButtonWithEncoder::ButtonWithEncoder(
Rect parent_rect,
std::string text,
bool instant_exec
) : Widget { parent_rect },
text_ { text },
instant_exec_ { instant_exec }
{
set_focusable(true);
}
void ButtonWithEncoder::set_text(const std::string value) {
text_ = value;
set_dirty();
}
int32_t ButtonWithEncoder::get_encoder_delta() {
return encoder_delta ;
}
void ButtonWithEncoder::set_encoder_delta( const int32_t delta )
{
encoder_delta = delta ;
}
std::string ButtonWithEncoder::text() const {
return text_;
}
void ButtonWithEncoder::paint(Painter& painter) {
Color bg, fg;
const auto r = screen_rect();
if (has_focus() || highlighted()) {
bg = style().foreground;
fg = Color::black();
} else {
bg = Color::grey();
fg = style().foreground;
}
const Style paint_style = { style().font, bg, fg };
painter.draw_rectangle({r.location(), {r.size().width(), 1}}, Color::light_grey());
painter.draw_rectangle({r.location().x(), r.location().y() + r.size().height() - 1, r.size().width(), 1}, Color::dark_grey());
painter.draw_rectangle({r.location().x() + r.size().width() - 1, r.location().y(), 1, r.size().height()}, Color::dark_grey());
painter.fill_rectangle(
{ r.location().x(), r.location().y() + 1, r.size().width() - 1, r.size().height() - 2 },
paint_style.background
);
const auto label_r = paint_style.font.size_of(text_);
painter.draw_string(
{ r.location().x() + (r.size().width() - label_r.width()) / 2, r.location().y() + (r.size().height() - label_r.height()) / 2 },
paint_style,
text_
);
}
void ButtonWithEncoder::on_focus() {
if( on_highlight )
on_highlight(*this);
}
bool ButtonWithEncoder::on_key(const KeyEvent key) {
if( key == KeyEvent::Select ) {
if( on_select ) {
on_select(*this);
return true;
}
} else {
if( on_dir ) {
return on_dir(*this, key);
}
}
return false;
}
bool ButtonWithEncoder::on_touch(const TouchEvent event) {
switch(event.type) {
case TouchEvent::Type::Start:
set_highlighted(true);
set_dirty();
if( on_touch_press) {
on_touch_press(*this);
}
if( on_select && instant_exec_ ) {
on_select(*this);
}
return true;
case TouchEvent::Type::End:
set_highlighted(false);
set_dirty();
if( on_touch_release) {
on_touch_release(*this);
}
if( on_select && !instant_exec_ ) {
on_select(*this);
}
return true;
default:
return false;
}
#if 0
switch(event.type) {
case TouchEvent::Type::Start:
flags.highlighted = true;
set_dirty();
return true;
case TouchEvent::Type::Move:
{
const bool new_highlighted = screen_rect().contains(event.point);
if( flags.highlighted != new_highlighted ) {
flags.highlighted = new_highlighted;
set_dirty();
}
}
return true;
case TouchEvent::Type::End:
if( flags.highlighted ) {
flags.highlighted = false;
set_dirty();
if( on_select ) {
on_select(*this);
}
}
return true;
default:
return false;
}
#endif
}
bool ButtonWithEncoder::on_encoder(const EncoderEvent delta) {
if( delta != 0 )
{
encoder_delta += delta ;
delta_change = true ;
on_change();
}
else
delta_change = 0 ;
return true ;
}
/* NewButton ****************************************************************/
NewButton::NewButton(
+45
View File
@@ -414,6 +414,51 @@ private:
bool instant_exec_ { false };
};
class ButtonWithEncoder : public Widget {
public:
std::function<void(ButtonWithEncoder&)> on_select { };
std::function<void(ButtonWithEncoder&)> on_touch_release { }; // Executed when releasing touch, after on_select.
std::function<void(ButtonWithEncoder&)> on_touch_press { }; // Executed when touching, before on_select.
std::function<bool(ButtonWithEncoder&, KeyEvent)> on_dir { };
std::function<void(ButtonWithEncoder&)> on_highlight { };
ButtonWithEncoder(Rect parent_rect, std::string text, bool instant_exec); // instant_exec: Execute on_select when you touching instead of releasing
ButtonWithEncoder(
Rect parent_rect,
std::string text
) : ButtonWithEncoder { parent_rect, text, false }
{
}
ButtonWithEncoder(
) : ButtonWithEncoder { { }, { } }
{
}
std::function<void()> on_change { };
void set_text(const std::string value);
int32_t get_encoder_delta();
void set_encoder_delta( const int32_t delta );
std::string text() const;
void paint(Painter& painter) override;
void on_focus() override;
bool on_key(const KeyEvent key) override;
bool on_touch(const TouchEvent event) override;
bool on_encoder(const EncoderEvent delta) override;
private:
std::string text_;
int32_t encoder_delta = 0 ;
bool delta_change = 0 ;
bool instant_exec_ { false };
};
class NewButton : public Widget {
public:
std::function<void(void)> on_select { };
+1 -1
View File
@@ -84,7 +84,7 @@ void WM8731::init() {
});
write(AnalogAudioPathControl {
.micboost = 1, // Enable 20dB boost
.micboost = 0, // Disable 20dB boost by default
.mutemic = 0, // Disable mute (unmute)
.insel = 1, // Microphone input to ADC
.bypass = 0,
+17 -7
View File
@@ -345,18 +345,28 @@ public:
void speaker_disable() {};
void microphone_enable() override {
// TODO: Implement
}
void microphone_enable(int8_t wm8731_boost_GUI) override {
microphone_mute(true); // c/m to reduce "plop noise" when changing wm8731_boost_GUI.
// chThdSleepMilliseconds(20); // does not help to reduce the "plop noise"
microphone_boost((wm8731_boost_GUI<2) ? 1 : 0 ); // 1 = Enable Boost (+20 dBs) . 0 = Disable Boost (0dBs).
chThdSleepMilliseconds(120); // >50 msegs, very effective , >100 msegs minor improvement ,120 msegs trade off speed .
microphone_mute(false);
// (void)alc_mode; In prev. fw version , when we did not use at all param., to avoid "unused warning" when compiling.)
}
void microphone_disable() override {
// TODO: Implement
}
// void microphone_mute(const bool mute) {
// map.r.analog_audio_path_control.mutemic = (mute ? 0 : 1);
// write(Register::AnalogAudioPathControl);
// }
void microphone_boost(const bool boost) {
map.r.analog_audio_path_control.micboost = (boost ? 1 : 0);
write(Register::AnalogAudioPathControl);
}
void microphone_mute(const bool mute) {
map.r.analog_audio_path_control.mutemic = (mute ? 1 : 0); //1 = Enable Mute , 0 = Disable Mute
write(Register::AnalogAudioPathControl);
}
// void set_adc_source(const ADCSource adc_source) {
// map.r.analog_audio_path_control.insel = toUType(adc_source);
+1 -1
Submodule hackrf updated: dfadf6a31c...e3e406491d
+1
View File
@@ -0,0 +1 @@
a=76000000,b=90000000,m=WFM,bw=16k,s=50KHz,d=WFM Japan
+1
View File
@@ -0,0 +1 @@
a=65800000,b=74000000,m=WFM,bw=16k,s=30KHz,d=WFM OIRT
+1
View File
@@ -0,0 +1 @@
a=87500000,b=108000000,m=WFM,bw=16k,s=50KHz,d=WFM Standard
+22
View File
@@ -0,0 +1,22 @@
a=150000,b=285000,m=AM,bw=DSB,s=5KHz,d=Longwave broadcast band|BCB (EU)
a=525000,b=1605000,m=AM,bw=DSB,s=5KHz,d=AM broadcast band|BCB (EU & J)
a=530000,b=1710000,m=AM,bw=DSB,s=5KHz,d=AM broadcast band|BCB (US)
a=1800000,b=29700000,m=WFM,bw=16k,d=Amateur_radio|Amateur
a=26900000,b=27400000,m=WFM,bw=16k,d=Citizens_band_radio|Citizens band
a=28000000,b=30000000,m=WFM,bw=16k,d=Amateur_radio|Amateur
a=29000000,b=54000000,m=WFM,bw=16k,d=Land mobile
a=50000000,b=54000000,m=WFM,bw=16k,d=Amateur_radio|Amateur
a=65000000,b=85000000,m=WFM,bw=16k,d=Land mobile (EU)
a=108000000,b=136000000,m=WFM,bw=16k,d=Aircraft
a=120000000,b=160000000,m=WFM,bw=16k,s=50KHz,d=Land mobile (EU)
a=132000000,b=174000000,m=WFM,bw=16k,s=50KHz,d=Land mobile
a=142000000,b=170000000,m=WFM,bw=16k,s=50KHz,d=Land mobile (J)
a=144000000,b=148000000,m=WFM,bw=16k,s=50KHz,d=Amateur_radio|Amateur
a=216000000,b=222000000,m=WFM,bw=16k,s=50KHz,d=Land mobile
a=222000000,b=225000000,m=WFM,bw=16k,s=50KHz,d=Amateur_radio|Amateur
a=335000000,b=384000000,m=WFM,bw=16k,s=50KHz,d=Land mobile (J)
a=406000000,b=512000000,m=WFM,bw=16k,s=50KHz,d=Land mobile
a=450000000,b=470000000,m=WFM,bw=16k,s=50KHz,d=Land mobile (J)
a=430000000,b=450000000,m=WFM,bw=16k,s=50KHz,d=Amateur_radio|Amateur
a=806000000,b=947000000,m=WFM,bw=16k,s=50KHz,d=Land mobile
a=1200000000,b=1600000000,m=WFM,bw=16k,s=50KHz,d=Amateur|Land mobile|GPS
+3
View File
@@ -0,0 +1,3 @@
##FREQ FILE SAMPLE RATE
315000000,SAMPLES/TeslaChargePort_US.C16,500000
433920000,SAMPLES/TeslaChargePort_EU_AU.C16,500000
View File