mirror of
https://github.com/portapack-mayhem/mayhem-firmware.git
synced 2026-09-15 19:13:00 +00:00
Compare commits
29 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 64f8158134 | |||
| 59f72cbff1 | |||
| 31c53dc455 | |||
| ff12d06757 | |||
| 5b540fa659 | |||
| 9cccfa63e5 | |||
| 6c838256df | |||
| c8f236a708 | |||
| 4641dcb449 | |||
| 458a6634bf | |||
| b8a64598ba | |||
| 09dff447de | |||
| 079329fc6c | |||
| 674059801d | |||
| 5020e5bd28 | |||
| c31fef0535 | |||
| a153cd741d | |||
| 5851b47f99 | |||
| 83a488e5b9 | |||
| 110a543ed3 | |||
| da5322765d | |||
| 8df05a57ea | |||
| bea9f444c6 | |||
| abd6177303 | |||
| d6a9c74665 | |||
| 5bb23b636e | |||
| d5296c6ac3 | |||
| c9863187d6 | |||
| 13e4f225ea |
+2
-2
@@ -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--------")
|
||||
|
||||
|
||||
@@ -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="It’s 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="It’s 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:  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:  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).
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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{
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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 */
|
||||
@@ -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__*/
|
||||
@@ -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();
|
||||
|
||||
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
|
||||
|
||||
}
|
||||
|
||||
@@ -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
|
||||
};
|
||||
}
|
||||
@@ -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
|
||||
@@ -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
@@ -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
|
||||
};
|
||||
}
|
||||
@@ -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
|
||||
|
||||
|
||||
*/
|
||||
@@ -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
@@ -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
@@ -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
@@ -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
|
||||
@@ -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";
|
||||
|
||||
@@ -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__ */
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
@@ -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
|
||||
@@ -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;
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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}};
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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__*/
|
||||
@@ -276,7 +276,7 @@ class APRSPacket {
|
||||
if (!is_digits(sub)) {
|
||||
return 0;
|
||||
} else {
|
||||
return std::stoi(sub);
|
||||
return atoi(sub.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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*)®, 2, buff, len)) return 0;
|
||||
return 0; // shoud have an error handler
|
||||
}
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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,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;
|
||||
|
||||
@@ -58,7 +58,10 @@ enum LangConsts {
|
||||
LANG_RESUME,
|
||||
LANG_FLOOD,
|
||||
LANG_SHOWQR,
|
||||
LANG_SAVE
|
||||
LANG_SAVE,
|
||||
LANG_LOCK,
|
||||
LANG_UNLOCK,
|
||||
LANG_BROWSE
|
||||
};
|
||||
|
||||
class LanguageHelper {
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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)
|
||||
Regular → Executable
BIN
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -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;
|
||||
@@ -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
Binary file not shown.
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Binary file not shown.
Binary file not shown.
@@ -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
Reference in New Issue
Block a user