Compare commits

..

29 Commits

Author SHA1 Message Date
Samir Sánchez Garnica 64f8158134 External App ROOK(Remote On-Off Keying) (#2363) 2024-11-17 21:23:56 +01:00
Totoo 59f72cbff1 Flipper sub (raw+binraw AND ONLY OOK) TX (#2361) 2024-11-16 18:03:53 +01:00
Erwin Ried 31c53dc455 Update README.md (#2362) 2024-11-15 14:46:30 +01:00
Erwin Ried ff12d06757 Update links README.md
(direct link to opensourcesdrlab for now, without grabify tracking due technical issue)
2024-11-15 13:38:49 +01:00
Erwin Ried 5b540fa659 Update README.md 2024-11-14 22:39:58 +01:00
Erwin Ried 9cccfa63e5 Update README.md 2024-11-14 22:35:32 +01:00
sommermorgentraum 6c838256df auto scroll the name list (#2358)
* auto scroll the name list

* script

* remove uneeded empty line in script

* script
2024-11-14 14:52:43 +01:00
RocketGod c8f236a708 CVS Spam v0.2 (#2357)
* Make the CVS Spam app

CHAOS.C16 is over 100mb and send to JLynx to be included in the sdcard ZIP file.

* indentation

* C16 files are perfect. Disregard any previous files for sdcard/CVSFILES. CHAOS now randomizes files to save space.

---------

Co-authored-by: sommermorgentraum <24917424+zxkmm@users.noreply.github.com>
2024-11-14 15:06:52 +08:00
Totoo 4641dcb449 Ookbrute (#2354) 2024-11-11 17:05:19 +01:00
gullradriel 458a6634bf Splash resize (#2353)
* resized default splash screens to maximum displayed size
* fix splash screen X,Y position to 0,16
2024-11-09 15:12:39 +01:00
RocketGod b8a64598ba Make the CVS Spam app (#2352) 2024-11-08 22:26:04 +01:00
RocketGod 09dff447de Create the Shopping Cart Lock app (#2326) 2024-11-08 16:10:25 +01:00
Erwin Ried 079329fc6c Update README.md
Wrong template was linked
2024-11-08 15:36:21 +01:00
Erwin Ried 674059801d Update front videos and links on README.md (#2351)
Some links were broken again and lets promote RocketGod's video :)
2024-11-08 14:41:55 +01:00
Totoo 5020e5bd28 I2cshell (#2348)
I2C shell implementation.
2024-11-08 11:46:27 +01:00
Totoo c31fef0535 Removed fake brightness (#2349) 2024-11-08 15:47:22 +08:00
Totoo a153cd741d remove the only 1 stoi (#2341) 2024-11-08 08:12:50 +01:00
sommermorgentraum 5851b47f99 add text for ccache in makefile to prevent confusing Ninja user (#2346)
* add necessary text for ccache in makefile to prevent confusing Ninja user

* typo fix

* textual
2024-11-07 23:02:52 +08:00
Brumi-2021 83a488e5b9 Auto switch C16/C8 default REC format in both BW directions. (#2343) 2024-11-07 10:55:32 +08:00
gullradriel 110a543ed3 save and restore region and or manual frequency values (#2340) 2024-11-05 14:56:38 +01:00
Benjamin Møller da5322765d Add about_simple updater from github (#2328)
* Generator for updating the about-page in PP from github.

* Fixing typo

* Rename generate_ui-about-simple.ccp.py to generate_ui-about-simple.cpp.py

Rename file, fix typo
2024-11-05 10:41:08 +08:00
gullradriel 8df05a57ea Disable ui_fsk_rx (#2337)
* removing ui_fsk_rx.cpp from targets

* removing unneeded ui_fsk_rx.hpp from includes

* deleting the now unused ui_fsk_rx.cpp and hpp files

---------

Co-authored-by: gullradriel <gullradriel@no-mail.com>
2024-11-04 08:28:03 +08:00
sommermorgentraum bea9f444c6 fine tune waveform and ook again (#2322) 2024-11-03 20:19:29 +01:00
jLynx abd6177303 H4M CPLD (#2335)
* Added CPLD code for H4M

* Added CPLD code for H4M

* Added CPLD code for H4M

* Added CPLD code for H4M

* Clean up

* Clean up
2024-11-03 11:25:43 +13:00
Totoo d6a9c74665 Auto start again (#2333)
* Extend autostart a bit

* @zxkmm 's sizeof fix
2024-11-02 22:15:33 +08:00
sommermorgentraum 5bb23b636e autostart fix 2 (#2331) 2024-11-02 10:43:42 +01:00
jLynx d5296c6ac3 H4M open source schematic (#2332)
* Create test20241102

* Delete hardware/test20241102

* Create H4 schematic files

H4 schematic files

* Delete hardware/portapack_h4/a

* Create 20241101

20241101

* Delete hardware/portapack_h4 directory

* Create 20241101

* Schematic Files for the H4M

The schematic files for the portapack H4M.

* Rename 20241101 to readme_h4m

* Update readme_h4m

---------

Co-authored-by: OpenSourceSDRLab <opensourcesdr@outlook.com>
2024-11-02 22:30:10 +13:00
Totoo c9863187d6 battery display imp (#2327) 2024-10-30 12:19:17 +01:00
sommermorgentraum 13e4f225ea bump hackrf fw bin (#2321) 2024-10-28 07:02:41 +13:00
235 changed files with 49927 additions and 662 deletions
+2 -2
View File
@@ -88,12 +88,12 @@ if(USE_CCACHE)
if(CCACHE_FOUND)
set(CMAKE_CXX_COMPILER_LAUNCHER ${CCACHE_FOUND})
set(CMAKE_C_COMPILER_LAUNCHER ${CCACHE_FOUND})
message(STATUS "Using ccache, please keep an eye on this because sometimes it's not quite stable and generated unusable binary.\n-- use `cmake -DUSE_CCACHE=OFF ..` to turn off ccache")
message(STATUS "Using ccache, please keep an eye on this because sometimes it's not quite stable and generated unusable binary.\n-- use `cmake -DUSE_CCACHE=OFF ..` (pure cmake) or `cmake -G Ninja -DUSE_CCACHE=OFF .. ` (cmake with Ninja) to turn off ccache")
else()
message(WARNING "ccache is enabled but not found on the system.")
endif()
else()
message(STATUS "Not using ccache, use `cmake -DUSE_CCACHE=ON ..` to turn on ccache")
message(STATUS "Not using ccache, use `cmake -DUSE_CCACHE=ON ..` (pure cmake) or `cmake -G Ninja -DUSE_CCACHE=ON ..` (cmake with Ninja) to turn on ccache")
endif()
message(STATUS "-------^ ccache info--------")
+7 -7
View File
@@ -11,15 +11,15 @@ This is a fork of the [Havoc](https://github.com/furrtek/portapack-havoc/) firmw
[<img src="https://raw.githubusercontent.com/wiki/portapack-mayhem/mayhem-firmware/img/hw_overview_h2_front.png" height="400">](https://github.com/portapack-mayhem/mayhem-firmware/wiki/Hardware-overview) [<img src="https://raw.githubusercontent.com/wiki/portapack-mayhem/mayhem-firmware/img/hw_overview_h2_inside.png" height="400">](https://github.com/portapack-mayhem/mayhem-firmware/wiki/Hardware-overview#portapack-internals)
*[PortaPack H2+HackRF+battery](https://grabify.link/ZYYPLB) (clone) with a custom [3d printed case](https://github.com/portapack-mayhem/mayhem-firmware/wiki/H2-Enclosure)*
*[PortaPack H2+HackRF+battery](https://grabify.link/P9CO0J) (clone) with a custom [3d printed case](https://github.com/portapack-mayhem/mayhem-firmware/wiki/3d-printed-enclosure)*
# What is this?
If you are new to *HackRF+PortaPack+Mayhem*, check these:
[<img alt="The new HackRF Portapack H4M" src="https://img.youtube.com/vi/onQRdCITmuk/maxresdefault.jpg" width="701">](https://grabify.link/0JUHZ6)
[<img alt="HackRF Portapack H4M - Getting Started Guide" src="https://img.youtube.com/vi/wzP0zWi85SI/maxresdefault.jpg" width="701">](https://grabify.link/F9MPOO)
[<img alt="Its TOO Easy to Accidentally Do Illegal Stuff with This" src="https://img.youtube.com/vi/OPckpjBSAOw/maxresdefault.jpg" width="172">](https://grabify.link/X4D5TF) [<img alt="What is the HackRF One Portapack H2+?" src="https://img.youtube.com/vi/alrFbY5vxt4/maxresdefault.jpg" width="172">](https://grabify.link/9UZGEW) [<img alt="Beginner's Guide To The HackRF & Portapak With Mayhem" src="https://img.youtube.com/vi/H-bqdWfbhpg/maxresdefault.jpg" width="172">](https://grabify.link/5MU2VH) [<img alt="HackRF 101 : Everything You Need to Know to Get Started!" src="https://img.youtube.com/vi/xGR_PMD9LeU/maxresdefault.jpg" width="172">](https://grabify.link/C0J6ZR)
[<img alt="Its TOO Easy to Accidentally Do Illegal Stuff with This" src="https://img.youtube.com/vi/OPckpjBSAOw/maxresdefault.jpg" width="172">](https://grabify.link/X4D5TF) [<img alt="What is the HackRF One Portapack H2+?" src="https://img.youtube.com/vi/alrFbY5vxt4/maxresdefault.jpg" width="172">](https://grabify.link/9UZGEW) [<img alt="The new HackRF Portapack H4M" src="https://img.youtube.com/vi/onQRdCITmuk/maxresdefault.jpg" width="172">](https://grabify.link/0JUHZ6) [<img alt="HackRF 101 : Everything You Need to Know to Get Started!" src="https://img.youtube.com/vi/xGR_PMD9LeU/maxresdefault.jpg" width="172">](https://grabify.link/C0J6ZR)
# Frequently Asked Questions
@@ -27,11 +27,11 @@ This repository expands upon the previous work by many people and aims to consta
## What to buy?
:heavy_check_mark: ![Static Badge](https://img.shields.io/badge/NEW-yellow) The fabulous [PortaPack H4M Mayhem](https://grabify.link/VPMPSL), featuring numerous improvements and accessories. Sold by our friends at [OpenSourceSDRLab](https://grabify.link/99SAMT). Join their giveaways on discord (check the badge on top).
:heavy_check_mark: ![Static Badge](https://img.shields.io/badge/NEW-yellow) The fabulous [PortaPack H4M Mayhem](https://opensourcesdrlab.com/products/h4m-receiver-and-spectrum-analyzer), featuring numerous improvements and accessories. Sold by our friends at [OpenSourceSDRLab](https://grabify.link/99SAMT). Join their giveaways on discord (check the badge on top).
:heavy_check_mark: A recommended one is this [PortaPack H2](https://grabify.link/ZYYPLB), that includes everything you need with the plastic case "inspired" on [this](https://github.com/portapack-mayhem/mayhem-firmware/wiki/H2-Enclosure).
:heavy_check_mark: A recommended one is this [PortaPack H2](https://grabify.link/P9CO0J), that includes everything you need with the plastic case "inspired" on [this](https://github.com/portapack-mayhem/mayhem-firmware/wiki/3d-printed-enclosure).
:heavy_check_mark: Some individuals lean towards the [H2 with a metal enclosure](https://grabify.link/XNGTAP), but its advantages remain debated. Share your insights on our [wiki](https://github.com/portapack-mayhem/mayhem-firmware/wiki/Hardware-overview).
:heavy_check_mark: Some individuals lean towards the [H2 with a metal enclosure](https://grabify.link/LZPBH9), but its advantages remain debated. Share your insights on our [wiki](https://github.com/portapack-mayhem/mayhem-firmware/wiki/Hardware-overview).
:warning: Be cautious , *ask* the seller about compatibility with the latest releases. Look out for the description of the item, if they provide the firmware files for an older version or they have custom setup instructions, this means it might be **NOT compatible**, for example:
@@ -55,7 +55,7 @@ Consider that the hardware and firmware has been created and maintain by a [lot]
To support the people behind the hardware, please buy a genuine [HackRF](https://greatscottgadgets.com/hackrf/) and [PortaPack](https://store.sharebrained.com/products/portapack-for-hackrf-one-kit).
## What if I really want something specific?
If what you need can be relevant in general, you can [request a feature](https://github.com/portapack-mayhem/mayhem-firmware/issues/new?labels=enhancement&template=feature_request.md). Alternatively, go to our Discord by clicking the chat badge on [top](#portapack-mayhem) and discuss there.
If what you need can be relevant in general, you can [request a feature](https://github.com/portapack-mayhem/mayhem-firmware/issues/new?assignees=&labels=enhancement&projects=&template=02_feature_request.yml). Alternatively, go to our Discord by clicking the chat badge on [top](#portapack-mayhem) and discuss there.
## What if I need help?
First, check the [documentation](https://github.com/portapack-mayhem/mayhem-firmware/wiki). If you find a bug or you think the problem is related to the current repository, please open an [issue](https://github.com/portapack-mayhem/mayhem-firmware/issues/new/choose).
+1 -1
View File
@@ -117,6 +117,7 @@ set(CSRC
usb_serial_descriptor.c
usb_serial_endpoints.c
usb_serial_device_to_host.c
i2c_device_to_host.c
${HACKRF_PATH}/firmware/common/usb.c
${HACKRF_PATH}/firmware/common/usb_queue.c
${HACKRF_PATH}/firmware/hackrf_usb/usb_device.c
@@ -291,7 +292,6 @@ set(CPPSRC
apps/ui_fileman.cpp
apps/ui_flash_utility.cpp
apps/ui_freqman.cpp
apps/ui_fsk_rx.cpp
apps/ui_iq_trim.cpp
apps/ui_level.cpp
apps/ui_looking_glass_app.cpp
+5 -2
View File
@@ -87,9 +87,12 @@ CaptureAppView::CaptureAppView(NavigationView& nav)
auto anti_alias_filter_bandwidth = filter_bandwidth_for_sampling_rate(actual_sample_rate);
receiver_model.set_baseband_bandwidth(anti_alias_filter_bandwidth);
// Automatically switch default capture format to C8 when bandwidth setting is increased to >=1.5MHz
// Automatically switch default capture format to C8 when bandwidth setting is increased to >=1.5MHz anb back to C16 for <=1,25Mhz
if ((bandwidth >= 1500000) && (previous_bandwidth < 1500000)) {
option_format.set_selected_index(1);
option_format.set_selected_index(1); // Default C8 format for REC, 1500K ... 5500k
}
if ((bandwidth <= 1250000) && (previous_bandwidth > 1250000)) {
option_format.set_selected_index(0); // Default C16 format for REC , 12k5 ... 1250K
}
previous_bandwidth = bandwidth;
+37 -2
View File
@@ -1,5 +1,8 @@
#include "ui_about_simple.hpp"
#define ROLL_SPEED_FRAME_PER_LINE 60
// cuz frame rate of pp screen is probably 60, scroll per sec
namespace ui {
// TODO: Generate this automatically from github
@@ -87,10 +90,42 @@ AboutView::AboutView(NavigationView& nav) {
}
}
void AboutView::on_frame_sync() {
if (interacted) return;
if (frame_sync_count++ % ROLL_SPEED_FRAME_PER_LINE == 0) {
const auto current = menu_view.highlighted_index();
const auto count = menu_view.item_count();
if (current < count - 1) {
menu_view.set_highlighted(current + 1);
} else {
menu_view.set_highlighted(0);
// ^ to go back to the REAL top instead of make the 2 at the top to make the title disappeares
menu_view.set_highlighted(2); // the first line that has human name
}
}
}
void AboutView::focus() {
button_ok.focus();
menu_view.set_highlighted(2); // the first line that has human name
}
bool AboutView::on_touch(const TouchEvent) {
interacted = true;
return false;
}
bool AboutView::on_key(const KeyEvent) {
interacted = true;
return false;
}
bool AboutView::on_encoder(const EncoderEvent) {
interacted = true;
menu_view.focus();
// put focus on last text line to make it more obvious that list is scrollable
menu_view.set_highlighted(10);
return false;
}
} /* namespace ui */
@@ -14,6 +14,13 @@ class AboutView : public View {
std::string title() const override { return "About"; };
private:
virtual bool on_key(const KeyEvent event);
virtual bool on_encoder(const EncoderEvent event);
virtual bool on_touch(const TouchEvent event);
bool interacted{false};
uint16_t frame_sync_count{0};
void on_frame_sync();
MenuView menu_view{
{0, 0, 240, 264},
true};
@@ -22,6 +29,12 @@ class AboutView : public View {
{240 / 3, 270, 240 / 3, 24},
"OK",
};
MessageHandlerRegistration message_handler_frame_sync{
Message::ID::DisplayFrameSync,
[this](const Message* const) {
this->on_frame_sync();
}};
};
} // namespace ui
+26 -6
View File
@@ -94,21 +94,39 @@ APRSRxView::APRSRxView(NavigationView& nav, Rect parent_rect)
record_view.set_sampling_rate(24000);
options_region.on_change = [this](size_t, int32_t i) {
if (i == 0) {
field_frequency.on_change = [this](rf::Frequency f) { (void)f; };
if (i == 0) { // MAN Manual setting
field_frequency.set_value(aprs_rx_freq);
} else if (i == 1) { // NA - North America - is also the default
field_frequency.set_value(144390000);
} else if (i == 1) {
} else if (i == 2) { // EUR
field_frequency.set_value(144800000);
} else if (i == 2) {
} else if (i == 3) { // AUS
field_frequency.set_value(145175000);
} else if (i == 3) {
} else if (i == 4) { // NZ
field_frequency.set_value(144575000);
} else if (i == 4) {
} else if (i == 5) { // ISS
field_frequency.set_value(145825000);
}
options_region_id = i;
receiver_model.set_target_frequency(field_frequency.value()); // Retune
field_frequency.on_change = [this](rf::Frequency f) {
aprs_rx_freq = f;
options_region.set_selected_index(0, true);
};
};
field_frequency.set_step(100);
options_region.set_selected_index(0, true);
field_frequency.on_edit = [this]() {
auto freq_view = nav_.push<FrequencyKeypadView>(field_frequency.value());
freq_view->on_changed = [this](rf::Frequency f) {
aprs_rx_freq = f;
field_frequency.set_value(f);
};
};
// Note: setting the region is also going to sef field_frequency.on_change
options_region.set_selected_index(options_region_id, true);
logger = std::make_unique<APRSLogger>();
if (logger)
@@ -124,6 +142,8 @@ APRSRxView::APRSRxView(NavigationView& nav, Rect parent_rect)
void APRSRxView::on_freqchg(int64_t freq) {
field_frequency.set_value(freq);
aprs_rx_freq = freq;
options_region.set_selected_index(0, true);
}
void APRSRxView::on_packet(const APRSPacketMessage* message) {
+14 -9
View File
@@ -190,6 +190,8 @@ class APRSRxView : public View {
private:
void on_data(uint32_t value, bool is_data);
bool reset_console = false;
uint8_t options_region_id = 1; // default to North America
rf::Frequency aprs_rx_freq{144390000}; // default to North America frequency
NavigationView& nav_;
RxRadioState radio_state_{
@@ -198,7 +200,10 @@ class APRSRxView : public View {
3072000 /* sampling rate */
};
app_settings::SettingsManager settings_{
"rx_aprs", app_settings::Mode::RX};
"rx_aprs",
app_settings::Mode::RX,
{{"options_region_id"sv, &options_region_id},
{"aprs_rx_freq"sv, &aprs_rx_freq}}};
uint8_t console_color{0};
std::string str_log{""};
@@ -220,15 +225,15 @@ class APRSRxView : public View {
OptionsField options_region{
{0 * 8, 0 * 8},
3,
{{"NA ", 0},
{"EUR", 1},
{"AUS", 2},
{"NZ ", 3},
{"ISS", 4}}};
{{"MAN", 0},
{"NA ", 1},
{"EUR", 2},
{"AUS", 3},
{"NZ ", 4},
{"ISS", 5}}};
RxFrequencyField field_frequency{
{3 * 8, 0 * 16},
nav_};
FrequencyField field_frequency{
{3 * 8, 0 * 16}};
// DEBUG
RecordView record_view{
+15 -3
View File
@@ -75,7 +75,19 @@ void BattinfoView::update_result() {
text_current.hidden(false);
text_charge.hidden(false);
text_current.set(to_string_dec_int(current) + " mA");
text_charge.set(current >= 0 ? "Charging" : "Discharging");
if (current >= 25) // when >25mA it is charging in any scenario
text_charge.set("Charging");
else {
if (current > -25) { // between -25 and 25
if (voltage > 4060 || percent == 100) { // the voltage is high enough, so it is full, that's why no mA
text_charge.set("Full");
} else {
text_charge.set("Holding"); // not enough voltage, so should charge. maybe the batttery is off, or USB power is not enough
}
} else {
text_charge.set("Discharging"); // less then -25mA, so it is discharging
}
}
labels_opt.hidden(false);
text_ttef.hidden(false);
@@ -103,7 +115,7 @@ void BattinfoView::update_result() {
if ((valid_mask & battery::BatteryManagement::BATT_VALID_TTEF) == battery::BatteryManagement::BATT_VALID_TTEF) {
text_ttef.hidden(false);
float ttef = 0;
if (current <= 0) {
if (current <= 0) { // we keep this yet
ttef = battery::BatteryManagement::get_tte();
} else {
ttef = battery::BatteryManagement::get_ttf();
@@ -133,7 +145,7 @@ void BattinfoView::update_result() {
}
if (uichg) set_dirty();
// to update status bar too, send message in behalf of batt manager
BatteryStateMessage msg{valid_mask, percent, current >= 0, voltage};
BatteryStateMessage msg{valid_mask, percent, current >= 25, voltage};
EventDispatcher::send_message(msg);
}
+28 -3
View File
@@ -25,6 +25,9 @@
#include "baseband_api.hpp"
#include "string_format.hpp"
#define PADDING_LEFT 1
#define PADDING_RIGHT 1
using namespace portapack;
namespace ui {
@@ -154,12 +157,34 @@ void EncodersConfigView::on_show() {
}
void EncodersConfigView::draw_waveform() {
// padding reason:
// in real world the signal would always start with low level and became low level again after yout turn off the radio;
// the waveform_buffer only controls drawing, the real send logic that been sent is controlled by frame_fragments
// so just for out of looking things
size_t length = frame_fragments.length();
for (size_t n = 0; n < length; n++)
waveform_buffer[n] = (frame_fragments[n] == '0') ? 0 : 1;
// currently not needed since all the supported OOK protocol wont exceed 550 yet
if (length + (PADDING_LEFT + PADDING_RIGHT) >= WAVEFORM_BUFFER_SIZE) {
length = WAVEFORM_BUFFER_SIZE - (PADDING_LEFT + PADDING_RIGHT);
}
waveform.set_length(length);
// padding l
for (size_t i = 0; i < PADDING_LEFT; i++) {
waveform_buffer[i] = 0;
}
// real wf
for (size_t n = 0; n < length; n++) {
waveform_buffer[n + PADDING_LEFT] = (frame_fragments[n] == '0') ? 0 : 1;
}
// padding r
for (size_t i = length + PADDING_LEFT; i < WAVEFORM_BUFFER_SIZE; i++) {
waveform_buffer[i] = 0;
}
waveform.set_length(length + PADDING_LEFT + PADDING_RIGHT);
waveform.set_dirty();
}
+3 -1
View File
@@ -32,6 +32,8 @@
#include <memory>
#include <vector>
#define WAVEFORM_BUFFER_SIZE 550
using namespace encoders;
namespace ui {
@@ -56,7 +58,7 @@ class EncodersConfigView : public View {
std::string frame_fragments = "0";
private:
int16_t waveform_buffer[550];
int16_t waveform_buffer[WAVEFORM_BUFFER_SIZE];
const encoder_def_t* encoder_def{};
void draw_waveform();
@@ -80,7 +80,7 @@ void ExternalModuleView::on_tick_second() {
continue;
}
std::string btnText = (std::string) "App " + std::to_string(device_info->application_count) + ": " + (const char*)appInfo->app_name;
std::string btnText = (std::string) "App " + std::to_string(i + 1) + ": " + (const char*)appInfo->app_name;
switch (appInfo->menu_location) {
case app_location_t::UTILITIES:
-198
View File
@@ -1,198 +0,0 @@
/*
* 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_fsk_rx.hpp"
#include "audio.hpp"
#include "baseband_api.hpp"
#include "portapack_persistent_memory.hpp"
#include "string_format.hpp"
#include "utility.hpp"
#include "file_path.hpp"
#include "ui_freqman.hpp"
using namespace portapack;
namespace pmem = portapack::persistent_memory;
void FskRxLogger::log_raw_data(const std::string& data, const uint32_t frequency) {
std::string entry = "Raw: F:" + to_string_dec_uint(frequency) + "Hz";
// // Raw hex dump of all the codewords
// for (size_t c = 0; c < 16; c++)
// entry += to_string_hex(packet[c], 8) + " ";
log_file.write_entry(data + entry);
}
void FskRxLogger::log_decoded(Timestamp timestamp, const std::string& text) {
log_file.write_entry(timestamp, text);
}
namespace ui {
//---------------------------------------------------------------------------------------------------------------
// Console View
//---------------------------------------------------------------------------------------------------------------
FskRxAppConsoleView::FskRxAppConsoleView(NavigationView& nav, Rect parent_rect)
: View(parent_rect), nav_{nav} {
add_child(&console);
};
void FskRxAppConsoleView::on_packet(uint32_t value, bool is_data) {
if (is_data) {
console.write(to_string_dec_uint(value) + " ");
}
}
void FskRxAppConsoleView::on_show() {
hidden(false);
}
void FskRxAppConsoleView::on_hide() {
hidden(true);
}
FskRxAppConsoleView::~FskRxAppConsoleView() {
}
//---------------------------------------------------------------------------------------------------------------
// Spectrum View
//---------------------------------------------------------------------------------------------------------------
FskRxAppView::FskRxAppView(NavigationView& nav, Rect parent_rect)
: View(parent_rect), nav_{nav} {
add_child(&waterfall);
hidden(true);
}
FskRxAppView::~FskRxAppView() {
}
void FskRxAppView::focus() {
}
void FskRxAppView::on_show() {
hidden(false);
waterfall.start();
}
void FskRxAppView::on_hide() {
hidden(true);
waterfall.stop();
}
//---------------------------------------------------------------------------------------------------------------
// Base View
//---------------------------------------------------------------------------------------------------------------
FskxRxMainView::FskxRxMainView(NavigationView& nav)
: nav_{nav} {
add_children({&tab_view,
&view_data,
&view_stream,
&labels,
&rssi,
&channel,
&field_rf_amp,
&field_lna,
&field_vga,
&field_frequency,
&deviation_frequency,
&record_view});
baseband::run_image(portapack::spi_flash::image_tag_fskrx);
// DEBUG
record_view.on_error = [&nav](std::string message) {
nav.display_modal("Error", message);
};
deviation_frequency.on_change = [this](rf::Frequency f) {
refresh_ui(f);
};
// Set initial sampling rate
/* Bandwidth of 2FSK is 2 * Deviation */
record_view.set_sampling_rate(initial_deviation * 2);
field_frequency.set_value(initial_target_frequency);
deviation_frequency.set_value(initial_deviation);
logger.append(logs_dir / u"FSKRX.TXT");
baseband::set_fsk(initial_deviation);
audio::output::start();
receiver_model.enable();
}
void FskxRxMainView::handle_decoded(Timestamp timestamp, const std::string& prefix) {
if (logging()) {
logger.log_decoded(timestamp, prefix);
}
}
void FskxRxMainView::refresh_ui(rf::Frequency deviationHz) {
/* Nyquist would imply a sample rate of 2x bandwidth, but because the ADC
* provides 2 values (I,Q), the sample_rate is equal to bandwidth here. */
/* Bandwidth of 2FSK is 2 * Deviation */
auto sample_rate = deviationHz * 2;
/* base_rate (bandwidth) is used for FFT calculation and display LCD, and also in recording writing SD Card rate. */
/* ex. sampling_rate values, 4Mhz, when recording 500 kHz (BW) and fs 8 Mhz, when selected 1 Mhz BW ... */
/* ex. recording 500kHz BW to .C16 file, base_rate clock 500kHz x2(I,Q) x 2 bytes (int signed) =2MB/sec rate SD Card. */
if (!view_stream.hidden()) {
view_stream.waterfall.stop();
}
// record_view determines the correct oversampling to apply and returns the actual sample rate.
// NB: record_view is what actually updates proc_capture baseband settings.
auto actual_sample_rate = record_view.set_sampling_rate(sample_rate);
// Update the radio model with the actual sampling rate.
receiver_model.set_sampling_rate(actual_sample_rate);
// Get suitable anti-aliasing BPF bandwidth for MAX2837 given the actual sample rate.
auto anti_alias_filter_bandwidth = filter_bandwidth_for_sampling_rate(actual_sample_rate);
receiver_model.set_baseband_bandwidth(anti_alias_filter_bandwidth);
if (!view_stream.hidden()) {
view_stream.waterfall.start();
}
}
void FskxRxMainView::focus() {
field_frequency.focus();
}
void FskxRxMainView::set_parent_rect(const Rect new_parent_rect) {
View::set_parent_rect(new_parent_rect);
ui::Rect waterfall_rect{0, 0, new_parent_rect.width(), new_parent_rect.height() - header_height};
view_stream.waterfall.set_parent_rect(waterfall_rect);
}
FskxRxMainView::~FskxRxMainView() {
audio::output::stop();
receiver_model.disable();
baseband::shutdown();
}
} /* namespace ui */
-177
View File
@@ -1,177 +0,0 @@
/*
* Copyright (C) 2015 Jared Boone, ShareBrained Technology, Inc.
* Copyright (C) 2018 Furrtek
* Copyright (C) 2023 gullradriel, Nilorea Studio Inc.
*
* 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_FSK_RX_H__
#define __UI_FSK_RX_H__
#include "ui_widget.hpp"
#include "ui_freq_field.hpp"
#include "ui_receiver.hpp"
#include "ui_record_view.hpp"
#include "ui_rssi.hpp"
#include "ui_spectrum.hpp"
#include "ui_tabview.hpp"
#include "app_settings.hpp"
#include "log_file.hpp"
#include "radio_state.hpp"
#include "pocsag_app.hpp"
#include <functional>
class FskRxLogger {
public:
Optional<File::Error> append(const std::filesystem::path& filename) {
return log_file.append(filename);
}
void log_raw_data(const std::string& data, const uint32_t frequency);
void log_decoded(Timestamp timestamp, const std::string& text);
private:
LogFile log_file{};
};
namespace ui {
class FskRxAppConsoleView : public View {
public:
FskRxAppConsoleView(NavigationView& nav, Rect parent_rec);
~FskRxAppConsoleView();
std::string title() const override { return "FSK RX Data"; };
void on_packet(uint32_t value, bool is_data);
void on_show() override;
void on_hide() override;
private:
NavigationView& nav_;
Console console{
{0, 0, 240, 224}};
};
class FskRxAppView : public View {
public:
FskRxAppView(NavigationView& nav, Rect parent_rect);
~FskRxAppView();
void focus() override;
void on_show() override;
void on_hide() override;
spectrum::WaterfallView waterfall{};
std::string title() const override { return "FSK RX Stream"; };
private:
NavigationView& nav_;
RxRadioState radio_state_{};
};
class FskxRxMainView : public View {
public:
FskxRxMainView(NavigationView& nav);
~FskxRxMainView();
void focus() override;
void set_parent_rect(const Rect new_parent_rect) override;
std::string title() const override { return "FSK RX"; };
private:
static constexpr uint32_t initial_target_frequency = 902'075'000;
static constexpr ui::Dim header_height = (5 * 16);
uint32_t initial_deviation{3750};
bool logging() const { return false; };
bool logging_raw() const { return false; };
NavigationView& nav_;
Rect view_rect = {0, header_height, 240, 224};
FskRxAppView view_stream{nav_, view_rect};
FskRxAppConsoleView view_data{nav_, view_rect};
TabView tab_view{
{"Data", Theme::getInstance()->fg_yellow->foreground, &view_data},
{"Stream", Theme::getInstance()->fg_cyan->foreground, &view_stream}};
void refresh_ui(rf::Frequency f);
void on_packet(uint32_t value, bool is_data);
void handle_decoded(Timestamp timestamp, const std::string& prefix);
uint32_t last_address = 0;
FskRxLogger logger{};
uint16_t packet_count = 0;
RxFrequencyField field_frequency{
{0 * 8, 4 * 8},
nav_};
RFAmpField field_rf_amp{
{11 * 8, 2 * 16}};
LNAGainField field_lna{
{13 * 8, 2 * 16}};
VGAGainField field_vga{
{16 * 8, 2 * 16}};
RSSI rssi{
{19 * 8 - 4, 35, 6 * 8, 4}};
Channel channel{
{19 * 8 - 4, 40, 6 * 8, 4}};
Labels labels{
{{0 * 8, 3 * 16}, "Deviation:", Theme::getInstance()->fg_light->foreground},
};
FrequencyField deviation_frequency{
{10 * 8, 3 * 16},
{3750, 500000},
};
// DEBUG
RecordView record_view{
{0 * 8, 4 * 16, 30 * 8, 1 * 16},
u"FSKRX_????.C16",
u"FSKRX",
RecordView::FileType::RawS16,
16384,
3};
MessageHandlerRegistration message_handler_packet{
Message::ID::AFSKData,
[this](Message* const p) {
const auto message = static_cast<const AFSKDataMessage*>(p);
this->view_data.on_packet(message->value, message->is_data);
}};
};
} /* namespace ui */
#endif /*__POCSAG_APP_H__*/
+2 -19
View File
@@ -324,7 +324,6 @@ SetUIView::SetUIView(NavigationView& nav) {
&toggle_bias_tee,
&toggle_clock,
&toggle_mute,
&toggle_fake_brightness,
&toggle_sd_card,
&button_save,
&button_cancel});
@@ -362,7 +361,6 @@ SetUIView::SetUIView(NavigationView& nav) {
toggle_clock.set_value(!pmem::ui_hide_clock());
toggle_speaker.set_value(!pmem::ui_hide_speaker());
toggle_mute.set_value(!pmem::ui_hide_mute());
toggle_fake_brightness.set_value(!pmem::ui_hide_fake_brightness());
toggle_battery_icon.set_value(!pmem::ui_hide_battery_icon());
toggle_battery_text.set_value(!pmem::ui_hide_numeric_battery());
toggle_sd_card.set_value(!pmem::ui_hide_sd_card());
@@ -391,7 +389,6 @@ SetUIView::SetUIView(NavigationView& nav) {
pmem::set_ui_hide_clock(!toggle_clock.value());
pmem::set_ui_hide_speaker(!toggle_speaker.value());
pmem::set_ui_hide_mute(!toggle_mute.value());
pmem::set_ui_hide_fake_brightness(!toggle_fake_brightness.value());
pmem::set_ui_hide_battery_icon(!toggle_battery_icon.value());
pmem::set_ui_hide_numeric_battery(!toggle_battery_text.value());
pmem::set_ui_hide_sd_card(!toggle_sd_card.value());
@@ -780,20 +777,13 @@ void SetConfigModeView::focus() {
/* SetDisplayView ************************************/
SetDisplayView::SetDisplayView(NavigationView& nav) {
add_children({&labels,
&field_fake_brightness,
&button_save,
add_children({&button_save,
&button_cancel,
&checkbox_invert_switch,
&checkbox_brightness_switch});
&checkbox_invert_switch});
field_fake_brightness.set_by_value(pmem::fake_brightness_level());
checkbox_brightness_switch.set_value(pmem::apply_fake_brightness());
checkbox_invert_switch.set_value(pmem::config_lcd_inverted_mode());
button_save.on_select = [&nav, this](Button&) {
pmem::set_apply_fake_brightness(checkbox_brightness_switch.value());
pmem::set_fake_brightness_level(field_fake_brightness.selected_index_value());
if (checkbox_invert_switch.value() != pmem::config_lcd_inverted_mode()) {
display.set_inverted(checkbox_invert_switch.value());
pmem::set_lcd_inverted_mode(checkbox_invert_switch.value());
@@ -801,13 +791,6 @@ SetDisplayView::SetDisplayView(NavigationView& nav) {
send_system_refresh();
nav.pop();
};
// only enable invert OR fake brightness
checkbox_invert_switch.on_select = [this](Checkbox&, bool v) {
if (v) checkbox_brightness_switch.set_value(false);
};
checkbox_brightness_switch.on_select = [this](Checkbox&, bool v) {
if (v) checkbox_invert_switch.set_value(false);
};
button_cancel.on_select = [&nav, this](Button&) {
nav.pop();
+3 -28
View File
@@ -363,12 +363,8 @@ class SetUIView : public View {
{19 * 8, 14 * 16 + 2, 16, 16},
&bitmap_icon_batt_text};
ImageToggle toggle_fake_brightness{
{21 * 8, 14 * 16 + 2, 16, 16},
&bitmap_icon_brightness};
ImageToggle toggle_sd_card{
{23 * 8, 14 * 16 + 2, 16, 16},
{21 * 8, 14 * 16 + 2, 16, 16},
&bitmap_sd_card_ok};
Button button_save{
@@ -710,8 +706,6 @@ class SetConfigModeView : public View {
};
};
using portapack::persistent_memory::fake_brightness_level_options;
class SetDisplayView : public View {
public:
SetDisplayView(NavigationView& nav);
@@ -721,27 +715,8 @@ class SetDisplayView : public View {
std::string title() const override { return "Display"; };
private:
Labels labels{
{{1 * 8, 1 * 16}, "Limits screen brightness", Theme::getInstance()->fg_light->foreground},
{{1 * 8, 2 * 16}, "(has a small performance", Theme::getInstance()->fg_light->foreground},
{{1 * 8, 3 * 16}, "impact when enabled).", Theme::getInstance()->fg_light->foreground},
{{2 * 8, 8 * 16}, "Brightness:", Theme::getInstance()->fg_light->foreground},
};
OptionsField field_fake_brightness{
{20 * 8, 8 * 16},
6,
{{"12.5%", fake_brightness_level_options::BRIGHTNESS_12p5},
{"25%", fake_brightness_level_options::BRIGHTNESS_25},
{"50%", fake_brightness_level_options::BRIGHTNESS_50}}};
Checkbox checkbox_brightness_switch{
{1 * 8, 5 * 16},
16,
"Enable brightness adjust"};
Checkbox checkbox_invert_switch{
{1 * 8, 10 * 16},
{1 * 8, 2 * 16},
23,
"Invert colors (For IPS)"};
@@ -795,7 +770,7 @@ class SetTouchscreenThresholdView : public View {
* threshold range: 1023/1 to 1023/128 = 1023 to 8
*/
NumberField field_threshold{
{1 * 8 + sizeof("Threshold:") * 8 + 8, 11 * 16},
{1 * 8 + 11 * 8 + 8, 11 * 16},
4,
{1, 1023},
1,
+310
View File
@@ -0,0 +1,310 @@
// CVS Spam app by RocketGod (@rocketgod-git) https://betaskynet.com
// Original .cu8 files by @jimilinuxguy https://github.com/jimilinuxguy/customer-assistance-buttons-sdr
// If you can read this, you're a nerd. :P
// Come join us at https://discord.gg/thepiratesreborn
#include "cvs_spam.hpp"
#include "io_file.hpp"
#include "metadata_file.hpp"
#include "oversample.hpp"
#include "io_convert.hpp"
#include "lfsr_random.hpp"
using namespace portapack;
namespace ui::external_app::cvs_spam {
void CVSSpamView::file_error(const std::filesystem::path& path, const std::string& error_details) {
nav_.display_modal("Error",
"File error:\n" + path.string() + "\n" + error_details);
}
void CVSSpamView::refresh_list() {
file_list.clear();
current_page = page;
uint32_t count = 0;
for (const auto& entry : std::filesystem::directory_iterator(cvsfiles_dir, u"*")) {
if (std::filesystem::is_regular_file(entry.status())) {
auto filename = entry.path().filename().string();
auto extension = entry.path().extension().string();
std::transform(extension.begin(), extension.end(), extension.begin(), ::tolower);
if (extension == ".c16" || extension == ".cu8") {
if (count >= (page - 1) * 50 && count < page * 50) {
file_list.push_back(entry.path());
if (file_list.size() == 50) {
page++;
break;
}
}
count++;
}
}
}
if (file_list.empty()) {
if (page == 1) {
menu_view.hidden(true);
text_empty.hidden(false);
} else {
page = 1;
refresh_list();
return;
}
} else {
menu_view.hidden(false);
text_empty.hidden(true);
menu_view.clear();
for (const auto& file : file_list) {
menu_view.add_item({file.filename().string(),
ui::Theme::getInstance()->fg_green->foreground,
nullptr,
[this](KeyEvent key) {
if (key == KeyEvent::Select) {
start_tx(menu_view.highlighted_index());
}
}});
}
page_info.set("Page " + std::to_string(current_page));
menu_view.set_highlighted(0);
}
if (file_list.size() < 50) {
page = 1;
}
}
void CVSSpamView::start_tx(const uint32_t id) {
if (is_active()) {
stop_tx();
return;
}
const uint32_t sample_rate = 250000;
current_file = cvsfiles_dir / file_list[id].filename();
File capture_file;
auto open_error = capture_file.open(current_file);
if (open_error) {
file_error(current_file,
"Cannot open file.\n"
"Initial file check failed.\n"
"Path: " +
cvsfiles_dir.string() +
"\n"
"Error: " +
std::to_string(static_cast<uint32_t>(open_error)));
return;
}
auto metadata_path = get_metadata_path(current_file);
auto metadata = read_metadata_file(metadata_path);
if (!metadata) {
metadata = capture_metadata{transmitter_model.target_frequency(), sample_rate};
}
auto file_size = capture_file.size();
capture_file.close();
replay_thread.reset();
transmitter_model.disable();
ready_signal = false;
baseband::set_sample_rate(metadata->sample_rate, get_oversample_rate(metadata->sample_rate));
auto reader = std::make_unique<FileConvertReader>();
if (auto error = reader->open(current_file)) {
file_error(current_file,
"Cannot read C16 data.\n"
"Check file format/perms.\n"
"Rate: " +
to_string_dec_uint(metadata->sample_rate) +
"\n"
"Size: " +
to_string_dec_uint(file_size) +
"\n"
"Error: " +
std::to_string(static_cast<uint32_t>(error)));
return;
}
progressbar.set_value(0);
transmitter_model.set_sampling_rate(get_actual_sample_rate(metadata->sample_rate));
transmitter_model.set_baseband_bandwidth(metadata->sample_rate <= 500000 ? 1750000 : 2500000);
transmitter_model.set_target_frequency(metadata->center_frequency);
transmitter_model.enable();
chThdSleepMilliseconds(100);
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);
});
}
void CVSSpamView::start_random_tx() {
if (is_active()) {
stop_tx();
return;
}
if (file_list.empty()) {
nav_.display_modal("Error", "No files found!");
return;
}
lfsr_v = lfsr_iterate(lfsr_v);
size_t random_index = lfsr_v % file_list.size();
const uint32_t sample_rate = 250000;
current_file = cvsfiles_dir / file_list[random_index].filename();
File capture_file;
auto open_error = capture_file.open(current_file);
if (open_error) {
file_error(current_file, "Cannot open file.\nInitial check failed.");
return;
}
auto metadata_path = get_metadata_path(current_file);
auto metadata = read_metadata_file(metadata_path);
if (!metadata) {
metadata = capture_metadata{transmitter_model.target_frequency(), sample_rate};
}
capture_file.close();
replay_thread.reset();
transmitter_model.disable();
ready_signal = false;
baseband::set_sample_rate(metadata->sample_rate, get_oversample_rate(metadata->sample_rate));
auto reader = std::make_unique<FileConvertReader>();
if (auto error = reader->open(current_file)) {
file_error(current_file, "Cannot read file data.");
return;
}
progressbar.set_value(0);
transmitter_model.set_sampling_rate(get_actual_sample_rate(metadata->sample_rate));
transmitter_model.set_baseband_bandwidth(metadata->sample_rate <= 500000 ? 1750000 : 2500000);
transmitter_model.set_target_frequency(metadata->center_frequency);
transmitter_model.enable();
chThdSleepMilliseconds(100);
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);
});
}
void CVSSpamView::on_tx_progress(const uint32_t progress) {
if (is_active()) {
progressbar.set_value(progress % 100);
progressbar.set_style(Theme::getInstance()->fg_red);
}
}
void CVSSpamView::focus() {
menu_view.focus();
}
bool CVSSpamView::is_active() const {
return (bool)replay_thread;
}
void CVSSpamView::stop_tx() {
replay_thread.reset();
transmitter_model.disable();
ready_signal = false;
thread_sync_complete = false;
chaos_mode = false;
progressbar.set_value(0);
chThdSleepMilliseconds(50);
}
CVSSpamView::CVSSpamView(NavigationView& nav)
: nav_{nav},
current_file{} {
baseband::run_image(portapack::spi_flash::image_tag_replay);
add_children({&menu_view,
&text_empty,
&button_prev_page,
&button_next_page,
&page_info,
&button_send,
&button_chaos,
&button_stop,
&progressbar});
button_send.set_style(Theme::getInstance()->fg_magenta);
button_chaos.set_style(Theme::getInstance()->fg_yellow);
button_stop.set_style(Theme::getInstance()->fg_red);
transmitter_model.set_sampling_rate(1536000);
transmitter_model.set_baseband_bandwidth(1750000);
transmitter_model.set_rf_amp(true);
transmitter_model.set_tx_gain(47);
transmitter_model.set_channel_bandwidth(1750000);
refresh_list();
button_prev_page.on_select = [this](Button&) {
if (is_active()) return;
if (current_page == 1) return;
if (current_page == 2) page = 1;
page = current_page - 1;
refresh_list();
};
button_next_page.on_select = [this](Button&) {
if (is_active()) return;
refresh_list();
};
button_send.on_select = [this](Button&) {
if (!file_list.empty()) {
start_tx(menu_view.highlighted_index());
}
};
button_chaos.on_select = [this](Button&) {
if (is_active()) {
chaos_mode = false;
stop_tx();
} else {
chaos_mode = true;
start_random_tx();
}
};
button_stop.on_select = [this](Button&) {
if (is_active()) {
stop_tx();
}
};
}
CVSSpamView::~CVSSpamView() {
stop_tx();
baseband::shutdown();
}
} // namespace ui::external_app::cvs_spam
+136
View File
@@ -0,0 +1,136 @@
// CVS Spam app by RocketGod (@rocketgod-git) https://betaskynet.com
// Original .cu8 files by @jimilinuxguy https://github.com/jimilinuxguy/customer-assistance-buttons-sdr
// If you can read this, you're a nerd. :P
// Come join us at https://discord.gg/thepiratesreborn
#pragma once
#include "ui_widget.hpp"
#include "ui_transmitter.hpp"
#include "replay_thread.hpp"
#include "baseband_api.hpp"
#include "ui_language.hpp"
#include "file_path.hpp"
using namespace portapack;
namespace ui::external_app::cvs_spam {
class CVSSpamView : public View {
public:
explicit CVSSpamView(NavigationView& nav);
~CVSSpamView();
void focus() override;
std::string title() const override { return "CVS Spam"; };
private:
static constexpr size_t read_size = 0x4000;
static constexpr size_t buffer_count = 3;
lfsr_word_t lfsr_v = 1;
bool chaos_mode{false};
NavigationView& nav_;
std::unique_ptr<ReplayThread> replay_thread{};
bool ready_signal{false};
bool thread_sync_complete{false};
std::filesystem::path current_file;
bool is_active() const;
void stop_tx();
void file_error(const std::filesystem::path& path, const std::string& error_details);
void refresh_list();
void start_tx(const uint32_t id);
void start_random_tx();
void on_tx_progress(const uint32_t progress);
uint32_t page = 1;
uint32_t current_page = 1;
std::vector<std::filesystem::path> file_list{};
MenuView menu_view{
{0, 0, 240, 180},
true};
Text text_empty{
{7 * 8, 12 * 8, 16 * 8, 16},
"Empty directory!"};
Button button_prev_page{
{0, 180, 50, 32},
"<"};
Button button_next_page{
{190, 180, 50, 32},
">"};
Text page_info{
{95, 188, 50, 16}};
Button button_send{
{0, 212, 75, 36},
"CALL"};
Button button_chaos{
{82, 212, 75, 36},
"CHAOS"};
Button button_stop{
{165, 212, 75, 36},
LanguageHelper::currentMessages[LANG_STOP]};
ProgressBar progressbar{
{0, 256, 240, 44}};
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) {
ready_signal = true;
}
}};
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);
}};
MessageHandlerRegistration message_handler_replay_thread_done{
Message::ID::ReplayThreadDone,
[this](const Message* const p) {
const auto message = *reinterpret_cast<const ReplayThreadDoneMessage*>(p);
if (message.return_code == ReplayThread::END_OF_FILE) {
if (chaos_mode) {
replay_thread.reset();
transmitter_model.disable();
ready_signal = false;
lfsr_v = lfsr_iterate(lfsr_v);
size_t random_index = lfsr_v % file_list.size();
menu_view.set_highlighted(random_index);
chThdSleepMilliseconds(100);
start_tx(random_index);
} else {
thread_sync_complete = true;
stop_tx();
}
} else if (message.return_code == ReplayThread::READ_ERROR) {
file_error(file_list[menu_view.highlighted_index()], "Read error during playback");
if (chaos_mode) {
replay_thread.reset();
transmitter_model.disable();
ready_signal = false;
lfsr_v = lfsr_iterate(lfsr_v);
size_t random_index = lfsr_v % file_list.size();
menu_view.set_highlighted(random_index);
chThdSleepMilliseconds(100);
start_tx(random_index);
}
}
}};
};
} // namespace ui::external_app::cvs_spam
+33
View File
@@ -0,0 +1,33 @@
// CVS Spam app by RocketGod (@rocketgod-git) https://betaskynet.com
// Original .cu8 files by @jimilinuxguy https://github.com/jimilinuxguy/customer-assistance-buttons-sdr
// If you can read this, you're a nerd. :P
// Come join us at https://discord.gg/thepiratesreborn
#include "ui.hpp"
#include "cvs_spam.hpp"
#include "ui_navigation.hpp"
#include "external_app.hpp"
namespace ui::external_app::cvs_spam {
void initialize_app(NavigationView& nav) {
nav.push<CVSSpamView>();
}
} // namespace ui::external_app::cvs_spam
extern "C" {
__attribute__((section(".external_app.app_cvs_spam.application_information"), used)) application_information_t _application_information_cvs_spam = {
(uint8_t*)0x00000000,
ui::external_app::cvs_spam::initialize_app,
CURRENT_HEADER_VERSION,
VERSION_MD5,
"CVS Spam",
{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81, 0x81},
ui::Color::red().v,
app_location_t::TX,
{'P', 'R', 'E', 'P'},
0x00000000};
}
+25
View File
@@ -106,6 +106,26 @@ set(EXTCPPSRC
#acars
external/acars_rx/main.cpp
external/acars_rx/acars_app.cpp
#shoppingcart_lock
external/shoppingcart_lock/main.cpp
external/shoppingcart_lock/shoppingcart_lock.cpp
#ookbrute
external/ookbrute/main.cpp
external/ookbrute/ui_ookbrute.cpp
#rook
external/rook/main.cpp
external/rook/ui_rook.cpp
#cvs_spam
external/cvs_spam/main.cpp
external/cvs_spam/cvs_spam.cpp
#flippertx
external/flippertx/main.cpp
external/flippertx/ui_flippertx.cpp
)
@@ -128,6 +148,7 @@ set(EXTAPPLIST
foxhunt_rx
audio_test
wardrivemap
cvs_spam
tpmsrx
protoview
adsbtx
@@ -135,4 +156,8 @@ set(EXTAPPLIST
sstvtx
random_password
#acars_rx
ookbrute
rook
shoppingcart_lock
flippertx
)
+32 -1
View File
@@ -48,6 +48,11 @@ MEMORY
ram_external_app_sstvtx(rwx) : org = 0xADC70000, len = 32k
ram_external_app_random_password(rwx) : org = 0xADC80000, len = 32k
ram_external_app_acars_rx(rwx) : org = 0xADC90000, len = 32k
ram_external_app_shoppingcart_lock(rwx) : org = 0xADCA0000, len = 32k
ram_external_app_cvs_spam(rwx) : org = 0xADCB0000, len = 32k
ram_external_app_ookbrute(rwx) : org = 0xADCC0000, len = 32k
ram_external_app_flippertx(rwx) : org = 0xADCD0000, len = 32k
ram_external_app_rook(rwx) : org = 0xADCE0000, len = 32k
}
SECTIONS
@@ -166,7 +171,6 @@ SECTIONS
*(*ui*external_app*tpmsrx*);
} > ram_external_app_tpmsrx
.external_app_protoview : ALIGN(4) SUBALIGN(4)
{
KEEP(*(.external_app.app_protoview.application_information));
@@ -204,7 +208,34 @@ SECTIONS
*(*ui*external_app*acars_rx*);
} > ram_external_app_acars_rx
.external_app_shoppingcart_lock : ALIGN(4) SUBALIGN(4)
{
KEEP(*(.external_app.app_shoppingcart_lock.application_information));
*(*ui*external_app*shoppingcart_lock*);
} > ram_external_app_shoppingcart_lock
.external_app_cvs_spam : ALIGN(4) SUBALIGN(4)
{
KEEP(*(.external_app.app_cvs_spam.application_information));
*(*ui*external_app*cvs_spam*);
} > ram_external_app_cvs_spam
.external_app_ookbrute : ALIGN(4) SUBALIGN(4)
{
KEEP(*(.external_app.app_ookbrute.application_information));
*(*ui*external_app*ookbrute*);
} > ram_external_app_ookbrute
.external_app_rook : ALIGN(4) SUBALIGN(4)
{
KEEP(*(.external_app.app_rook.application_information));
*(*ui*external_app*rook*);
} > ram_external_app_rook
.external_app_flippertx : ALIGN(4) SUBALIGN(4)
{
KEEP(*(.external_app.app_flippertx.application_information));
*(*ui*external_app*flippertx*);
} > ram_external_app_flippertx
}
+82
View File
@@ -0,0 +1,82 @@
/*
* Copyright (C) 2023 Bernd Herzog
*
* 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.hpp"
#include "ui_flippertx.hpp"
#include "ui_navigation.hpp"
#include "external_app.hpp"
namespace ui::external_app::flippertx {
void initialize_app(ui::NavigationView& nav) {
nav.push<FlipperTxView>();
}
} // namespace ui::external_app::flippertx
extern "C" {
__attribute__((section(".external_app.app_flippertx.application_information"), used)) application_information_t _application_information_flippertx = {
/*.memory_location = */ (uint8_t*)0x00000000,
/*.externalAppEntry = */ ui::external_app::flippertx::initialize_app,
/*.header_version = */ CURRENT_HEADER_VERSION,
/*.app_version = */ VERSION_MD5,
/*.app_name = */ "FlipperTx",
/*.bitmap_data = */ {
0x20,
0x00,
0x20,
0x00,
0x20,
0x00,
0x20,
0x00,
0xE0,
0x07,
0xF0,
0x0F,
0x30,
0x0C,
0x30,
0x0C,
0xF0,
0x0F,
0xF0,
0x0F,
0x70,
0x0D,
0xB0,
0x0E,
0x70,
0x0D,
0xB0,
0x0E,
0xF0,
0x0F,
0xE0,
0x07,
},
/*.icon_color = */ ui::Color::orange().v,
/*.menu_location = */ app_location_t::TX,
/*.m4_app_tag = portapack::spi_flash::image_tag_ookstreaming */ {'P', 'O', 'S', 'K'},
/*.m4_app_offset = */ 0x00000000, // will be filled at compile time
};
}
+285
View File
@@ -0,0 +1,285 @@
/*
* Copyright (C) 2024 HTotoo
*
* 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_flippertx.hpp"
#include "audio.hpp"
#include "rtc_time.hpp"
#include "baseband_api.hpp"
#include "string_format.hpp"
#include "portapack_persistent_memory.hpp"
#include "buffer_exchange.hpp"
using namespace portapack;
using namespace ui;
namespace ui::external_app::flippertx {
void FlipperTxView::focus() {
button_browse.focus();
}
void FlipperTxView::set_ready() {
ready_signal = true;
}
FlipperTxView::FlipperTxView(NavigationView& nav)
: nav_{nav} {
add_children({&button_startstop,
&field_frequency,
&tx_view,
&field_filename,
&button_browse});
button_startstop.on_select = [this](Button&) {
if (is_running) {
stop();
} else {
start();
}
};
button_browse.on_select = [this](Button&) {
auto open_view = nav_.push<FileLoadView>(".sub");
open_view->push_dir(subghz_dir);
open_view->on_changed = [this](std::filesystem::path new_file_path) {
if (on_file_changed(new_file_path)) {
; // tif (button_startstop.parent()) button_startstop.focus(); parent_ is null error.....
}
};
};
}
bool FlipperTxView::on_file_changed(std::filesystem::path new_file_path) {
submeta = read_flippersub_file(new_file_path);
filename = "";
if (!submeta.is_valid()) {
field_filename.set_text("File: err, bad file");
return false;
}
proto = submeta.value().protocol;
if (proto != FLIPPER_PROTO_RAW && proto != FLIPPER_PROTO_BINRAW) { // temp disabled
field_filename.set_text("File: err, not supp. proto");
return false;
}
preset = submeta.value().preset;
if (preset != FLIPPER_PRESET_OOK) {
field_filename.set_text("File: err, not supp. preset");
return false;
}
te = submeta.value().te;
binraw_bit_count = submeta.value().binraw_bit_count;
/*if (binraw_bit_count >= 512 * 800) {
field_filename.set_text("File: err, too long"); // should stream, but not in this scope YET
return false;
}*/
field_filename.set_text("File: " + new_file_path.string());
filename = new_file_path;
return true;
}
void FlipperTxView::stop() {
if (is_running && replay_thread) replay_thread.reset();
is_running = false;
ready_signal = false;
transmitter_model.disable();
baseband::shutdown();
button_startstop.set_text(LanguageHelper::currentMessages[LANG_START]);
}
bool FlipperTxView::start() {
if (filename.empty()) return false;
baseband::run_prepared_image(portapack::memory::map::m4_code.base());
transmitter_model.enable();
button_startstop.set_text(LanguageHelper::currentMessages[LANG_STOP]);
// start thread
replay_thread = std::make_unique<FlipperPlayThread>(
filename,
1024, 4,
&ready_signal,
submeta.value().protocol,
submeta.value().te,
[](uint32_t return_code) {
ReplayThreadDoneMessage message{return_code};
EventDispatcher::send_message(message);
});
is_running = true;
return true;
}
void FlipperTxView::on_tx_progress(const bool done) {
if (done) {
if (is_running) {
stop();
}
}
}
FlipperTxView::~FlipperTxView() {
stop();
}
FlipperPlayThread::FlipperPlayThread(
std::filesystem::path filename,
size_t read_size,
size_t buffer_count,
bool* ready_signal,
FlipperProto proto,
uint16_t te,
std::function<void(uint32_t return_code)> terminate_callback)
: config{read_size, buffer_count},
filename{filename},
ready_sig{ready_signal},
proto{proto},
te{te},
terminate_callback{std::move(terminate_callback)} {
thread = chThdCreateFromHeap(NULL, 6 * 1024, NORMALPRIO + 10, FlipperPlayThread::static_fn, this);
}
FlipperPlayThread::~FlipperPlayThread() {
if (thread) {
chThdTerminate(thread);
if (thread->p_refs) chThdWait(thread);
thread = nullptr;
}
}
msg_t FlipperPlayThread::static_fn(void* arg) {
auto obj = static_cast<FlipperPlayThread*>(arg);
const auto return_code = obj->run();
if (obj->terminate_callback) {
obj->terminate_callback(return_code);
}
chThdExit(0);
return 0;
}
uint32_t FlipperPlayThread::run() {
BasebandReplay replay{&config};
BufferExchange buffers{&config};
StreamBuffer* prefill_buffer{nullptr};
int32_t read_result = 0;
// assume it is ok, since prev we checked it.
// open the sub file
File f; // don't worry, destructor will close it.
auto error = f.open(filename);
if (error) return READ_ERROR;
// seek to the first data
if (proto == FLIPPER_PROTO_RAW)
seek_flipper_raw_first_data(f);
else {
seek_flipper_binraw_first_data(f);
}
// Wait for FIFOs to be allocated in baseband
// Wait for _view to tell us that the buffers are ready
while (!(*ready_sig) && !chThdShouldTerminate()) {
chThdSleep(100);
};
uint8_t readall = 0;
int32_t endsignals[3] = {0, 42069, 613379}; // unlikely a valid data
// While empty buffers fifo is not empty...
while (!buffers.empty() && !chThdShouldTerminate()) {
prefill_buffer = buffers.get_prefill();
if (prefill_buffer == nullptr) {
buffers.put_app(prefill_buffer);
} else {
size_t c = 0;
for (c = 0; c < config.read_size / 4;) {
read_result = 0;
if (0 == readall) {
if (proto == FLIPPER_PROTO_RAW) {
auto data = read_flipper_raw_next_data(f);
if (!data.is_valid()) {
((int32_t*)prefill_buffer->data())[c] = endsignals[++readall];
} else {
read_result = data.value();
((int32_t*)prefill_buffer->data())[c] = read_result;
}
c++;
} else { // BINRAW
auto data = read_flipper_binraw_next_data(f);
if (!data.is_valid())
readall = 1;
else {
read_result = data.value();
// add 8 data
for (uint8_t bit = 0; bit < 8; bit++) {
((int32_t*)prefill_buffer->data())[c + bit] = ((get_flipper_binraw_bitvalue(read_result, (7 - bit)) ? 1 : -1) * te);
c++;
}
}
}
} else {
((int32_t*)prefill_buffer->data())[c] = endsignals[readall];
if (readall == 1) readall++;
c++;
}
}
prefill_buffer->set_size(config.read_size);
buffers.put(prefill_buffer);
}
};
baseband::set_fifo_data(nullptr);
if (readall) return END_OF_FILE;
while (!chThdShouldTerminate()) {
auto buffer = buffers.get();
int32_t read_result = 0;
for (size_t d = 0; d < buffer->capacity() / 4; d++) {
read_result = -133469;
if (!readall) {
if (proto == FLIPPER_PROTO_RAW) {
auto data = read_flipper_raw_next_data(f);
if (!data.is_valid()) {
readall = 1;
} else {
read_result = data.value();
}
} else {
auto data = read_flipper_binraw_next_data(f);
if (!data.is_valid())
readall = 1;
else {
read_result = data.value();
// add 8 data
for (uint8_t bit = 0; bit < 8; bit++) {
((int32_t*)prefill_buffer->data())[d + bit] = ((get_flipper_binraw_bitvalue(read_result, (7 - bit)) ? 1 : -1) * te);
}
d += 7;
continue;
}
}
}
if (readall >= 1 && readall <= 2) {
read_result = endsignals[readall++];
}
((int32_t*)buffer->data())[d] = read_result;
}
buffer->set_size(buffer->capacity());
buffers.put(buffer);
if (readall == 3) return END_OF_FILE;
}
return TERMINATED;
}
} // namespace ui::external_app::flippertx
+171
View File
@@ -0,0 +1,171 @@
/*
* Copyright (C) 2024 HTotoo
*
* This file is part of PortaPack.
*
*/
#ifndef __UI_flippertx_H__
#define __UI_flippertx_H__
#include "ui.hpp"
#include "ui_language.hpp"
#include "ui_navigation.hpp"
#include "ui_transmitter.hpp"
#include "ui_freq_field.hpp"
#include "app_settings.hpp"
#include "radio_state.hpp"
#include "utility.hpp"
#include "string_format.hpp"
#include "file_path.hpp"
#include "metadata_file.hpp"
#include "flipper_subfile.hpp"
#include "ui_fileman.hpp"
#include "baseband_api.hpp"
using namespace ui;
namespace ui::external_app::flippertx {
#define OOK_SAMPLERATE 2280000U
class FlipperPlayThread;
class FlipperTxView : public View {
public:
FlipperTxView(NavigationView& nav);
~FlipperTxView();
void focus() override;
std::string title() const override {
return "FlipperTx";
};
private:
NavigationView& nav_;
TxRadioState radio_state_{
433920000 /* frequency */,
1750000 /* bandwidth */,
OOK_SAMPLERATE /* sampling rate */
};
TxFrequencyField field_frequency{
{0 * 8, 0 * 16},
nav_};
TransmitterView2 tx_view{
{11 * 8, 0 * 16},
/*short_ui*/ true};
app_settings::SettingsManager settings_{
"tx_flippertx", app_settings::Mode::TX};
TextField field_filename{
{0, 2 * 16, 300, 1 * 8},
"File: -"};
Button button_startstop{
{1, 6 * 16, 96, 24},
LanguageHelper::currentMessages[LANG_START]};
Button button_browse{
{1, 3 * 16 + 3, 96, 24},
LanguageHelper::currentMessages[LANG_BROWSE]};
bool is_running{false};
bool start();
void stop();
void set_ready();
void on_tx_progress(const bool done);
bool on_file_changed(std::filesystem::path new_file_path);
std::filesystem::path filename = {};
FlipperProto proto = FLIPPER_PROTO_UNSUPPORTED;
FlipperPreset preset = FLIPPER_PRESET_UNK;
uint16_t te = 0; // for binraw
uint32_t binraw_bit_count = 0;
bool ready_signal = false;
std::unique_ptr<FlipperPlayThread> replay_thread{};
Optional<flippersub_metadata> submeta{};
const std::filesystem::path subghz_dir = u"subghz";
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.done);
}};
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_replay_thread_done{
Message::ID::ReplayThreadDone,
[this](const Message* const p) {
// const auto message = *reinterpret_cast<const ReplayThreadDoneMessage*>(p);
(void)p;
// stop(); //don't stop for now, stop when i get the tx finished msg
}};
};
struct BasebandReplay {
BasebandReplay(ReplayConfig* const config) {
baseband::replay_start(config);
}
~BasebandReplay() {
// baseband::replay_stop(); // wont, since we need to send out that is in the buffer
}
};
class FlipperPlayThread {
public:
FlipperPlayThread(
std::filesystem::path,
size_t read_size,
size_t buffer_count,
bool* ready_signal,
FlipperProto proto,
uint16_t te,
std::function<void(uint32_t return_code)> terminate_callback);
~FlipperPlayThread();
FlipperPlayThread(const FlipperPlayThread&) = delete;
FlipperPlayThread(FlipperPlayThread&&) = delete;
FlipperPlayThread& operator=(const FlipperPlayThread&) = delete;
FlipperPlayThread& operator=(FlipperPlayThread&&) = delete;
const ReplayConfig& state() const {
return config;
};
enum FlipperPlayThread_return {
READ_ERROR = 0,
END_OF_FILE,
TERMINATED
};
private:
ReplayConfig config;
std::filesystem::path filename;
bool* ready_sig;
FlipperProto proto;
uint16_t te;
std::function<void(uint32_t return_code)> terminate_callback;
Thread* thread{nullptr};
static msg_t static_fn(void* arg);
uint32_t run();
};
}; // namespace ui::external_app::flippertx
#endif /*__UI_flippertx_H__*/
+82
View File
@@ -0,0 +1,82 @@
/*
* Copyright (C) 2023 Bernd Herzog
*
* 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.hpp"
#include "ui_ookbrute.hpp"
#include "ui_navigation.hpp"
#include "external_app.hpp"
namespace ui::external_app::ookbrute {
void initialize_app(ui::NavigationView& nav) {
nav.push<OokBruteView>();
}
} // namespace ui::external_app::ookbrute
extern "C" {
__attribute__((section(".external_app.app_ookbrute.application_information"), used)) application_information_t _application_information_ookbrute = {
/*.memory_location = */ (uint8_t*)0x00000000,
/*.externalAppEntry = */ ui::external_app::ookbrute::initialize_app,
/*.header_version = */ CURRENT_HEADER_VERSION,
/*.app_version = */ VERSION_MD5,
/*.app_name = */ "OokBrute",
/*.bitmap_data = */ {
0x20,
0x00,
0x20,
0x00,
0x20,
0x00,
0x20,
0x00,
0xE0,
0x07,
0xF0,
0x0F,
0x30,
0x0C,
0x30,
0x0C,
0xF0,
0x0F,
0xF0,
0x0F,
0x70,
0x0D,
0xB0,
0x0E,
0x70,
0x0D,
0xB0,
0x0E,
0xF0,
0x0F,
0xE0,
0x07,
},
/*.icon_color = */ ui::Color::orange().v,
/*.menu_location = */ app_location_t::TX,
/*.m4_app_tag = portapack::spi_flash::image_tag_ook */ {'P', 'O', 'O', 'K'},
/*.m4_app_offset = */ 0x00000000, // will be filled at compile time
};
}
+253
View File
@@ -0,0 +1,253 @@
/*
* Copyright (C) 2024 HTotoo
*
* 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_ookbrute.hpp"
#include "audio.hpp"
#include "rtc_time.hpp"
#include "baseband_api.hpp"
#include "string_format.hpp"
#include "portapack_persistent_memory.hpp"
using namespace portapack;
using namespace ui;
namespace ui::external_app::ookbrute {
void OokBruteView::focus() {
button_startstop.focus();
}
OokBruteView::OokBruteView(NavigationView& nav)
: nav_{nav} {
add_children({
&button_startstop,
&field_frequency,
&tx_view,
&options_atkmode,
&field_start,
&field_stop,
});
button_startstop.on_select = [this](Button&) {
if (is_running) {
is_running = false;
stop();
} else {
is_running = true;
start();
}
};
options_atkmode.on_change = [this](size_t, int32_t i) {
update_start_stop(i);
validate_start_stop();
};
field_start.on_change = [this](int32_t) {
validate_start_stop();
};
field_stop.on_change = [this](int32_t) {
validate_start_stop();
};
update_start_stop(0);
}
void OokBruteView::update_start_stop(uint32_t proto) {
uint8_t bits = 12;
switch (proto) {
default:
case 0:
case 2:
case 4:
bits = 12;
break;
case 1:
case 3:
case 5:
bits = 24;
break;
}
uint32_t max = (1 << bits) - 1;
field_start.set_range(0, max);
field_stop.set_range(0, max);
field_start.set_value(0);
field_stop.set_value(max);
}
void OokBruteView::validate_start_stop() {
if (field_start.value() > field_stop.value()) {
field_start.set_value(field_stop.value());
}
if (field_stop.value() < field_start.value()) {
field_stop.set_value(field_start.value());
}
}
void OokBruteView::generate_packet() {
uint32_t protocol = options_atkmode.selected_index_value();
uint8_t byte = 0;
size_t bitstream_length = 0;
uint8_t* bitstream = shared_memory.bb_data.data; // max 512 in size
uint32_t samples_per_bit = 0; // OOK_SAMPLERATE * bit_duration_in_sec
std::string dataFormat = "";
std::string zero = "";
std::string one = "";
uint16_t databits = 0;
uint16_t repeat = 1;
uint16_t pause_sym = 0;
if (protocol == 0) { // came 12
samples_per_bit = OOK_SAMPLERATE / ((3 * 1000) / 1);
dataFormat = "0000000000000000000000000000000000001CCCCCCCCCCCC0000"; // 36 0 preamble +start bit + data
databits = 12;
zero = "011";
one = "001";
repeat = 2;
pause_sym = 0;
}
if (protocol == 1) { // came24
samples_per_bit = OOK_SAMPLERATE / ((3 * 1000) / 1);
dataFormat = "0000000000000000000000000000000000001CCCCCCCCCCCCCCCCCCCCCCCC0000"; // 36 0 preamble +start bit + data
databits = 24;
zero = "011";
one = "001";
repeat = 2;
pause_sym = 0;
}
if (protocol == 2) { // nice12
samples_per_bit = OOK_SAMPLERATE * (680.0 / 1000000.0);
dataFormat = "000000000000000000000000000000000000000001CCCCCCCCCCCC0000"; // 36 0 preamble +start bit + data
databits = 12;
zero = "011";
one = "001";
repeat = 2;
pause_sym = 0;
}
if (protocol == 3) { // nice24
samples_per_bit = OOK_SAMPLERATE * (680.0 / 1000000.0);
dataFormat = "000000000000000000000000000000000000000001CCCCCCCCCCCCCCCCCCCCCCCC0000"; // 36 0 preamble +start bit + data
databits = 24;
zero = "011";
one = "001";
repeat = 2;
pause_sym = 0;
}
if (protocol == 4) { // holtek_ht12
samples_per_bit = OOK_SAMPLERATE * (390.0 / 1000000.0);
dataFormat = "0000000000000000000000000000000000001CCCCCCCCCCCC00000000000"; // 36 0 preamble +start bit + data.
databits = 12;
zero = "011";
one = "001";
repeat = 2;
pause_sym = 0;
}
if (protocol == 5) { // princeton24
samples_per_bit = OOK_SAMPLERATE * (450.0 / 1000000.0); // long = 3*
dataFormat = "000000000000000000000000000000000000CCCCCCCCCCCCCCCCCCCCCCCC10000000"; //
databits = 24;
zero = "1000";
one = "1110";
repeat = 6;
pause_sym = 0;
}
std::string fragments = ""; // storage
uint16_t cdb = 0; // current data bit
for (auto c : dataFormat) { // generate fragments from template
if (c == '0') fragments += '0';
if (c == '1') fragments += '1';
if (c == 'C') {
if (counter & (1 << (databits - cdb - 1))) {
fragments += one;
} else {
fragments += zero;
}
cdb++;
}
}
// create bitstream
for (auto c : fragments) {
byte <<= 1;
if (c != '0') byte |= 1;
if ((bitstream_length & 7) == 7)
bitstream[bitstream_length >> 3] = byte;
bitstream_length++;
}
// Finish last byte if needed
size_t padding = 8 - (bitstream_length & 7);
if (padding != 8) {
byte <<= padding;
bitstream[(bitstream_length + padding - 1) >> 3] = byte;
padding++;
}
// send bitstream
baseband::set_ook_data(
bitstream_length,
samples_per_bit,
repeat,
pause_sym,
0);
}
void OokBruteView::stop() {
transmitter_model.disable();
baseband::shutdown();
button_startstop.set_text(LanguageHelper::currentMessages[LANG_START]);
}
void OokBruteView::start() {
counter = field_start.value();
baseband::run_prepared_image(portapack::memory::map::m4_code.base());
transmitter_model.enable();
button_startstop.set_text(LanguageHelper::currentMessages[LANG_STOP]);
generate_packet();
}
void OokBruteView::on_tx_progress(const bool done) {
if (done) {
if (is_running) {
counter++;
field_start.set_value(counter);
if (counter > (uint32_t)field_stop.value()) {
stop();
} else {
generate_packet();
}
}
}
}
OokBruteView::~OokBruteView() {
is_running = false;
stop();
}
} // namespace ui::external_app::ookbrute
/*
https://web.archive.org/web/20230331125843/https://phreakerclub.com/447
*/
+106
View File
@@ -0,0 +1,106 @@
/*
* Copyright (C) 2024 HTotoo
*
* This file is part of PortaPack.
*
*/
#ifndef __UI_OOKBRUTE_H__
#define __UI_OOKBRUTE_H__
#include "ui.hpp"
#include "ui_language.hpp"
#include "ui_navigation.hpp"
#include "ui_transmitter.hpp"
#include "ui_freq_field.hpp"
#include "ui_record_view.hpp"
#include "app_settings.hpp"
#include "radio_state.hpp"
#include "utility.hpp"
using namespace ui;
namespace ui::external_app::ookbrute {
#define OOK_SAMPLERATE 2280000U
class OokBruteView : public View {
public:
OokBruteView(NavigationView& nav);
~OokBruteView();
void focus() override;
std::string title() const override {
return "OokBrute";
};
private:
NavigationView& nav_;
TxRadioState radio_state_{
433920000 /* frequency */,
1750000 /* bandwidth */,
OOK_SAMPLERATE /* sampling rate */
};
TxFrequencyField field_frequency{
{0 * 8, 0 * 16},
nav_};
TransmitterView2 tx_view{
{11 * 8, 0 * 16},
/*short_ui*/ true};
app_settings::SettingsManager settings_{
"tx_ookbrute", app_settings::Mode::TX};
Button button_startstop{
{0, 3 * 16, 96, 24},
LanguageHelper::currentMessages[LANG_START]};
NumberField field_start{
{0 * 8, 1 * 16},
8,
{0, 2500},
1,
' ',
true};
NumberField field_stop{
{11 * 8, 1 * 16},
9,
{0, 2500},
1,
' ',
true};
OptionsField options_atkmode{
{0 * 8, 2 * 16},
12,
{{"Came12", 0},
{"Came24", 1},
{"Nice12", 2},
{"Nice24", 3},
{"Holtek12", 4},
{"Princeton24", 5}}};
bool is_running{false};
uint32_t counter = 0; // for packet change
void start();
void stop();
void on_tx_progress(const bool done);
void validate_start_stop();
void update_start_stop(uint32_t proto);
void generate_packet();
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.done);
}};
};
}; // namespace ui::external_app::ookbrute
#endif /*__UI_OOKBRUTE_H__*/
+82
View File
@@ -0,0 +1,82 @@
/*
* Copyright (C) 2024 Samir Sánchez Garnica @sasaga92
*
* 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.hpp"
#include "ui_rook.hpp"
#include "ui_navigation.hpp"
#include "external_app.hpp"
namespace ui::external_app::rook {
void initialize_app(ui::NavigationView& nav) {
nav.push<ROOKAppView>();
}
} // namespace ui::external_app::rook
extern "C" {
__attribute__((section(".external_app.app_rook.application_information"), used)) application_information_t _application_information_rook = {
/*.memory_location = */ (uint8_t*)0x00000000,
/*.externalAppEntry = */ ui::external_app::rook::initialize_app,
/*.header_version = */ CURRENT_HEADER_VERSION,
/*.app_version = */ VERSION_MD5,
/*.app_name = */ "ROOK",
/*.bitmap_data = */ {
0x20,
0x00,
0x20,
0x00,
0x20,
0x00,
0x20,
0x00,
0xE0,
0x07,
0xF0,
0x0F,
0x30,
0x0C,
0x30,
0x0C,
0xF0,
0x0F,
0xF0,
0x0F,
0x70,
0x0D,
0xB0,
0x0E,
0x70,
0x0D,
0xB0,
0x0E,
0xF0,
0x0F,
0xE0,
0x07,
},
/*.icon_color = */ ui::Color::orange().v,
/*.menu_location = */ app_location_t::TX,
/*.m4_app_tag = portapack::spi_flash::image_tag_ook */ {'P', 'O', 'O', 'K'},
/*.m4_app_offset = */ 0x00000000, // will be filled at compile time
};
}
+275
View File
@@ -0,0 +1,275 @@
/*
* Copyright (C) 2024 Samir Sánchez Garnica @sasaga92
*
* 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_rook.hpp"
#include "portapack.hpp"
#include "io_file.hpp"
#include "ui_fileman.hpp"
#include "file_path.hpp"
#include <cstring>
#include "baseband_api.hpp"
#include "ui_textentry.hpp"
#include "encoders.hpp" // Includes data encoding functions for transmission
#include "baseband_api.hpp" // Includes baseband API for handling transmission settings
#include "file_reader.hpp"
#define PADDING_LEFT 1
#define PADDING_RIGHT 1
using namespace portapack;
using namespace ui;
namespace fs = std::filesystem;
namespace ui::external_app::rook {
void ROOKAppView::focus() {
button_set.focus();
}
// `start_tx` method: Configures and begins OOK data transmission with a specific message.
void ROOKAppView::start_tx(const std::string& message) {
size_t bitstream_length = encoders::make_bitstream(const_cast<std::string&>(message)); // Convert the message into a bitstream
// Retrieve selected sample rate using selected_index_value()
int32_t SAMPLE_RATE_VALUE = field_sample_rate.selected_index_value();
int32_t SYMBOL_RATE_VALUE = cant_symbol_rate.value();
int32_t REPEAT = cant_repeat.value();
int32_t PAUSE_SYMBOL = cant_pause_symbol.value();
transmitter_model.set_sampling_rate(SAMPLE_RATE_VALUE); // Set the OOK sampling rate
transmitter_model.set_baseband_bandwidth(1750000); // Set the baseband bandwidth
transmitter_model.enable(); // Enable the transmitter
// Configure OOK data and transmission characteristics
baseband::set_ook_data(
bitstream_length, // Length of the bitstream to transmit
SAMPLE_RATE_VALUE / SYMBOL_RATE_VALUE, // Calculate symbol period based on repetition rate
REPEAT, // Set the number of repetitions per symbol
PAUSE_SYMBOL // Set the pause between symbols
);
}
// `stop_tx` method: Stops the transmission and resets the progress bar.
void ROOKAppView::stop_tx() {
transmitter_model.disable(); // Disable the transmitter
progressBar_progress.set_value(0); // Reset progress bar to 0
}
// `on_file_changed` method: Called when a new file is loaded; parses file data into variables
void ROOKAppView::on_file_changed(const fs::path& new_file_path) {
payload.clear(); // Clear previous payload content
File data_file;
auto open_result = data_file.open(new_file_path);
if (open_result) {
nav_.display_modal("Error", "Unable to open file.");
return;
}
FileLineReader reader(data_file);
for (const auto& line : reader) {
// Split the line into segments to extract each value
size_t first_space = line.find(' ');
size_t second_space = line.find(' ', first_space + 1);
size_t third_space = line.find(' ', second_space + 1);
size_t fourth_space = line.find(' ', third_space + 1);
size_t fifth_space = line.find(' ', fourth_space + 1);
// Extract each component of the line
std::string frequency_str = line.substr(0, first_space);
std::string sample_rate_str = line.substr(first_space + 1, second_space - first_space - 1);
std::string symbols_rate_str = line.substr(second_space + 1, third_space - second_space - 1);
std::string repeat_str = line.substr(third_space + 1, fourth_space - third_space - 1);
std::string pause_symbol_str = line.substr(fourth_space + 1, fifth_space - fourth_space - 1);
std::string payload_data = line.substr(fifth_space + 1); // Extract binary payload as final value
// Convert and assign frequency
unsigned long long frequency = std::stoull(frequency_str);
field_frequency.set_value(frequency);
transmitter_model.set_target_frequency(frequency);
// Convert and assign symbols rate
unsigned int symbols_rate = static_cast<unsigned int>(atoi(symbols_rate_str.c_str()));
cant_symbol_rate.set_value(symbols_rate);
// Convert and assign repeat count
unsigned int repeat = static_cast<unsigned int>(atoi(repeat_str.c_str()));
cant_repeat.set_value(repeat);
// Convert and assign pause per symbol
unsigned int pause_symbol = static_cast<unsigned int>(atoi(pause_symbol_str.c_str()));
cant_pause_symbol.set_value(pause_symbol);
// Select sample rate based on value read from file
if (sample_rate_str == "250k") {
field_sample_rate.set_by_value(250000U);
} else if (sample_rate_str == "1M") {
field_sample_rate.set_by_value(1000000U);
} else if (sample_rate_str == "2M") {
field_sample_rate.set_by_value(2000000U);
} else if (sample_rate_str == "5M") {
field_sample_rate.set_by_value(5000000U);
} else if (sample_rate_str == "10M") {
field_sample_rate.set_by_value(10000000U);
} else if (sample_rate_str == "20M") {
field_sample_rate.set_by_value(20000000U);
} else {
nav_.display_modal("Error", "Invalid sample rate.");
return;
}
// Update payload with binary data
payload = payload_data;
// Process only the first line
break;
}
// Ensure UI elements are initialized before use
if (parent()) {
text_payload.set(payload);
button_start.focus();
} else {
text_payload.set("parent not available");
}
}
// `on_tx_progress` method: Updates the progress bar based on transmission progress.
void ROOKAppView::on_tx_progress(const uint32_t progress, const bool done) {
progressBar_progress.set_value(progress); // Update progress bar value
if (done) {
stop_tx(); // Stop transmission when progress reaches maximum
}
}
// `draw_waveform` method: Draws the waveform on the UI based on the payload data
void ROOKAppView::draw_waveform() {
// Padding reason:
// In real-world scenarios, the signal would always start low and return low after turning off the radio.
// `waveform_buffer` only controls drawing; the actual send logic is handled by frame_fragments.
size_t length = payload.length();
// Ensure waveform length does not exceed buffer size
if (length + (PADDING_LEFT + PADDING_RIGHT) >= WAVEFORM_BUFFER_SIZE) {
length = WAVEFORM_BUFFER_SIZE - (PADDING_LEFT + PADDING_RIGHT);
}
// Left padding
for (size_t i = 0; i < PADDING_LEFT; i++) {
waveform_buffer[i] = 0;
}
// Draw the actual waveform
for (size_t n = 0; n < length; n++) {
waveform_buffer[n + PADDING_LEFT] = (payload[n] == '0') ? 0 : 1;
}
// Right padding
for (size_t i = length + PADDING_LEFT; i < WAVEFORM_BUFFER_SIZE; i++) {
waveform_buffer[i] = 0;
}
waveform.set_length(length + PADDING_LEFT + PADDING_RIGHT);
waveform.set_dirty();
}
// Destructor for `ROOKAppView`: Disables the transmitter and shuts down the baseband
ROOKAppView::~ROOKAppView() {
transmitter_model.disable();
baseband::shutdown();
}
// Constructor for `ROOKAppView`: Sets up the app view and initializes UI elements
ROOKAppView::ROOKAppView(NavigationView& nav)
: nav_{nav} {
baseband::run_image(portapack::spi_flash::image_tag_ook);
add_children({
&field_frequency,
&tx_view,
&button_start,
&sample_rate,
&step_symbol_rate,
&cant_step_symbol_rate,
&field_sample_rate,
&field_symbol_rate,
&field_symbol_us_rate,
&cant_symbol_rate,
&text_payload,
&button_set,
&progressBar_progress,
&repeat,
&cant_repeat,
&field_pause_symbol,
&cant_pause_symbol,
&label_waveform,
&waveform,
&button_open,
});
// Initialize default values for controls
cant_pause_symbol.set_value(100);
cant_repeat.set_value(4);
button_open.on_select = [this](Button&) {
auto open_view = nav_.push<FileLoadView>(".ROOK");
ensure_directory(rook_dir);
open_view->push_dir(rook_dir);
open_view->on_changed = [this](std::filesystem::path new_file_path) {
// Postpone `on_file_changed` call until `FileLoadView` is closed
nav_.set_on_pop([this, new_file_path]() {
on_file_changed(new_file_path);
button_start.focus();
draw_waveform();
});
};
};
// Set up changes for symbol rate and step
cant_symbol_rate.on_change = [this](int32_t value) {
if (value != cant_symbol_rate.value())
cant_symbol_rate.set_value(value);
};
cant_step_symbol_rate.on_change = [this](size_t, int32_t value) {
cant_symbol_rate.set_step(value);
};
// Configure button to manually set payload through text input
button_set.on_select = [this, &nav](Button&) {
text_prompt(
nav,
payload,
100,
[this](std::string& s) {
text_payload.set(s);
draw_waveform();
});
};
draw_waveform();
button_start.on_select = [this](Button&) {
start_tx(payload); // Begin transmission
};
}
} // namespace ui::external_app::rook
+119
View File
@@ -0,0 +1,119 @@
/*
* Copyright (C) 2024 Samir Sánchez Garnica @sasaga92
*
* This file is part of PortaPack.
*
*/
#ifndef __UI_ROOK_H__
#define __UI_ROOK_H__
#include "ui.hpp"
#include "ui_widget.hpp"
#include "ui_navigation.hpp"
#include "string_format.hpp"
#include "radio_state.hpp"
#include "ui_freq_field.hpp"
#include "ui_transmitter.hpp"
#include "app_settings.hpp"
#include "transmitter_model.hpp"
#include <string>
using namespace ui;
namespace ui::external_app::rook {
#define PROGRESS_MAX 100
#define OOK_SAMPLERATE_DEFAULT 2280000U // Set the default Sample Rate
#define TRANSMISSION_FREQUENCY_DEFAULT 433920000U // Sets the default transmission frequency (27 MHz).
#define WAVEFORM_BUFFER_SIZE 550
class ROOKAppView : public View {
public:
void focus() override;
ROOKAppView(NavigationView& nav);
~ROOKAppView();
std::string title() const override {
return "RemoteOOK";
};
private:
NavigationView& nav_; // Reference to the navigation system.
std::string payload{""}; // Holds the data payload as a string.
uint32_t progress = 0; // Stores the current transmission progress.
int16_t waveform_buffer[WAVEFORM_BUFFER_SIZE]; // Buffer for waveform data.
void update();
void draw_waveform();
// Initiates data transmission with a specified message.
void start_tx(const std::string& message);
// Stops data transmission.
void stop_tx();
// Updates the transmission progress on the progress bar.
void on_tx_progress(const uint32_t progress, const bool done);
// Updates data when a new file is loaded.
void on_file_changed(const std::filesystem::path& new_file_path);
// Registers a message handler for transmission progress updates.
MessageHandlerRegistration message_handler_tx_progress{
Message::ID::TXProgress, // Transmission progress message ID.
[this](const Message* const p) { // Callback to handle the message.
const auto message = *reinterpret_cast<const TXProgressMessage*>(p);
this->on_tx_progress(message.progress, message.done);
}};
// Sets transmission frequency, bandwidth, and default sample rate for OOK.
TxRadioState radio_state_{TRANSMISSION_FREQUENCY_DEFAULT, 1750000, OOK_SAMPLERATE_DEFAULT};
// Settings manager for app configuration.
app_settings::SettingsManager settings_{"tx_rook", app_settings::Mode::TX};
// UI components for frequency and transmitter view.
TxFrequencyField field_frequency{{0 * 8, 0 * 16}, nav_};
TransmitterView2 tx_view{{20 * 7, 0 * 16}, true};
// Labels for various fields such as sample rate and repeat count.
Labels sample_rate{{{0, 40}, "S/Rate: ", Theme::getInstance()->fg_light->foreground}};
// Labels step_symbol_rate {{{160, 0}, "Step/Sym: ",Theme::getInstance()->fg_light->foreground}};
Labels step_symbol_rate{{{0, 18}, "Step/Symbols: ", Theme::getInstance()->fg_light->foreground}};
Labels repeat{{{0, 60}, "Repeat: ", Theme::getInstance()->fg_light->foreground}};
Labels field_symbol_rate{{{111, 40}, "Symbols: ", Theme::getInstance()->fg_light->foreground}};
Labels field_pause_symbol{{{111, 60}, "Pause/Sym: ", Theme::getInstance()->fg_light->foreground}};
Labels field_symbol_us_rate{{{210, 40}, "us ", Theme::getInstance()->fg_light->foreground}};
Labels label_waveform{{{0, 140}, "Waveform:", Theme::getInstance()->fg_light->foreground}};
// OptionsField for selectable sample rates.
OptionsField field_sample_rate{{55, 40}, 7, {{"250k", 250000U}, {"1M", 1000000U}, {"2M", 2000000U}, {"5M", 5000000U}, {"10M", 10000000U}, {"20M", 20000000U}}};
// OptionsField for step symbol rates.
OptionsField cant_step_symbol_rate{{105, 18}, 7, {{"1", 1}, {"10", 10}, {"100", 100}}};
// Number fields for symbols, pause between symbols, and repeat count.
NumberField cant_symbol_rate{{176, 40}, 4, {0, 9999}, 1, '0', false};
NumberField cant_pause_symbol{{200, 60}, 4, {0, 200}, 1, '0', false};
NumberField cant_repeat{{55, 60}, 3, {0, 100}, 1, '0', false};
// Text field to display the payload data.
Text text_payload{{0 * 8, 90, 30 * 8, 16}, "Payload:"};
// Buttons for setting configurations, opening files, and starting transmission.
Button button_set{{0, 110, 60, 28}, "Set"};
Button button_open{{100, 110, 80, 28}, "Open file"};
Button button_start{{80, 273, 80, 32}, "Start"};
// Progress bar to display transmission progress.
ProgressBar progressBar_progress{{2 * 8, 250, 208, 16}};
// Waveform display using waveform buffer and yellow theme color.
Waveform waveform{{0, 165, 240, 32}, waveform_buffer, 0, 0, true, Theme::getInstance()->fg_yellow->foreground};
};
}; // namespace ui::external_app::rook
#endif /*__UI_ROOK_H__*/
@@ -0,0 +1,63 @@
// RocketGod's Shopping Cart Lock app
// https://betaskynet.com
#include "ui.hpp"
#include "shoppingcart_lock.hpp"
#include "ui_navigation.hpp"
#include "external_app.hpp"
namespace ui::external_app::shoppingcart_lock {
void initialize_app(NavigationView& nav) {
baseband::run_image(portapack::spi_flash::image_tag_audio_tx);
nav.push<ShoppingCartLock>();
}
} // namespace ui::external_app::shoppingcart_lock
extern "C" {
__attribute__((section(".external_app.app_shoppingcart_lock.application_information"), used)) application_information_t _application_information_shoppingcart_lock = {
(uint8_t*)0x00000000,
ui::external_app::shoppingcart_lock::initialize_app,
CURRENT_HEADER_VERSION,
VERSION_MD5,
"Cart Lock",
{
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
0x7E,
0x7E,
0x00,
0x00,
0x00,
0x00,
0x00,
0x7E,
0x81,
0x81,
0x7E,
0x00,
0x00,
0x00,
0x7E,
0x81,
0x81,
0x81,
0x81,
0x7E,
0x00,
},
ui::Color::red().v,
app_location_t::UTILITIES,
{'P', 'A', 'T', 'X'},
0x00000000,
};
}
@@ -0,0 +1,235 @@
// RocketGod's Shopping Cart Lock app
// https://betaskynet.com
#include "shoppingcart_lock.hpp"
using namespace portapack;
namespace ui::external_app::shoppingcart_lock {
void ShoppingCartLock::log_event(const std::string& message) {
static const size_t MAX_LOG_LINES = 50;
static std::vector<std::string> message_history;
message_history.push_back(message);
if (message_history.size() > MAX_LOG_LINES) {
message_history.erase(message_history.begin());
menu_view.clear();
for (const auto& msg : message_history) {
menu_view.add_item({msg,
ui::Theme::getInstance()->fg_green->foreground,
nullptr,
[](KeyEvent) {}});
}
} else {
menu_view.add_item({message,
ui::Theme::getInstance()->fg_green->foreground,
nullptr,
[](KeyEvent) {}});
}
menu_view.set_highlighted(menu_view.item_count() - 1);
}
bool ShoppingCartLock::is_active() const {
return (bool)replay_thread;
}
void ShoppingCartLock::focus() {
menu_view.focus();
}
void ShoppingCartLock::stop() {
log_event(">>> STOP_SEQUENCE_START");
if (is_active()) {
log_event("... Resetting Replay Thread");
replay_thread.reset();
}
log_event("... Stopping Audio Output");
audio::output::stop();
log_event("... Resetting State Variables");
transmitter_model.disable();
ready_signal = false;
thread_sync_complete = false;
looping = false;
current_file = "";
log_event("<<< STOP_SEQUENCE_COMPLETE");
}
std::string ShoppingCartLock::list_wav_files() {
log_event(">>> WAV_SCAN_START");
auto reader = std::make_unique<WAVFileReader>();
bool found_lock = false;
bool found_unlock = false;
for (const auto& entry : std::filesystem::directory_iterator(wav_dir, u"*")) {
if (std::filesystem::is_regular_file(entry.status())) {
auto filename = entry.path().filename().string();
std::transform(filename.begin(), filename.end(), filename.begin(), ::tolower);
if (filename == shoppingcart_lock_file || filename == shoppingcart_unlock_file) {
std::string file_path = (wav_dir / filename).string();
if (reader->open(file_path)) {
if (filename == shoppingcart_lock_file) {
found_lock = true;
log_event("... Found: " + shoppingcart_lock_file);
log_event("Sample Rate: " + std::to_string(reader->sample_rate()));
log_event("Channels: " + std::to_string(reader->channels()));
log_event("Bits/Sample: " + std::to_string(reader->bits_per_sample()));
}
if (filename == shoppingcart_unlock_file) {
found_unlock = true;
log_event("... Found: " + shoppingcart_unlock_file);
log_event("Sample Rate: " + std::to_string(reader->sample_rate()));
log_event("Channels: " + std::to_string(reader->channels()));
log_event("Bits/Sample: " + std::to_string(reader->bits_per_sample()));
}
}
}
if (found_lock && found_unlock) {
break;
}
}
}
if (!found_lock || !found_unlock) {
log_event("!!! Missing Required Files:");
if (!found_lock) log_event("!!! Missing: " + shoppingcart_lock_file);
if (!found_unlock) log_event("!!! Missing: " + shoppingcart_unlock_file);
menu_view.hidden(true);
text_empty.hidden(false);
} else {
log_event("... All Required Files Found");
menu_view.hidden(false);
text_empty.hidden(true);
}
log_event("<<< WAV_SCAN_COMPLETE");
return found_lock && found_unlock ? "Required WAV files found" : "Missing required WAV files";
}
void ShoppingCartLock::wait_for_thread() {
uint32_t timeout = 100;
while (!ready_signal && timeout > 0) {
chThdYield();
timeout--;
}
}
void ShoppingCartLock::restart_playback() {
auto reader = std::make_unique<WAVFileReader>();
std::string file_path = (wav_dir / current_file).string();
if (!reader->open(file_path)) return;
replay_thread = std::make_unique<ReplayThread>(
std::move(reader),
BUFFER_SIZE,
NUM_BUFFERS,
&ready_signal,
[](uint32_t return_code) {
ReplayThreadDoneMessage message{return_code};
EventDispatcher::send_message(message);
});
log_event(">> SENDING <<");
audio::output::start();
transmitter_model.enable();
}
void ShoppingCartLock::play_audio(const std::string& filename, bool loop) {
auto reader = std::make_unique<WAVFileReader>();
stop();
std::string file_path = (wav_dir / filename).string();
if (!reader->open(file_path)) {
nav_.display_modal("Error", "Cannot open " + filename);
return;
}
const uint32_t wav_sample_rate = reader->sample_rate();
const uint16_t wav_bits_per_sample = reader->bits_per_sample();
current_file = filename;
looping = loop;
replay_thread = std::make_unique<ReplayThread>(
std::move(reader),
BUFFER_SIZE,
NUM_BUFFERS,
&ready_signal,
[](uint32_t return_code) {
ReplayThreadDoneMessage message{return_code};
EventDispatcher::send_message(message);
});
wait_for_thread();
log_event("... Configuring Baseband");
const uint32_t bb_sample_rate = 1536000;
const uint32_t decimation = bb_sample_rate / wav_sample_rate;
baseband::set_audiotx_config(
bb_sample_rate / decimation,
0.0f,
5.0f,
wav_bits_per_sample,
wav_bits_per_sample,
0,
true,
false,
false,
false);
baseband::set_sample_rate(wav_sample_rate);
log_event("... Starting Audio Output");
audio::output::start();
log_event("... Setting Max Volume");
audio::headphone::set_volume(audio::headphone::volume_range().max);
transmitter_model.enable();
log_event(">>> Playback Started <<<");
}
ShoppingCartLock::ShoppingCartLock(NavigationView& nav)
: nav_{nav} {
add_children({&menu_view,
&text_empty,
&button_lock,
&button_unlock,
&button_stop});
button_lock.on_select = [this](Button&) {
if (is_active()) stop();
log_event(">>> LOCK_SEQUENCE_START");
play_audio(shoppingcart_lock_file, true);
};
button_unlock.on_select = [this](Button&) {
if (is_active()) stop();
log_event(">>> UNLOCK_SEQUENCE_START");
play_audio(shoppingcart_unlock_file, true);
};
button_stop.on_select = [this](Button&) {
log_event(">>> STOPPING AUDIO");
stop();
};
list_wav_files();
log_event("[+] INITIALIZATION COMPLETE");
log_event("[+] PORTAPACK ARMED");
log_event("[*] STATUS: READY");
}
ShoppingCartLock::~ShoppingCartLock() {
stop();
baseband::shutdown();
}
} // namespace ui::external_app::shoppingcart_lock
@@ -0,0 +1,102 @@
// RocketGod's Shopping Cart Lock app
// https://betaskynet.com
#pragma once
#include "ui_widget.hpp"
#include "ui_transmitter.hpp"
#include "replay_thread.hpp"
#include "baseband_api.hpp"
#include "io_wave.hpp"
#include "audio.hpp"
#include "portapack_shared_memory.hpp"
#include "ui_language.hpp"
#include "file_path.hpp"
namespace ui::external_app::shoppingcart_lock {
class ShoppingCartLock : public View {
public:
explicit ShoppingCartLock(NavigationView& nav);
~ShoppingCartLock();
ShoppingCartLock(const ShoppingCartLock&) = delete;
ShoppingCartLock& operator=(const ShoppingCartLock&) = delete;
std::string title() const override { return "Cart Lock"; };
void focus() override;
private:
static constexpr size_t BUFFER_SIZE = 8192;
static constexpr size_t NUM_BUFFERS = 8;
const std::string shoppingcart_lock_file{"shopping_cart_lock.wav"};
const std::string shoppingcart_unlock_file{"shopping_cart_unlock.wav"};
NavigationView& nav_;
std::unique_ptr<ReplayThread> replay_thread{};
bool ready_signal{false};
bool thread_sync_complete{false};
bool looping{false};
std::string current_file{};
struct WAVProperties {
uint32_t sample_rate;
uint16_t bits_per_sample;
size_t file_size;
};
void log_event(const std::string& message);
std::string list_wav_files();
void handle_error(const std::string& message);
void play_audio(const std::string& filename, bool loop = false);
void stop();
bool is_active() const;
void wait_for_thread();
void restart_playback();
MenuView menu_view{
{0, 0, 240, 150},
true};
Text text_empty{
{40, 70, 160, 16},
"RocketGod was here"};
Button button_lock{
{40, 165, 160, 35},
LanguageHelper::currentMessages[LANG_LOCK]};
Button button_unlock{
{40, 205, 160, 35},
LanguageHelper::currentMessages[LANG_UNLOCK]};
Button button_stop{
{40, 245, 160, 35},
LanguageHelper::currentMessages[LANG_STOP]};
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) {
ready_signal = true;
}
}};
MessageHandlerRegistration message_handler_replay_thread_done{
Message::ID::ReplayThreadDone,
[this](const Message* const p) {
const auto message = *reinterpret_cast<const ReplayThreadDoneMessage*>(p);
if (message.return_code == ReplayThread::END_OF_FILE && looping) {
if (is_active()) {
chThdSleepMilliseconds(50);
restart_playback();
}
} else {
thread_sync_complete = true;
stop();
}
}};
};
} // namespace ui::external_app::shoppingcart_lock
+2
View File
@@ -30,6 +30,7 @@ const std::filesystem::path audio_dir = u"AUDIO";
const std::filesystem::path blerx_dir = u"BLERX";
const std::filesystem::path bletx_dir = u"BLETX";
const std::filesystem::path captures_dir = u"CAPTURES";
const std::filesystem::path cvsfiles_dir = u"CVSFILES";
const std::filesystem::path debug_dir = u"DEBUG";
const std::filesystem::path firmware_dir = u"FIRMWARE";
const std::filesystem::path freqman_dir = u"FREQMAN";
@@ -47,3 +48,4 @@ const std::filesystem::path splash_dir = u"SPLASH";
const std::filesystem::path sstv_dir = u"SSTV";
const std::filesystem::path wav_dir = u"WAV";
const std::filesystem::path whipcalc_dir = u"WHIPCALC";
const std::filesystem::path rook_dir = u"ROOK";
+2
View File
@@ -32,6 +32,7 @@ extern const std::filesystem::path audio_dir;
extern const std::filesystem::path blerx_dir;
extern const std::filesystem::path bletx_dir;
extern const std::filesystem::path captures_dir;
extern const std::filesystem::path cvsfiles_dir;
extern const std::filesystem::path debug_dir;
extern const std::filesystem::path firmware_dir;
extern const std::filesystem::path freqman_dir;
@@ -49,5 +50,6 @@ extern const std::filesystem::path splash_dir;
extern const std::filesystem::path sstv_dir;
extern const std::filesystem::path wav_dir;
extern const std::filesystem::path whipcalc_dir;
extern const std::filesystem::path rook_dir;
#endif /* __FILE_PATH_H__ */
+127 -31
View File
@@ -29,15 +29,16 @@
namespace fs = std::filesystem;
using namespace std::literals;
const std::string_view filetype_name = "Filetype"sv;
const std::string_view frequency_name = "Frequency"sv;
const std::string_view latitude_name_old = "Latitute"sv;
const std::string_view longitude_name_old = "Longitude"sv;
const std::string_view latitude_name = "Lat"sv;
const std::string_view longitude_name = "Lon"sv;
const std::string_view protocol_name = "Protocol"sv;
const std::string_view preset_name = "Preset"sv;
const std::string_view te_name = "TE"sv; // only in BinRAW
const std::string filetype_name = "Filetype";
const std::string frequency_name = "Frequency";
const std::string latitude_name_old = "Latitute";
const std::string longitude_name_old = "Longitude";
const std::string latitude_name = "Lat";
const std::string longitude_name = "Lon";
const std::string protocol_name = "Protocol";
const std::string preset_name = "Preset";
const std::string te_name = "TE"; // only in BinRAW
const std::string bit_count_name = "Bit"; // for us, only in BinRAW
/*
Filetype: Flipper SubGhz Key File
@@ -72,39 +73,54 @@ raw_data- positive: carrier for n time, negative: no carrier for n time. (us)
Optional<flippersub_metadata> read_flippersub_file(const fs::path& path) {
File f;
auto error = f.open(path);
if (error)
return {};
flippersub_metadata metadata{};
auto reader = FileLineReader(f);
for (const auto& line : reader) {
auto cols = split_string(line, ':');
if (cols.size() != 2)
char ch = 0;
std::string line = "";
auto fr = f.read(&ch, 1);
while (!fr.is_error() && fr.value() > 0) {
if (line.length() < 130 && ch != '\n') line += ch;
if (ch != '\n') {
fr = f.read(&ch, 1);
continue;
}
auto it = line.find(':', 0);
if (it == std::string::npos) {
fr = f.read(&ch, 1);
continue; // Bad line.
if (cols[1].length() <= 1) continue;
std::string fixed = cols[1].data() + 1;
}
std::string fixed = line.data() + it + 1;
fixed = trim(fixed);
if (cols[0] == filetype_name) {
std::string head = line.substr(0, it);
line = "";
if (fixed.length() <= 1) {
fr = f.read(&ch, 1);
continue;
}
if (head == filetype_name) {
if (fixed != "Flipper SubGhz Key File" && fixed != "Flipper SubGhz RAW File") return {}; // not supported
} else if (cols[0] == frequency_name)
} else if (head == frequency_name)
parse_int(fixed, metadata.center_frequency);
else if (cols[0] == latitude_name)
else if (head == latitude_name)
parse_float_meta(fixed, metadata.latitude);
else if (cols[0] == longitude_name)
else if (head == longitude_name)
parse_float_meta(fixed, metadata.longitude);
else if (cols[0] == latitude_name_old)
else if (head == latitude_name_old)
parse_float_meta(fixed, metadata.latitude);
else if (cols[0] == longitude_name_old)
else if (head == longitude_name_old)
parse_float_meta(fixed, metadata.longitude);
else if (cols[0] == protocol_name) {
else if (head == protocol_name) {
if (fixed == "RAW") metadata.protocol = FLIPPER_PROTO_RAW;
if (fixed == "BinRAW") metadata.protocol = FLIPPER_PROTO_BINRAW;
} else if (cols[0] == te_name) {
} else if (head == te_name) {
metadata.te = atoi(fixed.c_str());
} else if (cols[0] == preset_name) {
} else if (head == bit_count_name) {
metadata.binraw_bit_count = atol(fixed.c_str());
} else if (head == preset_name) {
if (fixed.find("FSK") != std::string::npos) {
metadata.preset = FLIPPER_PRESET_2FSK;
} else if (fixed.find("Ook") != std::string::npos) {
@@ -112,12 +128,92 @@ Optional<flippersub_metadata> read_flippersub_file(const fs::path& path) {
} else if (fixed.find("Custom") != std::string::npos) {
metadata.preset = FLIPPER_PRESET_CUSTOM;
}
} else
continue;
}
fr = f.read(&ch, 1);
}
f.close();
if (metadata.center_frequency == 0) return {}; // Parse failed.
return metadata;
}
bool seek_flipper_raw_first_data(File& f) {
f.seek(0);
std::string chs = "";
char ch;
while (f.read(&ch, 1)) {
if (ch == '\r') continue;
if (ch == '\n') {
chs = "";
continue;
};
chs += ch;
if (ch == 0) break;
if (chs == "RAW_Data: ") {
return true;
}
}
return false;
}
bool seek_flipper_binraw_first_data(File& f, bool seekzero) {
if (seekzero) f.seek(0);
std::string chs = "";
char ch;
while (f.read(&ch, 1)) {
if (ch == '\r') continue;
if (ch == '\n') {
chs = "";
continue;
};
if (ch == 0) break;
chs += ch;
if (chs == "Data_RAW: ") {
return true;
}
}
return false;
}
Optional<int32_t> read_flipper_raw_next_data(File& f) {
// RAW_Data: 5832 -12188 130 -162
std::string chs = "";
char ch = 0;
while (f.read(&ch, 1).is_ok()) {
if (ch == '\r') continue; // should not present
if ((ch == ' ') || ch == '\n') {
if (chs == "RAW_Data:") {
chs = "";
continue;
}
break;
};
if (ch == 0) break;
chs += ch;
}
if (chs == "") return {};
return atol(chs.c_str());
}
Optional<uint8_t> read_flipper_binraw_next_data(File& f) {
// Data_RAW: 02 10 84 BUT THERE ARE Bit_RAW lines to skip!
std::string chs = "";
char ch = 0;
while (f.read(&ch, 1)) {
if (ch == '\r') continue; // should not present
if ((ch == ' ') || ch == '\n') {
if (chs == "RAW_Data:") {
chs = "";
continue;
}
break;
};
if (ch == 0) break;
chs += ch;
}
if (chs == "") return {};
return static_cast<uint8_t>(std::stoul(chs, nullptr, 16));
}
bool get_flipper_binraw_bitvalue(uint8_t byte, uint8_t nthBit) {
return (byte & (1 << nthBit)) != 0;
}
+6
View File
@@ -44,9 +44,15 @@ struct flippersub_metadata {
FlipperProto protocol = FLIPPER_PROTO_UNSUPPORTED;
FlipperPreset preset = FLIPPER_PRESET_UNK;
uint16_t te = 0;
uint32_t binraw_bit_count = 0;
};
Optional<flippersub_metadata> read_flippersub_file(const std::filesystem::path& path);
bool seek_flipper_raw_first_data(File& f);
bool seek_flipper_binraw_first_data(File& f, bool seekzero = true);
Optional<int32_t> read_flipper_raw_next_data(File& f);
Optional<uint8_t> read_flipper_binraw_next_data(File& f);
bool get_flipper_binraw_bitvalue(uint8_t byte, uint8_t nthBit);
// Maybe sometime there will be a data part reader / converter
+110
View File
@@ -0,0 +1,110 @@
/*
* Copyright (C) 2023 Bernd Herzog
* Copyright (C) 2024 HTotoo
*
* 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 "i2c_device_to_host.h"
#include "i2cdevmanager_c_api.h"
#include <string.h>
I2CShellDriver I2CD1;
// pp to i2c data tx
static void onotifyi2c(GenericQueue* qp) {
I2CShellDriver* sdp = chQGetLink(qp);
uint8_t buff[I2CSHELL_BUFFERS_SIZE];
int n = chOQGetFullI(&sdp->oqueue);
if (n > I2CSHELL_BUFFERS_SIZE) n = I2CSHELL_BUFFERS_SIZE; // don't overflow
if (n > 0) {
for (int i = 0; i < n; i++) {
buff[i] = chOQGetI(&sdp->oqueue);
}
int ret;
chSysUnlock();
do {
ret = oNofityI2cFromShell(&buff[0], n); // i2c_write
if (ret == -1)
chThdSleepMilliseconds(1);
} while (ret == -1);
chSysLock();
}
}
static size_t write(void* ip, const uint8_t* bp, size_t n) {
return chOQWriteTimeout(&((I2CShellDriver*)ip)->oqueue, bp,
n, TIME_INFINITE);
}
static size_t read(void* ip, uint8_t* bp, size_t n) {
return chIQReadTimeout(&((I2CShellDriver*)ip)->iqueue, bp,
n, TIME_INFINITE);
}
static msg_t put(void* ip, uint8_t b) {
return chOQPutTimeout(&((I2CShellDriver*)ip)->oqueue, b, TIME_INFINITE);
}
static msg_t get(void* ip) {
return chIQGetTimeout(&((I2CShellDriver*)ip)->iqueue, TIME_INFINITE);
}
static msg_t putt(void* ip, uint8_t b, systime_t timeout) {
return chOQPutTimeout(&((I2CShellDriver*)ip)->oqueue, b, timeout);
}
static msg_t gett(void* ip, systime_t timeout) {
return chIQGetTimeout(&((I2CShellDriver*)ip)->iqueue, timeout);
}
static size_t writet(void* ip, const uint8_t* bp, size_t n, systime_t time) {
return chOQWriteTimeout(&((I2CShellDriver*)ip)->oqueue, bp, n, time);
}
static size_t readt(void* ip, uint8_t* bp, size_t n, systime_t time) {
return chIQReadTimeout(&((I2CShellDriver*)ip)->iqueue, bp, n, time);
}
static const struct I2CShellDriverVMT vmt = {
write, read, put, get,
putt, gett, writet, readt};
void init_i2c_shell_driver(I2CShellDriver* sdp) {
sdp->vmt = &vmt;
chIQInit(&sdp->iqueue, sdp->ib, I2CSHELL_BUFFERS_SIZE, NULL, sdp);
chOQInit(&sdp->oqueue, sdp->ob, I2CSHELL_BUFFERS_SIZE, onotifyi2c, sdp);
}
// i2c->pp data rx
void complete_i2chost_to_device_transfer(uint8_t* data, size_t length) {
chSysLock();
for (unsigned int i = 0; i < length; i++) {
msg_t ret;
do {
ret = chIQPutI(&I2CD1.iqueue, data[i]);
if (ret == Q_FULL) {
chSysUnlock();
chThdSleepMilliseconds(1); // wait for shell thread when buffer is full
chSysLock();
}
} while (ret == Q_FULL);
}
chSysUnlock();
}
+58
View File
@@ -0,0 +1,58 @@
/*
* Copyright (C) 2023 Bernd Herzog
* Copyright (C) 2024 HTotoo
*
* 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 __I2C_DEVICE_TO_HOST_H
#define __I2C_DEVICE_TO_HOST_H
#include "ch.h"
#include "hal.h"
#ifndef I2CSHELL_BUFFERS_SIZE
#define I2CSHELL_BUFFERS_SIZE 64
#endif
struct I2CShellDriverVMT {
_base_asynchronous_channel_methods
};
struct I2CShellDriver {
/** @brief Virtual Methods Table.*/
const struct I2CShellDriverVMT* vmt;
InputQueue iqueue; /* Output queue.*/
OutputQueue oqueue; /* Input circular buffer.*/
uint8_t ib[I2CSHELL_BUFFERS_SIZE]; /* Output circular buffer.*/
uint8_t ob[I2CSHELL_BUFFERS_SIZE];
};
typedef struct I2CShellDriver I2CShellDriver;
extern I2CShellDriver I2CD1;
#ifdef __cplusplus
extern "C" {
#endif
void init_i2c_shell_driver(I2CShellDriver* sdp);
#ifdef __cplusplus
}
#endif
#endif
+2
View File
@@ -139,6 +139,7 @@ Continuous (Fox-oring)
#include "sd_card.hpp"
#include <string.h>
#include "i2cdevmanager.hpp"
#include "rffc507x.hpp" /* c/m, avoiding initial short ON Ant_DC_Bias pulse, from cold reset */
rffc507x::RFFC507x first_if;
@@ -159,6 +160,7 @@ static void event_loop() {
event_dispatcher.set_display_sleep(true);
}};
portapack::setEventDispatcherToUSBSerial(&event_dispatcher);
i2cdev::I2CDevManager::setEventDispatcher(&event_dispatcher);
system_view.get_navigation_view()->handle_autostart();
event_dispatcher.run();
}
@@ -11,10 +11,32 @@ namespace ui {
/* static */ std::vector<DynamicBitmap<16, 16>> ExternalItemsMenuLoader::bitmaps;
// iterates over all ppma-s, and if it is runnable on the current system, it'll call the callback, and pass info.
/* static */ void ExternalItemsMenuLoader::load_all_external_items_callback(std::function<void(AppInfoConsole&)> callback) {
// iterates over all possible ext apps-s, and if it is runnable on the current system, it'll call the callback, and pass minimal info. used to print to console, and for autostart setting's app list. where the minimal info is enough
// please keep in sync with load_external_items
/* static */ void ExternalItemsMenuLoader::load_all_external_items_callback(std::function<void(AppInfoConsole&)> callback, bool module_included) {
if (!callback) return;
auto dev = (i2cdev::I2cDev_PPmod*)i2cdev::I2CDevManager::get_dev_by_model(I2C_DEVMDL::I2CDECMDL_PPMOD);
if (dev && module_included) {
auto device_info = dev->readDeviceInfo();
if (device_info.has_value()) {
for (uint32_t i = 0; i < device_info->application_count; i++) {
auto appInfo = dev->getStandaloneAppInfo(i);
if (appInfo.has_value() == false) {
continue;
}
if (appInfo->header_version > CURRENT_STANDALONE_APPLICATION_API_VERSION)
continue;
AppInfoConsole appInfoConsole = {reinterpret_cast<char*>(&appInfo->app_name[0]), reinterpret_cast<char*>(&appInfo->app_name[0]), appInfo->menu_location};
callback(appInfoConsole);
}
}
}
if (sd_card::status() != sd_card::Status::Mounted)
return;
@@ -36,18 +58,16 @@ namespace ui {
continue;
bool versionMatches = VERSION_MD5 == application_information.app_version;
if (!versionMatches) continue;
// here the app is startable and good.
std::string appshortname = filePath.filename().string();
if (appshortname.size() >= 5 && appshortname.substr(appshortname.size() - 5) == ".ppma") {
// Remove the ".ppma" suffix
appshortname = appshortname.substr(0, appshortname.size() - 5);
if (versionMatches) {
std::string appshortname = filePath.filename().string();
if (appshortname.size() >= 5 && appshortname.substr(appshortname.size() - 5) == ".ppma") {
// Remove the ".ppma" suffix
appshortname = appshortname.substr(0, appshortname.size() - 5);
}
AppInfoConsole appInfoConsole = {appshortname.c_str(), reinterpret_cast<char*>(&application_information.app_name[0]), application_information.menu_location};
callback(appInfoConsole);
}
AppInfoConsole info{
.appCallName = appshortname.c_str(),
.appFriendlyName = reinterpret_cast<char*>(&application_information.app_name[0]),
.appLocation = application_information.menu_location};
callback(info);
}
for (const auto& entry : std::filesystem::directory_iterator(apps_dir, u"*.ppmp")) {
@@ -64,21 +84,16 @@ namespace ui {
if (!readResult)
continue;
if (application_information.header_version < CURRENT_STANDALONE_APPLICATION_API_VERSION)
if (application_information.header_version > CURRENT_STANDALONE_APPLICATION_API_VERSION)
continue;
// here the app is startable and good.
std::string appshortname = filePath.filename().string();
if (appshortname.size() >= 5 && appshortname.substr(appshortname.size() - 5) == ".ppmp") {
// Remove the ".ppmp" suffix
appshortname = appshortname.substr(0, appshortname.size() - 5);
}
AppInfoConsole info{
.appCallName = appshortname.c_str(),
.appFriendlyName = reinterpret_cast<char*>(&application_information.app_name[0]),
.appLocation = application_information.menu_location};
callback(info);
AppInfoConsole appInfoConsole = {appshortname.c_str(), reinterpret_cast<char*>(&application_information.app_name[0]), application_information.menu_location};
callback(appInfoConsole);
}
}
@@ -60,7 +60,7 @@ class ExternalItemsMenuLoader {
static bool run_external_app(ui::NavigationView&, std::filesystem::path);
static bool run_standalone_app(ui::NavigationView&, std::filesystem::path);
static bool run_module_app(ui::NavigationView&, uint8_t*, size_t);
static void load_all_external_items_callback(std::function<void(AppInfoConsole&)> callback);
static void load_all_external_items_callback(std::function<void(AppInfoConsole&)> callback, bool module_included = false);
private:
static std::vector<DynamicBitmap<16, 16>> bitmaps;
+25 -30
View File
@@ -43,7 +43,6 @@
#include "ui_flash_utility.hpp"
#include "ui_font_fixed_8x16.hpp"
#include "ui_freqman.hpp"
#include "ui_fsk_rx.hpp"
#include "ui_iq_trim.hpp"
#include "ui_level.hpp"
#include "ui_looking_glass_app.hpp"
@@ -309,15 +308,6 @@ SystemStatusView::SystemStatusView(
battery_icon.on_select = [this]() { on_battery_details(); };
battery_text.on_select = [this]() { on_battery_details(); };
button_fake_brightness.on_select = [this](ImageButton&) {
set_dirty();
pmem::toggle_fake_brightness_level();
refresh();
if (nullptr != parent()) {
parent()->set_dirty(); // The parent of NavigationView shal be the SystemView
}
};
button_bias_tee.on_select = [this](ImageButton&) {
this->on_bias_tee();
};
@@ -384,7 +374,6 @@ void SystemStatusView::refresh() {
// Display "Disable speaker" icon only if AK4951 Codec which has separate speaker/headphone control
if (audio::speaker_disable_supported() && !pmem::ui_hide_speaker()) status_icons.add(&toggle_speaker);
if (!pmem::ui_hide_fake_brightness() && !pmem::config_lcd_inverted_mode()) status_icons.add(&button_fake_brightness);
if (battery::BatteryManagement::isDetected()) {
batt_was_inited = true;
if (!pmem::ui_hide_battery_icon()) {
@@ -417,9 +406,6 @@ void SystemStatusView::refresh() {
button_converter.set_bitmap(pmem::config_updown_converter() ? &bitmap_icon_downconvert : &bitmap_icon_upconvert);
button_converter.set_foreground(pmem::config_converter() ? Theme::getInstance()->fg_red->foreground : Theme::getInstance()->fg_light->foreground);
// Fake Brightness
button_fake_brightness.set_foreground((pmem::apply_fake_brightness() & (!pmem::config_lcd_inverted_mode())) ? *Theme::getInstance()->status_active : Theme::getInstance()->fg_light->foreground);
set_dirty();
}
@@ -724,31 +710,40 @@ void NavigationView::handle_autostart() {
"nav"sv,
{{"autostart_app"sv, &autostart_app}}};
if (!autostart_app.empty()) {
bool app_started = false;
// try innerapp
bool started = false;
// inner app
if (StartAppByName(autostart_app.c_str())) {
app_started = true;
} else {
// try outside app
auto external_items = ExternalItemsMenuLoader::load_external_items(app_location_t::HOME, *this);
for (const auto& item : external_items) {
if (item.text == autostart_app) {
item.on_select();
app_started = true;
break;
started = true;
}
if (!started) {
// ppma
std::string appwithpath = "/" + apps_dir.string() + "/" + autostart_app + ".ppma";
std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t> conv;
std::filesystem::path pth = conv.from_bytes(appwithpath.c_str());
if (ui::ExternalItemsMenuLoader::run_external_app(*this, pth)) {
started = true;
}
if (!started) {
// ppmp / standalone
appwithpath = "/" + apps_dir.string() + "/" + autostart_app + ".ppmp";
pth = conv.from_bytes(appwithpath.c_str());
if (ui::ExternalItemsMenuLoader::run_standalone_app(*this, pth)) {
started = true;
}
}
}
if (!app_started) {
if (!started) {
display_modal(
"Notice", "Autostart failed:\n" +
autostart_app +
"\nupdate sdcard content\n" +
"and check if .ppma exists");
}
}
} // autostart end
return;
}
/* Helpers **************************************************************/
@@ -991,7 +986,7 @@ BMPView::BMPView(NavigationView& nav)
void BMPView::paint(Painter&) {
if (!portapack::display.drawBMP2({0, 0}, splash_dot_bmp))
portapack::display.drawBMP({(240 - 230) / 2, (320 - 50) / 2 - 10}, splash_bmp, (const uint8_t[]){0x29, 0x18, 0x16});
portapack::display.drawBMP({0, 16}, splash_bmp, (const uint8_t[]){0x29, 0x18, 0x16});
}
bool BMPView::on_touch(const TouchEvent event) {
-6
View File
@@ -279,12 +279,6 @@ class SystemStatusView : public View {
Theme::getInstance()->fg_light->foreground,
Theme::getInstance()->bg_dark->background};
ImageButton button_fake_brightness{
{0, 0, 2 * 8, 1 * 16},
&bitmap_icon_brightness,
*Theme::getInstance()->status_active,
Theme::getInstance()->bg_dark->background};
SDCardStatusView sd_card_status_view{
{0, 0 * 16, 2 * 8, 1 * 16}};
+14
View File
@@ -38,6 +38,7 @@
#include "performance_counter.hpp"
#include "usb_serial_device_to_host.h"
#include "i2c_device_to_host.h"
#include "chprintf.h"
#include "chqueues.h"
#include "ui_external_items_menu_loader.hpp"
@@ -59,6 +60,7 @@
#define palOutputPad(port, pad) (LPC_GPIO->DIR[(port)] |= 1 << (pad))
static EventDispatcher* _eventDispatcherInstance = NULL;
static bool shell_i2c_created = false;
static EventDispatcher* getEventDispatcherInstance() {
return _eventDispatcherInstance;
}
@@ -1222,7 +1224,19 @@ static const ShellConfig shell_cfg1 = {
(BaseSequentialStream*)&SUSBD1,
commands};
static const ShellConfig shell_cfg2 = {
(BaseSequentialStream*)&I2CD1,
commands};
void create_shell(EventDispatcher* evtd) {
_eventDispatcherInstance = evtd;
shellCreate(&shell_cfg1, SHELL_WA_SIZE, NORMALPRIO + 10);
}
extern "C" void create_shell_i2c(EventDispatcher* evtd) {
if (shell_i2c_created) return;
shell_i2c_created = true;
init_i2c_shell_driver(&I2CD1);
_eventDispatcherInstance = evtd;
shellCreate(&shell_cfg2, SHELL_WA_SIZE, NORMALPRIO + 10);
}
@@ -31,4 +31,12 @@ class EventDispatcher;
void create_shell(EventDispatcher* evtd);
#ifdef __cplusplus
extern "C" {
#endif
void create_shell_i2c(EventDispatcher* evtd);
#ifdef __cplusplus
}
#endif
#endif
+8
View File
@@ -656,6 +656,14 @@ set(MODE_CPPSRC
)
DeclareTargets(PADT adsbtx)
### OOKStream
set(MODE_CPPSRC
proc_ook_stream_tx.cpp
)
DeclareTargets(POSK ookstream)
### HackRF "factory" firmware
+127
View File
@@ -0,0 +1,127 @@
/*
* Copyright (C) 2024 HTotoo
*
* 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 "proc_ook_stream_tx.hpp"
#include "sine_table_int8.hpp"
#include "portapack_shared_memory.hpp"
#include "event_m4.hpp"
#include "utility.hpp"
OOKProcessorStreamed::OOKProcessorStreamed() {
configured = false;
baseband_thread.start();
}
inline void OOKProcessorStreamed::write_sample(const buffer_c8_t& buffer, bool bit_value, size_t i) {
int8_t re, im;
if (bit_value) {
phase = (phase + 200); // What ?
sphase = phase + (64 << 18);
re = (sine_table_i8[(sphase & 0x03FC0000) >> 18]);
im = (sine_table_i8[(phase & 0x03FC0000) >> 18]);
} else {
re = 0;
im = 0;
}
buffer.p[i] = {re, im};
}
void OOKProcessorStreamed::execute(const buffer_c8_t& buffer) {
if (!configured || !stream) return;
for (size_t i = 0; i < buffer.count; i++) {
if (rem_samples <= curr_samples) {
// get a new sample from stream
int32_t sample = -13346;
rem_samples = 0; // reset my pointer
curr_samples = 0;
size_t readed = 0;
if (configured) readed = stream->read(&sample, 4); // read from stream // todo htotoo error handling?!
if (readed == 0) {
txprogress_message.progress = -10;
shared_memory.application_queue.push(txprogress_message); // debug
} else {
if (sample == endsignals[readerrs + 1]) { // if no more samples, stop
readerrs++;
if (readerrs == 2) {
configured = false;
txprogress_message.done = true;
txprogress_message.progress = 100;
curr_hilow = false;
shared_memory.application_queue.push(txprogress_message);
}
} else {
if (sample < 0) {
rem_samples = OOK_SAMPLERATE * ((-1 * sample) / 1000000.0);
curr_hilow = false;
} else {
rem_samples = OOK_SAMPLERATE * (sample / 1000000.0);
curr_hilow = true;
}
}
}
}
++curr_samples;
write_sample(buffer, curr_hilow, i);
}
}
void OOKProcessorStreamed::on_message(const Message* const message) {
switch (message->id) {
case Message::ID::ReplayConfig:
configured = false;
replay_config(*reinterpret_cast<const ReplayConfigMessage*>(message));
break;
case Message::ID::FIFOData:
configured = true;
txprogress_message.progress = -4;
shared_memory.application_queue.push(txprogress_message);
break;
default:
break;
}
}
void OOKProcessorStreamed::replay_config(const ReplayConfigMessage& message) {
if (message.config) {
txprogress_message.progress = -2;
shared_memory.application_queue.push(txprogress_message);
stream = std::make_unique<StreamOutput>(message.config);
// Tell application that the buffers and FIFO pointers are ready, prefill
RequestSignalMessage sig_message{RequestSignalMessage::Signal::FillRequest};
shared_memory.application_queue.push(sig_message);
} else {
txprogress_message.progress = -3;
shared_memory.application_queue.push(txprogress_message);
stream.reset();
}
}
int main() {
EventDispatcher event_dispatcher{std::make_unique<OOKProcessorStreamed>()};
event_dispatcher.run();
return 0;
}
+65
View File
@@ -0,0 +1,65 @@
/*
* Copyright (C) 2024 HTotoo
*
* 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.
*/
/*
For usage check the FlipperTX app. Don't forget to "close" the tx by sending 42069, 613379 values at the end of the stream.
Only close baseband when you get the TX done msg, not on replay thread done, because, there can still data in the buffer.
*/
#ifndef __PROC_OOKSTREAMTX_HPP__
#define __PROC_OOKSTREAMTX_HPP__
#include "baseband_processor.hpp"
#include "baseband_thread.hpp"
#include "stream_output.hpp"
#include <array>
#include <memory>
#define OOK_SAMPLERATE 2280000U
class OOKProcessorStreamed : public BasebandProcessor {
public:
OOKProcessorStreamed();
void execute(const buffer_c8_t& buffer) override;
void on_message(const Message* const message) override;
private:
uint32_t rem_samples = 0;
uint32_t curr_samples = 0;
bool curr_hilow = false;
uint32_t phase{0}, sphase{0};
void write_sample(const buffer_c8_t& buffer, bool bit_value, size_t i);
std::unique_ptr<StreamOutput> stream{};
bool configured{false};
void replay_config(const ReplayConfigMessage& message);
int32_t endsignals[3] = {0, 42069, 613379}; // 0 is skipped, count from 1, don't ask...
uint8_t readerrs = 0; // to count in the array
TXProgressMessage txprogress_message{};
/* NB: Threads should be the last members in the class definition. */
BasebandThread baseband_thread{OOK_SAMPLERATE, this, baseband::Direction::Transmit};
};
#endif /*__PROC_OOKSTREAMTX_HPP__*/
+1 -1
View File
@@ -276,7 +276,7 @@ class APRSPacket {
if (!is_digits(sub)) {
return 0;
} else {
return std::stoi(sub);
return atoi(sub.c_str());
}
}
+1 -1
View File
@@ -192,7 +192,7 @@ void I2cDev_MAX17055::update() {
getBatteryInfo(validity, batteryPercentage, voltage, current);
// send local message
BatteryStateMessage msg{validity, batteryPercentage, current >= 0, voltage};
BatteryStateMessage msg{validity, batteryPercentage, current >= 25, voltage};
EventDispatcher::send_message(msg);
}
+59 -10
View File
@@ -23,47 +23,86 @@
#include "portapack.hpp"
#include <optional>
#define SENSORUPDATETIME 10
extern "C" {
void complete_i2chost_to_device_transfer(uint8_t* data, size_t length);
void create_shell_i2c(EventDispatcher* evtd);
}
namespace i2cdev {
bool I2cDev_PPmod::init(uint8_t addr_) {
if (addr_ != I2CDEV_PPMOD_ADDR_1) return false;
addr = addr_;
model = I2CDECMDL_PPMOD;
query_interval = 10;
query_interval = 1; // self timer will handle the update interval per subdevice
mask = get_features_mask();
if (mask & (uint64_t)SupportedFeatures::FEAT_SHELL) {
create_shell_i2c(I2CDevManager::get_event_dispatcher());
}
return true;
}
void I2cDev_PPmod::update() {
auto mask = get_features_mask();
if (mask & (uint64_t)SupportedFeatures::FEAT_GPS) {
// mask = get_features_mask(); //saved on init. replug device if something changed. //needs to revise when modules come out.
if (mask & (uint64_t)SupportedFeatures::FEAT_GPS && self_timer % SENSORUPDATETIME == 0) {
auto data = get_gps_data();
if (data.has_value()) {
GPSPosDataMessage msg{data.value().latitude, data.value().longitude, (int32_t)data.value().altitude, (int32_t)data.value().speed, data.value().sats_in_use};
EventDispatcher::send_message(msg);
}
}
if (mask & (uint64_t)SupportedFeatures::FEAT_ORIENTATION) {
if (mask & (uint64_t)SupportedFeatures::FEAT_ORIENTATION && self_timer % SENSORUPDATETIME == 0) {
auto data = get_orientation_data();
if (data.has_value()) {
OrientationDataMessage msg{(uint16_t)data.value().angle, (int16_t)data.value().tilt};
EventDispatcher::send_message(msg);
}
}
if (mask & (uint64_t)SupportedFeatures::FEAT_ENVIRONMENT) {
if (mask & (uint64_t)SupportedFeatures::FEAT_ENVIRONMENT && self_timer % SENSORUPDATETIME == 0) {
auto data = get_environment_data();
if (data.has_value()) {
EnvironmentDataMessage msg{data.value().temperature, data.value().humidity, data.value().pressure};
EventDispatcher::send_message(msg);
}
}
if (mask & (uint64_t)SupportedFeatures::FEAT_LIGHT) {
if (mask & (uint64_t)SupportedFeatures::FEAT_LIGHT && self_timer % SENSORUPDATETIME == 0) {
auto data = get_light_data();
if (data.has_value()) {
LightDataMessage msg{data.value()};
EventDispatcher::send_message(msg);
}
}
if (mask & (uint64_t)SupportedFeatures::FEAT_SHELL) {
auto commcnt = get_shell_buffer_bytes();
if (commcnt > 0) {
bool has_more = false;
uint8_t buff[65]; // 0 th byte is the has_more flag, and size sent
do {
if (get_shell_get_buffer_data(buff, 65)) {
if (buff[0] == 0xff) {
break; // error
}
has_more = buff[0] & 0x80;
size_t size = buff[0] & 0x7F;
complete_i2chost_to_device_transfer(&buff[1], size);
} else {
has_more = false;
}
} while (has_more);
}
}
self_timer++;
if (self_timer >= 250) {
self_timer = 0; // rounding bc of uint8_t overflow
}
}
bool I2cDev_PPmod::get_shell_get_buffer_data(uint8_t* buff, size_t len) {
Command cmd = Command::COMMAND_SHELL_MODTOPP_DATA;
return i2c_read((uint8_t*)&cmd, 2, buff, len);
}
std::optional<orientation_t> I2cDev_PPmod::get_orientation_data() {
@@ -106,18 +145,28 @@ std::optional<uint16_t> I2cDev_PPmod::get_light_data() {
return data;
}
uint16_t I2cDev_PPmod::get_shell_buffer_bytes() {
Command cmd = Command::COMMAND_SHELL_MODTOPP_DATA_SIZE;
uint16_t data;
bool success = i2c_read((uint8_t*)&cmd, 2, (uint8_t*)&data, sizeof(uint16_t));
if (success == false) {
return 0;
}
return data;
}
uint64_t I2cDev_PPmod::get_features_mask() {
uint64_t mask = 0;
uint64_t mask_ = 0;
Command cmd = Command::COMMAND_GETFEATURE_MASK;
bool success = i2c_read((uint8_t*)&cmd, 2, (uint8_t*)&mask, sizeof(mask));
bool success = i2c_read((uint8_t*)&cmd, 2, (uint8_t*)&mask_, sizeof(mask_));
if (success == false) {
return 0;
}
// sanity check
if (mask == UINT64_MAX) {
if (mask_ == UINT64_MAX) {
return 0;
}
return mask;
return mask_;
}
std::optional<I2cDev_PPmod::device_info> I2cDev_PPmod::readDeviceInfo() {
+10
View File
@@ -55,6 +55,10 @@ class I2cDev_PPmod : public I2cDev {
COMMAND_GETFEAT_DATA_ORIENTATION,
COMMAND_GETFEAT_DATA_ENVIRONMENT,
COMMAND_GETFEAT_DATA_LIGHT,
// Shell specific communication
COMMAND_SHELL_PPTOMOD_DATA, // pp shell to esp. size not defined
COMMAND_SHELL_MODTOPP_DATA_SIZE, // how many bytes the esp has to send to pp's shell
COMMAND_SHELL_MODTOPP_DATA, // the actual bytes sent by esp. 1st byte's 1st bit is the "hasmore" flag, the remaining 7 bits are the size of the data. exactly 64 byte follows.
};
@@ -85,6 +89,12 @@ class I2cDev_PPmod : public I2cDev {
std::optional<orientation_t> get_orientation_data();
std::optional<environment_t> get_environment_data();
std::optional<uint16_t> get_light_data();
uint16_t get_shell_buffer_bytes();
bool get_shell_get_buffer_data(uint8_t* buff, size_t len);
private:
uint8_t self_timer = 0;
uint64_t mask = 0; // feauture mask, that indicates what the device can do. this will determinate what we will query from the device
};
} /* namespace i2cdev */
+9 -8
View File
@@ -4,14 +4,15 @@
#include <cstdint>
enum class SupportedFeatures : uint64_t {
FEAT_NONE = 0,
FEAT_EXT_APP = 1 << 0,
FEAT_UART = 1 << 1,
FEAT_GPS = 1 << 2,
FEAT_ORIENTATION = 1 << 3,
FEAT_ENVIRONMENT = 1 << 4,
FEAT_LIGHT = 1 << 5,
FEAT_DISPLAY = 1 << 6
FEAT_NONE = 0, // no polling needed
FEAT_EXT_APP = 1 << 0, // supplies external app
FEAT_UART = 1 << 1, // supplies UART communication
FEAT_GPS = 1 << 2, // can be queried for GPS info
FEAT_ORIENTATION = 1 << 3, // can be queried for orientation info
FEAT_ENVIRONMENT = 1 << 4, // can be queried for environment info
FEAT_LIGHT = 1 << 5, // can be queried for light info
FEAT_DISPLAY = 1 << 6, // can handle special display output
FEAT_SHELL = 1 << 7, // can handle shell commands (polling needed for that)
};
typedef struct
+9
View File
@@ -41,6 +41,7 @@ bool I2CDevManager::force_scan = false;
Thread* I2CDevManager::thread;
std::vector<I2DevListElement> I2CDevManager::devlist;
Mutex I2CDevManager::mutex_list{};
EventDispatcher* I2CDevManager::_eventDispatcher;
/*
DEAR DEVELOPERS!
@@ -343,3 +344,11 @@ msg_t I2CDevManager::timer_fn(void* arg) {
}
}; // namespace i2cdev
extern "C" int oNofityI2cFromShell(uint8_t* buff, size_t len) {
i2cdev::I2cDev* dev = i2cdev::I2CDevManager::get_dev_by_model(I2C_DEVMDL::I2CDECMDL_PPMOD);
if (!dev) return 0; // nothing to send to, so /dev/null
uint16_t reg = 9; // COMMAND_SHELL_PPTOMOD_DATA;
if (dev->i2c_write((uint8_t*)&reg, 2, buff, len)) return 0;
return 0; // shoud have an error handler
}
+4
View File
@@ -87,6 +87,8 @@ class I2CDevManager {
static I2cDev* get_dev_by_model(I2C_DEVMDL model); // caller function needs to cast to the specific device!
static std::vector<I2C_DEVMDL> get_dev_list_by_model(); // returns the currently discovered
static std::vector<uint8_t> get_gev_list_by_addr(); // returns the currently discovered
static void setEventDispatcher(EventDispatcher* ed) { _eventDispatcher = ed; }
static EventDispatcher* get_event_dispatcher() { return _eventDispatcher; }
private:
static uint16_t scan_interval;
@@ -99,6 +101,8 @@ class I2CDevManager {
static msg_t timer_fn(void* arg);
static Thread* thread;
static Mutex mutex_list;
static EventDispatcher* _eventDispatcher;
};
}; // namespace i2cdev
#endif
+13
View File
@@ -0,0 +1,13 @@
#ifndef I2CDEVMANAGER_C_API_H
#define I2CDEVMANAGER_C_API_H
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
int oNofityI2cFromShell(uint8_t* buff, size_t len);
#ifdef __cplusplus
}
#endif
#endif
-8
View File
@@ -77,18 +77,10 @@ void IO::reference_oscillator(const bool enable) {
io_write(1, io_reg);
}
bool IO::get_dark_cover() {
return portapack::persistent_memory::apply_fake_brightness() & (!portapack::persistent_memory::config_lcd_inverted_mode());
}
bool IO::get_is_inverted() {
return portapack::persistent_memory::config_lcd_inverted_mode();
}
uint8_t IO::get_brightness() {
return portapack::persistent_memory::fake_brightness_level();
}
uint32_t IO::io_update(const TouchPinsConfig write_value) {
/* Very touchy code to save context of PortaPack data bus while the
* resistive touch pin drive is changed. Order of operations is
-19
View File
@@ -162,9 +162,6 @@ class IO {
}
void lcd_write_pixel(ui::Color pixel) {
if (get_dark_cover()) {
pixel.v = DARKENED_PIXEL(pixel.v, get_brightness());
}
lcd_write_data(pixel.v);
}
@@ -173,18 +170,12 @@ class IO {
}
void lcd_write_pixels(ui::Color pixel, size_t n) {
if (get_dark_cover()) {
pixel.v = DARKENED_PIXEL(pixel.v, get_brightness());
}
while (n--) {
lcd_write_data(pixel.v);
}
}
void lcd_write_pixels_unrolled8(ui::Color pixel, size_t n) {
if (get_dark_cover()) {
pixel.v = DARKENED_PIXEL(pixel.v, get_brightness());
}
auto v = pixel.v;
n >>= 3;
while (n--) {
@@ -232,9 +223,6 @@ class IO {
return switches_raw;
}
bool get_is_inverted();
bool get_dark_cover();
uint8_t get_brightness();
// TODO: cache the value ^^ & ^ to increaase performance, need a trigger cuz init doesn't work. And since the constructor is constexpr, we can't use with in class var to cache it. maybe cache from outside somewhere and pass it here as argument.
uint32_t io_update(const TouchPinsConfig write_value);
@@ -416,13 +404,6 @@ class IO {
const auto value_low = data_read();
uint32_t original_value = (value_high << 8) | value_low;
if (get_is_inverted()) return original_value;
if (get_dark_cover()) {
// this is read data, so if the fake brightness is enabled AKA get_dark_cover() == true,
// then shift to back side AKA UNDARKENED_PIXEL, to prevent read shifted darkern info
original_value = UNDARKENED_PIXEL(original_value, get_brightness());
}
return original_value;
}
@@ -109,7 +109,7 @@ struct ui_config_t {
bool hide_clock : 1;
bool clock_show_date : 1;
bool clkout_enabled : 1;
bool apply_fake_brightness : 1;
bool unused_FB : 1; // apply_fake_brightness
bool stealth_mode : 1;
bool config_login : 1;
bool config_splash : 1;
@@ -130,7 +130,7 @@ struct ui_config2_t {
bool hide_sd_card : 1;
bool hide_mute : 1;
bool hide_fake_brightness : 1;
bool UNUSED_3 : 1;
bool hide_numeric_battery : 1;
bool hide_battery_icon : 1;
bool override_batt_calc : 1;
@@ -226,9 +226,6 @@ struct data_t {
// Rotary encoder dial sensitivity (encoder.cpp/hpp)
uint16_t encoder_dial_sensitivity : 4;
// fake brightness level (not switch, switch is in another place)
uint16_t fake_brightness_level : 4;
// Encoder rotation rate multiplier for larger increments when rotated rapidly
uint16_t encoder_rate_multiplier : 4;
@@ -300,7 +297,6 @@ struct data_t {
frequency_tx_correction(0),
encoder_dial_sensitivity(DIAL_SENSITIVITY_NORMAL),
fake_brightness_level(BRIGHTNESS_50),
encoder_rate_multiplier(1),
UNUSED(0),
@@ -469,7 +465,6 @@ void init() {
set_config_mode_storage_direct(config_mode_backup);
// Firmware upgrade handling - adjust newly defined fields where 0 is an invalid default
if (fake_brightness_level() == 0) set_fake_brightness_level(BRIGHTNESS_50);
if (menu_color().v == 0) set_menu_color(Color::grey());
}
@@ -650,10 +645,6 @@ bool stealth_mode() {
return data->ui_config.stealth_mode;
}
bool apply_fake_brightness() {
return data->ui_config.apply_fake_brightness;
}
bool config_login() {
return data->ui_config.config_login;
}
@@ -757,10 +748,6 @@ void set_config_backlight_timer(const backlight_config_t& new_value) {
data->ui_config.enable_backlight_timeout = static_cast<uint8_t>(new_value.timeout_enabled());
}
void set_apply_fake_brightness(const bool v) {
data->ui_config.apply_fake_brightness = v;
}
uint32_t pocsag_last_address() {
return data->pocsag_last_address;
}
@@ -947,9 +934,7 @@ bool ui_hide_clock() {
bool ui_hide_sd_card() {
return data->ui_config2.hide_sd_card;
}
bool ui_hide_fake_brightness() {
return data->ui_config2.hide_fake_brightness;
}
bool ui_hide_numeric_battery() {
return data->ui_config2.hide_numeric_battery;
}
@@ -992,9 +977,6 @@ void set_ui_hide_clock(bool v) {
void set_ui_hide_sd_card(bool v) {
data->ui_config2.hide_sd_card = v;
}
void set_ui_hide_fake_brightness(bool v) {
data->ui_config2.hide_fake_brightness = v;
}
void set_ui_hide_numeric_battery(bool v) {
data->ui_config2.hide_numeric_battery = v;
}
@@ -1112,26 +1094,6 @@ void set_config_dst(dst_config_t v) {
rtc_time::dst_init();
}
// Fake brightness level (switch is in another place)
uint8_t fake_brightness_level() {
return data->fake_brightness_level;
}
void set_fake_brightness_level(uint8_t v) {
data->fake_brightness_level = v;
}
// Cycle through 4 brightness options: disabled -> enabled/50% -> enabled/25% -> enabled/12.5% -> disabled
void toggle_fake_brightness_level() {
bool fbe = apply_fake_brightness();
if (config_lcd_inverted_mode()) return; // for now only inverted mode OR fake brightness
if ((!fbe) || (data->fake_brightness_level >= BRIGHTNESS_12p5)) {
set_apply_fake_brightness(!fbe);
data->fake_brightness_level = BRIGHTNESS_50;
} else {
data->fake_brightness_level++;
}
}
// Menu Color Scheme
Color menu_color() {
return data->menu_color;
@@ -1249,7 +1211,6 @@ bool debug_dump() {
pmem_dump_file.write_line("headphone_volume_cb: " + to_string_dec_int(data->headphone_volume_cb));
pmem_dump_file.write_line("config_mode_storage: 0x" + to_string_hex(data->config_mode_storage, 8));
pmem_dump_file.write_line("dst_config: 0x" + to_string_hex((uint32_t)data->dst_config.v, 8));
pmem_dump_file.write_line("fake_brightness_level: " + to_string_dec_uint(data->fake_brightness_level));
pmem_dump_file.write_line("menu_color: 0x" + to_string_hex(data->menu_color.v, 4));
pmem_dump_file.write_line("touchscreen_threshold: " + to_string_dec_uint(data->touchscreen_threshold));
@@ -1266,7 +1227,6 @@ bool debug_dump() {
pmem_dump_file.write_line("ui_config hide_clock: " + to_string_dec_uint(data->ui_config.hide_clock));
pmem_dump_file.write_line("ui_config clock_with_date: " + to_string_dec_uint(data->ui_config.clock_show_date));
pmem_dump_file.write_line("ui_config clkout_enabled: " + to_string_dec_uint(data->ui_config.clkout_enabled));
pmem_dump_file.write_line("ui_config apply_fake_brightness: " + to_string_dec_uint(data->ui_config.apply_fake_brightness));
pmem_dump_file.write_line("ui_config stealth_mode: " + to_string_dec_uint(data->ui_config.stealth_mode));
pmem_dump_file.write_line("ui_config config_login: " + to_string_dec_uint(data->ui_config.config_login));
pmem_dump_file.write_line("ui_config config_splash: " + to_string_dec_uint(data->ui_config.config_splash));
@@ -1281,7 +1241,6 @@ bool debug_dump() {
pmem_dump_file.write_line("ui_config2 hide_clock: " + to_string_dec_uint(data->ui_config2.hide_clock));
pmem_dump_file.write_line("ui_config2 hide_sd_card: " + to_string_dec_uint(data->ui_config2.hide_sd_card));
pmem_dump_file.write_line("ui_config2 hide_mute: " + to_string_dec_uint(data->ui_config2.hide_mute));
pmem_dump_file.write_line("ui_config2 hide_fake_brightness: " + to_string_dec_uint(data->ui_config2.hide_fake_brightness));
pmem_dump_file.write_line("ui_config2 hide_battery_icon: " + to_string_dec_uint(data->ui_config2.hide_battery_icon));
pmem_dump_file.write_line("ui_config2 hide_numeric_battery: " + to_string_dec_uint(data->ui_config2.hide_numeric_battery));
pmem_dump_file.write_line("ui_config2 theme_id: " + to_string_dec_uint(data->ui_config2.theme_id));
@@ -135,12 +135,6 @@ typedef union {
} dst_config_t;
static_assert(sizeof(dst_config_t) == sizeof(uint32_t));
enum fake_brightness_level_options {
BRIGHTNESS_50 = 1,
BRIGHTNESS_25 = 2,
BRIGHTNESS_12p5 = 3, // 12p5 is 12.5
};
namespace cache {
/* Set values in cache to sensible defaults. */
@@ -273,15 +267,6 @@ uint16_t clkout_freq();
dst_config_t config_dst();
void set_config_dst(dst_config_t v);
/* Fake brightness */
// switch (if do color change):
bool apply_fake_brightness();
void set_apply_fake_brightness(const bool v);
// level (color change level):
uint8_t fake_brightness_level();
void set_fake_brightness_level(uint8_t v);
void toggle_fake_brightness_level();
/* Touchscreen threshold */
uint16_t touchscreen_threshold();
void set_touchscreen_threshold(uint16_t v);
@@ -334,7 +319,6 @@ bool ui_hide_camera();
bool ui_hide_sleep();
bool ui_hide_bias_tee();
bool ui_hide_clock();
bool ui_hide_fake_brightness();
bool ui_hide_numeric_battery();
bool ui_hide_battery_icon();
bool ui_hide_sd_card();
@@ -348,7 +332,6 @@ void set_ui_hide_camera(bool v);
void set_ui_hide_sleep(bool v);
void set_ui_hide_bias_tee(bool v);
void set_ui_hide_clock(bool v);
void set_ui_hide_fake_brightness(bool v);
void set_ui_hide_numeric_battery(bool v);
void set_ui_hide_battery_icon(bool v);
void set_ui_hide_sd_card(bool v);
+1
View File
@@ -104,6 +104,7 @@ constexpr image_tag_t image_tag_fskrx{'P', 'F', 'S', 'R'};
constexpr image_tag_t image_tag_jammer{'P', 'J', 'A', 'M'};
constexpr image_tag_t image_tag_mic_tx{'P', 'M', 'T', 'X'};
constexpr image_tag_t image_tag_ook{'P', 'O', 'O', 'K'};
constexpr image_tag_t image_tag_ookstream{'P', 'O', 'S', 'K'};
constexpr image_tag_t image_tag_rds{'P', 'R', 'D', 'S'};
constexpr image_tag_t image_tag_replay{'P', 'R', 'E', 'P'};
constexpr image_tag_t image_tag_gps{'P', 'G', 'P', 'S'};
+1 -1
View File
@@ -1,7 +1,7 @@
#include "ui_language.hpp"
// use the exact position in this array! the enum's value is the identifier. Best to add to the end
const char* LanguageHelper::englishMessages[] = {"OK", "Cancel", "Error", "Modem setup", "Debug", "Log", "Done", "Start", "Stop", "Scan", "Clear", "Ready", "Data:", "Loop", "Reset", "Pause", "Resume", "Flood", "Show QR", "Save"};
const char* LanguageHelper::englishMessages[] = {"OK", "Cancel", "Error", "Modem setup", "Debug", "Log", "Done", "Start", "Stop", "Scan", "Clear", "Ready", "Data:", "Loop", "Reset", "Pause", "Resume", "Flood", "Show QR", "Save", "Lock", "Unlock", "Browse"};
// multi language support will changes (not in use for now)
const char** LanguageHelper::currentMessages = englishMessages;
+4 -1
View File
@@ -58,7 +58,10 @@ enum LangConsts {
LANG_RESUME,
LANG_FLOOD,
LANG_SHOWQR,
LANG_SAVE
LANG_SAVE,
LANG_LOCK,
LANG_UNLOCK,
LANG_BROWSE
};
class LanguageHelper {
+2 -2
View File
@@ -2681,9 +2681,9 @@ void Waveform::paint(Painter& painter) {
x = prev_x + x_inc;
h /= 2;
prev_y = y_offset + h + (*(data_start++) * y_scale);
prev_y = y_offset + h - (*(data_start++) * y_scale);
for (n = 1; n < length_; n++) {
y = y_offset + h + (*(data_start++) * y_scale);
y = y_offset + h - (*(data_start++) * y_scale);
display.draw_line({prev_x, prev_y}, {(Coord)x, y}, color_);
prev_x = x;
+3 -1
View File
@@ -2,7 +2,7 @@
# Convert png icons to bitmap.hpp inspired by
# make_bitmap.py - Copyright (C) 2016 Furrtek
# Convert bitmap.hpp to icons inspyred by
# Convert bitmap.hpp to icons inspired by
# bitmap_arr_reverse_decode.py - Copyright (C) 2015 Jared Boone, ShareBrained Technology, Inc.
# bitmap_arr_reverse_decode.py - Copyleft (ɔ) 2024 zxkmm with the GPL license
# Copysomething (c) 2024 LupusE with the license, needed by the PortaPack project
@@ -138,6 +138,8 @@ def pp_write_bitmaphpp(pngicons_path, hpp_outpath):
print("Find your bitmap.hpp at", hpp_outpath)
### Convert from a bitmap.hpp file one or all icons in png.
###########################################################
@@ -0,0 +1,219 @@
#!/usr/bin/env python3
# Copysomething (c) 2024 LupusE with the license, needed by the PortaPack project
#
# 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.
#
import argparse
import json
import os
import re
import requests
import sys
cppheader = """#include "ui_about_simple.hpp"
#define ROLL_SPEED_FRAME_PER_LINE 60
// cuz frame rate of pp screen is probably 60, scroll per sec
namespace ui {
// Information: a line starting with a '#' will be yellow coloured
const std::"""
cppfooter = """
AboutView::AboutView(NavigationView& nav) {
add_children({&menu_view,
&button_ok});
button_ok.on_select = [&nav](Button&) {
nav.pop();
};
menu_view.on_left = [this]() {
button_ok.focus();
};
menu_view.on_right = [this]() {
button_ok.focus();
};
for (const std::string& authors_line : authors_list) {
// if it's starting with #, it's a title and we have to substract the '#' and paint yellow
if (authors_line.size() > 0) {
if (authors_line[0] == '#') {
menu_view.add_item(
{authors_line.substr(1, authors_line.size() - 1),
ui::Theme::getInstance()->fg_yellow->foreground,
nullptr,
nullptr});
} else {
menu_view.add_item(
{authors_line,
Theme::getInstance()->bg_darkest->foreground,
nullptr,
nullptr});
}
}
}
}
void AboutView::on_frame_sync() {
if (interacted) return;
if (frame_sync_count++ % ROLL_SPEED_FRAME_PER_LINE == 0) {
const auto current = menu_view.highlighted_index();
const auto count = menu_view.item_count();
if (current < count - 1) {
menu_view.set_highlighted(current + 1);
} else {
menu_view.set_highlighted(0);
// ^ to go back to the REAL top instead of make the 2 at the top to make the title disappeares
menu_view.set_highlighted(2); // the first line that has human name
}
}
}
void AboutView::focus() {
button_ok.focus();
menu_view.set_highlighted(2); // the first line that has human name
}
bool AboutView::on_touch(const TouchEvent) {
interacted = true;
return false;
}
bool AboutView::on_key(const KeyEvent) {
interacted = true;
return false;
}
bool AboutView::on_encoder(const EncoderEvent) {
interacted = true;
menu_view.focus();
return false;
}
} /* namespace ui */
"""
def get_contributors(url):
contributors_list = [] ## Raw list of contributor names
logins = json.loads(requests.get(url).text)
try:
print(f"Could not reach URL - Error: {logins['status']} Messsage: {logins['message']}")
## Status f.ex. 404 / message f.ex. "Not Found" or "API rate limit exceeded for...".
sys.exit()
except:
pass
for gh_user in logins:
clean_ghuser = re.sub('[^a-zA-Z0-9-]', '.', gh_user['login']) ## replace non printable character with .
contributors_list.append(clean_ghuser)
contributor_id = 0
contrib_format = [] ## Formated list of contributors, max 30 char per line
for contributor in contributors_list:
contributor_id +=1
contrib_format.append(contributor)
line_len = len(",".join(contrib_format).split("\n")[-1])
if contributor_id < len(contributors_list) and line_len+len(contributors_list[contributor_id]) >=30:
contrib_format.append("\n")
return(",".join(contrib_format).replace("\n,","\n")) # replace to erase first , in followup lines
def generate_content(projects):
project_contrib = []
project_contrib.append("string authors_list[] = {\n")
project_contrib.append(" \"# * List of contributors * \",\n")
for project in projects:
project_contrib.append(" \" \",\n")
project_contrib.append(f" \"#{project[0]}:\",\n")
url = f"https://api.github.com/repos/{project[1]}/{project[2]}/contributors?per_page={project[3]}"
contrib_mayhem = get_contributors(url).split("\n")
for line in contrib_mayhem:
project_contrib.append(f" \"{line}\",\n")
project_contrib.append(" \" \"};\n")
return("".join(project_contrib))
def pp_create_ui_about_simple_cpp(cpp_file, cppheader, cppcontent, cppfooter):
uiaboutsimplecpp_file = []
uiaboutsimplecpp_file.append(cppheader)
uiaboutsimplecpp_file.append(cppcontent)
uiaboutsimplecpp_file.append(cppfooter)
with open(cpp_file, "w", encoding="utf-8") as file:
file.writelines(uiaboutsimplecpp_file)
print("Find your ui_simple_about.cpp at", cpp_file)
def pp_change_ui_about_simple_cpp(cpp_file, cppcontent):
content = []
content_pattern = re.compile(r"string authors_list\[\] = {\n(?:\s+(?:.*,\n)+\s+.*};\n)", re.MULTILINE)
# Read original file
with open(cpp_file, 'r') as file:
filedata = file.read()
# Replace regex content with generated list
for match in content_pattern.finditer(filedata):
content.append(match[0])
filedata = filedata.replace(content[0], cppcontent)
# Write new file
with open(cpp_file, 'w') as file:
file.write(filedata)
projects = []
## Format: Project title, Github name, Github repo, Amount of contributors
projects.append(["Mayhem-Firmware","portapack-mayhem","mayhem-firmware","50"])
projects.append(["Havoc","furrtek","portapack-havoc","50"])
projects.append(["PortaPack","sharebrained","portapack-hackrf","50"])
projects.append(["HackRF","mossmann","hackrf","15"])
## processing
#############
if __name__ == '__main__':
parser = argparse.ArgumentParser(
description="This tool updates the ui_about_simple.cpp from PortaPack firmware from Github contributors. If no file is given, the file will be generated.",
)
parser.add_argument("--cpp", help="Path of the source ui_about_simple.cpp to update.", default="ui_about_simple.cpp")
parser.add_argument("--new","-n", help="Generate a new file")
args = parser.parse_args()
if args.cpp:
cpp_file = os.path.join(os.getcwd(),args.cpp)
else:
cpp_file = os.path.join(os.getcwd(),"ui_about_simple.cpp")
cppcontent = generate_content(projects)
if args.new or not os.path.isfile(args.cpp):
pp_create_ui_about_simple_cpp(cpp_file, cppheader, cppcontent, cppfooter)
else:
pp_change_ui_about_simple_cpp(cpp_file, cppcontent)
BIN
View File
Binary file not shown.
Binary file not shown.
Binary file not shown.
+14
View File
@@ -0,0 +1,14 @@
**/*.qws
**/*.chg
**/smart.log
**/db/
**/incremental_db/
**/output_files/*.done
**/output_files/*.smsg
**/output_files/*.summary
**/output_files/*.jdi
**/output_files/*.pin
**/output_files/*.pof
**/output_files/*.rpt
**/output_files/*.sld
**/simulation/
@@ -0,0 +1,109 @@
#
# Copyright (C) 2017 Jared Boone, ShareBrained Technology, Inc.
# Copyright (C) 2024 jLynx.net https://github.com/jLynx
#
# 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.
# Makefile based on Altera Quartus documentation example, topic
# "About Using Quartus II from the Command Line"
###################################################################
# Project Configuration:
#
# Specify the name of the design (project) and Quartus II Settings
# File (.qsf) and the list of source files used.
###################################################################
PROJECT=portapack_h4m_cpld
SOURCE_FILES=top.vhd
ASSIGNMENT_FILES=$(PROJECT).qpf $(PROJECT).qsf $(PROJECT).sdc
OUTPUT_DIR=output_files
###################################################################
# Main Targets
#
# all: build everything
# clean: remove output files and database
###################################################################
all: smart.log $(OUTPUT_DIR)/$(PROJECT).asm.rpt $(OUTPUT_DIR)/$(PROJECT).sta.rpt
clean:
rm -rf *.chg *.qws smart.log db/ incremental_db/ $(OUTPUT_DIR)/
map: smart.log $(OUTPUT_DIR)/$(PROJECT).map.rpt
fit: smart.log $(OUTPUT_DIR)/$(PROJECT).fit.rpt
asm: smart.log $(OUTPUT_DIR)/$(PROJECT).asm.rpt
sta: smart.log $(OUTPUT_DIR)/$(PROJECT).sta.rpt
smart: smart.log
###################################################################
# Executable Configuration
###################################################################
MAP_ARGS=
FIT_ARGS=
ASM_ARGS=
STA_ARGS=
###################################################################
# Target implementations
###################################################################
STAMP = echo done >
$(OUTPUT_DIR)/$(PROJECT).map.rpt: $(SOURCE_FILES)
quartus_map $(MAP_ARGS) $(PROJECT)
$(STAMP) fit.chg
$(OUTPUT_DIR)/$(PROJECT).fit.rpt: fit.chg $(OUTPUT_DIR)/$(PROJECT).map.rpt
quartus_fit $(FIT_ARGS) $(PROJECT)
$(STAMP) asm.chg
$(STAMP) sta.chg
$(OUTPUT_DIR)/$(PROJECT).asm.rpt: asm.chg $(OUTPUT_DIR)/$(PROJECT).fit.rpt
quartus_asm $(ASM_ARGS) $(PROJECT)
$(OUTPUT_DIR)/$(PROJECT).sta.rpt: sta.chg $(OUTPUT_DIR)/$(PROJECT).fit.rpt
quartus_sta $(STA_ARGS) $(PROJECT)
smart.log: $(ASSIGNMENT_FILES) $(OUTPUT_DIR)
quartus_sh --determine_smart_action $(PROJECT) > smart.log
###################################################################
# Project initialization
###################################################################
$(OUTPUT_DIR):
mkdir $(OUTPUT_DIR)
$(ASSIGNMENT_FILES): $(OUTPUT_DIR)
quartus_sh --prepare $(PROJECT)
fit.chg:
$(STAMP) fit.chg
sta.chg:
$(STAMP) sta.chg
asm.chg:
$(STAMP) asm.chg
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,30 @@
# -------------------------------------------------------------------------- #
#
# Copyright (C) 1991-2014 Altera Corporation
# Your use of Altera Corporation's design tools, logic functions
# and other software and tools, and its AMPP partner logic
# functions, and any output files from any of the foregoing
# (including device programming or simulation files), and any
# associated documentation or information are expressly subject
# to the terms and conditions of the Altera Program License
# Subscription Agreement, Altera MegaCore Function License
# Agreement, or other applicable license agreement, including,
# without limitation, that your use is for the sole purpose of
# programming logic devices manufactured by Altera and sold by
# Altera or its authorized distributors. Please refer to the
# applicable agreement for further details.
#
# -------------------------------------------------------------------------- #
#
# Quartus II 32-bit
# Version 13.1.4 Build 182 03/12/2014 SJ Web Edition
# Date created = 21:24:55 April 29, 2014
#
# -------------------------------------------------------------------------- #
QUARTUS_VERSION = "13.1"
DATE = "21:24:55 April 29, 2014"
# Revisions
PROJECT_REVISION = "portapack_h4m_cpld"
@@ -0,0 +1,352 @@
# -------------------------------------------------------------------------- #
#
# Copyright (C) 1991-2014 Altera Corporation
# Your use of Altera Corporation's design tools, logic functions
# and other software and tools, and its AMPP partner logic
# functions, and any output files from any of the foregoing
# (including device programming or simulation files), and any
# associated documentation or information are expressly subject
# to the terms and conditions of the Altera Program License
# Subscription Agreement, Altera MegaCore Function License
# Agreement, or other applicable license agreement, including,
# without limitation, that your use is for the sole purpose of
# programming logic devices manufactured by Altera and sold by
# Altera or its authorized distributors. Please refer to the
# applicable agreement for further details.
#
# -------------------------------------------------------------------------- #
#
# Quartus II 32-bit
# Version 13.1.4 Build 182 03/12/2014 SJ Web Edition
# Date created = 21:24:55 April 29, 2014
#
# -------------------------------------------------------------------------- #
#
# Notes:
#
# 1) The default values for assignments are stored in the file:
# portapack_h4m_cpld_assignment_defaults.qdf
# If this file doesn't exist, see file:
# assignment_defaults.qdf
#
# 2) Altera recommends that you do not modify this file. This
# file is updated automatically by the Quartus II software
# and any changes you make may be lost or overwritten.
#
# -------------------------------------------------------------------------- #
set_global_assignment -name FAMILY "MAX II"
set_global_assignment -name DEVICE EPM240T100C5
set_global_assignment -name TOP_LEVEL_ENTITY top
set_global_assignment -name ORIGINAL_QUARTUS_VERSION 13.1
set_global_assignment -name PROJECT_CREATION_TIME_DATE "21:24:55 APRIL 29, 2014"
set_global_assignment -name LAST_QUARTUS_VERSION "22.1std.1 Lite Edition"
set_global_assignment -name PROJECT_OUTPUT_DIRECTORY output_files
set_global_assignment -name MIN_CORE_JUNCTION_TEMP 0
set_global_assignment -name MAX_CORE_JUNCTION_TEMP 85
set_global_assignment -name DEVICE_FILTER_PIN_COUNT 100
set_global_assignment -name ERROR_CHECK_FREQUENCY_DIVISOR "-1"
set_global_assignment -name EDA_SIMULATION_TOOL "Questa Intel FPGA (VHDL)"
set_global_assignment -name EDA_NETLIST_WRITER_OUTPUT_DIR simulation/modelsim -section_id eda_simulation
set_global_assignment -name EDA_OUTPUT_DATA_FORMAT VHDL -section_id eda_simulation
set_global_assignment -name VHDL_INPUT_VERSION VHDL_2008
set_global_assignment -name VHDL_SHOW_LMF_MAPPING_MESSAGES OFF
set_global_assignment -name STRATIX_DEVICE_IO_STANDARD "3.3-V LVCMOS"
set_instance_assignment -name IO_STANDARD "3.3V SCHMITT TRIGGER INPUT" -to SW_D
set_instance_assignment -name IO_STANDARD "3.3V SCHMITT TRIGGER INPUT" -to SW_L
set_instance_assignment -name IO_STANDARD "3.3V SCHMITT TRIGGER INPUT" -to SW_R
set_instance_assignment -name IO_STANDARD "3.3V SCHMITT TRIGGER INPUT" -to SW_ROT_A
set_instance_assignment -name IO_STANDARD "3.3V SCHMITT TRIGGER INPUT" -to SW_ROT_B
set_instance_assignment -name IO_STANDARD "3.3V SCHMITT TRIGGER INPUT" -to SW_SEL
set_instance_assignment -name IO_STANDARD "3.3V SCHMITT TRIGGER INPUT" -to SW_U
set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to TP_D
set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to TP_L
set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to TP_R
set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to TP_U
set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to LCD_DB[15]
set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to LCD_DB[14]
set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to LCD_DB[13]
set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to LCD_DB[12]
set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to LCD_DB[11]
set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to LCD_DB[10]
set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to LCD_DB[9]
set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to LCD_DB[8]
set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to LCD_DB[7]
set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to LCD_DB[6]
set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to LCD_DB[5]
set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to LCD_DB[4]
set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to LCD_DB[3]
set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to LCD_DB[2]
set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to LCD_DB[1]
set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to LCD_DB[0]
set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to LCD_RDX
set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to LCD_RS
set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to LCD_TE
set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to LCD_WRX
set_global_assignment -name EDA_TEST_BENCH_ENABLE_STATUS TEST_BENCH_MODE -section_id eda_simulation
set_global_assignment -name EDA_NATIVELINK_SIMULATION_TEST_BENCH top_tb -section_id eda_simulation
set_global_assignment -name EDA_TEST_BENCH_NAME top_tb -section_id eda_simulation
set_global_assignment -name EDA_DESIGN_INSTANCE_NAME uut -section_id top_tb
set_global_assignment -name EDA_TEST_BENCH_MODULE_NAME top_tb -section_id top_tb
set_global_assignment -name POWER_PRESET_COOLING_SOLUTION "NO HEAT SINK WITH STILL AIR"
set_global_assignment -name EDA_TEST_BENCH_RUN_SIM_FOR "500 ns" -section_id top_tb
set_global_assignment -name EDA_TEST_BENCH_FILE top_tb.vhd -section_id top_tb
set_global_assignment -name EDA_BOARD_DESIGN_BOUNDARY_SCAN_TOOL "BSDL (Boundary Scan)"
set_global_assignment -name EDA_NETLIST_WRITER_OUTPUT_DIR /home/jboone/src/portapack/portapack_hackrf/hardware/portapack_h2/cpld -section_id eda_board_design_boundary_scan
set_global_assignment -name EDA_BOARD_BOUNDARY_SCAN_OPERATION POST_CONFIG -section_id eda_board_design_boundary_scan
set_global_assignment -name AUTO_RESTART_CONFIGURATION OFF
set_global_assignment -name ENABLE_CONFIGURATION_PINS OFF
set_global_assignment -name ENABLE_NCE_PIN OFF
set_global_assignment -name ENABLE_BOOT_SEL_PIN OFF
set_global_assignment -name USE_CONFIGURATION_DEVICE ON
set_global_assignment -name GENERATE_RBF_FILE OFF
set_global_assignment -name GENERATE_SVF_FILE ON
set_global_assignment -name RESERVE_ALL_UNUSED_PINS "AS INPUT TRI-STATED WITH BUS-HOLD"
set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to LCD_RESETX
set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to MCU_ADDR
set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to MCU_D[7]
set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to MCU_D[6]
set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to MCU_D[5]
set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to MCU_D[4]
set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to MCU_D[3]
set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to MCU_D[2]
set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to MCU_D[1]
set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to MCU_D[0]
set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to MCU_DIR
set_instance_assignment -name WEAK_PULL_UP_RESISTOR ON -to SW_D
set_instance_assignment -name WEAK_PULL_UP_RESISTOR ON -to SW_L
set_instance_assignment -name WEAK_PULL_UP_RESISTOR ON -to SW_R
set_instance_assignment -name WEAK_PULL_UP_RESISTOR ON -to SW_U
set_instance_assignment -name WEAK_PULL_UP_RESISTOR ON -to SW_ROT_B
set_instance_assignment -name WEAK_PULL_UP_RESISTOR ON -to SW_SEL
set_instance_assignment -name WEAK_PULL_UP_RESISTOR ON -to SW_ROT_A
set_instance_assignment -name CURRENT_STRENGTH_NEW "MINIMUM CURRENT" -to LCD_DB[15]
set_instance_assignment -name CURRENT_STRENGTH_NEW "MINIMUM CURRENT" -to LCD_DB[14]
set_instance_assignment -name CURRENT_STRENGTH_NEW "MINIMUM CURRENT" -to LCD_DB[13]
set_instance_assignment -name CURRENT_STRENGTH_NEW "MINIMUM CURRENT" -to LCD_DB[12]
set_instance_assignment -name CURRENT_STRENGTH_NEW "MINIMUM CURRENT" -to LCD_DB[11]
set_instance_assignment -name CURRENT_STRENGTH_NEW "MINIMUM CURRENT" -to LCD_DB[10]
set_instance_assignment -name CURRENT_STRENGTH_NEW "MINIMUM CURRENT" -to LCD_DB[9]
set_instance_assignment -name CURRENT_STRENGTH_NEW "MINIMUM CURRENT" -to LCD_DB[8]
set_instance_assignment -name CURRENT_STRENGTH_NEW "MINIMUM CURRENT" -to LCD_DB[7]
set_instance_assignment -name CURRENT_STRENGTH_NEW "MINIMUM CURRENT" -to LCD_DB[6]
set_instance_assignment -name CURRENT_STRENGTH_NEW "MINIMUM CURRENT" -to LCD_DB[5]
set_instance_assignment -name CURRENT_STRENGTH_NEW "MINIMUM CURRENT" -to LCD_DB[4]
set_instance_assignment -name CURRENT_STRENGTH_NEW "MINIMUM CURRENT" -to LCD_DB[3]
set_instance_assignment -name CURRENT_STRENGTH_NEW "MINIMUM CURRENT" -to LCD_DB[2]
set_instance_assignment -name CURRENT_STRENGTH_NEW "MINIMUM CURRENT" -to LCD_DB[1]
set_instance_assignment -name CURRENT_STRENGTH_NEW "MINIMUM CURRENT" -to LCD_DB[0]
set_instance_assignment -name CURRENT_STRENGTH_NEW "MINIMUM CURRENT" -to LCD_RDX
set_instance_assignment -name CURRENT_STRENGTH_NEW "MINIMUM CURRENT" -to LCD_RESETX
set_instance_assignment -name CURRENT_STRENGTH_NEW "MINIMUM CURRENT" -to LCD_RS
set_instance_assignment -name CURRENT_STRENGTH_NEW "MINIMUM CURRENT" -to LCD_TE
set_instance_assignment -name CURRENT_STRENGTH_NEW "MINIMUM CURRENT" -to LCD_WRX
set_instance_assignment -name CURRENT_STRENGTH_NEW "MINIMUM CURRENT" -to MCU_ADDR
set_instance_assignment -name CURRENT_STRENGTH_NEW "MINIMUM CURRENT" -to MCU_D[7]
set_instance_assignment -name CURRENT_STRENGTH_NEW "MINIMUM CURRENT" -to MCU_D[6]
set_instance_assignment -name CURRENT_STRENGTH_NEW "MINIMUM CURRENT" -to MCU_D[5]
set_instance_assignment -name CURRENT_STRENGTH_NEW "MINIMUM CURRENT" -to MCU_D[4]
set_instance_assignment -name CURRENT_STRENGTH_NEW "MINIMUM CURRENT" -to MCU_D[3]
set_instance_assignment -name CURRENT_STRENGTH_NEW "MINIMUM CURRENT" -to MCU_D[2]
set_instance_assignment -name CURRENT_STRENGTH_NEW "MINIMUM CURRENT" -to MCU_D[1]
set_instance_assignment -name CURRENT_STRENGTH_NEW "MINIMUM CURRENT" -to MCU_D[0]
set_instance_assignment -name CURRENT_STRENGTH_NEW "MINIMUM CURRENT" -to MCU_DIR
set_instance_assignment -name CURRENT_STRENGTH_NEW "MINIMUM CURRENT" -to SW_D
set_instance_assignment -name CURRENT_STRENGTH_NEW "MINIMUM CURRENT" -to SW_L
set_instance_assignment -name CURRENT_STRENGTH_NEW "MINIMUM CURRENT" -to SW_R
set_instance_assignment -name CURRENT_STRENGTH_NEW "MINIMUM CURRENT" -to SW_ROT_A
set_instance_assignment -name CURRENT_STRENGTH_NEW "MINIMUM CURRENT" -to SW_ROT_B
set_instance_assignment -name CURRENT_STRENGTH_NEW "MINIMUM CURRENT" -to SW_SEL
set_instance_assignment -name CURRENT_STRENGTH_NEW "MINIMUM CURRENT" -to SW_U
set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to TP_D
set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to TP_L
set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to TP_R
set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to TP_U
set_instance_assignment -name SLOW_SLEW_RATE ON -to LCD_DB[15]
set_instance_assignment -name SLOW_SLEW_RATE ON -to LCD_DB[14]
set_instance_assignment -name SLOW_SLEW_RATE ON -to LCD_DB[13]
set_instance_assignment -name SLOW_SLEW_RATE ON -to LCD_DB[12]
set_instance_assignment -name SLOW_SLEW_RATE ON -to LCD_DB[11]
set_instance_assignment -name SLOW_SLEW_RATE ON -to LCD_DB[10]
set_instance_assignment -name SLOW_SLEW_RATE ON -to LCD_DB[9]
set_instance_assignment -name SLOW_SLEW_RATE ON -to LCD_DB[8]
set_instance_assignment -name SLOW_SLEW_RATE ON -to LCD_DB[7]
set_instance_assignment -name SLOW_SLEW_RATE ON -to LCD_DB[6]
set_instance_assignment -name SLOW_SLEW_RATE ON -to LCD_DB[5]
set_instance_assignment -name SLOW_SLEW_RATE ON -to LCD_DB[4]
set_instance_assignment -name SLOW_SLEW_RATE ON -to LCD_DB[3]
set_instance_assignment -name SLOW_SLEW_RATE ON -to LCD_DB[2]
set_instance_assignment -name SLOW_SLEW_RATE ON -to LCD_DB[1]
set_instance_assignment -name SLOW_SLEW_RATE ON -to LCD_DB[0]
set_instance_assignment -name SLOW_SLEW_RATE ON -to LCD_RDX
set_instance_assignment -name SLOW_SLEW_RATE ON -to LCD_RESETX
set_instance_assignment -name SLOW_SLEW_RATE ON -to LCD_RS
set_instance_assignment -name SLOW_SLEW_RATE ON -to LCD_TE
set_instance_assignment -name SLOW_SLEW_RATE ON -to LCD_WRX
set_instance_assignment -name SLOW_SLEW_RATE ON -to MCU_ADDR
set_instance_assignment -name SLOW_SLEW_RATE ON -to MCU_D[7]
set_instance_assignment -name SLOW_SLEW_RATE ON -to MCU_D[6]
set_instance_assignment -name SLOW_SLEW_RATE ON -to MCU_D[5]
set_instance_assignment -name SLOW_SLEW_RATE ON -to MCU_D[4]
set_instance_assignment -name SLOW_SLEW_RATE ON -to MCU_D[3]
set_instance_assignment -name SLOW_SLEW_RATE ON -to MCU_D[2]
set_instance_assignment -name SLOW_SLEW_RATE ON -to MCU_D[1]
set_instance_assignment -name SLOW_SLEW_RATE ON -to MCU_D[0]
set_instance_assignment -name SLOW_SLEW_RATE ON -to MCU_DIR
set_instance_assignment -name SLOW_SLEW_RATE ON -to SW_D
set_instance_assignment -name SLOW_SLEW_RATE ON -to SW_L
set_instance_assignment -name SLOW_SLEW_RATE ON -to SW_R
set_instance_assignment -name SLOW_SLEW_RATE ON -to SW_ROT_A
set_instance_assignment -name SLOW_SLEW_RATE ON -to SW_ROT_B
set_instance_assignment -name SLOW_SLEW_RATE ON -to SW_SEL
set_instance_assignment -name SLOW_SLEW_RATE ON -to SW_U
set_instance_assignment -name SLOW_SLEW_RATE ON -to TP_D
set_instance_assignment -name SLOW_SLEW_RATE ON -to TP_L
set_instance_assignment -name SLOW_SLEW_RATE ON -to TP_R
set_instance_assignment -name SLOW_SLEW_RATE ON -to TP_U
set_global_assignment -name ENABLE_DEVICE_WIDE_RESET OFF
set_global_assignment -name IOBANK_VCCIO 3.3V -section_id 2
set_global_assignment -name IOBANK_VCCIO 3.3V -section_id 1
set_instance_assignment -name PCI_IO OFF -to MCU_DIR
set_global_assignment -name ALLOW_LVTTL_LVCMOS_INPUT_LEVELS_TO_OVERDRIVE_INPUT_BUFFER ON
set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to LCD_BACKLIGHT
set_instance_assignment -name CURRENT_STRENGTH_NEW "MINIMUM CURRENT" -to LCD_BACKLIGHT
set_instance_assignment -name SLOW_SLEW_RATE ON -to LCD_BACKLIGHT
set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to AUDIO_RESETX
set_instance_assignment -name CURRENT_STRENGTH_NEW "MINIMUM CURRENT" -to AUDIO_RESETX
set_instance_assignment -name SLOW_SLEW_RATE ON -to AUDIO_RESETX
set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to MCU_LCD_RDX
set_instance_assignment -name CURRENT_STRENGTH_NEW "MINIMUM CURRENT" -to MCU_LCD_RDX
set_instance_assignment -name SLOW_SLEW_RATE ON -to MCU_LCD_RDX
set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to MCU_LCD_WRX
set_instance_assignment -name CURRENT_STRENGTH_NEW "MINIMUM CURRENT" -to MCU_LCD_WRX
set_instance_assignment -name SLOW_SLEW_RATE ON -to MCU_LCD_WRX
set_instance_assignment -name PCI_IO OFF -to MCU_LCD_WRX
set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to MCU_IO_STBX
set_instance_assignment -name CURRENT_STRENGTH_NEW "MINIMUM CURRENT" -to MCU_IO_STBX
set_instance_assignment -name SLOW_SLEW_RATE ON -to MCU_IO_STBX
set_instance_assignment -name WEAK_PULL_UP_RESISTOR ON -to TP_R
set_instance_assignment -name WEAK_PULL_UP_RESISTOR ON -to TP_D
set_instance_assignment -name WEAK_PULL_UP_RESISTOR ON -to TP_L
set_instance_assignment -name WEAK_PULL_UP_RESISTOR ON -to TP_U
set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to MCU_LCD_TE
set_instance_assignment -name CURRENT_STRENGTH_NEW "MINIMUM CURRENT" -to MCU_LCD_TE
set_instance_assignment -name SLOW_SLEW_RATE ON -to MCU_LCD_TE
set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to MCU_P2_8
set_instance_assignment -name CURRENT_STRENGTH_NEW "MINIMUM CURRENT" -to MCU_P2_8
set_instance_assignment -name SLOW_SLEW_RATE ON -to MCU_P2_8
set_instance_assignment -name PCI_IO OFF -to MCU_P2_8
set_global_assignment -name NUM_PARALLEL_PROCESSORS ALL
set_instance_assignment -name WEAK_PULL_UP_RESISTOR ON -to LCD_DB[15]
set_instance_assignment -name WEAK_PULL_UP_RESISTOR ON -to LCD_DB[14]
set_instance_assignment -name WEAK_PULL_UP_RESISTOR ON -to LCD_DB[13]
set_instance_assignment -name WEAK_PULL_UP_RESISTOR ON -to LCD_DB[12]
set_instance_assignment -name WEAK_PULL_UP_RESISTOR ON -to LCD_DB[11]
set_instance_assignment -name WEAK_PULL_UP_RESISTOR ON -to LCD_DB[10]
set_instance_assignment -name WEAK_PULL_UP_RESISTOR ON -to LCD_DB[9]
set_instance_assignment -name WEAK_PULL_UP_RESISTOR ON -to LCD_DB[8]
set_instance_assignment -name WEAK_PULL_UP_RESISTOR ON -to LCD_DB[7]
set_instance_assignment -name WEAK_PULL_UP_RESISTOR ON -to LCD_DB[6]
set_instance_assignment -name WEAK_PULL_UP_RESISTOR ON -to LCD_DB[5]
set_instance_assignment -name WEAK_PULL_UP_RESISTOR ON -to LCD_DB[4]
set_instance_assignment -name WEAK_PULL_UP_RESISTOR ON -to LCD_DB[3]
set_instance_assignment -name WEAK_PULL_UP_RESISTOR ON -to LCD_DB[2]
set_instance_assignment -name WEAK_PULL_UP_RESISTOR ON -to LCD_DB[1]
set_instance_assignment -name WEAK_PULL_UP_RESISTOR ON -to LCD_DB[0]
set_instance_assignment -name WEAK_PULL_UP_RESISTOR ON -to MCU_D[7]
set_instance_assignment -name WEAK_PULL_UP_RESISTOR ON -to MCU_D[6]
set_instance_assignment -name WEAK_PULL_UP_RESISTOR ON -to MCU_D[5]
set_instance_assignment -name WEAK_PULL_UP_RESISTOR ON -to MCU_D[4]
set_instance_assignment -name WEAK_PULL_UP_RESISTOR ON -to MCU_D[3]
set_instance_assignment -name WEAK_PULL_UP_RESISTOR ON -to MCU_D[2]
set_instance_assignment -name WEAK_PULL_UP_RESISTOR ON -to MCU_D[1]
set_instance_assignment -name WEAK_PULL_UP_RESISTOR ON -to MCU_D[0]
set_instance_assignment -name WEAK_PULL_UP_RESISTOR ON -to MCU_ADDR
set_instance_assignment -name WEAK_PULL_UP_RESISTOR ON -to MCU_DIR
set_instance_assignment -name WEAK_PULL_UP_RESISTOR ON -to MCU_IO_STBX
set_instance_assignment -name WEAK_PULL_UP_RESISTOR ON -to MCU_LCD_RDX
set_instance_assignment -name WEAK_PULL_UP_RESISTOR OFF -to MCU_LCD_WRX
set_instance_assignment -name WEAK_PULL_UP_RESISTOR OFF -to MCU_P2_8
set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to GPS_TIMEPULSE
set_instance_assignment -name CURRENT_STRENGTH_NEW "MINIMUM CURRENT" -to GPS_TIMEPULSE
set_instance_assignment -name SLOW_SLEW_RATE ON -to GPS_TIMEPULSE
set_instance_assignment -name PCI_IO OFF -to GPS_TIMEPULSE
set_instance_assignment -name WEAK_PULL_UP_RESISTOR ON -to GPS_TIMEPULSE
set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to GPS_TX_READY
set_instance_assignment -name CURRENT_STRENGTH_NEW "MINIMUM CURRENT" -to GPS_TX_READY
set_instance_assignment -name SLOW_SLEW_RATE ON -to GPS_TX_READY
set_instance_assignment -name PCI_IO OFF -to GPS_TX_READY
set_instance_assignment -name WEAK_PULL_UP_RESISTOR ON -to GPS_TX_READY
set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to REF_EN
set_instance_assignment -name CURRENT_STRENGTH_NEW "MINIMUM CURRENT" -to REF_EN
set_instance_assignment -name SLOW_SLEW_RATE ON -to REF_EN
set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to GPS_RESETX
set_instance_assignment -name CURRENT_STRENGTH_NEW "MINIMUM CURRENT" -to GPS_RESETX
set_instance_assignment -name SLOW_SLEW_RATE ON -to GPS_RESETX
set_location_assignment PIN_58 -to REF_EN
set_location_assignment PIN_72 -to MCU_DIR
set_location_assignment PIN_41 -to MCU_IO_STBX
set_location_assignment PIN_40 -to MCU_LCD_TE
set_location_assignment PIN_43 -to MCU_P2_8
set_location_assignment PIN_71 -to MCU_LCD_WRX
set_location_assignment PIN_42 -to MCU_ADDR
set_location_assignment PIN_39 -to MCU_LCD_RDX
set_location_assignment PIN_35 -to MCU_D[0]
set_location_assignment PIN_33 -to MCU_D[2]
set_location_assignment PIN_28 -to MCU_D[4]
set_location_assignment PIN_27 -to MCU_D[6]
set_location_assignment PIN_8 -to TP_U
set_location_assignment PIN_7 -to TP_L
set_location_assignment PIN_6 -to TP_D
set_location_assignment PIN_5 -to TP_R
set_location_assignment PIN_26 -to MCU_D[7]
set_location_assignment PIN_29 -to MCU_D[5]
set_location_assignment PIN_30 -to MCU_D[3]
set_location_assignment PIN_36 -to MCU_D[1]
set_location_assignment PIN_73 -to GPS_RESETX
set_location_assignment PIN_75 -to GPS_TX_READY
set_location_assignment PIN_74 -to GPS_TIMEPULSE
set_location_assignment PIN_34 -to SW_U
set_location_assignment PIN_37 -to SW_L
set_location_assignment PIN_17 -to SW_SEL
set_location_assignment PIN_12 -to SW_R
set_location_assignment PIN_14 -to SW_D
set_location_assignment PIN_15 -to SW_ROT_A
set_location_assignment PIN_16 -to SW_ROT_B
set_location_assignment PIN_99 -to LCD_DB[0]
set_location_assignment PIN_98 -to LCD_DB[1]
set_location_assignment PIN_97 -to LCD_DB[2]
set_location_assignment PIN_96 -to LCD_DB[3]
set_location_assignment PIN_95 -to LCD_DB[4]
set_location_assignment PIN_92 -to LCD_DB[5]
set_location_assignment PIN_91 -to LCD_DB[6]
set_location_assignment PIN_90 -to LCD_DB[7]
set_location_assignment PIN_89 -to LCD_DB[8]
set_location_assignment PIN_88 -to LCD_DB[9]
set_location_assignment PIN_87 -to LCD_DB[10]
set_location_assignment PIN_86 -to LCD_DB[11]
set_location_assignment PIN_85 -to LCD_DB[12]
set_location_assignment PIN_84 -to LCD_DB[13]
set_location_assignment PIN_83 -to LCD_DB[14]
set_location_assignment PIN_82 -to LCD_DB[15]
set_location_assignment PIN_100 -to LCD_RESETX
set_location_assignment PIN_1 -to LCD_RDX
set_location_assignment PIN_3 -to LCD_RS
set_location_assignment PIN_2 -to LCD_WRX
set_location_assignment PIN_76 -to LCD_BACKLIGHT
set_location_assignment PIN_4 -to LCD_TE
set_global_assignment -name ENABLE_OCT_DONE OFF
set_location_assignment PIN_38 -to DEVICE_RESET_V
set_location_assignment PIN_44 -to DEVICE_RESET
set_global_assignment -name SDC_FILE portapack_h4m_cpld.sdc
set_global_assignment -name VHDL_FILE top.vhd
set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SYSOFF
set_location_assignment PIN_47 -to SYSOFF
set_instance_assignment -name WEAK_PULL_UP_RESISTOR OFF -to SYSOFF
@@ -0,0 +1,116 @@
## Generated SDC file "portapack_hackrf_one_cpld.sdc"
## Copyright (C) 1991-2014 Altera Corporation
## Your use of Altera Corporation's design tools, logic functions
## and other software and tools, and its AMPP partner logic
## functions, and any output files from any of the foregoing
## (including device programming or simulation files), and any
## associated documentation or information are expressly subject
## to the terms and conditions of the Altera Program License
## Subscription Agreement, Altera MegaCore Function License
## Agreement, or other applicable license agreement, including,
## without limitation, that your use is for the sole purpose of
## programming logic devices manufactured by Altera and sold by
## Altera or its authorized distributors. Please refer to the
## applicable agreement for further details.
## VENDOR "Altera"
## PROGRAM "Quartus II"
## VERSION "Version 13.1.4 Build 182 03/12/2014 SJ Web Edition"
## DATE "Sat May 3 10:22:18 2014"
##
## DEVICE "5M40ZE64C5"
##
# RS = 0, D = DB[15:8]
# wait max(tast = 0 ns, CPLD setup = ?)
# WR = 0, D = DB[7:0]
# wait max(CPLD )
#**************************************************************
# Time Information
#**************************************************************
set_time_format -unit ns -decimal_places 3
set mcu_clk_period 4.9
set lcd_data_wr_setup 10.0
set lcd_data_wr_hold 10.0
#**************************************************************
# Create Clock
#**************************************************************
create_clock -name {MCU_LCD_WRX} -period 66.000 -waveform { 0.000 33.000 } [get_ports {MCU_LCD_WRX}]
#create_clock -name strobe_virt -period 66.000
#**************************************************************
# Create Generated Clock
#**************************************************************
#**************************************************************
# Set Clock Latency
#**************************************************************
#**************************************************************
# Set Clock Uncertainty
#**************************************************************
#**************************************************************
# Set Input Delay
#**************************************************************
#set_input_delay -clock strobe_virt [get_ports {D[*]}]
#**************************************************************
# Set Output Delay
#**************************************************************
#**************************************************************
# Set Clock Groups
#**************************************************************
#**************************************************************
# Set False Path
#**************************************************************
#set_false_path -from [get_clocks {MCU_IO_STBX}] -to [get_ports {TP_D TP_L TP_R TP_U}]
#set_false_path -from [get_ports {SW_D SW_L SW_R SW_ROT_A SW_ROT_B SW_SEL SW_U}] -to [get_ports {MCU_D[*]}]
#**************************************************************
# Set Multicycle Path
#**************************************************************
#**************************************************************
# Set Maximum Delay
#**************************************************************
#**************************************************************
# Set Minimum Delay
#**************************************************************
#**************************************************************
# Set Input Transition
#**************************************************************
@@ -0,0 +1 @@
dft_skip_oct_vccn_check = on
@@ -0,0 +1,207 @@
--
-- Copyright (C) 2012 Jared Boone, ShareBrained Technology, Inc.
-- Copyright (C) 2024 jLynx.net https://github.com/jLynx
--
-- 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.
library ieee;
use ieee.std_logic_1164.all;
entity top is
port (
MCU_D : inout std_logic_vector(7 downto 0);
MCU_DIR : in std_logic;
MCU_IO_STBX : in std_logic;
MCU_LCD_WRX : in std_logic;
MCU_ADDR : in std_logic;
MCU_LCD_TE : out std_logic;
MCU_P2_8 : in std_logic;
MCU_LCD_RDX : in std_logic;
TP_U : out std_logic;
TP_D : out std_logic;
TP_L : out std_logic;
TP_R : out std_logic;
SW_SEL : in std_logic;
SW_ROT_A : in std_logic;
SW_ROT_B : in std_logic;
SW_U : in std_logic;
SW_D : in std_logic;
SW_L : in std_logic;
SW_R : in std_logic;
LCD_RESETX : out std_logic;
LCD_RS : out std_logic;
LCD_WRX : out std_logic;
LCD_RDX : out std_logic;
LCD_DB : inout std_logic_vector(15 downto 0);
LCD_TE : in std_logic;
LCD_BACKLIGHT : out std_logic;
SYSOFF : out std_logic;
AUDIO_RESETX : out std_logic;
REF_EN : out std_logic;
GPS_RESETX : out std_logic;
GPS_TX_READY : in std_logic;
GPS_TIMEPULSE : in std_logic;
DEVICE_RESET : in std_logic;
DEVICE_RESET_V : in std_logic
);
end top;
architecture rtl of top is
signal switches : std_logic_vector(7 downto 0);
type data_direction_t is (from_mcu, to_mcu);
signal data_dir : data_direction_t;
signal mcu_data_out_lcd : std_logic_vector(7 downto 0);
signal mcu_data_out_io : std_logic_vector(7 downto 0);
signal mcu_data_out : std_logic_vector(7 downto 0);
signal mcu_data_in : std_logic_vector(7 downto 0);
signal lcd_data_in : std_logic_vector(15 downto 0);
signal lcd_data_in_mux : std_logic_vector(7 downto 0);
signal lcd_data_out : std_logic_vector(15 downto 0);
signal lcd_data_in_q : std_logic_vector(7 downto 0) := (others => '0');
signal lcd_data_out_q : std_logic_vector(7 downto 0) := (others => '0');
signal tp_q : std_logic_vector(7 downto 0) := (others => '0');
signal lcd_reset_q : std_logic := '1';
signal lcd_backlight_q : std_logic := '0';
signal sysoff_q : std_logic := '0';
signal audio_reset_q : std_logic := '1';
signal ref_en_q : std_logic := '0';
signal device_reset_q : std_logic := '1';
signal dir_read : boolean;
signal dir_write : boolean;
signal lcd_read_strobe : boolean;
signal lcd_write_strobe : boolean;
signal lcd_write : boolean;
signal io_strobe : boolean;
signal io_read_strobe : boolean;
signal io_write_strobe : boolean;
signal reset_flag: boolean := false;
signal reset_sync: std_logic := '1';
signal counter: integer range 0 to 25000000 := 0; -- Adjust the count value for desired delay (e.g., 1 second with a 25 MHz clock)
constant COUNTER_MAX: integer := 25000000; -- Adjust this value to match the counter range
begin
-- I/O data
switches <= LCD_TE & not SW_ROT_B & not SW_ROT_A & not SW_SEL & not SW_U & not SW_D & not SW_L & not SW_R;
TP_U <= tp_q(3) when tp_q(7) = '1' else 'Z';
TP_D <= tp_q(2) when tp_q(6) = '1' else 'Z';
TP_L <= tp_q(1) when tp_q(5) = '1' else 'Z';
TP_R <= tp_q(0) when tp_q(4) = '1' else 'Z';
LCD_BACKLIGHT <= lcd_backlight_q;
SYSOFF <= sysoff_q;
MCU_LCD_TE <= LCD_TE;
-- State management
data_dir <= to_mcu when MCU_DIR = '1' else from_mcu;
dir_read <= (data_dir = to_mcu);
dir_write <= (data_dir = from_mcu);
io_strobe <= (MCU_IO_STBX = '0');
io_read_strobe <= io_strobe and dir_read;
lcd_read_strobe <= (MCU_LCD_RDX = '0');
lcd_write <= not lcd_read_strobe;
-- LCD interface
LCD_RS <= MCU_ADDR;
LCD_RDX <= MCU_LCD_RDX;
LCD_WRX <= MCU_LCD_WRX;
lcd_data_out <= lcd_data_out_q & mcu_data_in;
lcd_data_in <= LCD_DB;
LCD_DB <= lcd_data_out when lcd_write else (others => 'Z');
-- Reference clock
REF_EN <= ref_en_q;
-- Peripheral reset control
LCD_RESETX <= not lcd_reset_q;
AUDIO_RESETX <= not audio_reset_q;
GPS_RESETX <= '1';
-- MCU interface
mcu_data_out_lcd <= lcd_data_in(15 downto 8) when lcd_read_strobe else lcd_data_in_q;
mcu_data_out_io <= switches;
mcu_data_out <= mcu_data_out_io when io_read_strobe else mcu_data_out_lcd;
mcu_data_in <= MCU_D;
MCU_D <= mcu_data_out when dir_read else (others => 'Z');
-- Synchronous behaviors:
-- LCD write: Capture LCD high byte on LCD_WRX falling edge.
process(MCU_LCD_WRX, mcu_data_in)
begin
if falling_edge(MCU_LCD_WRX) then
lcd_data_out_q <= mcu_data_in;
end if;
end process;
-- LCD read: Capture LCD low byte on LCD_RD falling edge.
process(MCU_LCD_RDX, lcd_data_in)
begin
if rising_edge(MCU_LCD_RDX) then
lcd_data_in_q <= lcd_data_in(7 downto 0);
end if;
end process;
-- I/O write (to resistive touch panel): Capture data from
-- MCU and hold on TP pins until further notice.
process(MCU_IO_STBX, dir_write, mcu_data_in, MCU_ADDR)
begin
if rising_edge(MCU_IO_STBX) and dir_write then
if MCU_ADDR = '0' then
tp_q <= mcu_data_in;
else
lcd_reset_q <= mcu_data_in(0);
audio_reset_q <= mcu_data_in(1);
ref_en_q <= mcu_data_in(6);
lcd_backlight_q <= mcu_data_in(7);
sysoff_q <= mcu_data_in(2);
end if;
end if;
end process;
end rtl;
+58
View File
@@ -0,0 +1,58 @@
# Project Setup Guide
## Prerequisites
- Intel Quartus Prime
- Supra-2023.02.b0-7773ca8a-win64-all
## Installation Steps
1. **Project Setup**
- Create a new AG256SL100 project in Quartus Prime
- (Alternatively, copy an existing project)
2. **Code Implementation**
- Implement your code in the project
- Compile the project to verify there are no errors
- Ensure successful compilation before proceeding
3. **Supra Configuration**
- Launch Supra.exe
- Navigate to: File → Project → Open Project
- Select the H4M project when prompted
- Select Tools → Migrate → Next
4. **Additional Setup**
- Follow the on-screen prompts
- You will need to:
- Open a second Quartus project
- Execute a provided script
5. **Programming**
- In Supra, go to: Tools → Program
- Click "Query device ID"
- Verify the returned ID is: 0x00025610
6. **File Selection**
- Select the programming file (if not automatically loaded)
- Use the .prg file from the Supra src folder (non-SRAM version)
7. **Programming Process**
- Click "Program" to begin
- Note: The counter shows elapsed seconds, not progress percentage
- Programming is complete when "USB driver disconnected" message appears
## Troubleshooting
If you encounter any issues, ensure:
- All prerequisites are properly installed
- Project configurations are correct
- Device connections are secure
@@ -0,0 +1,62 @@
[GuiMigrateSetupPage]
fromDir=../AG256SL100
design=portapack_h4m_cpld
device=AG256SL100
veFile=
ipFiles=
backwardCompatible=false
modeGroup=false
modeQuartus=true
modeSynplicity=false
modeNative=false
[GuiMigrateRunPage]
isMC=false
count=
jobs=
seed=
retry=0
fitting=0
fitter=0
effort=0
holdx=0
skew=0
skope=0
preset=0
adjust=0
target=0
tuning=0
corner=0
flow=0
orgPlace=false
quartusSdc=false
probeForce=false
probeState=@ByteArray(\0\0\0\xff\0\0\0\0\0\0\0\x1\0\0\0\x1\0\0\0\x2\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\x2m\0\0\0\x2\0\x1\x1\x1\0\0\0\0\0\0\0\0\0\0\0\0\x64\0\0\0K\0\0\0\x4\0\0\0\0\0\0\0\x2\0\0\x1\xc2\0\0\0\x1\0\0\0\0\0\0\0\xab\0\0\0\x1\0\0\0\0)
probeCount=5
probe0From=
probe0Pad=
probe1From=
probe1Pad=
probe2From=
probe2Pad=
probe3From=
probe3Pad=
probe4From=
probe4Pad=
[GuiProgramScreen]
hardwareId=0
blasterSpeed=70
prgFile=portapack_h4m_cpld.prg
eraseBox=false
cable=0
runAction=program
eraseChip=true
eraseFrom=
eraseTo=
binFile=
readFrom=
readTo=
[MainWindow]
recentFile.0=
@@ -0,0 +1,114 @@
if {![info exist MODE ]} {set MODE QUARTUS}
if {![info exists QUARTUS_SDC]} {set QUARTUS_SDC true}
if {![info exists CORNER]} {set CORNER ""}
if {![info exist COUNT]} {set COUNT 6}
if {![info exist JOBS ]} {set JOBS 1}
if {![info exist SEEDS ]} {set SEEDS {0 0 0 0 666 888 }}
if {![info exist EFFORTS ]} {set EFFORTS {highest highest highest highest high high }}
if {![info exist FITTERS ]} {set FITTERS {hybrid hybrid hybrid hybrid hybrid hybrid }}
if {![info exist FITTINGS]} {set FITTINGS {timing_more timing_more timing_more timing timing basic }}
if {![info exist SKEWS ]} {set SKEWS {advanced advanced advanced advanced aggressive basic }}
if {![info exist HOLDXS ]} {set HOLDXS {default default default default default default}}
set bc_config "./bc_config.txt"
if { [file exists $bc_config] } {
alta::tcl_highlight "Using MC config $bc_config.\n"
source "$bc_config"
}
#######################################################################
proc get_rand_value { values } {
if {[llength $values] == 0} { return {} }
return [lindex $values [expr {int(rand()*10000)%[llength $values]}]]
}
set results "bc_results"
set summary "bc_summary.txt"
file delete -force $results; file mkdir $results
file delete $summary; print -nonewline "" >! $summary
set is_parallel [expr $JOBS > 1]
set is_color ""; set is_gui ""; set is_quiet ""
if { $is_parallel } {
set is_gui "--quiet"
} else {
if { [alta::tcl_is_color] } { set is_color "--color" }
if { [alta::tcl_is_gui ] } { set is_gui "--gui" }
}
#######################################################################
set progs {}
set titles {}
for {set id 1} {$id <= $COUNT} {incr id} {
set result_dir "$results/$id"
file mkdir $result_dir
set seed [get_rand_value $SEEDS ]
set effort [get_rand_value $EFFORTS ]
set skew [get_rand_value $SKEWS ]
set fitter [get_rand_value $FITTERS ]
set fitting [get_rand_value $FITTINGS]
set holdx [get_rand_value $HOLDXS ]
set prog [list [info nameofexec] $is_quiet $is_color $is_gui -B --batch --mode $MODE]
alta::lconcat prog [list -X "set QUARTUS_SDC $QUARTUS_SDC"]
if { $CORNER != "" } {
alta::lconcat prog [list -X "set CORNER $CORNER"]
}
alta::lconcat prog [list -X "set RESULT_DIR $result_dir"]
if { $seed != "" } {
alta::lconcat prog [list -X "set SEED $seed"]
}
if { $effort != "" } {
alta::lconcat prog [list -X "set EFFORT $effort"]
}
if { $fitter != "" } {
alta::lconcat prog [list -X "set FITTER $fitter"]
}
if { $fitting != "" } {
alta::lconcat prog [list -X "set FITTING $fitting"]
}
if { $skew != "" } {
alta::lconcat prog [list -X "set SKEW $skew"]
}
if { $holdx != "" } {
alta::lconcat prog [list -X "set HOLDX $holdx"]
}
#alta::lconcat prog [list -F af_run.tcl]
lappend progs $prog
lappend titles "#$id $result_dir"
}
#######################################################################
if { $is_parallel } {
set bg_progs {}
foreach bg_prog $progs {
lappend bg_progs [lappend bg_prog $is_quiet]
}
bg_exec_queue $titles $bg_progs $JOBS
}
#######################################################################
for {set id 1} {$id <= $COUNT} {incr id} {
set result_dir "$results/$id"
set prog [lindex $progs [expr $id-1]]
set title [lindex $titles [expr $id-1]]
if { ! $is_parallel } {
puts $title
puts $prog
eval exec -ignorestderr $prog >&@ stdout
}
print "***************************************************************************\n" >> $summary
print "$title\n" >> $summary
cat "$result_dir/alta_db/fmax.rpt" >> $summary
cat "$result_dir/alta_db/xfer.rpt" >> $summary
print "" >> $summary
}
alta::tcl_highlight "Check $summary for result.\n"
@@ -0,0 +1,50 @@
set AGM_SUPRA true
set DESIGN "portapack_h4m_cpld"
set IPLIST {alta_bram alta_bram9k alta_sram alta_wram alta_pll alta_pllx alta_pllv alta_pllve alta_boot alta_osc alta_mult alta_multm alta_ufm alta_ufms alta_ufml alta_i2c alta_spi alta_irda alta_mcu alta_mcu_m3 alta_saradc alta_adc alta_dac alta_cmp }
lappend IPLIST alta_rv32
proc set_alta_partition {inst tag} {
set full_name [get_name_info -observable_type pre_synthesis -info full_path $inst]
set inst_name [get_name_info -observable_type pre_synthesis -info short_full_path $inst]
set base_name [get_name_info -observable_type pre_synthesis -info instance_name $inst]
set section_id [string map { [ _ ] _ . _ | _} $inst_name]
eval "set_global_assignment -name PARTITION_COLOR 52377 -section_id $section_id -tag $tag"
eval "set_global_assignment -name PARTITION_NETLIST_TYPE SOURCE -section_id $section_id -tag $tag"
eval "set_global_assignment -name PARTITION_FITTER_PRESERVATION_LEVEL PLACEMENT_AND_ROUTING -section_id $section_id -tag $tag"
eval "set_instance_assignment -name PARTITION_HIERARCHY $section_id -to $full_name -section_id $section_id -tag $tag"
}
load_package flow
if { $DESIGN == "" } {
set DESIGN $::quartus(args)
}
project_open $DESIGN
set tag alta_auto
if { [llength $IPLIST] > 0 } {
# A Quartus bug saves PARTITION_HIERARCHY assignments without tag. Use section_id to remove them.
set asgn_col [get_all_global_assignments -name PARTITION_NETLIST_TYPE -tag $tag]
foreach_in_collection part $asgn_col {
set section_id [lindex $part 0]
eval "remove_all_instance_assignments -name PARTITION_HIERARCHY -section_id $section_id"
}
eval "remove_all_global_assignments -name PARTITION_COLOR -tag $tag"
eval "remove_all_global_assignments -name PARTITION_NETLIST_TYPE -tag $tag"
eval "remove_all_global_assignments -name PARTITION_FITTER_PRESERVATION_LEVEL -tag $tag"
catch { execute_module -tool map }
foreach ip $IPLIST {
foreach_in_collection inst [get_names -node_type hierarchy -observable_type pre_synthesis -filter "$ip:*"] {
set_alta_partition $inst $tag
}
foreach_in_collection inst [get_names -node_type hierarchy -observable_type pre_synthesis -filter "*|$ip:*"] {
set_alta_partition $inst $tag
}
}
}
eval "set_global_assignment -name EDA_MAINTAIN_DESIGN_HIERARCHY PARTITION_ONLY -section_id eda_simulation"
project_close
exit
@@ -0,0 +1,79 @@
map -import
if { [info exists DESIGN] && ! [info exists TOP_MODULE] } {
set TOP_MODULE "$DESIGN"
}
if { ! [info exists DESIGN] } {
set DESIGN "portapack_h4m_cpld"
}
if { ! [info exists TOP_MODULE] } {
set TOP_MODULE "top"
}
set verilogs { }
if { [ llength $verilogs ] == 0 } {
set verilogs "A:/Users/jLynx/Documents/Code/C/portapack-mayhem/hardware/portapack_h4m/CPLD/AG256SL100/${DESIGN}.v"
}
foreach verilog $verilogs {
read_verilog "$verilog"
}
read_verilog -sv -lib +/agm/rodina/cells_sim.v
read_verilog -sv -lib +/agm/common/m9k_bb.v
read_verilog -sv -lib +/agm/common/altpll_bb.v
hierarchy -check -top ${TOP_MODULE}
synth -run coarse -top ${DESIGN}
map proc
opt_expr
opt_clean
check
opt
wreduce
alumacc
share
opt
fsm
opt -fast
memory -nomap
opt_clean
memory_bram -rules +/agm/common/brams.txt
techmap -map +/agm/common/brams_map.v
opt -fast -mux_undef -undriven -fine -full
memory_map
opt -undriven -fine
techmap -autoproc -map +/techmap.v -map +/agm/rodina/arith_map.v
dffsr2dff
dff2dffe -direct-match \$_DFF_*
opt -full
techmap -map +/agm/rodina/cells_map.v
agm_dffeas
opt -full
clean -purge
setundef -undriven -zero
abc -markgroups -dff
opt_expr -mux_undef -undriven -full
opt_merge
opt_rmdff
opt_clean
abc -lut 4
clean
techmap -map +/agm/rodina/cells_map.v
dffinit -ff dffeas Q INIT
clean -purge
hierarchy -check
check -noinit
write_verilog -bitblasted -attr2comment -defparam -decimal -renameprefix syn_ ${DESIGN}.vqm
# exec sed -i "/\\\\\\\$paramod/s/\[$=\\]/_/g" ${DESIGN}.vqm
@@ -0,0 +1,50 @@
set AGM_SUPRA true
set RETRY 0
set DESIGN "portapack_h4m_cpld"
if { [is_project_open] } {
export_assignments
}
set is_compatible false
if { $is_compatible } {
cd A:/Users/jLynx/Documents/Code/C/portapack-mayhem/hardware/portapack_h4m/CPLD/AG256SL100
qexec "[file join $::quartus(binpath) quartus_eda] $DESIGN --simulation --tool=modelsim --format=verilog"
} else {
set FITTER_EFFORTS {"STANDARD FIT" "STANDARD FIT" "FAST FIT" "FAST FIT" "FAST FIT"}
set SEEDS [list [expr int(rand()*100)] \
[expr int(rand()*100)] \
[expr int(rand()*100)] \
[expr int(rand()*100)] \
[expr int(rand()*100)]]
set PLACEMENT_EFFORTS [list [expr rand()*5+0.1] \
[expr rand()*5+0.1] \
[expr rand()*5+0.1] \
[expr rand()*5+0.1] \
[expr rand()*5+0.1]]
set ROUTER_EFFORTS [list [expr rand()*5+0.25] \
[expr rand()*5+0.25] \
[expr rand()*5+0.25] \
[expr rand()*5+0.25] \
[expr rand()*5+0.25]]
qexec "[file join $::quartus(binpath) quartus_sh] -t af_ip.tcl"
load_package flow
project_open $DESIGN
set RETRY [expr $RETRY<[llength $FITTER_EFFORTS]?$RETRY:[llength $FITTER_EFFORTS]]
for {set nn -1} {$nn < $RETRY} {incr nn} {
if {$nn >= 0} {
set_global_assignment -name FITTER_EFFORT \"[lindex $FITTER_EFFORTS $nn]\"
set_global_assignment -name SEED [lindex $SEEDS $nn]
set_global_assignment -name PLACEMENT_EFFORT_MULTIPLIER [lindex $PLACEMENT_EFFORTS $nn]
set_global_assignment -name ROUTER_EFFORT_MULTIPLIER [lindex $ROUTER_EFFORTS $nn]
}
set code [catch {execute_flow -compile} msg]
if { $code == 0 } { break }
}
}
@@ -0,0 +1,340 @@
set ALTA_SUPRA true
set sh_continue_on_error false
set sh_echo_on_source true
set sh_quiet_on_source true
set cc_critical_as_fatal true
set rt_incremental_route true
set ta_report_auto 1
set ta_report_auto_constraints $ta_report_auto
if { ! [info exists RESULT_DIR] } {
set RESULT_DIR "."
} elseif { ! [info exists alta_work] } {
set alta_work "${RESULT_DIR}/alta_db"
}
if { ! [info exists DEVICE] } {
set DEVICE "AG256SL100"
}
if { [info exists DESIGN] && ! [info exists TOP_MODULE] } {
set TOP_MODULE "$DESIGN"
}
if { ! [info exists DESIGN] } {
set DESIGN "portapack_h4m_cpld"
}
if { ! [info exists TOP_MODULE] } {
set TOP_MODULE "top"
}
if { ! [info exists IP_FILES] } {
set IP_FILES {}
}
if { ! [info exists VE_FILE] } {
set VE_FILE ""
}
if { ! [info exists TIMING_DERATE] } {
set TIMING_DERATE {1.000000 1.000000}
}
if { [info exists NO_ROUTE] && $NO_ROUTE } {
set no_route "-no_route"
} else {
set no_route ""
}
if { ! [info exists RETRY] } { set RETRY 0 }
if { ! [info exists SEED ] } { set SEED 666 }
set seed_rand ""
if { $SEED == 0 } { set seed_rand "-seed_rand" }
if { [info exists QUARTUS_SDC] } {
set sdc_remove_quartus_column_name $QUARTUS_SDC
}
if { ! [info exists ORG_PLACE] } { set ORG_PLACE false }
if { ! [info exists MODE] } { set MODE "QUARTUS" }
if { ! [info exists FLOW] } { set FLOW "ALL" }
if { $FLOW == "PROBE" } {
if { ! [info exists PROBE_FORCE] } { set PROBE_FORCE false }
if { ! [info exists PREFIX] } { set PREFIX "probe_" }
}
if { ! [info exists PREFIX] } {
set RESULT $DESIGN
} else {
set RESULT $PREFIX$DESIGN
}
if { $FLOW == "GEN" || $FLOW == "PACK" || $FLOW == "LOAD" } { set no_route "-no_route" }
set RUN "run"
if { $FLOW == "CHECK" } {
set RUN "check"
} elseif { $FLOW == "PROBE" } {
set RUN "probe"
} elseif { $FLOW == "GEN" } {
set RUN "gen"
}
if { ! [info exists alta_logs] } {
set alta_logs "${RESULT_DIR}/alta_logs"
}
file mkdir $alta_logs
alta::begin_log_cmd "$alta_logs/${RUN}.log" "$alta_logs/${RUN}.err"
alta::tcl_whisper "Cmd : [alta::prog_path] [alta::prog_version]([alta::prog_subversion])\n"
alta::tcl_whisper "Args : [string map {\{ \" \} \"} $tcl_cmd_args]\n"
set_seed_rand $SEED
set ar_timing_derate ${TIMING_DERATE}
date_time
if { [file exists "./${DESIGN}.pre.asf"] } {
alta::tcl_highlight "Using pre-ASF file ${DESIGN}.pre.asf.\n"
source "./${DESIGN}.pre.asf"
}
set LOAD_DB false
set LOAD_PLACE false
set LOAD_ROUTE false
if { $FLOW == "LOAD" || $FLOW == "CHECK" || $FLOW == "PROBE" } {
set LOAD_DB true
set LOAD_PLACE true
set LOAD_ROUTE true
} elseif { $FLOW == "R" || $FLOW == "ROUTE" } {
set LOAD_DB true
set LOAD_PLACE true
}
set ORIGINAL_QSF "A:/Users/jLynx/Documents/Code/C/portapack-mayhem/hardware/portapack_h4m/CPLD/AG256SL100/./portapack_h4m_cpld.qsf"
set ORIGINAL_PIN "A:/Users/jLynx/Documents/Code/C/portapack-mayhem/hardware/portapack_h4m/CPLD/AG256SL100/output_files/portapack_h4m_cpld.pin"
#################################################################################
while (1) {
if { [info exists CORNER] } { set_mode -corner $CORNER; }
eval "load_architect ${no_route} -type ${DEVICE} 1 1 1000 1000"
foreach ip_file $IP_FILES { read_ip $ip_file; }
if { $FLOW == "GEN" } {
if { ! [info exists CONFIG_BITS] } {
set CONFIG_BITS "${RESULT_DIR}/${DESIGN}.bin"
}
if { [llength $CONFIG_BITS] > 1 } {
if { ! [info exists BOOT_BINARY] } {
set BOOT_BINARY "${RESULT_DIR}/${DESIGN}_boot.bin"
}
if { ! [info exists CONFIG_ADDRESSES] } {
set CONFIG_ADDRESSES ""
}
generate_binary -master $BOOT_BINARY -inputs $CONFIG_BITS -address $CONFIG_ADDRESSES
} else {
set CONFIG_ROOT [file rootname [lindex $CONFIG_BITS 0]]
set SLAVE_RBF "${CONFIG_ROOT}_slave.rbf"
set MASTER_BINARY "${CONFIG_ROOT}_master.bin"
if { [file exists [lindex $CONFIG_BITS 0]] } {
generate_binary -slave $SLAVE_RBF -inputs [lindex $CONFIG_BITS 0] -reverse
generate_binary -master $MASTER_BINARY -inputs [lindex $CONFIG_BITS 0]
}
if { ! [info exists BOOT_BINARY] } {
set BOOT_BINARY $MASTER_BINARY
}
}
set PRG_FILE [file rootname $BOOT_BINARY].prg
set AS_FILE [file rootname $BOOT_BINARY]_as.prg
generate_programming_file $BOOT_BINARY -erase $ERASE \
-program $PROGRAM -verify $VERIFY -offset $OFFSET \
-prg $PRG_FILE -as $AS_FILE
break
}
if { $LOAD_DB } {
load_db -top ${TOP_MODULE}
set sdc "./${DESIGN}.adc"
if { ! [file exists $sdc] } { set sdc "./${DESIGN}.sdc"; }
if { [file exists $sdc] } { read_sdc $sdc; }
} elseif { $MODE == "QUARTUS" } {
set verilog ${DESIGN}.vo
set is_migrated false
if { ! [file exists $verilog] } {
set verilog "./simulation/modelsim/${DESIGN}.vo"
set is_migrated true
}
if { ! [file exists $verilog] } {
error "Can not find design verilog file $verilog"
}
alta::tcl_highlight "Using design verilog file $verilog.\n"
set ret [read_design -top ${TOP_MODULE} -ve $VE_FILE -qsf $ORIGINAL_QSF $verilog -hierachy 1]
if { !$ret } { exit -1; }
set sdc "./${DESIGN}.adc"
if { ! [file exists $sdc] } { set sdc "./${DESIGN}.sdc"; }
if { ! [file exists $sdc] } {
alta::tcl_warn "Can not find design SDC file $sdc"
} else {
alta::tcl_highlight "Using design SDC file $sdc.\n"
read_sdc $sdc
}
} elseif { $MODE == "SYNPLICITY" || $MODE == "NATIVE" } {
set db_gclk_assignment_level 2
set verilog ${DESIGN}.vqm
set is_migrated false
if { ! [file exists $verilog] } {
error "Can not find design verilog file $verilog"
}
set sdc "./${DESIGN}.adc"
if { ! [file exists $sdc] } { set sdc "./${DESIGN}.sdc"; }
alta::tcl_highlight "Using design verilog file $verilog.\n"
if { ! [file exists $sdc] } {
alta::tcl_warn "Can not find design SDC file $sdc"
set ret [read_design_and_pack -sdc $sdc -top ${TOP_MODULE} $verilog]
} else {
alta::tcl_highlight "Using design SDC file $sdc.\n"
set ret [read_design_and_pack -top ${TOP_MODULE} $verilog]
}
if { !$ret } { exit -1; }
} else {
error "Unsupported mode $MODE"
}
if { $FLOW == "PACK" } { break }
if { [info exists FITTING] } {
if { $FITTING == "Auto" } { set FITTING auto; }
set_mode -fitting $FITTING
}
if { [info exists FITTER] } {
if { $FITTER == "Auto" } {
if { $MODE == "QUARTUS" } { set FITTER hybrid; } else { set FITTER full; }
}
if { $MODE == "SYNPLICITY" || $MODE == "NATIVE" } { set FITTER full; }
set_mode -fitter $FITTER
}
if { [info exists EFFORT] } { set_mode -effort $EFFORT; }
if { [info exists SKEW ] } { set_mode -skew $SKEW ; }
if { [info exists SKOPE ] } { set_mode -skope $SKOPE ; }
if { [info exists HOLDX ] } { set_mode -holdx $HOLDX; }
if { [info exists TUNING] } { set_mode -tuning $TUNING; }
if { [info exists TARGET] } { set_mode -target $TARGET; }
if { [info exists PRESET] } { set_mode -preset $PRESET; }
if { [info exists ADJUST] } { set pl_criticality_wadjust $ADJUST; }
set alta_aqf $::alta_work/alta.aqf
if { $LOAD_DB } {
# Empty
} elseif { true } {
if { [file exists $VE_FILE] } {
set ORIGINAL_PIN ""
} elseif { ! [file exists $ORIGINAL_PIN] } {
if { $is_migrated } {
error "Can not find design PIN file $ORIGINAL_PIN, please compile design first"
}
set ORIGINAL_PIN ""
}
if { [file exists $ORIGINAL_QSF] } {
alta::convert_quartus_settings_cmd $ORIGINAL_QSF $ORIGINAL_PIN $alta_aqf
} elseif { $is_migrated } {
error "Can not find design exported QSF file $ORIGINAL_QSF, please export assigments first"
}
}
if { [file exists "$alta_aqf"] } {
alta::tcl_highlight "Using AQF file $alta_aqf.\n"
source "$alta_aqf"
}
if { [file exists "./${DESIGN}.asf"] } {
alta::tcl_highlight "Using ASF file ${DESIGN}.asf.\n"
source "./${DESIGN}.asf"
}
if { $FLOW == "PROBE" } {
set ret [place_pseudo -user_io -place_io -place_pll -place_gclk]
if { !$ret } { exit -1 }
set force ""
if { [info exists PROBE_FORCE] && $PROBE_FORCE } { set force "-force" }
eval "probe_design -froms {${PROBE_FROMS}} -tos {${PROBE_TOS}} ${force}"
} elseif { $FLOW == "CHECK" } {
set ret [place_pseudo -user_io -place_io -place_pll -place_gclk]
if { !$ret } { exit -1 }
if { [file exists "./${DESIGN}.chk"] } {
alta::tcl_highlight "Using CHK file ${DESIGN}.chk.\n"
source "./${DESIGN}.chk"
place_design -dry
check_design -rule led_guide
} else {
error "Can not find design CHECK file ${DESIGN}.chk"
}
} else {
set ret [place_pseudo -user_io -place_io -place_pll -place_gclk -warn_io]
if { !$ret } { exit -1 }
set org_place ""
set load_place ""
set load_route ""
set quiet ""
if { $ORG_PLACE } { set org_place "-org_place" ; }
if { $LOAD_PLACE } { set load_place "-load_place"; }
if { $LOAD_ROUTE } { set load_route "-load_route"; }
eval "place_and_route_design $org_place $load_place $load_route \
-retry $RETRY $seed_rand $quiet"
}
date_time
if { $FLOW != "CHECK" } {
if { $FLOW != "PROBE" } {
#report_timing -verbose 1 -file $::alta_work/timing.rpt.gz
report_timing -verbose 2 -setup -file $::alta_work/setup.rpt.gz
report_timing -verbose 2 -setup -brief -file $::alta_work/setup_summary.rpt.gz
report_timing -verbose 2 -hold -file $::alta_work/hold.rpt.gz
report_timing -verbose 2 -hold -brief -file $::alta_work/hold_summary.rpt.gz
set ta_report_auto_constraints 0
report_timing -fmax -file $::alta_work/fmax.rpt
report_timing -xfer -file $::alta_work/xfer.rpt
set ta_report_auto_constraints $ta_report_auto
#set ta_coverage_limit "0.95 0.90"
set ta_dump_uncovered 1
report_timing -verbose 1 -coverage >! $::alta_work/coverage.rpt.gz
#unset ta_coverage_limit
unset ta_dump_uncovered
if { ! [info exists rt_report_timing_fast] } {
set rt_report_timing_fast false
}
if { $rt_report_timing_fast } {
set_timing_corner fast
route_delay -quiet
report_timing -verbose 2 -setup -file $::alta_work/setup_fast.rpt.gz
report_timing -verbose 2 -setup -brief -file $::alta_work/setup_fast_summary.rpt.gz
report_timing -verbose 2 -hold -file $::alta_work/hold_fast.rpt.gz
report_timing -verbose 2 -hold -brief -file $::alta_work/hold_fast_summary.rpt.gz
set ta_report_auto_constraints 0
report_timing -fmax -file $::alta_work/fmax_fast.rpt
report_timing -xfer -file $::alta_work/xfer_fast.rpt
set ta_report_auto_constraints $ta_report_auto
}
write_routed_design "${RESULT_DIR}/${RESULT}_routed.v"
}
bitgen normal -prg "${RESULT_DIR}/${RESULT}.prg" -bin "${RESULT_DIR}/${RESULT}.bin"
bitgen sram -prg "${RESULT_DIR}/${RESULT}_sram.prg"
bitgen download -bin "${RESULT_DIR}/${RESULT}.bin" -svf "${RESULT_DIR}/${RESULT}_download.svf"
generate_binary -slave "${RESULT_DIR}/${RESULT}_slave.rbf" \
-inputs "${RESULT_DIR}/${RESULT}.bin" -reverse
generate_binary -master "${RESULT_DIR}/${RESULT}_master.bin" \
-inputs "${RESULT_DIR}/${RESULT}.bin"
generate_programming_file "${RESULT_DIR}/${RESULT}_master.bin" -prg "${RESULT_DIR}/${RESULT}_master.prg" \
-as "${RESULT_DIR}/${RESULT}_master_as.prg" -hybrid "${RESULT_DIR}/${RESULT}_hybrid.prg"
}
break
}
if { [file exists "./${DESIGN}.post.asf"] } {
alta::tcl_highlight "Using post-ASF file ${DESIGN}.post.asf.\n"
source "./${DESIGN}.post.asf"
}
date_time
exit
@@ -0,0 +1,266 @@
set_global_assignment -name DEVICE_IO_STANDARD "3.3-V LVCMOS"
set_global_assignment -name RESERVE_ALL_UNUSED_PINS "AS INPUT TRI-STATED WITH BUS-HOLD"
set_global_assignment -name ENABLE_DEVICE_WIDE_RESET "OFF"
set_instance_assignment -name WEAK_PULL_UP_RESISTOR "ON" -to SW_D
set_instance_assignment -name WEAK_PULL_UP_RESISTOR "ON" -to SW_L
set_instance_assignment -name WEAK_PULL_UP_RESISTOR "ON" -to SW_R
set_instance_assignment -name WEAK_PULL_UP_RESISTOR "ON" -to SW_U
set_instance_assignment -name WEAK_PULL_UP_RESISTOR "ON" -to SW_ROT_B
set_instance_assignment -name WEAK_PULL_UP_RESISTOR "ON" -to SW_SEL
set_instance_assignment -name WEAK_PULL_UP_RESISTOR "ON" -to SW_ROT_A
set_instance_assignment -name SLOW_SLEW_RATE "ON" -to LCD_DB[15]
set_instance_assignment -name SLOW_SLEW_RATE "ON" -to LCD_DB[14]
set_instance_assignment -name SLOW_SLEW_RATE "ON" -to LCD_DB[13]
set_instance_assignment -name SLOW_SLEW_RATE "ON" -to LCD_DB[12]
set_instance_assignment -name SLOW_SLEW_RATE "ON" -to LCD_DB[11]
set_instance_assignment -name SLOW_SLEW_RATE "ON" -to LCD_DB[10]
set_instance_assignment -name SLOW_SLEW_RATE "ON" -to LCD_DB[9]
set_instance_assignment -name SLOW_SLEW_RATE "ON" -to LCD_DB[8]
set_instance_assignment -name SLOW_SLEW_RATE "ON" -to LCD_DB[7]
set_instance_assignment -name SLOW_SLEW_RATE "ON" -to LCD_DB[6]
set_instance_assignment -name SLOW_SLEW_RATE "ON" -to LCD_DB[5]
set_instance_assignment -name SLOW_SLEW_RATE "ON" -to LCD_DB[4]
set_instance_assignment -name SLOW_SLEW_RATE "ON" -to LCD_DB[3]
set_instance_assignment -name SLOW_SLEW_RATE "ON" -to LCD_DB[2]
set_instance_assignment -name SLOW_SLEW_RATE "ON" -to LCD_DB[1]
set_instance_assignment -name SLOW_SLEW_RATE "ON" -to LCD_DB[0]
set_instance_assignment -name SLOW_SLEW_RATE "ON" -to LCD_RDX
set_instance_assignment -name SLOW_SLEW_RATE "ON" -to LCD_RESETX
set_instance_assignment -name SLOW_SLEW_RATE "ON" -to LCD_RS
set_instance_assignment -name SLOW_SLEW_RATE "ON" -to LCD_TE
set_instance_assignment -name SLOW_SLEW_RATE "ON" -to LCD_WRX
set_instance_assignment -name SLOW_SLEW_RATE "ON" -to MCU_ADDR
set_instance_assignment -name SLOW_SLEW_RATE "ON" -to MCU_D[7]
set_instance_assignment -name SLOW_SLEW_RATE "ON" -to MCU_D[6]
set_instance_assignment -name SLOW_SLEW_RATE "ON" -to MCU_D[5]
set_instance_assignment -name SLOW_SLEW_RATE "ON" -to MCU_D[4]
set_instance_assignment -name SLOW_SLEW_RATE "ON" -to MCU_D[3]
set_instance_assignment -name SLOW_SLEW_RATE "ON" -to MCU_D[2]
set_instance_assignment -name SLOW_SLEW_RATE "ON" -to MCU_D[1]
set_instance_assignment -name SLOW_SLEW_RATE "ON" -to MCU_D[0]
set_instance_assignment -name SLOW_SLEW_RATE "ON" -to MCU_DIR
set_instance_assignment -name SLOW_SLEW_RATE "ON" -to SW_D
set_instance_assignment -name SLOW_SLEW_RATE "ON" -to SW_L
set_instance_assignment -name SLOW_SLEW_RATE "ON" -to SW_R
set_instance_assignment -name SLOW_SLEW_RATE "ON" -to SW_ROT_A
set_instance_assignment -name SLOW_SLEW_RATE "ON" -to SW_ROT_B
set_instance_assignment -name SLOW_SLEW_RATE "ON" -to SW_SEL
set_instance_assignment -name SLOW_SLEW_RATE "ON" -to SW_U
set_instance_assignment -name SLOW_SLEW_RATE "ON" -to TP_D
set_instance_assignment -name SLOW_SLEW_RATE "ON" -to TP_L
set_instance_assignment -name SLOW_SLEW_RATE "ON" -to TP_R
set_instance_assignment -name SLOW_SLEW_RATE "ON" -to TP_U
set_instance_assignment -name SLOW_SLEW_RATE "ON" -to LCD_BACKLIGHT
set_instance_assignment -name SLOW_SLEW_RATE "ON" -to AUDIO_RESETX
set_instance_assignment -name SLOW_SLEW_RATE "ON" -to MCU_LCD_RDX
set_instance_assignment -name SLOW_SLEW_RATE "ON" -to MCU_LCD_WRX
set_instance_assignment -name SLOW_SLEW_RATE "ON" -to MCU_IO_STBX
set_instance_assignment -name WEAK_PULL_UP_RESISTOR "ON" -to TP_R
set_instance_assignment -name WEAK_PULL_UP_RESISTOR "ON" -to TP_D
set_instance_assignment -name WEAK_PULL_UP_RESISTOR "ON" -to TP_L
set_instance_assignment -name WEAK_PULL_UP_RESISTOR "ON" -to TP_U
set_instance_assignment -name SLOW_SLEW_RATE "ON" -to MCU_LCD_TE
set_instance_assignment -name SLOW_SLEW_RATE "ON" -to MCU_P2_8
set_instance_assignment -name WEAK_PULL_UP_RESISTOR "ON" -to LCD_DB[15]
set_instance_assignment -name WEAK_PULL_UP_RESISTOR "ON" -to LCD_DB[14]
set_instance_assignment -name WEAK_PULL_UP_RESISTOR "ON" -to LCD_DB[13]
set_instance_assignment -name WEAK_PULL_UP_RESISTOR "ON" -to LCD_DB[12]
set_instance_assignment -name WEAK_PULL_UP_RESISTOR "ON" -to LCD_DB[11]
set_instance_assignment -name WEAK_PULL_UP_RESISTOR "ON" -to LCD_DB[10]
set_instance_assignment -name WEAK_PULL_UP_RESISTOR "ON" -to LCD_DB[9]
set_instance_assignment -name WEAK_PULL_UP_RESISTOR "ON" -to LCD_DB[8]
set_instance_assignment -name WEAK_PULL_UP_RESISTOR "ON" -to LCD_DB[7]
set_instance_assignment -name WEAK_PULL_UP_RESISTOR "ON" -to LCD_DB[6]
set_instance_assignment -name WEAK_PULL_UP_RESISTOR "ON" -to LCD_DB[5]
set_instance_assignment -name WEAK_PULL_UP_RESISTOR "ON" -to LCD_DB[4]
set_instance_assignment -name WEAK_PULL_UP_RESISTOR "ON" -to LCD_DB[3]
set_instance_assignment -name WEAK_PULL_UP_RESISTOR "ON" -to LCD_DB[2]
set_instance_assignment -name WEAK_PULL_UP_RESISTOR "ON" -to LCD_DB[1]
set_instance_assignment -name WEAK_PULL_UP_RESISTOR "ON" -to LCD_DB[0]
set_instance_assignment -name WEAK_PULL_UP_RESISTOR "ON" -to MCU_D[7]
set_instance_assignment -name WEAK_PULL_UP_RESISTOR "ON" -to MCU_D[6]
set_instance_assignment -name WEAK_PULL_UP_RESISTOR "ON" -to MCU_D[5]
set_instance_assignment -name WEAK_PULL_UP_RESISTOR "ON" -to MCU_D[4]
set_instance_assignment -name WEAK_PULL_UP_RESISTOR "ON" -to MCU_D[3]
set_instance_assignment -name WEAK_PULL_UP_RESISTOR "ON" -to MCU_D[2]
set_instance_assignment -name WEAK_PULL_UP_RESISTOR "ON" -to MCU_D[1]
set_instance_assignment -name WEAK_PULL_UP_RESISTOR "ON" -to MCU_D[0]
set_instance_assignment -name WEAK_PULL_UP_RESISTOR "ON" -to MCU_ADDR
set_instance_assignment -name WEAK_PULL_UP_RESISTOR "ON" -to MCU_DIR
set_instance_assignment -name WEAK_PULL_UP_RESISTOR "ON" -to MCU_IO_STBX
set_instance_assignment -name WEAK_PULL_UP_RESISTOR "ON" -to MCU_LCD_RDX
set_instance_assignment -name WEAK_PULL_UP_RESISTOR "OFF" -to MCU_LCD_WRX
set_instance_assignment -name WEAK_PULL_UP_RESISTOR "OFF" -to MCU_P2_8
set_instance_assignment -name SLOW_SLEW_RATE "ON" -to GPS_TIMEPULSE
set_instance_assignment -name WEAK_PULL_UP_RESISTOR "ON" -to GPS_TIMEPULSE
set_instance_assignment -name SLOW_SLEW_RATE "ON" -to GPS_TX_READY
set_instance_assignment -name WEAK_PULL_UP_RESISTOR "ON" -to GPS_TX_READY
set_instance_assignment -name SLOW_SLEW_RATE "ON" -to REF_EN
set_instance_assignment -name SLOW_SLEW_RATE "ON" -to GPS_RESETX
set_instance_assignment -name WEAK_PULL_UP_RESISTOR "OFF" -to SYSOFF
set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to AUDIO_RESETX
set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to DEVICE_RESET
set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to DEVICE_RESET_V
set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to GPS_RESETX
set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to GPS_TIMEPULSE
set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to GPS_TX_READY
set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to LCD_BACKLIGHT
set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to LCD_DB[0]
set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to LCD_DB[10]
set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to LCD_DB[11]
set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to LCD_DB[12]
set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to LCD_DB[13]
set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to LCD_DB[14]
set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to LCD_DB[15]
set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to LCD_DB[1]
set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to LCD_DB[2]
set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to LCD_DB[3]
set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to LCD_DB[4]
set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to LCD_DB[5]
set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to LCD_DB[6]
set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to LCD_DB[7]
set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to LCD_DB[8]
set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to LCD_DB[9]
set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to LCD_RDX
set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to LCD_RESETX
set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to LCD_RS
set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to LCD_TE
set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to LCD_WRX
set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to MCU_ADDR
set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to MCU_DIR
set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to MCU_D[0]
set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to MCU_D[1]
set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to MCU_D[2]
set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to MCU_D[3]
set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to MCU_D[4]
set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to MCU_D[5]
set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to MCU_D[6]
set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to MCU_D[7]
set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to MCU_IO_STBX
set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to MCU_LCD_RDX
set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to MCU_LCD_TE
set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to MCU_LCD_WRX
set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to MCU_P2_8
set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to REF_EN
set_instance_assignment -name IO_STANDARD "3.3V Schmitt Trigger Input" -to SW_D
set_instance_assignment -name IO_STANDARD "3.3V Schmitt Trigger Input" -to SW_L
set_instance_assignment -name IO_STANDARD "3.3V Schmitt Trigger Input" -to SW_R
set_instance_assignment -name IO_STANDARD "3.3V Schmitt Trigger Input" -to SW_ROT_A
set_instance_assignment -name IO_STANDARD "3.3V Schmitt Trigger Input" -to SW_ROT_B
set_instance_assignment -name IO_STANDARD "3.3V Schmitt Trigger Input" -to SW_SEL
set_instance_assignment -name IO_STANDARD "3.3V Schmitt Trigger Input" -to SW_U
set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to SYSOFF
set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to TP_D
set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to TP_L
set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to TP_R
set_instance_assignment -name IO_STANDARD "3.3-V LVCMOS" -to TP_U
set_instance_assignment -name CURRENT_STRENGTH_NEW "MINIMUM CURRENT" -to AUDIO_RESETX
set_instance_assignment -name CURRENT_STRENGTH_NEW "MINIMUM CURRENT" -to GPS_RESETX
set_instance_assignment -name CURRENT_STRENGTH_NEW "MINIMUM CURRENT" -to GPS_TIMEPULSE
set_instance_assignment -name CURRENT_STRENGTH_NEW "MINIMUM CURRENT" -to GPS_TX_READY
set_instance_assignment -name CURRENT_STRENGTH_NEW "MINIMUM CURRENT" -to LCD_BACKLIGHT
set_instance_assignment -name CURRENT_STRENGTH_NEW "MINIMUM CURRENT" -to LCD_DB[0]
set_instance_assignment -name CURRENT_STRENGTH_NEW "MINIMUM CURRENT" -to LCD_DB[10]
set_instance_assignment -name CURRENT_STRENGTH_NEW "MINIMUM CURRENT" -to LCD_DB[11]
set_instance_assignment -name CURRENT_STRENGTH_NEW "MINIMUM CURRENT" -to LCD_DB[12]
set_instance_assignment -name CURRENT_STRENGTH_NEW "MINIMUM CURRENT" -to LCD_DB[13]
set_instance_assignment -name CURRENT_STRENGTH_NEW "MINIMUM CURRENT" -to LCD_DB[14]
set_instance_assignment -name CURRENT_STRENGTH_NEW "MINIMUM CURRENT" -to LCD_DB[15]
set_instance_assignment -name CURRENT_STRENGTH_NEW "MINIMUM CURRENT" -to LCD_DB[1]
set_instance_assignment -name CURRENT_STRENGTH_NEW "MINIMUM CURRENT" -to LCD_DB[2]
set_instance_assignment -name CURRENT_STRENGTH_NEW "MINIMUM CURRENT" -to LCD_DB[3]
set_instance_assignment -name CURRENT_STRENGTH_NEW "MINIMUM CURRENT" -to LCD_DB[4]
set_instance_assignment -name CURRENT_STRENGTH_NEW "MINIMUM CURRENT" -to LCD_DB[5]
set_instance_assignment -name CURRENT_STRENGTH_NEW "MINIMUM CURRENT" -to LCD_DB[6]
set_instance_assignment -name CURRENT_STRENGTH_NEW "MINIMUM CURRENT" -to LCD_DB[7]
set_instance_assignment -name CURRENT_STRENGTH_NEW "MINIMUM CURRENT" -to LCD_DB[8]
set_instance_assignment -name CURRENT_STRENGTH_NEW "MINIMUM CURRENT" -to LCD_DB[9]
set_instance_assignment -name CURRENT_STRENGTH_NEW "MINIMUM CURRENT" -to LCD_RDX
set_instance_assignment -name CURRENT_STRENGTH_NEW "MINIMUM CURRENT" -to LCD_RESETX
set_instance_assignment -name CURRENT_STRENGTH_NEW "MINIMUM CURRENT" -to LCD_RS
set_instance_assignment -name CURRENT_STRENGTH_NEW "MINIMUM CURRENT" -to LCD_TE
set_instance_assignment -name CURRENT_STRENGTH_NEW "MINIMUM CURRENT" -to LCD_WRX
set_instance_assignment -name CURRENT_STRENGTH_NEW "MINIMUM CURRENT" -to MCU_ADDR
set_instance_assignment -name CURRENT_STRENGTH_NEW "MINIMUM CURRENT" -to MCU_DIR
set_instance_assignment -name CURRENT_STRENGTH_NEW "MINIMUM CURRENT" -to MCU_D[0]
set_instance_assignment -name CURRENT_STRENGTH_NEW "MINIMUM CURRENT" -to MCU_D[1]
set_instance_assignment -name CURRENT_STRENGTH_NEW "MINIMUM CURRENT" -to MCU_D[2]
set_instance_assignment -name CURRENT_STRENGTH_NEW "MINIMUM CURRENT" -to MCU_D[3]
set_instance_assignment -name CURRENT_STRENGTH_NEW "MINIMUM CURRENT" -to MCU_D[4]
set_instance_assignment -name CURRENT_STRENGTH_NEW "MINIMUM CURRENT" -to MCU_D[5]
set_instance_assignment -name CURRENT_STRENGTH_NEW "MINIMUM CURRENT" -to MCU_D[6]
set_instance_assignment -name CURRENT_STRENGTH_NEW "MINIMUM CURRENT" -to MCU_D[7]
set_instance_assignment -name CURRENT_STRENGTH_NEW "MINIMUM CURRENT" -to MCU_IO_STBX
set_instance_assignment -name CURRENT_STRENGTH_NEW "MINIMUM CURRENT" -to MCU_LCD_RDX
set_instance_assignment -name CURRENT_STRENGTH_NEW "MINIMUM CURRENT" -to MCU_LCD_TE
set_instance_assignment -name CURRENT_STRENGTH_NEW "MINIMUM CURRENT" -to MCU_LCD_WRX
set_instance_assignment -name CURRENT_STRENGTH_NEW "MINIMUM CURRENT" -to MCU_P2_8
set_instance_assignment -name CURRENT_STRENGTH_NEW "MINIMUM CURRENT" -to REF_EN
set_instance_assignment -name CURRENT_STRENGTH_NEW "MINIMUM CURRENT" -to SW_D
set_instance_assignment -name CURRENT_STRENGTH_NEW "MINIMUM CURRENT" -to SW_L
set_instance_assignment -name CURRENT_STRENGTH_NEW "MINIMUM CURRENT" -to SW_R
set_instance_assignment -name CURRENT_STRENGTH_NEW "MINIMUM CURRENT" -to SW_ROT_A
set_instance_assignment -name CURRENT_STRENGTH_NEW "MINIMUM CURRENT" -to SW_ROT_B
set_instance_assignment -name CURRENT_STRENGTH_NEW "MINIMUM CURRENT" -to SW_SEL
set_instance_assignment -name CURRENT_STRENGTH_NEW "MINIMUM CURRENT" -to SW_U
set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to SYSOFF
set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to TP_D
set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to TP_L
set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to TP_R
set_instance_assignment -name CURRENT_STRENGTH_NEW "MAXIMUM CURRENT" -to TP_U
set_location_assignment PIN_57 -to AUDIO_RESETX
set_location_assignment PIN_44 -to DEVICE_RESET
set_location_assignment PIN_38 -to DEVICE_RESET_V
set_location_assignment PIN_73 -to GPS_RESETX
set_location_assignment PIN_74 -to GPS_TIMEPULSE
set_location_assignment PIN_75 -to GPS_TX_READY
set_location_assignment PIN_76 -to LCD_BACKLIGHT
set_location_assignment PIN_99 -to LCD_DB[0]
set_location_assignment PIN_87 -to LCD_DB[10]
set_location_assignment PIN_86 -to LCD_DB[11]
set_location_assignment PIN_85 -to LCD_DB[12]
set_location_assignment PIN_84 -to LCD_DB[13]
set_location_assignment PIN_83 -to LCD_DB[14]
set_location_assignment PIN_82 -to LCD_DB[15]
set_location_assignment PIN_98 -to LCD_DB[1]
set_location_assignment PIN_97 -to LCD_DB[2]
set_location_assignment PIN_96 -to LCD_DB[3]
set_location_assignment PIN_95 -to LCD_DB[4]
set_location_assignment PIN_92 -to LCD_DB[5]
set_location_assignment PIN_91 -to LCD_DB[6]
set_location_assignment PIN_90 -to LCD_DB[7]
set_location_assignment PIN_89 -to LCD_DB[8]
set_location_assignment PIN_88 -to LCD_DB[9]
set_location_assignment PIN_1 -to LCD_RDX
set_location_assignment PIN_100 -to LCD_RESETX
set_location_assignment PIN_3 -to LCD_RS
set_location_assignment PIN_4 -to LCD_TE
set_location_assignment PIN_2 -to LCD_WRX
set_location_assignment PIN_42 -to MCU_ADDR
set_location_assignment PIN_72 -to MCU_DIR
set_location_assignment PIN_35 -to MCU_D[0]
set_location_assignment PIN_36 -to MCU_D[1]
set_location_assignment PIN_33 -to MCU_D[2]
set_location_assignment PIN_30 -to MCU_D[3]
set_location_assignment PIN_28 -to MCU_D[4]
set_location_assignment PIN_29 -to MCU_D[5]
set_location_assignment PIN_27 -to MCU_D[6]
set_location_assignment PIN_26 -to MCU_D[7]
set_location_assignment PIN_41 -to MCU_IO_STBX
set_location_assignment PIN_39 -to MCU_LCD_RDX
set_location_assignment PIN_40 -to MCU_LCD_TE
set_location_assignment PIN_71 -to MCU_LCD_WRX
set_location_assignment PIN_43 -to MCU_P2_8
set_location_assignment PIN_58 -to REF_EN
set_location_assignment PIN_14 -to SW_D
set_location_assignment PIN_37 -to SW_L
set_location_assignment PIN_12 -to SW_R
set_location_assignment PIN_15 -to SW_ROT_A
set_location_assignment PIN_16 -to SW_ROT_B
set_location_assignment PIN_17 -to SW_SEL
set_location_assignment PIN_34 -to SW_U
set_location_assignment PIN_47 -to SYSOFF
set_location_assignment PIN_6 -to TP_D
set_location_assignment PIN_7 -to TP_L
set_location_assignment PIN_5 -to TP_R
set_location_assignment PIN_8 -to TP_U
@@ -0,0 +1,38 @@
set_instance_assignment -name ENABLE_OPEN_DRAIN -to TP_U~output false
set_instance_assignment -name ENABLE_OPEN_DRAIN -to TP_L~output false
set_instance_assignment -name ENABLE_OPEN_DRAIN -to TP_R~output false
set_instance_assignment -name ENABLE_OPEN_DRAIN -to TP_D~output false
set_instance_assignment -name ENABLE_OPEN_DRAIN -to MCU_D[1]~output false
set_instance_assignment -name ENABLE_OPEN_DRAIN -to MCU_D[2]~output false
set_instance_assignment -name ENABLE_OPEN_DRAIN -to MCU_D[0]~output false
set_instance_assignment -name ENABLE_OPEN_DRAIN -to MCU_D[6]~output false
set_instance_assignment -name ENABLE_OPEN_DRAIN -to MCU_D[7]~output false
set_instance_assignment -name ENABLE_OPEN_DRAIN -to LCD_DB[8]~output false
set_instance_assignment -name ENABLE_OPEN_DRAIN -to LCD_DB[0]~output false
set_instance_assignment -name ENABLE_OPEN_DRAIN -to LCD_DB[6]~output false
set_instance_assignment -name ENABLE_OPEN_DRAIN -to LCD_DB[14]~output false
set_instance_assignment -name ENABLE_OPEN_DRAIN -to LCD_DB[15]~output false
set_instance_assignment -name ENABLE_OPEN_DRAIN -to LCD_DB[7]~output false
set_instance_assignment -name ENABLE_OPEN_DRAIN -to LCD_DB[1]~output false
set_instance_assignment -name ENABLE_OPEN_DRAIN -to MCU_D[5]~output false
set_instance_assignment -name ENABLE_OPEN_DRAIN -to MCU_D[3]~output false
set_instance_assignment -name ENABLE_OPEN_DRAIN -to MCU_D[4]~output false
set_instance_assignment -name ENABLE_OPEN_DRAIN -to LCD_DB[2]~output false
set_instance_assignment -name ENABLE_OPEN_DRAIN -to LCD_DB[9]~output false
set_instance_assignment -name ENABLE_OPEN_DRAIN -to LCD_DB[10]~output false
set_instance_assignment -name ENABLE_OPEN_DRAIN -to LCD_DB[13]~output false
set_instance_assignment -name ENABLE_OPEN_DRAIN -to LCD_DB[5]~output false
set_instance_assignment -name ENABLE_OPEN_DRAIN -to LCD_DB[3]~output false
set_instance_assignment -name ENABLE_OPEN_DRAIN -to LCD_DB[4]~output false
set_instance_assignment -name ENABLE_OPEN_DRAIN -to LCD_DB[11]~output false
set_instance_assignment -name ENABLE_OPEN_DRAIN -to LCD_DB[12]~output false
set_instance_assignment -name ENABLE_OPEN_DRAIN -to LCD_RDX~output false
set_instance_assignment -name ENABLE_OPEN_DRAIN -to LCD_WRX~output false
set_instance_assignment -name ENABLE_OPEN_DRAIN -to LCD_RS~output false
set_instance_assignment -name ENABLE_OPEN_DRAIN -to MCU_LCD_TE~output false
set_instance_assignment -name ENABLE_OPEN_DRAIN -to LCD_RESETX~output false
set_instance_assignment -name ENABLE_OPEN_DRAIN -to REF_EN~output false
set_instance_assignment -name ENABLE_OPEN_DRAIN -to LCD_BACKLIGHT~output false
set_instance_assignment -name ENABLE_OPEN_DRAIN -to SYSOFF~output false
set_instance_assignment -name ENABLE_OPEN_DRAIN -to AUDIO_RESETX~output false
set_instance_assignment -name ENABLE_OPEN_DRAIN -to GPS_RESETX~output false
@@ -0,0 +1,29 @@
tp_q[3] clken_ctrl_X1_Y15_N0
tp_q[4] clken_ctrl_X1_Y15_N0
lcd_backlight_q clken_ctrl_X1_Y15_N1
tp_q[0] clken_ctrl_X1_Y15_N0
lcd_reset_q clken_ctrl_X1_Y15_N1
tp_q[1] clken_ctrl_X1_Y15_N0
audio_reset_q clken_ctrl_X1_Y15_N1
tp_q[7] clken_ctrl_X1_Y15_N0
tp_q[2] clken_ctrl_X1_Y15_N0
tp_q[5] clken_ctrl_X1_Y15_N0
ref_en_q clken_ctrl_X1_Y15_N1
sysoff_q clken_ctrl_X1_Y15_N1
tp_q[6] clken_ctrl_X1_Y15_N0
lcd_data_in_q[0] clken_ctrl_X1_Y19_N0
lcd_data_in_q[6] clken_ctrl_X1_Y19_N0
lcd_data_out_q[1] clken_ctrl_X1_Y20_N0
lcd_data_out_q[2] clken_ctrl_X1_Y20_N0
lcd_data_out_q[6] clken_ctrl_X1_Y20_N0
lcd_data_out_q[7] clken_ctrl_X1_Y20_N0
lcd_data_out_q[0] clken_ctrl_X1_Y20_N0
lcd_data_in_q[7] clken_ctrl_X1_Y21_N0
lcd_data_in_q[1] clken_ctrl_X1_Y21_N0
lcd_data_in_q[2] clken_ctrl_X1_Y24_N0
lcd_data_in_q[4] clken_ctrl_X1_Y26_N0
lcd_data_out_q[4] clken_ctrl_X1_Y26_N1
lcd_data_out_q[3] clken_ctrl_X1_Y26_N1
lcd_data_out_q[5] clken_ctrl_X1_Y26_N1
lcd_data_in_q[3] clken_ctrl_X1_Y26_N0
lcd_data_in_q[5] clken_ctrl_X1_Y26_N0
@@ -0,0 +1,859 @@
SW_L~input|datain SW_L~input|datain
SW_L~input|oe SW_L~input|oe
SW_L~input|outclk SW_L~input|outclk
SW_L~input|outclkena SW_L~input|outclkena
SW_L~input|inclk SW_L~input|inclk
SW_L~input|inclkena SW_L~input|inclkena
SW_L~input|areset SW_L~input|areset
SW_L~input|sreset SW_L~input|sreset
SW_L~input|combout SW_L~input|combout
SW_L~input|padio SW_L~input|padio
SW_R~input|datain SW_R~input|datain
SW_R~input|oe SW_R~input|oe
SW_R~input|outclk SW_R~input|outclk
SW_R~input|outclkena SW_R~input|outclkena
SW_R~input|inclk SW_R~input|inclk
SW_R~input|inclkena SW_R~input|inclkena
SW_R~input|areset SW_R~input|areset
SW_R~input|sreset SW_R~input|sreset
SW_R~input|combout SW_R~input|combout
SW_R~input|padio SW_R~input|padio
TP_U~output|datain TP_U~output|datain
TP_U~output|oe TP_U~output|oe
TP_U~output|outclk TP_U~output|outclk
TP_U~output|outclkena TP_U~output|outclkena
TP_U~output|inclk TP_U~output|inclk
TP_U~output|inclkena TP_U~output|inclkena
TP_U~output|areset TP_U~output|areset
TP_U~output|sreset TP_U~output|sreset
TP_U~output|padio TP_U~output|padio
TP_L~output|datain TP_L~output|datain
TP_L~output|oe TP_L~output|oe
TP_L~output|outclk TP_L~output|outclk
TP_L~output|outclkena TP_L~output|outclkena
TP_L~output|inclk TP_L~output|inclk
TP_L~output|inclkena TP_L~output|inclkena
TP_L~output|areset TP_L~output|areset
TP_L~output|sreset TP_L~output|sreset
TP_L~output|padio TP_L~output|padio
SW_ROT_B~input|datain SW_ROT_B~input|datain
SW_ROT_B~input|oe SW_ROT_B~input|oe
SW_ROT_B~input|outclk SW_ROT_B~input|outclk
SW_ROT_B~input|outclkena SW_ROT_B~input|outclkena
SW_ROT_B~input|inclk SW_ROT_B~input|inclk
SW_ROT_B~input|inclkena SW_ROT_B~input|inclkena
SW_ROT_B~input|areset SW_ROT_B~input|areset
SW_ROT_B~input|sreset SW_ROT_B~input|sreset
SW_ROT_B~input|combout SW_ROT_B~input|combout
SW_ROT_B~input|padio SW_ROT_B~input|padio
TP_R~output|datain TP_R~output|datain
TP_R~output|oe TP_R~output|oe
TP_R~output|outclk TP_R~output|outclk
TP_R~output|outclkena TP_R~output|outclkena
TP_R~output|inclk TP_R~output|inclk
TP_R~output|inclkena TP_R~output|inclkena
TP_R~output|areset TP_R~output|areset
TP_R~output|sreset TP_R~output|sreset
TP_R~output|padio TP_R~output|padio
TP_D~output|datain TP_D~output|datain
TP_D~output|oe TP_D~output|oe
TP_D~output|outclk TP_D~output|outclk
TP_D~output|outclkena TP_D~output|outclkena
TP_D~output|inclk TP_D~output|inclk
TP_D~output|inclkena TP_D~output|inclkena
TP_D~output|areset TP_D~output|areset
TP_D~output|sreset TP_D~output|sreset
TP_D~output|padio TP_D~output|padio
MCU_D[1]~output|datain MCU_D[1]~output|datain
MCU_D[1]~output|oe MCU_D[1]~output|oe
MCU_D[1]~output|outclk MCU_D[1]~output|outclk
MCU_D[1]~output|outclkena MCU_D[1]~output|outclkena
MCU_D[1]~output|inclk MCU_D[1]~output|inclk
MCU_D[1]~output|inclkena MCU_D[1]~output|inclkena
MCU_D[1]~output|areset MCU_D[1]~output|areset
MCU_D[1]~output|sreset MCU_D[1]~output|sreset
MCU_D[1]~output|combout MCU_D[1]~output|combout
MCU_D[1]~output|padio MCU_D[1]~output|padio
MCU_D[2]~output|datain MCU_D[2]~output|datain
MCU_D[2]~output|oe MCU_D[2]~output|oe
MCU_D[2]~output|outclk MCU_D[2]~output|outclk
MCU_D[2]~output|outclkena MCU_D[2]~output|outclkena
MCU_D[2]~output|inclk MCU_D[2]~output|inclk
MCU_D[2]~output|inclkena MCU_D[2]~output|inclkena
MCU_D[2]~output|areset MCU_D[2]~output|areset
MCU_D[2]~output|sreset MCU_D[2]~output|sreset
MCU_D[2]~output|combout MCU_D[2]~output|combout
MCU_D[2]~output|padio MCU_D[2]~output|padio
MCU_DIR~input|datain MCU_DIR~input|datain
MCU_DIR~input|oe MCU_DIR~input|oe
MCU_DIR~input|outclk MCU_DIR~input|outclk
MCU_DIR~input|outclkena MCU_DIR~input|outclkena
MCU_DIR~input|inclk MCU_DIR~input|inclk
MCU_DIR~input|inclkena MCU_DIR~input|inclkena
MCU_DIR~input|areset MCU_DIR~input|areset
MCU_DIR~input|sreset MCU_DIR~input|sreset
MCU_DIR~input|combout MCU_DIR~input|combout
MCU_DIR~input|padio MCU_DIR~input|padio
MCU_D[0]~output|datain MCU_D[0]~output|datain
MCU_D[0]~output|oe MCU_D[0]~output|oe
MCU_D[0]~output|outclk MCU_D[0]~output|outclk
MCU_D[0]~output|outclkena MCU_D[0]~output|outclkena
MCU_D[0]~output|inclk MCU_D[0]~output|inclk
MCU_D[0]~output|inclkena MCU_D[0]~output|inclkena
MCU_D[0]~output|areset MCU_D[0]~output|areset
MCU_D[0]~output|sreset MCU_D[0]~output|sreset
MCU_D[0]~output|combout MCU_D[0]~output|combout
MCU_D[0]~output|padio MCU_D[0]~output|padio
MCU_D[6]~output|datain MCU_D[6]~output|datain
MCU_D[6]~output|oe MCU_D[6]~output|oe
MCU_D[6]~output|outclk MCU_D[6]~output|outclk
MCU_D[6]~output|outclkena MCU_D[6]~output|outclkena
MCU_D[6]~output|inclk MCU_D[6]~output|inclk
MCU_D[6]~output|inclkena MCU_D[6]~output|inclkena
MCU_D[6]~output|areset MCU_D[6]~output|areset
MCU_D[6]~output|sreset MCU_D[6]~output|sreset
MCU_D[6]~output|combout MCU_D[6]~output|combout
MCU_D[6]~output|padio MCU_D[6]~output|padio
MCU_D[7]~output|datain MCU_D[7]~output|datain
MCU_D[7]~output|oe MCU_D[7]~output|oe
MCU_D[7]~output|outclk MCU_D[7]~output|outclk
MCU_D[7]~output|outclkena MCU_D[7]~output|outclkena
MCU_D[7]~output|inclk MCU_D[7]~output|inclk
MCU_D[7]~output|inclkena MCU_D[7]~output|inclkena
MCU_D[7]~output|areset MCU_D[7]~output|areset
MCU_D[7]~output|sreset MCU_D[7]~output|sreset
MCU_D[7]~output|combout MCU_D[7]~output|combout
MCU_D[7]~output|padio MCU_D[7]~output|padio
LCD_DB[8]~output|datain LCD_DB[8]~output|datain
LCD_DB[8]~output|oe LCD_DB[8]~output|oe
LCD_DB[8]~output|outclk LCD_DB[8]~output|outclk
LCD_DB[8]~output|outclkena LCD_DB[8]~output|outclkena
LCD_DB[8]~output|inclk LCD_DB[8]~output|inclk
LCD_DB[8]~output|inclkena LCD_DB[8]~output|inclkena
LCD_DB[8]~output|areset LCD_DB[8]~output|areset
LCD_DB[8]~output|sreset LCD_DB[8]~output|sreset
LCD_DB[8]~output|combout LCD_DB[8]~output|combout
LCD_DB[8]~output|padio LCD_DB[8]~output|padio
LCD_DB[0]~output|datain LCD_DB[0]~output|datain
LCD_DB[0]~output|oe LCD_DB[0]~output|oe
LCD_DB[0]~output|outclk LCD_DB[0]~output|outclk
LCD_DB[0]~output|outclkena LCD_DB[0]~output|outclkena
LCD_DB[0]~output|inclk LCD_DB[0]~output|inclk
LCD_DB[0]~output|inclkena LCD_DB[0]~output|inclkena
LCD_DB[0]~output|areset LCD_DB[0]~output|areset
LCD_DB[0]~output|sreset LCD_DB[0]~output|sreset
LCD_DB[0]~output|combout LCD_DB[0]~output|combout
LCD_DB[0]~output|padio LCD_DB[0]~output|padio
LCD_DB[6]~output|datain LCD_DB[6]~output|datain
LCD_DB[6]~output|oe LCD_DB[6]~output|oe
LCD_DB[6]~output|outclk LCD_DB[6]~output|outclk
LCD_DB[6]~output|outclkena LCD_DB[6]~output|outclkena
LCD_DB[6]~output|inclk LCD_DB[6]~output|inclk
LCD_DB[6]~output|inclkena LCD_DB[6]~output|inclkena
LCD_DB[6]~output|areset LCD_DB[6]~output|areset
LCD_DB[6]~output|sreset LCD_DB[6]~output|sreset
LCD_DB[6]~output|combout LCD_DB[6]~output|combout
LCD_DB[6]~output|padio LCD_DB[6]~output|padio
LCD_DB[14]~output|datain LCD_DB[14]~output|datain
LCD_DB[14]~output|oe LCD_DB[14]~output|oe
LCD_DB[14]~output|outclk LCD_DB[14]~output|outclk
LCD_DB[14]~output|outclkena LCD_DB[14]~output|outclkena
LCD_DB[14]~output|inclk LCD_DB[14]~output|inclk
LCD_DB[14]~output|inclkena LCD_DB[14]~output|inclkena
LCD_DB[14]~output|areset LCD_DB[14]~output|areset
LCD_DB[14]~output|sreset LCD_DB[14]~output|sreset
LCD_DB[14]~output|combout LCD_DB[14]~output|combout
LCD_DB[14]~output|padio LCD_DB[14]~output|padio
LCD_DB[15]~output|datain LCD_DB[15]~output|datain
LCD_DB[15]~output|oe LCD_DB[15]~output|oe
LCD_DB[15]~output|outclk LCD_DB[15]~output|outclk
LCD_DB[15]~output|outclkena LCD_DB[15]~output|outclkena
LCD_DB[15]~output|inclk LCD_DB[15]~output|inclk
LCD_DB[15]~output|inclkena LCD_DB[15]~output|inclkena
LCD_DB[15]~output|areset LCD_DB[15]~output|areset
LCD_DB[15]~output|sreset LCD_DB[15]~output|sreset
LCD_DB[15]~output|combout LCD_DB[15]~output|combout
LCD_DB[15]~output|padio LCD_DB[15]~output|padio
LCD_DB[7]~output|datain LCD_DB[7]~output|datain
LCD_DB[7]~output|oe LCD_DB[7]~output|oe
LCD_DB[7]~output|outclk LCD_DB[7]~output|outclk
LCD_DB[7]~output|outclkena LCD_DB[7]~output|outclkena
LCD_DB[7]~output|inclk LCD_DB[7]~output|inclk
LCD_DB[7]~output|inclkena LCD_DB[7]~output|inclkena
LCD_DB[7]~output|areset LCD_DB[7]~output|areset
LCD_DB[7]~output|sreset LCD_DB[7]~output|sreset
LCD_DB[7]~output|combout LCD_DB[7]~output|combout
LCD_DB[7]~output|padio LCD_DB[7]~output|padio
LCD_DB[1]~output|datain LCD_DB[1]~output|datain
LCD_DB[1]~output|oe LCD_DB[1]~output|oe
LCD_DB[1]~output|outclk LCD_DB[1]~output|outclk
LCD_DB[1]~output|outclkena LCD_DB[1]~output|outclkena
LCD_DB[1]~output|inclk LCD_DB[1]~output|inclk
LCD_DB[1]~output|inclkena LCD_DB[1]~output|inclkena
LCD_DB[1]~output|areset LCD_DB[1]~output|areset
LCD_DB[1]~output|sreset LCD_DB[1]~output|sreset
LCD_DB[1]~output|combout LCD_DB[1]~output|combout
LCD_DB[1]~output|padio LCD_DB[1]~output|padio
MCU_D[5]~output|datain MCU_D[5]~output|datain
MCU_D[5]~output|oe MCU_D[5]~output|oe
MCU_D[5]~output|outclk MCU_D[5]~output|outclk
MCU_D[5]~output|outclkena MCU_D[5]~output|outclkena
MCU_D[5]~output|inclk MCU_D[5]~output|inclk
MCU_D[5]~output|inclkena MCU_D[5]~output|inclkena
MCU_D[5]~output|areset MCU_D[5]~output|areset
MCU_D[5]~output|sreset MCU_D[5]~output|sreset
MCU_D[5]~output|combout MCU_D[5]~output|combout
MCU_D[5]~output|padio MCU_D[5]~output|padio
MCU_D[3]~output|datain MCU_D[3]~output|datain
MCU_D[3]~output|oe MCU_D[3]~output|oe
MCU_D[3]~output|outclk MCU_D[3]~output|outclk
MCU_D[3]~output|outclkena MCU_D[3]~output|outclkena
MCU_D[3]~output|inclk MCU_D[3]~output|inclk
MCU_D[3]~output|inclkena MCU_D[3]~output|inclkena
MCU_D[3]~output|areset MCU_D[3]~output|areset
MCU_D[3]~output|sreset MCU_D[3]~output|sreset
MCU_D[3]~output|combout MCU_D[3]~output|combout
MCU_D[3]~output|padio MCU_D[3]~output|padio
MCU_D[4]~output|datain MCU_D[4]~output|datain
MCU_D[4]~output|oe MCU_D[4]~output|oe
MCU_D[4]~output|outclk MCU_D[4]~output|outclk
MCU_D[4]~output|outclkena MCU_D[4]~output|outclkena
MCU_D[4]~output|inclk MCU_D[4]~output|inclk
MCU_D[4]~output|inclkena MCU_D[4]~output|inclkena
MCU_D[4]~output|areset MCU_D[4]~output|areset
MCU_D[4]~output|sreset MCU_D[4]~output|sreset
MCU_D[4]~output|combout MCU_D[4]~output|combout
MCU_D[4]~output|padio MCU_D[4]~output|padio
LCD_DB[2]~output|datain LCD_DB[2]~output|datain
LCD_DB[2]~output|oe LCD_DB[2]~output|oe
LCD_DB[2]~output|outclk LCD_DB[2]~output|outclk
LCD_DB[2]~output|outclkena LCD_DB[2]~output|outclkena
LCD_DB[2]~output|inclk LCD_DB[2]~output|inclk
LCD_DB[2]~output|inclkena LCD_DB[2]~output|inclkena
LCD_DB[2]~output|areset LCD_DB[2]~output|areset
LCD_DB[2]~output|sreset LCD_DB[2]~output|sreset
LCD_DB[2]~output|combout LCD_DB[2]~output|combout
LCD_DB[2]~output|padio LCD_DB[2]~output|padio
LCD_DB[9]~output|datain LCD_DB[9]~output|datain
LCD_DB[9]~output|oe LCD_DB[9]~output|oe
LCD_DB[9]~output|outclk LCD_DB[9]~output|outclk
LCD_DB[9]~output|outclkena LCD_DB[9]~output|outclkena
LCD_DB[9]~output|inclk LCD_DB[9]~output|inclk
LCD_DB[9]~output|inclkena LCD_DB[9]~output|inclkena
LCD_DB[9]~output|areset LCD_DB[9]~output|areset
LCD_DB[9]~output|sreset LCD_DB[9]~output|sreset
LCD_DB[9]~output|combout LCD_DB[9]~output|combout
LCD_DB[9]~output|padio LCD_DB[9]~output|padio
LCD_DB[10]~output|datain LCD_DB[10]~output|datain
LCD_DB[10]~output|oe LCD_DB[10]~output|oe
LCD_DB[10]~output|outclk LCD_DB[10]~output|outclk
LCD_DB[10]~output|outclkena LCD_DB[10]~output|outclkena
LCD_DB[10]~output|inclk LCD_DB[10]~output|inclk
LCD_DB[10]~output|inclkena LCD_DB[10]~output|inclkena
LCD_DB[10]~output|areset LCD_DB[10]~output|areset
LCD_DB[10]~output|sreset LCD_DB[10]~output|sreset
LCD_DB[10]~output|combout LCD_DB[10]~output|combout
LCD_DB[10]~output|padio LCD_DB[10]~output|padio
SW_D~input|datain SW_D~input|datain
SW_D~input|oe SW_D~input|oe
SW_D~input|outclk SW_D~input|outclk
SW_D~input|outclkena SW_D~input|outclkena
SW_D~input|inclk SW_D~input|inclk
SW_D~input|inclkena SW_D~input|inclkena
SW_D~input|areset SW_D~input|areset
SW_D~input|sreset SW_D~input|sreset
SW_D~input|combout SW_D~input|combout
SW_D~input|padio SW_D~input|padio
LCD_DB[13]~output|datain LCD_DB[13]~output|datain
LCD_DB[13]~output|oe LCD_DB[13]~output|oe
LCD_DB[13]~output|outclk LCD_DB[13]~output|outclk
LCD_DB[13]~output|outclkena LCD_DB[13]~output|outclkena
LCD_DB[13]~output|inclk LCD_DB[13]~output|inclk
LCD_DB[13]~output|inclkena LCD_DB[13]~output|inclkena
LCD_DB[13]~output|areset LCD_DB[13]~output|areset
LCD_DB[13]~output|sreset LCD_DB[13]~output|sreset
LCD_DB[13]~output|combout LCD_DB[13]~output|combout
LCD_DB[13]~output|padio LCD_DB[13]~output|padio
LCD_DB[5]~output|datain LCD_DB[5]~output|datain
LCD_DB[5]~output|oe LCD_DB[5]~output|oe
LCD_DB[5]~output|outclk LCD_DB[5]~output|outclk
LCD_DB[5]~output|outclkena LCD_DB[5]~output|outclkena
LCD_DB[5]~output|inclk LCD_DB[5]~output|inclk
LCD_DB[5]~output|inclkena LCD_DB[5]~output|inclkena
LCD_DB[5]~output|areset LCD_DB[5]~output|areset
LCD_DB[5]~output|sreset LCD_DB[5]~output|sreset
LCD_DB[5]~output|combout LCD_DB[5]~output|combout
LCD_DB[5]~output|padio LCD_DB[5]~output|padio
LCD_DB[3]~output|datain LCD_DB[3]~output|datain
LCD_DB[3]~output|oe LCD_DB[3]~output|oe
LCD_DB[3]~output|outclk LCD_DB[3]~output|outclk
LCD_DB[3]~output|outclkena LCD_DB[3]~output|outclkena
LCD_DB[3]~output|inclk LCD_DB[3]~output|inclk
LCD_DB[3]~output|inclkena LCD_DB[3]~output|inclkena
LCD_DB[3]~output|areset LCD_DB[3]~output|areset
LCD_DB[3]~output|sreset LCD_DB[3]~output|sreset
LCD_DB[3]~output|combout LCD_DB[3]~output|combout
LCD_DB[3]~output|padio LCD_DB[3]~output|padio
LCD_DB[4]~output|datain LCD_DB[4]~output|datain
LCD_DB[4]~output|oe LCD_DB[4]~output|oe
LCD_DB[4]~output|outclk LCD_DB[4]~output|outclk
LCD_DB[4]~output|outclkena LCD_DB[4]~output|outclkena
LCD_DB[4]~output|inclk LCD_DB[4]~output|inclk
LCD_DB[4]~output|inclkena LCD_DB[4]~output|inclkena
LCD_DB[4]~output|areset LCD_DB[4]~output|areset
LCD_DB[4]~output|sreset LCD_DB[4]~output|sreset
LCD_DB[4]~output|combout LCD_DB[4]~output|combout
LCD_DB[4]~output|padio LCD_DB[4]~output|padio
SW_ROT_A~input|datain SW_ROT_A~input|datain
SW_ROT_A~input|oe SW_ROT_A~input|oe
SW_ROT_A~input|outclk SW_ROT_A~input|outclk
SW_ROT_A~input|outclkena SW_ROT_A~input|outclkena
SW_ROT_A~input|inclk SW_ROT_A~input|inclk
SW_ROT_A~input|inclkena SW_ROT_A~input|inclkena
SW_ROT_A~input|areset SW_ROT_A~input|areset
SW_ROT_A~input|sreset SW_ROT_A~input|sreset
SW_ROT_A~input|combout SW_ROT_A~input|combout
SW_ROT_A~input|padio SW_ROT_A~input|padio
SW_U~input|datain SW_U~input|datain
SW_U~input|oe SW_U~input|oe
SW_U~input|outclk SW_U~input|outclk
SW_U~input|outclkena SW_U~input|outclkena
SW_U~input|inclk SW_U~input|inclk
SW_U~input|inclkena SW_U~input|inclkena
SW_U~input|areset SW_U~input|areset
SW_U~input|sreset SW_U~input|sreset
SW_U~input|combout SW_U~input|combout
SW_U~input|padio SW_U~input|padio
LCD_DB[11]~output|datain LCD_DB[11]~output|datain
LCD_DB[11]~output|oe LCD_DB[11]~output|oe
LCD_DB[11]~output|outclk LCD_DB[11]~output|outclk
LCD_DB[11]~output|outclkena LCD_DB[11]~output|outclkena
LCD_DB[11]~output|inclk LCD_DB[11]~output|inclk
LCD_DB[11]~output|inclkena LCD_DB[11]~output|inclkena
LCD_DB[11]~output|areset LCD_DB[11]~output|areset
LCD_DB[11]~output|sreset LCD_DB[11]~output|sreset
LCD_DB[11]~output|combout LCD_DB[11]~output|combout
LCD_DB[11]~output|padio LCD_DB[11]~output|padio
LCD_DB[12]~output|datain LCD_DB[12]~output|datain
LCD_DB[12]~output|oe LCD_DB[12]~output|oe
LCD_DB[12]~output|outclk LCD_DB[12]~output|outclk
LCD_DB[12]~output|outclkena LCD_DB[12]~output|outclkena
LCD_DB[12]~output|inclk LCD_DB[12]~output|inclk
LCD_DB[12]~output|inclkena LCD_DB[12]~output|inclkena
LCD_DB[12]~output|areset LCD_DB[12]~output|areset
LCD_DB[12]~output|sreset LCD_DB[12]~output|sreset
LCD_DB[12]~output|combout LCD_DB[12]~output|combout
LCD_DB[12]~output|padio LCD_DB[12]~output|padio
LCD_RDX~output|datain LCD_RDX~output|datain
LCD_RDX~output|oe LCD_RDX~output|oe
LCD_RDX~output|outclk LCD_RDX~output|outclk
LCD_RDX~output|outclkena LCD_RDX~output|outclkena
LCD_RDX~output|inclk LCD_RDX~output|inclk
LCD_RDX~output|inclkena LCD_RDX~output|inclkena
LCD_RDX~output|areset LCD_RDX~output|areset
LCD_RDX~output|sreset LCD_RDX~output|sreset
LCD_RDX~output|padio LCD_RDX~output|padio
SW_SEL~input|datain SW_SEL~input|datain
SW_SEL~input|oe SW_SEL~input|oe
SW_SEL~input|outclk SW_SEL~input|outclk
SW_SEL~input|outclkena SW_SEL~input|outclkena
SW_SEL~input|inclk SW_SEL~input|inclk
SW_SEL~input|inclkena SW_SEL~input|inclkena
SW_SEL~input|areset SW_SEL~input|areset
SW_SEL~input|sreset SW_SEL~input|sreset
SW_SEL~input|combout SW_SEL~input|combout
SW_SEL~input|padio SW_SEL~input|padio
MCU_IO_STBX~input|datain MCU_IO_STBX~input|datain
MCU_IO_STBX~input|oe MCU_IO_STBX~input|oe
MCU_IO_STBX~input|outclk MCU_IO_STBX~input|outclk
MCU_IO_STBX~input|outclkena MCU_IO_STBX~input|outclkena
MCU_IO_STBX~input|inclk MCU_IO_STBX~input|inclk
MCU_IO_STBX~input|inclkena MCU_IO_STBX~input|inclkena
MCU_IO_STBX~input|areset MCU_IO_STBX~input|areset
MCU_IO_STBX~input|sreset MCU_IO_STBX~input|sreset
MCU_IO_STBX~input|combout MCU_IO_STBX~input|combout
MCU_IO_STBX~input|padio MCU_IO_STBX~input|padio
MCU_LCD_RDX~input|datain MCU_LCD_RDX~input|datain
MCU_LCD_RDX~input|oe MCU_LCD_RDX~input|oe
MCU_LCD_RDX~input|outclk MCU_LCD_RDX~input|outclk
MCU_LCD_RDX~input|outclkena MCU_LCD_RDX~input|outclkena
MCU_LCD_RDX~input|inclk MCU_LCD_RDX~input|inclk
MCU_LCD_RDX~input|inclkena MCU_LCD_RDX~input|inclkena
MCU_LCD_RDX~input|areset MCU_LCD_RDX~input|areset
MCU_LCD_RDX~input|sreset MCU_LCD_RDX~input|sreset
MCU_LCD_RDX~input|combout MCU_LCD_RDX~input|combout
MCU_LCD_RDX~input|padio MCU_LCD_RDX~input|padio
MCU_LCD_WRX~input|datain MCU_LCD_WRX~input|datain
MCU_LCD_WRX~input|oe MCU_LCD_WRX~input|oe
MCU_LCD_WRX~input|outclk MCU_LCD_WRX~input|outclk
MCU_LCD_WRX~input|outclkena MCU_LCD_WRX~input|outclkena
MCU_LCD_WRX~input|inclk MCU_LCD_WRX~input|inclk
MCU_LCD_WRX~input|inclkena MCU_LCD_WRX~input|inclkena
MCU_LCD_WRX~input|areset MCU_LCD_WRX~input|areset
MCU_LCD_WRX~input|sreset MCU_LCD_WRX~input|sreset
MCU_LCD_WRX~input|combout MCU_LCD_WRX~input|combout
MCU_LCD_WRX~input|padio MCU_LCD_WRX~input|padio
LCD_WRX~output|datain LCD_WRX~output|datain
LCD_WRX~output|oe LCD_WRX~output|oe
LCD_WRX~output|outclk LCD_WRX~output|outclk
LCD_WRX~output|outclkena LCD_WRX~output|outclkena
LCD_WRX~output|inclk LCD_WRX~output|inclk
LCD_WRX~output|inclkena LCD_WRX~output|inclkena
LCD_WRX~output|areset LCD_WRX~output|areset
LCD_WRX~output|sreset LCD_WRX~output|sreset
LCD_WRX~output|padio LCD_WRX~output|padio
LCD_RS~output|datain LCD_RS~output|datain
LCD_RS~output|oe LCD_RS~output|oe
LCD_RS~output|outclk LCD_RS~output|outclk
LCD_RS~output|outclkena LCD_RS~output|outclkena
LCD_RS~output|inclk LCD_RS~output|inclk
LCD_RS~output|inclkena LCD_RS~output|inclkena
LCD_RS~output|areset LCD_RS~output|areset
LCD_RS~output|sreset LCD_RS~output|sreset
LCD_RS~output|padio LCD_RS~output|padio
MCU_ADDR~input|datain MCU_ADDR~input|datain
MCU_ADDR~input|oe MCU_ADDR~input|oe
MCU_ADDR~input|outclk MCU_ADDR~input|outclk
MCU_ADDR~input|outclkena MCU_ADDR~input|outclkena
MCU_ADDR~input|inclk MCU_ADDR~input|inclk
MCU_ADDR~input|inclkena MCU_ADDR~input|inclkena
MCU_ADDR~input|areset MCU_ADDR~input|areset
MCU_ADDR~input|sreset MCU_ADDR~input|sreset
MCU_ADDR~input|combout MCU_ADDR~input|combout
MCU_ADDR~input|padio MCU_ADDR~input|padio
MCU_LCD_TE~output|datain MCU_LCD_TE~output|datain
MCU_LCD_TE~output|oe MCU_LCD_TE~output|oe
MCU_LCD_TE~output|outclk MCU_LCD_TE~output|outclk
MCU_LCD_TE~output|outclkena MCU_LCD_TE~output|outclkena
MCU_LCD_TE~output|inclk MCU_LCD_TE~output|inclk
MCU_LCD_TE~output|inclkena MCU_LCD_TE~output|inclkena
MCU_LCD_TE~output|areset MCU_LCD_TE~output|areset
MCU_LCD_TE~output|sreset MCU_LCD_TE~output|sreset
MCU_LCD_TE~output|padio MCU_LCD_TE~output|padio
LCD_TE~input|datain LCD_TE~input|datain
LCD_TE~input|oe LCD_TE~input|oe
LCD_TE~input|outclk LCD_TE~input|outclk
LCD_TE~input|outclkena LCD_TE~input|outclkena
LCD_TE~input|inclk LCD_TE~input|inclk
LCD_TE~input|inclkena LCD_TE~input|inclkena
LCD_TE~input|areset LCD_TE~input|areset
LCD_TE~input|sreset LCD_TE~input|sreset
LCD_TE~input|combout LCD_TE~input|combout
LCD_TE~input|padio LCD_TE~input|padio
LCD_RESETX~output|datain LCD_RESETX~output|datain
LCD_RESETX~output|oe LCD_RESETX~output|oe
LCD_RESETX~output|outclk LCD_RESETX~output|outclk
LCD_RESETX~output|outclkena LCD_RESETX~output|outclkena
LCD_RESETX~output|inclk LCD_RESETX~output|inclk
LCD_RESETX~output|inclkena LCD_RESETX~output|inclkena
LCD_RESETX~output|areset LCD_RESETX~output|areset
LCD_RESETX~output|sreset LCD_RESETX~output|sreset
LCD_RESETX~output|padio LCD_RESETX~output|padio
REF_EN~output|datain REF_EN~output|datain
REF_EN~output|oe REF_EN~output|oe
REF_EN~output|outclk REF_EN~output|outclk
REF_EN~output|outclkena REF_EN~output|outclkena
REF_EN~output|inclk REF_EN~output|inclk
REF_EN~output|inclkena REF_EN~output|inclkena
REF_EN~output|areset REF_EN~output|areset
REF_EN~output|sreset REF_EN~output|sreset
REF_EN~output|padio REF_EN~output|padio
LCD_BACKLIGHT~output|datain LCD_BACKLIGHT~output|datain
LCD_BACKLIGHT~output|oe LCD_BACKLIGHT~output|oe
LCD_BACKLIGHT~output|outclk LCD_BACKLIGHT~output|outclk
LCD_BACKLIGHT~output|outclkena LCD_BACKLIGHT~output|outclkena
LCD_BACKLIGHT~output|inclk LCD_BACKLIGHT~output|inclk
LCD_BACKLIGHT~output|inclkena LCD_BACKLIGHT~output|inclkena
LCD_BACKLIGHT~output|areset LCD_BACKLIGHT~output|areset
LCD_BACKLIGHT~output|sreset LCD_BACKLIGHT~output|sreset
LCD_BACKLIGHT~output|padio LCD_BACKLIGHT~output|padio
SYSOFF~output|datain SYSOFF~output|datain
SYSOFF~output|oe SYSOFF~output|oe
SYSOFF~output|outclk SYSOFF~output|outclk
SYSOFF~output|outclkena SYSOFF~output|outclkena
SYSOFF~output|inclk SYSOFF~output|inclk
SYSOFF~output|inclkena SYSOFF~output|inclkena
SYSOFF~output|areset SYSOFF~output|areset
SYSOFF~output|sreset SYSOFF~output|sreset
SYSOFF~output|padio SYSOFF~output|padio
AUDIO_RESETX~output|datain AUDIO_RESETX~output|datain
AUDIO_RESETX~output|oe AUDIO_RESETX~output|oe
AUDIO_RESETX~output|outclk AUDIO_RESETX~output|outclk
AUDIO_RESETX~output|outclkena AUDIO_RESETX~output|outclkena
AUDIO_RESETX~output|inclk AUDIO_RESETX~output|inclk
AUDIO_RESETX~output|inclkena AUDIO_RESETX~output|inclkena
AUDIO_RESETX~output|areset AUDIO_RESETX~output|areset
AUDIO_RESETX~output|sreset AUDIO_RESETX~output|sreset
AUDIO_RESETX~output|padio AUDIO_RESETX~output|padio
MCU_P2_8~input|datain MCU_P2_8~input|datain
MCU_P2_8~input|oe MCU_P2_8~input|oe
MCU_P2_8~input|outclk MCU_P2_8~input|outclk
MCU_P2_8~input|outclkena MCU_P2_8~input|outclkena
MCU_P2_8~input|inclk MCU_P2_8~input|inclk
MCU_P2_8~input|inclkena MCU_P2_8~input|inclkena
MCU_P2_8~input|areset MCU_P2_8~input|areset
MCU_P2_8~input|sreset MCU_P2_8~input|sreset
MCU_P2_8~input|combout MCU_P2_8~input|combout
MCU_P2_8~input|padio MCU_P2_8~input|padio
GPS_TX_READY~input|datain GPS_TX_READY~input|datain
GPS_TX_READY~input|oe GPS_TX_READY~input|oe
GPS_TX_READY~input|outclk GPS_TX_READY~input|outclk
GPS_TX_READY~input|outclkena GPS_TX_READY~input|outclkena
GPS_TX_READY~input|inclk GPS_TX_READY~input|inclk
GPS_TX_READY~input|inclkena GPS_TX_READY~input|inclkena
GPS_TX_READY~input|areset GPS_TX_READY~input|areset
GPS_TX_READY~input|sreset GPS_TX_READY~input|sreset
GPS_TX_READY~input|combout GPS_TX_READY~input|combout
GPS_TX_READY~input|padio GPS_TX_READY~input|padio
DEVICE_RESET~input|datain DEVICE_RESET~input|datain
DEVICE_RESET~input|oe DEVICE_RESET~input|oe
DEVICE_RESET~input|outclk DEVICE_RESET~input|outclk
DEVICE_RESET~input|outclkena DEVICE_RESET~input|outclkena
DEVICE_RESET~input|inclk DEVICE_RESET~input|inclk
DEVICE_RESET~input|inclkena DEVICE_RESET~input|inclkena
DEVICE_RESET~input|areset DEVICE_RESET~input|areset
DEVICE_RESET~input|sreset DEVICE_RESET~input|sreset
DEVICE_RESET~input|combout DEVICE_RESET~input|combout
DEVICE_RESET~input|padio DEVICE_RESET~input|padio
GPS_TIMEPULSE~input|datain GPS_TIMEPULSE~input|datain
GPS_TIMEPULSE~input|oe GPS_TIMEPULSE~input|oe
GPS_TIMEPULSE~input|outclk GPS_TIMEPULSE~input|outclk
GPS_TIMEPULSE~input|outclkena GPS_TIMEPULSE~input|outclkena
GPS_TIMEPULSE~input|inclk GPS_TIMEPULSE~input|inclk
GPS_TIMEPULSE~input|inclkena GPS_TIMEPULSE~input|inclkena
GPS_TIMEPULSE~input|areset GPS_TIMEPULSE~input|areset
GPS_TIMEPULSE~input|sreset GPS_TIMEPULSE~input|sreset
GPS_TIMEPULSE~input|combout GPS_TIMEPULSE~input|combout
GPS_TIMEPULSE~input|padio GPS_TIMEPULSE~input|padio
DEVICE_RESET_V~input|datain DEVICE_RESET_V~input|datain
DEVICE_RESET_V~input|oe DEVICE_RESET_V~input|oe
DEVICE_RESET_V~input|outclk DEVICE_RESET_V~input|outclk
DEVICE_RESET_V~input|outclkena DEVICE_RESET_V~input|outclkena
DEVICE_RESET_V~input|inclk DEVICE_RESET_V~input|inclk
DEVICE_RESET_V~input|inclkena DEVICE_RESET_V~input|inclkena
DEVICE_RESET_V~input|areset DEVICE_RESET_V~input|areset
DEVICE_RESET_V~input|sreset DEVICE_RESET_V~input|sreset
DEVICE_RESET_V~input|combout DEVICE_RESET_V~input|combout
DEVICE_RESET_V~input|padio DEVICE_RESET_V~input|padio
GPS_RESETX~output|datain GPS_RESETX~output|datain
GPS_RESETX~output|oe GPS_RESETX~output|oe
GPS_RESETX~output|outclk GPS_RESETX~output|outclk
GPS_RESETX~output|outclkena GPS_RESETX~output|outclkena
GPS_RESETX~output|inclk GPS_RESETX~output|inclk
GPS_RESETX~output|inclkena GPS_RESETX~output|inclkena
GPS_RESETX~output|areset GPS_RESETX~output|areset
GPS_RESETX~output|sreset GPS_RESETX~output|sreset
GPS_RESETX~output|padio GPS_RESETX~output|padio
lcd_reset_q~0|dataa lcd_reset_q~0|A
lcd_reset_q~0|datab lcd_reset_q~0|B
lcd_reset_q~0|datac lcd_reset_q~0|C
lcd_reset_q~0|datad lcd_reset_q~0|D
lcd_reset_q~0|combout lcd_reset_q~0|LutOut
|datac tp_q[3]|C
tp_q[3]|clk tp_q[3]|Clk
tp_q[3]|clrn tp_q[3]|AsyncReset
tp_q[3]|sclr tp_q[3]|SyncReset
tp_q[3]|sload tp_q[3]|SyncLoad
tp_q[3]|q tp_q[3]|Q
tp_q[4]~feeder|dataa tp_q[4]|A
tp_q[4]~feeder|datab tp_q[4]|B
tp_q[4]~feeder|datac tp_q[4]|C
tp_q[4]~feeder|datad tp_q[4]|D
tp_q[4]|clk tp_q[4]|Clk
tp_q[4]|clrn tp_q[4]|AsyncReset
tp_q[4]~feeder|combout tp_q[4]|LutOut
tp_q[4]|q tp_q[4]|Q
lcd_backlight_q~feeder|dataa lcd_backlight_q|A
lcd_backlight_q~feeder|datab lcd_backlight_q|B
lcd_backlight_q~feeder|datac lcd_backlight_q|C
lcd_backlight_q~feeder|datad lcd_backlight_q|D
lcd_backlight_q|clk lcd_backlight_q|Clk
lcd_backlight_q|clrn lcd_backlight_q|AsyncReset
lcd_backlight_q~feeder|combout lcd_backlight_q|LutOut
lcd_backlight_q|q lcd_backlight_q|Q
|datac tp_q[0]|C
tp_q[0]|clk tp_q[0]|Clk
tp_q[0]|clrn tp_q[0]|AsyncReset
tp_q[0]|sclr tp_q[0]|SyncReset
tp_q[0]|sload tp_q[0]|SyncLoad
tp_q[0]|q tp_q[0]|Q
lcd_reset_q~1|dataa lcd_reset_q|A
lcd_reset_q~1|datab lcd_reset_q|B
lcd_reset_q~1|datac lcd_reset_q|C
lcd_reset_q~1|datad lcd_reset_q|D
lcd_reset_q|clk lcd_reset_q|Clk
lcd_reset_q|clrn lcd_reset_q|AsyncReset
lcd_reset_q~1|combout lcd_reset_q|LutOut
lcd_reset_q|q lcd_reset_q|Q
|datac tp_q[1]|C
tp_q[1]|clk tp_q[1]|Clk
tp_q[1]|clrn tp_q[1]|AsyncReset
tp_q[1]|sclr tp_q[1]|SyncReset
tp_q[1]|sload tp_q[1]|SyncLoad
tp_q[1]|q tp_q[1]|Q
audio_reset_q~0|dataa audio_reset_q|A
audio_reset_q~0|datab audio_reset_q|B
audio_reset_q~0|datac audio_reset_q|C
audio_reset_q~0|datad audio_reset_q|D
audio_reset_q|clk audio_reset_q|Clk
audio_reset_q|clrn audio_reset_q|AsyncReset
audio_reset_q~0|combout audio_reset_q|LutOut
audio_reset_q|q audio_reset_q|Q
tp_q[7]~feeder|dataa tp_q[7]|A
tp_q[7]~feeder|datab tp_q[7]|B
tp_q[7]~feeder|datac tp_q[7]|C
tp_q[7]~feeder|datad tp_q[7]|D
tp_q[7]|clk tp_q[7]|Clk
tp_q[7]|clrn tp_q[7]|AsyncReset
tp_q[7]~feeder|combout tp_q[7]|LutOut
tp_q[7]|q tp_q[7]|Q
tp_q[2]~feeder|dataa tp_q[2]|A
tp_q[2]~feeder|datab tp_q[2]|B
tp_q[2]~feeder|datac tp_q[2]|C
tp_q[2]~feeder|datad tp_q[2]|D
tp_q[2]|clk tp_q[2]|Clk
tp_q[2]|clrn tp_q[2]|AsyncReset
tp_q[2]~feeder|combout tp_q[2]|LutOut
tp_q[2]|q tp_q[2]|Q
|datac tp_q[5]|C
tp_q[5]|clk tp_q[5]|Clk
tp_q[5]|clrn tp_q[5]|AsyncReset
tp_q[5]|sclr tp_q[5]|SyncReset
tp_q[5]|sload tp_q[5]|SyncLoad
tp_q[5]|q tp_q[5]|Q
ref_en_q~feeder|dataa ref_en_q|A
ref_en_q~feeder|datab ref_en_q|B
ref_en_q~feeder|datac ref_en_q|C
ref_en_q~feeder|datad ref_en_q|D
ref_en_q|clk ref_en_q|Clk
ref_en_q|clrn ref_en_q|AsyncReset
ref_en_q~feeder|combout ref_en_q|LutOut
ref_en_q|q ref_en_q|Q
tp_q[3]~0|dataa tp_q[3]~0|A
tp_q[3]~0|datab tp_q[3]~0|B
tp_q[3]~0|datac tp_q[3]~0|C
tp_q[3]~0|datad tp_q[3]~0|D
tp_q[3]~0|combout tp_q[3]~0|LutOut
sysoff_q~feeder|dataa sysoff_q|A
sysoff_q~feeder|datab sysoff_q|B
sysoff_q~feeder|datac sysoff_q|C
sysoff_q~feeder|datad sysoff_q|D
sysoff_q|clk sysoff_q|Clk
sysoff_q|clrn sysoff_q|AsyncReset
sysoff_q~feeder|combout sysoff_q|LutOut
sysoff_q|q sysoff_q|Q
tp_q[6]~feeder|dataa tp_q[6]|A
tp_q[6]~feeder|datab tp_q[6]|B
tp_q[6]~feeder|datac tp_q[6]|C
tp_q[6]~feeder|datad tp_q[6]|D
tp_q[6]|clk tp_q[6]|Clk
tp_q[6]|clrn tp_q[6]|AsyncReset
tp_q[6]~feeder|combout tp_q[6]|LutOut
tp_q[6]|q tp_q[6]|Q
tp_q[3]|ena clken_ctrl_X1_Y15_N0|ClkEn
tp_q[4]|ena clken_ctrl_X1_Y15_N0|ClkEn
lcd_backlight_q|ena clken_ctrl_X1_Y15_N1|ClkEn
tp_q[0]|ena clken_ctrl_X1_Y15_N0|ClkEn
lcd_reset_q|ena clken_ctrl_X1_Y15_N1|ClkEn
tp_q[1]|ena clken_ctrl_X1_Y15_N0|ClkEn
audio_reset_q|ena clken_ctrl_X1_Y15_N1|ClkEn
tp_q[7]|ena clken_ctrl_X1_Y15_N0|ClkEn
tp_q[2]|ena clken_ctrl_X1_Y15_N0|ClkEn
tp_q[5]|ena clken_ctrl_X1_Y15_N0|ClkEn
ref_en_q|ena clken_ctrl_X1_Y15_N1|ClkEn
sysoff_q|ena clken_ctrl_X1_Y15_N1|ClkEn
tp_q[6]|ena clken_ctrl_X1_Y15_N0|ClkEn
mcu_data_out[7]~15|dataa mcu_data_out[7]~15|A
mcu_data_out[7]~15|datab mcu_data_out[7]~15|B
mcu_data_out[7]~15|datac mcu_data_out[7]~15|C
mcu_data_out[7]~15|datad mcu_data_out[7]~15|D
mcu_data_out[7]~15|combout mcu_data_out[7]~15|LutOut
mcu_data_out[6]~13|dataa mcu_data_out[6]~13|A
mcu_data_out[6]~13|datab mcu_data_out[6]~13|B
mcu_data_out[6]~13|datac mcu_data_out[6]~13|C
mcu_data_out[6]~13|datad mcu_data_out[6]~13|D
mcu_data_out[6]~13|combout mcu_data_out[6]~13|LutOut
mcu_data_out[1]~3|dataa mcu_data_out[1]~3|A
mcu_data_out[1]~3|datab mcu_data_out[1]~3|B
mcu_data_out[1]~3|datac mcu_data_out[1]~3|C
mcu_data_out[1]~3|datad mcu_data_out[1]~3|D
mcu_data_out[1]~3|combout mcu_data_out[1]~3|LutOut
mcu_data_out[0]~1|dataa mcu_data_out[0]~1|A
mcu_data_out[0]~1|datab mcu_data_out[0]~1|B
mcu_data_out[0]~1|datac mcu_data_out[0]~1|C
mcu_data_out[0]~1|datad mcu_data_out[0]~1|D
mcu_data_out[0]~1|combout mcu_data_out[0]~1|LutOut
mcu_data_out[0]~0|dataa lcd_data_in_q[0]|A
mcu_data_out[0]~0|datab lcd_data_in_q[0]|B
mcu_data_out[0]~0|datac lcd_data_in_q[0]|C
mcu_data_out[0]~0|datad lcd_data_in_q[0]|D
lcd_data_in_q[0]|clk lcd_data_in_q[0]|Clk
lcd_data_in_q[0]|clrn lcd_data_in_q[0]|AsyncReset
lcd_data_in_q[0]|sclr lcd_data_in_q[0]|SyncReset
lcd_data_in_q[0]|sload lcd_data_in_q[0]|SyncLoad
mcu_data_out[0]~0|combout lcd_data_in_q[0]|LutOut
lcd_data_in_q[0]|q lcd_data_in_q[0]|Q
mcu_data_out[6]~12|dataa lcd_data_in_q[6]|A
mcu_data_out[6]~12|datab lcd_data_in_q[6]|B
mcu_data_out[6]~12|datac lcd_data_in_q[6]|C
mcu_data_out[6]~12|datad lcd_data_in_q[6]|D
lcd_data_in_q[6]|clk lcd_data_in_q[6]|Clk
lcd_data_in_q[6]|clrn lcd_data_in_q[6]|AsyncReset
lcd_data_in_q[6]|sclr lcd_data_in_q[6]|SyncReset
lcd_data_in_q[6]|sload lcd_data_in_q[6]|SyncLoad
mcu_data_out[6]~12|combout lcd_data_in_q[6]|LutOut
lcd_data_in_q[6]|q lcd_data_in_q[6]|Q
lcd_data_in_q[0]|ena clken_ctrl_X1_Y19_N0|ClkEn
lcd_data_in_q[6]|ena clken_ctrl_X1_Y19_N0|ClkEn
lcd_data_out_q[1]~feeder|dataa lcd_data_out_q[1]|A
lcd_data_out_q[1]~feeder|datab lcd_data_out_q[1]|B
lcd_data_out_q[1]~feeder|datac lcd_data_out_q[1]|C
lcd_data_out_q[1]~feeder|datad lcd_data_out_q[1]|D
lcd_data_out_q[1]|clk lcd_data_out_q[1]|Clk
lcd_data_out_q[1]|clrn lcd_data_out_q[1]|AsyncReset
lcd_data_out_q[1]~feeder|combout lcd_data_out_q[1]|LutOut
lcd_data_out_q[1]|q lcd_data_out_q[1]|Q
lcd_data_out_q[2]~feeder|dataa lcd_data_out_q[2]|A
lcd_data_out_q[2]~feeder|datab lcd_data_out_q[2]|B
lcd_data_out_q[2]~feeder|datac lcd_data_out_q[2]|C
lcd_data_out_q[2]~feeder|datad lcd_data_out_q[2]|D
lcd_data_out_q[2]|clk lcd_data_out_q[2]|Clk
lcd_data_out_q[2]|clrn lcd_data_out_q[2]|AsyncReset
lcd_data_out_q[2]~feeder|combout lcd_data_out_q[2]|LutOut
lcd_data_out_q[2]|q lcd_data_out_q[2]|Q
|datac lcd_data_out_q[6]|C
lcd_data_out_q[6]|clk lcd_data_out_q[6]|Clk
lcd_data_out_q[6]|clrn lcd_data_out_q[6]|AsyncReset
lcd_data_out_q[6]|sclr lcd_data_out_q[6]|SyncReset
lcd_data_out_q[6]|sload lcd_data_out_q[6]|SyncLoad
lcd_data_out_q[6]|q lcd_data_out_q[6]|Q
lcd_data_out_q[7]~feeder|dataa lcd_data_out_q[7]|A
lcd_data_out_q[7]~feeder|datab lcd_data_out_q[7]|B
lcd_data_out_q[7]~feeder|datac lcd_data_out_q[7]|C
lcd_data_out_q[7]~feeder|datad lcd_data_out_q[7]|D
lcd_data_out_q[7]|clk lcd_data_out_q[7]|Clk
lcd_data_out_q[7]|clrn lcd_data_out_q[7]|AsyncReset
lcd_data_out_q[7]~feeder|combout lcd_data_out_q[7]|LutOut
lcd_data_out_q[7]|q lcd_data_out_q[7]|Q
lcd_data_out_q[0]~feeder|dataa lcd_data_out_q[0]|A
lcd_data_out_q[0]~feeder|datab lcd_data_out_q[0]|B
lcd_data_out_q[0]~feeder|datac lcd_data_out_q[0]|C
lcd_data_out_q[0]~feeder|datad lcd_data_out_q[0]|D
lcd_data_out_q[0]|clk lcd_data_out_q[0]|Clk
lcd_data_out_q[0]|clrn lcd_data_out_q[0]|AsyncReset
lcd_data_out_q[0]~feeder|combout lcd_data_out_q[0]|LutOut
lcd_data_out_q[0]|q lcd_data_out_q[0]|Q
lcd_data_out_q[1]|ena clken_ctrl_X1_Y20_N0|ClkEn
lcd_data_out_q[2]|ena clken_ctrl_X1_Y20_N0|ClkEn
lcd_data_out_q[6]|ena clken_ctrl_X1_Y20_N0|ClkEn
lcd_data_out_q[7]|ena clken_ctrl_X1_Y20_N0|ClkEn
lcd_data_out_q[0]|ena clken_ctrl_X1_Y20_N0|ClkEn
mcu_data_out[7]~14|dataa lcd_data_in_q[7]|A
mcu_data_out[7]~14|datab lcd_data_in_q[7]|B
mcu_data_out[7]~14|datac lcd_data_in_q[7]|C
mcu_data_out[7]~14|datad lcd_data_in_q[7]|D
lcd_data_in_q[7]|clk lcd_data_in_q[7]|Clk
lcd_data_in_q[7]|clrn lcd_data_in_q[7]|AsyncReset
lcd_data_in_q[7]|sclr lcd_data_in_q[7]|SyncReset
lcd_data_in_q[7]|sload lcd_data_in_q[7]|SyncLoad
mcu_data_out[7]~14|combout lcd_data_in_q[7]|LutOut
lcd_data_in_q[7]|q lcd_data_in_q[7]|Q
mcu_data_out[1]~2|dataa lcd_data_in_q[1]|A
mcu_data_out[1]~2|datab lcd_data_in_q[1]|B
mcu_data_out[1]~2|datac lcd_data_in_q[1]|C
mcu_data_out[1]~2|datad lcd_data_in_q[1]|D
lcd_data_in_q[1]|clk lcd_data_in_q[1]|Clk
lcd_data_in_q[1]|clrn lcd_data_in_q[1]|AsyncReset
lcd_data_in_q[1]|sclr lcd_data_in_q[1]|SyncReset
lcd_data_in_q[1]|sload lcd_data_in_q[1]|SyncLoad
mcu_data_out[1]~2|combout lcd_data_in_q[1]|LutOut
lcd_data_in_q[1]|q lcd_data_in_q[1]|Q
lcd_data_in_q[7]|ena clken_ctrl_X1_Y21_N0|ClkEn
lcd_data_in_q[1]|ena clken_ctrl_X1_Y21_N0|ClkEn
mcu_data_out[3]~7|dataa mcu_data_out[3]~7|A
mcu_data_out[3]~7|datab mcu_data_out[3]~7|B
mcu_data_out[3]~7|datac mcu_data_out[3]~7|C
mcu_data_out[3]~7|datad mcu_data_out[3]~7|D
mcu_data_out[3]~7|combout mcu_data_out[3]~7|LutOut
mcu_data_out[4]~9|dataa mcu_data_out[4]~9|A
mcu_data_out[4]~9|datab mcu_data_out[4]~9|B
mcu_data_out[4]~9|datac mcu_data_out[4]~9|C
mcu_data_out[4]~9|datad mcu_data_out[4]~9|D
mcu_data_out[4]~9|combout mcu_data_out[4]~9|LutOut
mcu_data_out[2]~5|dataa mcu_data_out[2]~5|A
mcu_data_out[2]~5|datab mcu_data_out[2]~5|B
mcu_data_out[2]~5|datac mcu_data_out[2]~5|C
mcu_data_out[2]~5|datad mcu_data_out[2]~5|D
mcu_data_out[2]~5|combout mcu_data_out[2]~5|LutOut
mcu_data_out[5]~11|dataa mcu_data_out[5]~11|A
mcu_data_out[5]~11|datab mcu_data_out[5]~11|B
mcu_data_out[5]~11|datac mcu_data_out[5]~11|C
mcu_data_out[5]~11|datad mcu_data_out[5]~11|D
mcu_data_out[5]~11|combout mcu_data_out[5]~11|LutOut
mcu_data_out[2]~4|dataa lcd_data_in_q[2]|A
mcu_data_out[2]~4|datab lcd_data_in_q[2]|B
mcu_data_out[2]~4|datac lcd_data_in_q[2]|C
mcu_data_out[2]~4|datad lcd_data_in_q[2]|D
lcd_data_in_q[2]|clk lcd_data_in_q[2]|Clk
lcd_data_in_q[2]|clrn lcd_data_in_q[2]|AsyncReset
lcd_data_in_q[2]|sclr lcd_data_in_q[2]|SyncReset
lcd_data_in_q[2]|sload lcd_data_in_q[2]|SyncLoad
mcu_data_out[2]~4|combout lcd_data_in_q[2]|LutOut
lcd_data_in_q[2]|q lcd_data_in_q[2]|Q
lcd_data_in_q[2]|ena clken_ctrl_X1_Y24_N0|ClkEn
mcu_data_out[4]~8|dataa lcd_data_in_q[4]|A
mcu_data_out[4]~8|datab lcd_data_in_q[4]|B
mcu_data_out[4]~8|datac lcd_data_in_q[4]|C
mcu_data_out[4]~8|datad lcd_data_in_q[4]|D
lcd_data_in_q[4]|clk lcd_data_in_q[4]|Clk
lcd_data_in_q[4]|clrn lcd_data_in_q[4]|AsyncReset
lcd_data_in_q[4]|sclr lcd_data_in_q[4]|SyncReset
lcd_data_in_q[4]|sload lcd_data_in_q[4]|SyncLoad
mcu_data_out[4]~8|combout lcd_data_in_q[4]|LutOut
lcd_data_in_q[4]|q lcd_data_in_q[4]|Q
lcd_data_out_q[4]~feeder|dataa lcd_data_out_q[4]|A
lcd_data_out_q[4]~feeder|datab lcd_data_out_q[4]|B
lcd_data_out_q[4]~feeder|datac lcd_data_out_q[4]|C
lcd_data_out_q[4]~feeder|datad lcd_data_out_q[4]|D
lcd_data_out_q[4]|clk lcd_data_out_q[4]|Clk
lcd_data_out_q[4]|clrn lcd_data_out_q[4]|AsyncReset
lcd_data_out_q[4]~feeder|combout lcd_data_out_q[4]|LutOut
lcd_data_out_q[4]|q lcd_data_out_q[4]|Q
|datac lcd_data_out_q[3]|C
lcd_data_out_q[3]|clk lcd_data_out_q[3]|Clk
lcd_data_out_q[3]|clrn lcd_data_out_q[3]|AsyncReset
lcd_data_out_q[3]|sclr lcd_data_out_q[3]|SyncReset
lcd_data_out_q[3]|sload lcd_data_out_q[3]|SyncLoad
lcd_data_out_q[3]|q lcd_data_out_q[3]|Q
|datac lcd_data_out_q[5]|C
lcd_data_out_q[5]|clk lcd_data_out_q[5]|Clk
lcd_data_out_q[5]|clrn lcd_data_out_q[5]|AsyncReset
lcd_data_out_q[5]|sclr lcd_data_out_q[5]|SyncReset
lcd_data_out_q[5]|sload lcd_data_out_q[5]|SyncLoad
lcd_data_out_q[5]|q lcd_data_out_q[5]|Q
mcu_data_out[3]~6|dataa lcd_data_in_q[3]|A
mcu_data_out[3]~6|datab lcd_data_in_q[3]|B
mcu_data_out[3]~6|datac lcd_data_in_q[3]|C
mcu_data_out[3]~6|datad lcd_data_in_q[3]|D
lcd_data_in_q[3]|clk lcd_data_in_q[3]|Clk
lcd_data_in_q[3]|clrn lcd_data_in_q[3]|AsyncReset
lcd_data_in_q[3]|sclr lcd_data_in_q[3]|SyncReset
lcd_data_in_q[3]|sload lcd_data_in_q[3]|SyncLoad
mcu_data_out[3]~6|combout lcd_data_in_q[3]|LutOut
lcd_data_in_q[3]|q lcd_data_in_q[3]|Q
mcu_data_out[5]~10|dataa lcd_data_in_q[5]|A
mcu_data_out[5]~10|datab lcd_data_in_q[5]|B
mcu_data_out[5]~10|datac lcd_data_in_q[5]|C
mcu_data_out[5]~10|datad lcd_data_in_q[5]|D
lcd_data_in_q[5]|clk lcd_data_in_q[5]|Clk
lcd_data_in_q[5]|clrn lcd_data_in_q[5]|AsyncReset
lcd_data_in_q[5]|sclr lcd_data_in_q[5]|SyncReset
lcd_data_in_q[5]|sload lcd_data_in_q[5]|SyncLoad
mcu_data_out[5]~10|combout lcd_data_in_q[5]|LutOut
lcd_data_in_q[5]|q lcd_data_in_q[5]|Q
lcd_data_in_q[4]|ena clken_ctrl_X1_Y26_N0|ClkEn
lcd_data_out_q[4]|ena clken_ctrl_X1_Y26_N1|ClkEn
lcd_data_out_q[3]|ena clken_ctrl_X1_Y26_N1|ClkEn
lcd_data_out_q[5]|ena clken_ctrl_X1_Y26_N1|ClkEn
lcd_data_in_q[3]|ena clken_ctrl_X1_Y26_N0|ClkEn
lcd_data_in_q[5]|ena clken_ctrl_X1_Y26_N0|ClkEn
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,112 @@
set_location_assignment -to MCU_D[7] PIN_26
set_location_assignment -to MCU_D[6] PIN_27
set_location_assignment -to MCU_D[5] PIN_29
set_location_assignment -to MCU_D[4] PIN_28
set_location_assignment -to MCU_D[3] PIN_30
set_location_assignment -to MCU_D[2] PIN_33
set_location_assignment -to MCU_D[1] PIN_36
set_location_assignment -to MCU_D[0] PIN_35
set_location_assignment -to MCU_DIR PIN_72
set_location_assignment -to MCU_IO_STBX PIN_41
set_location_assignment -to MCU_LCD_WRX PIN_71
set_location_assignment -to MCU_ADDR PIN_42
set_location_assignment -to MCU_LCD_TE PIN_40
set_location_assignment -to MCU_P2_8 PIN_43
set_location_assignment -to MCU_LCD_RDX PIN_39
set_location_assignment -to TP_U PIN_8
set_location_assignment -to TP_D PIN_6
set_location_assignment -to TP_L PIN_7
set_location_assignment -to TP_R PIN_5
set_location_assignment -to SW_SEL PIN_17
set_location_assignment -to SW_ROT_A PIN_15
set_location_assignment -to SW_ROT_B PIN_16
set_location_assignment -to SW_U PIN_34
set_location_assignment -to SW_D PIN_14
set_location_assignment -to SW_L PIN_37
set_location_assignment -to SW_R PIN_12
set_location_assignment -to LCD_RESETX PIN_100
set_location_assignment -to LCD_RS PIN_3
set_location_assignment -to LCD_WRX PIN_2
set_location_assignment -to LCD_RDX PIN_1
set_location_assignment -to LCD_DB[15] PIN_82
set_location_assignment -to LCD_DB[14] PIN_83
set_location_assignment -to LCD_DB[13] PIN_84
set_location_assignment -to LCD_DB[12] PIN_85
set_location_assignment -to LCD_DB[11] PIN_86
set_location_assignment -to LCD_DB[10] PIN_87
set_location_assignment -to LCD_DB[9] PIN_88
set_location_assignment -to LCD_DB[8] PIN_89
set_location_assignment -to LCD_DB[7] PIN_90
set_location_assignment -to LCD_DB[6] PIN_91
set_location_assignment -to LCD_DB[5] PIN_92
set_location_assignment -to LCD_DB[4] PIN_95
set_location_assignment -to LCD_DB[3] PIN_96
set_location_assignment -to LCD_DB[2] PIN_97
set_location_assignment -to LCD_DB[1] PIN_98
set_location_assignment -to LCD_DB[0] PIN_99
set_location_assignment -to LCD_TE PIN_4
set_location_assignment -to LCD_BACKLIGHT PIN_76
set_location_assignment -to SYSOFF PIN_47
set_location_assignment -to AUDIO_RESETX PIN_57
set_location_assignment -to REF_EN PIN_58
set_location_assignment -to GPS_RESETX PIN_73
set_location_assignment -to GPS_TX_READY PIN_75
set_location_assignment -to GPS_TIMEPULSE PIN_74
set_location_assignment -to DEVICE_RESET PIN_44
set_location_assignment -to DEVICE_RESET_V PIN_38
set_instance_assignment -name IO_STANDARD -to MCU_D[7] "3.3-V LVCMOS"
set_instance_assignment -name IO_STANDARD -to MCU_D[6] "3.3-V LVCMOS"
set_instance_assignment -name IO_STANDARD -to MCU_D[5] "3.3-V LVCMOS"
set_instance_assignment -name IO_STANDARD -to MCU_D[4] "3.3-V LVCMOS"
set_instance_assignment -name IO_STANDARD -to MCU_D[3] "3.3-V LVCMOS"
set_instance_assignment -name IO_STANDARD -to MCU_D[2] "3.3-V LVCMOS"
set_instance_assignment -name IO_STANDARD -to MCU_D[1] "3.3-V LVCMOS"
set_instance_assignment -name IO_STANDARD -to MCU_D[0] "3.3-V LVCMOS"
set_instance_assignment -name IO_STANDARD -to MCU_DIR "3.3-V LVCMOS"
set_instance_assignment -name IO_STANDARD -to MCU_IO_STBX "3.3-V LVCMOS"
set_instance_assignment -name IO_STANDARD -to MCU_LCD_WRX "3.3-V LVCMOS"
set_instance_assignment -name IO_STANDARD -to MCU_ADDR "3.3-V LVCMOS"
set_instance_assignment -name IO_STANDARD -to MCU_LCD_TE "3.3-V LVCMOS"
set_instance_assignment -name IO_STANDARD -to MCU_P2_8 "3.3-V LVCMOS"
set_instance_assignment -name IO_STANDARD -to MCU_LCD_RDX "3.3-V LVCMOS"
set_instance_assignment -name IO_STANDARD -to TP_U "3.3-V LVCMOS"
set_instance_assignment -name IO_STANDARD -to TP_D "3.3-V LVCMOS"
set_instance_assignment -name IO_STANDARD -to TP_L "3.3-V LVCMOS"
set_instance_assignment -name IO_STANDARD -to TP_R "3.3-V LVCMOS"
set_instance_assignment -name IO_STANDARD -to SW_SEL "3.3V Schmitt Trigger Input"
set_instance_assignment -name IO_STANDARD -to SW_ROT_A "3.3V Schmitt Trigger Input"
set_instance_assignment -name IO_STANDARD -to SW_ROT_B "3.3V Schmitt Trigger Input"
set_instance_assignment -name IO_STANDARD -to SW_U "3.3V Schmitt Trigger Input"
set_instance_assignment -name IO_STANDARD -to SW_D "3.3V Schmitt Trigger Input"
set_instance_assignment -name IO_STANDARD -to SW_L "3.3V Schmitt Trigger Input"
set_instance_assignment -name IO_STANDARD -to SW_R "3.3V Schmitt Trigger Input"
set_instance_assignment -name IO_STANDARD -to LCD_RESETX "3.3-V LVCMOS"
set_instance_assignment -name IO_STANDARD -to LCD_RS "3.3-V LVCMOS"
set_instance_assignment -name IO_STANDARD -to LCD_WRX "3.3-V LVCMOS"
set_instance_assignment -name IO_STANDARD -to LCD_RDX "3.3-V LVCMOS"
set_instance_assignment -name IO_STANDARD -to LCD_DB[15] "3.3-V LVCMOS"
set_instance_assignment -name IO_STANDARD -to LCD_DB[14] "3.3-V LVCMOS"
set_instance_assignment -name IO_STANDARD -to LCD_DB[13] "3.3-V LVCMOS"
set_instance_assignment -name IO_STANDARD -to LCD_DB[12] "3.3-V LVCMOS"
set_instance_assignment -name IO_STANDARD -to LCD_DB[11] "3.3-V LVCMOS"
set_instance_assignment -name IO_STANDARD -to LCD_DB[10] "3.3-V LVCMOS"
set_instance_assignment -name IO_STANDARD -to LCD_DB[9] "3.3-V LVCMOS"
set_instance_assignment -name IO_STANDARD -to LCD_DB[8] "3.3-V LVCMOS"
set_instance_assignment -name IO_STANDARD -to LCD_DB[7] "3.3-V LVCMOS"
set_instance_assignment -name IO_STANDARD -to LCD_DB[6] "3.3-V LVCMOS"
set_instance_assignment -name IO_STANDARD -to LCD_DB[5] "3.3-V LVCMOS"
set_instance_assignment -name IO_STANDARD -to LCD_DB[4] "3.3-V LVCMOS"
set_instance_assignment -name IO_STANDARD -to LCD_DB[3] "3.3-V LVCMOS"
set_instance_assignment -name IO_STANDARD -to LCD_DB[2] "3.3-V LVCMOS"
set_instance_assignment -name IO_STANDARD -to LCD_DB[1] "3.3-V LVCMOS"
set_instance_assignment -name IO_STANDARD -to LCD_DB[0] "3.3-V LVCMOS"
set_instance_assignment -name IO_STANDARD -to LCD_TE "3.3-V LVCMOS"
set_instance_assignment -name IO_STANDARD -to LCD_BACKLIGHT "3.3-V LVCMOS"
set_instance_assignment -name IO_STANDARD -to SYSOFF "3.3-V LVCMOS"
set_instance_assignment -name IO_STANDARD -to AUDIO_RESETX "3.3-V LVCMOS"
set_instance_assignment -name IO_STANDARD -to REF_EN "3.3-V LVCMOS"
set_instance_assignment -name IO_STANDARD -to GPS_RESETX "3.3-V LVCMOS"
set_instance_assignment -name IO_STANDARD -to GPS_TX_READY "3.3-V LVCMOS"
set_instance_assignment -name IO_STANDARD -to GPS_TIMEPULSE "3.3-V LVCMOS"
set_instance_assignment -name IO_STANDARD -to DEVICE_RESET "3.3-V LVCMOS"
set_instance_assignment -name IO_STANDARD -to DEVICE_RESET_V "3.3-V LVCMOS"
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,125 @@
ssWJbg*O-TSHdTjR
^ykYUbZxhrN\/z*-xm-x%`T`=`t
dvaLDM\AMw:PPKa/udH;9|0c0g0w
n[tI{:2nE=y+CYTwlSOHfH<H<
^G`"ZxhrN\/z*-xm-x%`T`Q`!
d(J_A[~2aW[Ag\5RK4jN$%a%i%:
;^':y?GyRP[qV/udH;9|0]0c0c
6wnbVgw#6,-;rD&)jR)j ENEIEI
o={ 0 `VZ'35qBwqBoW&WMW<
G$<H2Hp.L5lFXMk1MkGu u u5
q+9SoSuTRR`%*1i|1iqtHtHtR
OA.-i-F,BmVCRlSwlSOH H Hm
^ftYZYjSK|%$?p2Wp2^)M)M)|
(`VmQm34^-|MvDd{Dd(8-8-8-
%sf)i)B@SUoz*-xm-x%`U`t`!
dP0vAvh,zw] cG cdKsK1Ks
cAMn9nX-}J6~KpRKpc:}:O:f
$f TATq0|n5LjN4jN$%C%i%i
;|{+y+>#vBe29at9a;CkCvC]
|>*qKqx4w /B;9H;9|0<0c0g
6wnbnV{.MD&)jR)j ECEIEf
o={ 0 `V>'35qBwqBoWXWMW&
G$<H2Hp.NlFXMk1MkGu`u u`
q+9SoSuTG`%*1i|1iqtJtHtH
OA.-i*-XCRlSwlSOHBH HB
^ftYZxhrN\/z*-xm-x%`=`t`!
dP0vAt_] cG cdK+K!K+
cAMn9a\5RK4jN$%,%|%{
;|{+y"RGe29at9a;CwCvC_
|.*hK[qqZ/udH;9|0w0g0<
7w4bn,yDP5R)j EdECEf
oP{+0 VZ'35qBwqBoWMWZW&
G0<V2H.LlFXMk1MkGu u5u`
qa9&oSTN`%*1i|1iqtHtltl
On.!i-,yVCRlSwlSOHyH<H
^]tkZYSM%$?p2Wp2^)|);)m
(%VbQm47|MvDd{Dd(8"8C8"
%8fGi)@5oz*-xm-x%`Q`!`S
d20nAv,gw] cG cdK!K+K+
cqM[9D@9gaX"6!`RKpc:v:&:}
$7 cAG+A"Jq-5RK4jNQ/BQN`/$%,%C%{
;8{ y|{+yR+Gefpt9a;C]C_C_
|.*hK>*qKZqo/udH;98zv89+z|0=0n0g
7w4b6wnbr[35qBwqBoWRWZW<
G0<V2$<H2ynKFv71MkGu&u`uw
qa9&o+9Sox3_%8\|1i!C?!icCqt^tNtR
On.!i(mi:CYTwlSOH;H<H
^xhZQNXz*-xm-x%`T`=`Q
d_:Av]Q{G cdK+KsKz
cgQ9A6!`RKpc:O:&:O
$"lAM+JAs5RK4jN$%,%C%C
;:"yR-?y>efpt9a;C_CkC!
|1tKZ/udH;9|0g0n0g
($b([=3\HwqBoWZW&WM
GOy2VFv71MkGu u5uL
q=M=>..%*1i|1iqt"tltR
O+(i-CRlSwlSOH<HyH
^P`Zf$?p2Wp2^);)|)B
(y6QLMvDd{Dd(8C8"8<
%\EiGz*-xm-x%`!`Q`5
d938{|j`d|NAQN`/A-{A6{:Ad,$%|%|%,
;S=Mp&d/(Njb*jk3bZfb_fab9 ECEfE
oK7*Hf1y'*io!icCo_RoMNlo5lqtHtJtl
OW{ITq?gs=dQGdS_Q!^Qg<^Q/C(878"8C
%w{#pg|:3`p9^pCV9"S9T}O9_&c:v:}:&
$1 oKQ`r=/9K89+zKo3KVn]KCg|0<0n0g
2)}P&bko7yk2hGu`u`uLw
q!C?-TiqS?#iXBitB;i8<OHyHyH<
^q-R=0QGdS_Q!^Qg^7Q/^(8"8"8^
%gWk:{A|cjVAYzAWzeA\+dK!KzK+
c^V2|KAQN`/A-{A6C,Ad,$%i%|%,
;&4}/dK89+zKo3KVn3KCg|0w0<0g
*3JoH0fB1Y0L<0"&M0uZoWRW&WZ
GgJR*\o!icCo_RoMN"o5lqtJtNtl
Oq#0g0Zq2&-Z1KZamNZ[K^)|)m)K
(_GTQkwGj_. UdQ)(8"8"8@
%WgFiFwxwi2pi'@!o%`Q`S`SU
dV|UAU9c9AQ{AX,zwdK&K!K&
cV^l9l*p*9!`9'-}Jc:v:}:Sv
$/Q\A\1N1ARKAv0|n$%|%C%|
;4&%y%SaSyfpy5#vB;C!CkC]
|z8)K)X9XKudKA4w |0<0n0c
3*}b}2j2bP5bK{.M ECEfEU
oYfs0sKBK0\H0xV>'oWRWXW^
GJg{2{bkb2XMk2h.5lGu u`uLj
qC!AoABiBo*1io<TR`qtHtJtl
O#q/i/WSWiRlSiJ,mVOH HyH;
^-q.Z. 2 Z?p2Z<S|%^)|)m)@
(_GTQTwdwQvDdQ)4-|(8"8<8R
%WgFiFwxwi*-xi'@Uo%`Q`=`=
dV|UAU9c9A cAX,rwdK1K!Kr
cV^l9l*p*9~Kp9'-iJc:O:f:S&
$/Q\A`r=/9KA|0<0<03
3*}bko7yk2hF5Gu`u`u&
qO!1oABiBo*1iTl`%RqtHtRtR
OQqli/WSWiRlS,BVCyOH HBHB
^DqpZ. 2 Z?p2Sm%$B^)M)m)@
(fGDQTwdwQvDd4"|MA(8-8<8R
%vg-iFwxwi*-x@toz;%`t`=`St
d^| AU9c9A c,&w]zzdK1KsKz&
cr^K9l*p*9~Kp-#J6Sfc:O:S:u
$VQjA\1N1ALjN09n5{:$%i%{%9
;d/GKN5bK ECECEfC
o7*HfY5Ks0fB1Y0L<0"<RoWXWXW<
G'-7gJXb{2gkIJ2KL2}L\Gu`uLuL
q4$\!C*BAo!icCo_RoMNlqtHtJtR
O{ITq#RW/iqS?#iXBitmBOH;HyHB
^sw0q-? .Zq2&-Z1KZamM^)B)m)K
(cH0G_vwTQGdS_Q!^Qg<R(8"8<8^
%{#pg|:3`p9^pCV9"S9TSvc:f:f:&
$ oKQ`r=/9K89+zKo3KV3p|0<030g
1X5*ko7yk2gkIJ2KL2}w5Gu u`u5
q4$\!c-{g2Zq2&-Z1KZamK^)B)|);
(cH0GSY{:cA|cjVAYzAWs1dK&KsK+
cd0`^C| ray&ad4yGwy kg;C!CkC_
|(k(BGGKA|0<0<0n
jRbK{ M ECECEa
oBw0xV<'oWXWXW<Z
Gk12h.wlGu`u`u
qi|o<TJ`qtJtJtRH
OSwiJ,yVC<OHyHyHy
^2WZ<SM%^)|)|)B
(d{Q)47|(8"8"8R
%xmi'@5o%`Q`Q`SU
dcGAX,gwdK!K!Kzz
File diff suppressed because it is too large Load Diff

Some files were not shown because too many files have changed in this diff Show More