mirror of
https://github.com/portapack-mayhem/mayhem-firmware.git
synced 2026-09-16 03:22:59 +00:00
Compare commits
25 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| b8a64598ba | |||
| 09dff447de | |||
| 079329fc6c | |||
| 674059801d | |||
| 5020e5bd28 | |||
| c31fef0535 | |||
| a153cd741d | |||
| 5851b47f99 | |||
| 83a488e5b9 | |||
| 110a543ed3 | |||
| da5322765d | |||
| 8df05a57ea | |||
| bea9f444c6 | |||
| abd6177303 | |||
| d6a9c74665 | |||
| 5bb23b636e | |||
| d5296c6ac3 | |||
| c9863187d6 | |||
| 13e4f225ea | |||
| 0df2c085a1 | |||
| a4c2e155e5 | |||
| c90f0944b1 | |||
| 7a38b04192 | |||
| 9f84ccbe1f | |||
| cb3774ad81 |
+6
-2
@@ -23,6 +23,10 @@ cmake_policy(SET CMP0005 NEW)
|
||||
|
||||
set(CMAKE_TOOLCHAIN_FILE ${CMAKE_CURRENT_LIST_DIR}/firmware/toolchain-arm-cortex-m.cmake)
|
||||
|
||||
set(CMAKE_COLOR_MAKEFILE ON)
|
||||
|
||||
add_compile_options(-fdiagnostics-color=always)
|
||||
|
||||
option(USE_CCACHE "Enable ccache, please keep an eye on this because sometimes it's not quite stable and generated unusable binary" OFF)
|
||||
|
||||
project(portapack-h1)
|
||||
@@ -84,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/BKKTWY) (clone) with a custom [3d printed case](https://github.com/portapack-mayhem/mayhem-firmware/wiki/H2-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
|
||||
|
||||
@@ -29,9 +29,9 @@ This repository expands upon the previous work by many people and aims to consta
|
||||
|
||||
: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: 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/BKKTWY), 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: 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/CB3JC5), 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;
|
||||
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -213,6 +213,11 @@ const char* WeatherView::getWeatherSensorTypeName(FPROTO_WEATHER_SENSOR type) {
|
||||
return "EmosE601x";
|
||||
case FPW_SolightTE44:
|
||||
return "SolightTE44";
|
||||
case FPW_Bresser3CH:
|
||||
case FPW_Bresser3CH_V1:
|
||||
return "Bresser3CH";
|
||||
case FPW_Vauno_EN8822:
|
||||
return "Vauno EN8822";
|
||||
case FPW_Invalid:
|
||||
default:
|
||||
return "Unknown";
|
||||
@@ -532,6 +537,42 @@ WeatherRecentEntry WeatherView::process_data(const WeatherDataMessage* data) {
|
||||
i16 |= 0xf000;
|
||||
}
|
||||
ret.temp = (float)i16 / 10.0;
|
||||
break;
|
||||
case FPW_Bresser3CH:
|
||||
ret.id = (data->decode_data >> 28) & 0xff;
|
||||
ret.channel = ((data->decode_data >> 27) & 0x01) | (((data->decode_data >> 26) & 0x01) << 1);
|
||||
// ret.btn = ((data->decode_data >> 25) & 0x1);
|
||||
ret.battery_low = ((data->decode_data >> 24) & 0x1);
|
||||
i16 = (data->decode_data >> 12) & 0x0fff;
|
||||
/* Handle signed data */
|
||||
if (i16 & 0x0800) {
|
||||
i16 |= 0xf000;
|
||||
}
|
||||
ret.temp = (float)i16 / 10.0;
|
||||
ret.humidity = data->decode_data & 0xff;
|
||||
break;
|
||||
case FPW_Bresser3CH_V1:
|
||||
ret.id = (data->decode_data >> 32) & 0xff;
|
||||
ret.battery_low = ((data->decode_data >> 31) & 0x1);
|
||||
// ret.btn = (data->decode_data >> 30) & 0x1;
|
||||
ret.channel = (data->decode_data >> 28) & 0x3;
|
||||
ret.temp = (data->decode_data >> 16) & 0xfff;
|
||||
ret.temp = FProtoGeneral::locale_fahrenheit_to_celsius((float)(ret.temp - 900) / 10.0);
|
||||
ret.humidity = (data->decode_data >> 8) & 0xff;
|
||||
break;
|
||||
|
||||
case FPW_Vauno_EN8822:
|
||||
ret.id = (data->decode_data >> 34) & 0xff;
|
||||
ret.battery_low = (data->decode_data >> 33) & 0x01;
|
||||
ret.channel = ((data->decode_data >> 30) & 0x03);
|
||||
i16 = (data->decode_data >> 18) & 0x0fff;
|
||||
/* Handle signed data */
|
||||
if (i16 & 0x0800) {
|
||||
i16 |= 0xf000;
|
||||
}
|
||||
ret.temp = (float)i16 / 10.0;
|
||||
ret.humidity = (data->decode_data >> 11) & 0x7f;
|
||||
|
||||
break;
|
||||
case FPW_Invalid:
|
||||
default:
|
||||
|
||||
+313
@@ -0,0 +1,313 @@
|
||||
// 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"
|
||||
|
||||
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 = 500000;
|
||||
|
||||
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_chaos_tx() {
|
||||
if (is_active()) {
|
||||
stop_tx();
|
||||
return;
|
||||
}
|
||||
|
||||
const std::filesystem::path chaos_file_path = cvsfiles_dir / "chaos.c16";
|
||||
const uint32_t sample_rate = 500000;
|
||||
|
||||
File capture_file;
|
||||
auto open_error = capture_file.open(chaos_file_path);
|
||||
if (open_error) {
|
||||
file_error(chaos_file_path,
|
||||
"Cannot open CHAOS.C16.\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(chaos_file_path);
|
||||
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(chaos_file_path)) {
|
||||
file_error(chaos_file_path,
|
||||
"Cannot read CHAOS.C16.\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::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();
|
||||
audio::output::stop();
|
||||
ready_signal = false;
|
||||
thread_sync_complete = 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&) {
|
||||
start_chaos_tx();
|
||||
};
|
||||
|
||||
button_stop.on_select = [this](Button&) {
|
||||
if (is_active()) {
|
||||
stop_tx();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
CVSSpamView::~CVSSpamView() {
|
||||
stop_tx();
|
||||
baseband::shutdown();
|
||||
}
|
||||
|
||||
} // namespace ui::external_app::cvs_spam
|
||||
+115
@@ -0,0 +1,115 @@
|
||||
// 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"
|
||||
#include "audio.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;
|
||||
|
||||
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_chaos_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 (is_active()) {
|
||||
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");
|
||||
}
|
||||
}};
|
||||
};
|
||||
|
||||
} // 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};
|
||||
}
|
||||
+10
-1
@@ -106,7 +106,14 @@ 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
|
||||
|
||||
#cvs_spam
|
||||
external/cvs_spam/main.cpp
|
||||
external/cvs_spam/cvs_spam.cpp
|
||||
)
|
||||
|
||||
set(EXTAPPLIST
|
||||
@@ -128,6 +135,7 @@ set(EXTAPPLIST
|
||||
foxhunt_rx
|
||||
audio_test
|
||||
wardrivemap
|
||||
cvs_spam
|
||||
tpmsrx
|
||||
protoview
|
||||
adsbtx
|
||||
@@ -135,4 +143,5 @@ set(EXTAPPLIST
|
||||
sstvtx
|
||||
random_password
|
||||
#acars_rx
|
||||
shoppingcart_lock
|
||||
)
|
||||
|
||||
+12
-2
@@ -48,6 +48,8 @@ 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
|
||||
}
|
||||
|
||||
SECTIONS
|
||||
@@ -166,7 +168,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 +205,16 @@ 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
|
||||
|
||||
}
|
||||
|
||||
@@ -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";
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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"
|
||||
@@ -149,6 +148,7 @@ const NavigationView::AppList NavigationView::appList = {
|
||||
{"search", "Search", RX, Color::yellow(), &bitmap_icon_search, new ViewFactory<SearchView>()},
|
||||
{"subghzd", "SubGhzD", RX, Color::yellow(), &bitmap_icon_remote, new ViewFactory<SubGhzDView>()},
|
||||
{"weather", "Weather", RX, Color::green(), &bitmap_icon_thermometer, new ViewFactory<WeatherView>()},
|
||||
//{"fskrx", "FSK RX", RX, Color::yellow(), &bitmap_icon_remote, new ViewFactory<FskxRxMainView>()}, //for JT
|
||||
//{"dmr", "DMR", RX, Color::dark_grey(), &bitmap_icon_dmr, new ViewFactory<NotImplementedView>()},
|
||||
//{"sigfox", "SIGFOX", RX, Color::dark_grey(), &bitmap_icon_fox, new ViewFactory<NotImplementedView>()},
|
||||
//{"lora", "LoRa", RX, Color::dark_grey(), &bitmap_icon_lora, new ViewFactory<NotImplementedView>()},
|
||||
@@ -308,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();
|
||||
};
|
||||
@@ -383,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()) {
|
||||
@@ -416,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();
|
||||
}
|
||||
|
||||
@@ -723,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 **************************************************************/
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -0,0 +1,197 @@
|
||||
|
||||
#ifndef __FPROTO_Bresser3ch_H__
|
||||
#define __FPROTO_Bresser3ch_H__
|
||||
|
||||
#include "weatherbase.hpp"
|
||||
|
||||
#define BRESSER_V0_DATA 36
|
||||
#define BRESSER_V0_DATA_AND_TAIL 52
|
||||
#define BRESSER_V1_DATA 40
|
||||
|
||||
typedef enum {
|
||||
Bresser3chDecoderStepReset = 0,
|
||||
Bresser3chDecoderStepV0SaveDuration,
|
||||
Bresser3chDecoderStepV0CheckDuration,
|
||||
Bresser3chDecoderStepV0TailCheckDuration,
|
||||
Bresser3chDecoderStepV1PreambleDn,
|
||||
Bresser3chDecoderStepV1PreambleUp,
|
||||
Bresser3chDecoderStepV1SaveDuration,
|
||||
Bresser3chDecoderStepV1CheckDuration,
|
||||
} Bresser3chDecoderStepV1;
|
||||
|
||||
class FProtoWeatheBresser3CH : public FProtoWeatherBase {
|
||||
public:
|
||||
FProtoWeatheBresser3CH() {
|
||||
sensorType = FPW_Bresser3CH;
|
||||
}
|
||||
|
||||
void feed(bool level, uint32_t duration) {
|
||||
switch (parser_step) {
|
||||
case Bresser3chDecoderStepReset:
|
||||
if (level && DURATION_DIFF(duration, te_short * 3) < te_delta) {
|
||||
te_last = duration;
|
||||
parser_step = Bresser3chDecoderStepV1PreambleDn;
|
||||
decode_data = 0;
|
||||
decode_count_bit = 0;
|
||||
} else if ((!level) && duration >= te_long) {
|
||||
parser_step = Bresser3chDecoderStepV0SaveDuration;
|
||||
decode_data = 0;
|
||||
decode_count_bit = 0;
|
||||
}
|
||||
break;
|
||||
|
||||
case Bresser3chDecoderStepV0SaveDuration:
|
||||
if (level) {
|
||||
te_last = duration;
|
||||
if (decode_count_bit < BRESSER_V0_DATA) {
|
||||
parser_step = Bresser3chDecoderStepV0CheckDuration;
|
||||
} else {
|
||||
parser_step = Bresser3chDecoderStepV0TailCheckDuration;
|
||||
}
|
||||
} else {
|
||||
parser_step = Bresser3chDecoderStepReset;
|
||||
}
|
||||
break;
|
||||
|
||||
case Bresser3chDecoderStepV0CheckDuration:
|
||||
if (!level) {
|
||||
if (DURATION_DIFF(te_last, te_short) < te_delta) {
|
||||
if (DURATION_DIFF(duration, te_short * 2) < te_delta) {
|
||||
subghz_protocol_blocks_add_bit(0);
|
||||
parser_step = Bresser3chDecoderStepV0SaveDuration;
|
||||
} else if (
|
||||
DURATION_DIFF(duration, te_short * 4) < te_delta) {
|
||||
subghz_protocol_blocks_add_bit(1);
|
||||
parser_step = Bresser3chDecoderStepV0SaveDuration;
|
||||
} else
|
||||
parser_step = Bresser3chDecoderStepReset;
|
||||
} else
|
||||
parser_step = Bresser3chDecoderStepReset;
|
||||
} else
|
||||
parser_step = Bresser3chDecoderStepReset;
|
||||
break;
|
||||
|
||||
case Bresser3chDecoderStepV0TailCheckDuration:
|
||||
if (!level) {
|
||||
if (duration >= te_long) {
|
||||
if (decode_count_bit == BRESSER_V0_DATA_AND_TAIL &&
|
||||
ws_protocol_bresser_3ch_check_v0()) {
|
||||
decode_count_bit = BRESSER_V0_DATA;
|
||||
sensorType = FPW_Bresser3CH;
|
||||
// ws_protocol_bresser_3ch_extract_data_v0();
|
||||
if (callback) {
|
||||
callback(this);
|
||||
}
|
||||
}
|
||||
decode_data = 0;
|
||||
decode_count_bit = 0;
|
||||
parser_step = Bresser3chDecoderStepReset;
|
||||
} else if (
|
||||
decode_count_bit < BRESSER_V0_DATA_AND_TAIL &&
|
||||
DURATION_DIFF(te_last, te_short) < te_delta &&
|
||||
DURATION_DIFF(duration, te_short * 2) < te_delta) {
|
||||
decode_count_bit++;
|
||||
parser_step = Bresser3chDecoderStepV0SaveDuration;
|
||||
} else
|
||||
parser_step = Bresser3chDecoderStepReset;
|
||||
} else
|
||||
parser_step = Bresser3chDecoderStepReset;
|
||||
break;
|
||||
|
||||
case Bresser3chDecoderStepV1PreambleDn:
|
||||
if ((!level) && DURATION_DIFF(duration, te_short_v1 * 3) < te_delta) {
|
||||
if (DURATION_DIFF(te_last, te_short_v1 * 12) < te_delta * 2) {
|
||||
// End of sync after 4*750 (12*250) high values, start reading the message
|
||||
parser_step = Bresser3chDecoderStepV1SaveDuration;
|
||||
} else {
|
||||
parser_step = Bresser3chDecoderStepV1PreambleUp;
|
||||
}
|
||||
} else {
|
||||
parser_step = Bresser3chDecoderStepReset;
|
||||
}
|
||||
break;
|
||||
|
||||
case Bresser3chDecoderStepV1PreambleUp:
|
||||
if (level && DURATION_DIFF(duration, te_short_v1 * 3) < te_delta) {
|
||||
te_last = te_last + duration;
|
||||
parser_step = Bresser3chDecoderStepV1PreambleDn;
|
||||
} else {
|
||||
parser_step = Bresser3chDecoderStepReset;
|
||||
}
|
||||
break;
|
||||
|
||||
case Bresser3chDecoderStepV1SaveDuration:
|
||||
if (decode_count_bit == BRESSER_V1_DATA) {
|
||||
if (ws_protocol_bresser_3ch_check_v1()) {
|
||||
// ws_protocol_bresser_3ch_extract_data_v1(&instance->generic);
|
||||
sensorType = FPW_Bresser3CH_V1;
|
||||
if (callback) {
|
||||
callback(this);
|
||||
}
|
||||
}
|
||||
decode_data = 0;
|
||||
decode_count_bit = 0;
|
||||
parser_step = Bresser3chDecoderStepReset;
|
||||
} else if (level) {
|
||||
te_last = duration;
|
||||
parser_step = Bresser3chDecoderStepV1CheckDuration;
|
||||
} else {
|
||||
parser_step = Bresser3chDecoderStepReset;
|
||||
}
|
||||
break;
|
||||
|
||||
case Bresser3chDecoderStepV1CheckDuration:
|
||||
if (!level) {
|
||||
if (DURATION_DIFF(te_last, te_short_v1) < te_delta && DURATION_DIFF(duration, te_long_v1) < te_delta) {
|
||||
subghz_protocol_blocks_add_bit(0);
|
||||
parser_step = Bresser3chDecoderStepV1SaveDuration;
|
||||
} else if (
|
||||
DURATION_DIFF(te_last, te_long_v1) < te_delta && DURATION_DIFF(duration, te_short_v1) < te_delta) {
|
||||
subghz_protocol_blocks_add_bit(1);
|
||||
parser_step = Bresser3chDecoderStepV1SaveDuration;
|
||||
} else
|
||||
parser_step = Bresser3chDecoderStepReset;
|
||||
} else
|
||||
parser_step = Bresser3chDecoderStepReset;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
uint32_t te_short = 475;
|
||||
uint32_t te_long = 3900;
|
||||
uint32_t te_delta = 150;
|
||||
|
||||
uint32_t te_short_v1 = 250;
|
||||
uint32_t te_long_v1 = 500;
|
||||
|
||||
bool ws_protocol_bresser_3ch_check_v0() {
|
||||
if (!decode_data) return false;
|
||||
// No CRC, so better sanity checks here
|
||||
if (((decode_data >> 8) & 0x0f) != 0x0f) return false; // separator not 0xf
|
||||
if (((decode_data >> 28) & 0xff) == 0xff) return false; // ID only ones?
|
||||
if (((decode_data >> 28) & 0xff) == 0x00) return false; // ID only zeroes?
|
||||
if (((decode_data >> 25) & 0x0f) == 0x0f) return false; // flags only ones?
|
||||
if (((decode_data >> 25) & 0x0f) == 0x00) return false; // flags only zeroes?
|
||||
if (((decode_data >> 12) & 0x0fff) == 0x0fff)
|
||||
return false; // temperature maxed out?
|
||||
if ((decode_data & 0xff) < 20)
|
||||
return false; // humidity percentage less than 20?
|
||||
if ((decode_data & 0xff) > 95)
|
||||
return false; // humidity percentage more than 95?
|
||||
return true;
|
||||
}
|
||||
bool ws_protocol_bresser_3ch_check_v1() {
|
||||
if (!decode_data) return false;
|
||||
|
||||
uint8_t sum = (((decode_data >> 32) & 0xff) +
|
||||
((decode_data >> 24) & 0xff) +
|
||||
((decode_data >> 16) & 0xff) +
|
||||
((decode_data >> 8) & 0xff)) &
|
||||
0xff;
|
||||
|
||||
return (decode_data & 0xff) == sum;
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,88 @@
|
||||
|
||||
#ifndef __FPROTO_VAUNO_EN8822_H__
|
||||
#define __FPROTO_VAUNO_EN8822_H__
|
||||
|
||||
#include "weatherbase.hpp"
|
||||
|
||||
typedef enum {
|
||||
VaunoEN8822CDecoderStepReset = 0,
|
||||
VaunoEN8822CDecoderStepSaveDuration,
|
||||
VaunoEN8822CDecoderStepCheckDuration,
|
||||
} VaunoEN8822CDecoderStep;
|
||||
|
||||
class FProtoWeatherVaunoEN8822 : public FProtoWeatherBase {
|
||||
public:
|
||||
FProtoWeatherVaunoEN8822() {
|
||||
sensorType = FPW_Vauno_EN8822;
|
||||
}
|
||||
|
||||
void feed(bool level, uint32_t duration) override {
|
||||
switch (parser_step) {
|
||||
case VaunoEN8822CDecoderStepReset:
|
||||
if ((!level) && DURATION_DIFF(duration, te_long * 4) < te_delta) {
|
||||
parser_step = VaunoEN8822CDecoderStepSaveDuration;
|
||||
decode_data = 0;
|
||||
decode_count_bit = 0;
|
||||
}
|
||||
break;
|
||||
|
||||
case VaunoEN8822CDecoderStepSaveDuration:
|
||||
if (level) {
|
||||
te_last = duration;
|
||||
parser_step = VaunoEN8822CDecoderStepCheckDuration;
|
||||
} else {
|
||||
parser_step = VaunoEN8822CDecoderStepReset;
|
||||
}
|
||||
break;
|
||||
|
||||
case VaunoEN8822CDecoderStepCheckDuration:
|
||||
if (!level) {
|
||||
if (DURATION_DIFF(te_last, te_short) < te_delta) {
|
||||
if (DURATION_DIFF(duration, te_long * 2) < te_delta) {
|
||||
subghz_protocol_blocks_add_bit(1);
|
||||
parser_step = VaunoEN8822CDecoderStepSaveDuration;
|
||||
} else if (DURATION_DIFF(duration, te_long) < te_delta) {
|
||||
subghz_protocol_blocks_add_bit(0);
|
||||
parser_step = VaunoEN8822CDecoderStepSaveDuration;
|
||||
} else if (DURATION_DIFF(duration, te_long * 4) < te_delta) {
|
||||
parser_step = VaunoEN8822CDecoderStepReset;
|
||||
if (decode_count_bit == min_count_bit_for_found && ws_protocol_vauno_en8822c_check()) {
|
||||
// ws_protocol_vauno_en8822c_extract_data(&instance->generic);
|
||||
|
||||
if (callback) {
|
||||
callback(this);
|
||||
}
|
||||
} else if (decode_count_bit == 1) {
|
||||
parser_step = VaunoEN8822CDecoderStepSaveDuration;
|
||||
}
|
||||
decode_data = 0;
|
||||
decode_count_bit = 0;
|
||||
} else
|
||||
parser_step = VaunoEN8822CDecoderStepReset;
|
||||
} else
|
||||
parser_step = VaunoEN8822CDecoderStepReset;
|
||||
} else
|
||||
parser_step = VaunoEN8822CDecoderStepReset;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
// timing values
|
||||
uint32_t te_short = 500;
|
||||
uint32_t te_long = 1940;
|
||||
uint32_t te_delta = 150;
|
||||
uint32_t min_count_bit_for_found = 42;
|
||||
|
||||
bool ws_protocol_vauno_en8822c_check() {
|
||||
if (!decode_data) return false;
|
||||
// The sum of all nibbles should match the last 6 bits
|
||||
uint8_t sum = 0;
|
||||
for (uint8_t i = 6; i <= 38; i += 4) {
|
||||
sum += ((decode_data >> i) & 0x0f);
|
||||
}
|
||||
return sum != 0 && (sum & 0x3f) == (decode_data & 0x3f);
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -29,6 +29,8 @@ So include here the .hpp, and add a new element to the protos vector in the cons
|
||||
#include "w-acurite5in1.hpp"
|
||||
#include "w-emose601x.hpp"
|
||||
#include "w-solight_te44.hpp"
|
||||
#include "w-bresser_3ch.hpp"
|
||||
#include "w-vauno_en8822.hpp"
|
||||
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
@@ -66,10 +68,13 @@ class WeatherProtos : public FProtoListGeneral {
|
||||
protos[FPW_Acurite5in1] = new FProtoWeatherAcurite5in1();
|
||||
protos[FPW_EmosE601x] = new FProtoWeatherEmosE601x();
|
||||
protos[FPW_SolightTE44] = new FProtoWeatherSolightTE44();
|
||||
protos[FPW_Bresser3CH] = new FProtoWeatheBresser3CH();
|
||||
protos[FPW_Bresser3CH_V1] = nullptr; // done by FProtoWeatheBresser3CH
|
||||
protos[FPW_Vauno_EN8822] = new FProtoWeatherVaunoEN8822();
|
||||
|
||||
// set callback for them
|
||||
for (uint8_t i = 0; i < FPW_COUNT; ++i) {
|
||||
protos[i]->setCallback(callbackTarget);
|
||||
if (protos[i] != NULL) protos[i]->setCallback(callbackTarget);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -39,6 +39,9 @@ enum FPROTO_WEATHER_SENSOR {
|
||||
FPW_Acurite5in1 = 21,
|
||||
FPW_EmosE601x = 22,
|
||||
FPW_SolightTE44 = 23,
|
||||
FPW_Bresser3CH = 24,
|
||||
FPW_Bresser3CH_V1 = 25,
|
||||
FPW_Vauno_EN8822 = 26,
|
||||
FPW_COUNT // this must be the last
|
||||
};
|
||||
|
||||
|
||||
@@ -38,32 +38,79 @@ void SubGhzDProcessor::execute(const buffer_c8_t& buffer) {
|
||||
feed_channel_stats(decim_1_out);
|
||||
|
||||
for (size_t i = 0; i < decim_1_out.count; i++) {
|
||||
threshold = (low_estimate + high_estimate) / 2;
|
||||
int32_t const hysteresis = threshold / 8; // +-12%
|
||||
int16_t re = decim_1_out.p[i].real();
|
||||
int16_t im = decim_1_out.p[i].imag();
|
||||
uint32_t mag = ((uint32_t)re * (uint32_t)re) + ((uint32_t)im * (uint32_t)im);
|
||||
|
||||
mag = (mag >> 12); // Decim samples are calculated with saturated gain . (we could also reduce that sat. param at configure time)
|
||||
mag = (mag >> 10);
|
||||
int32_t const ook_low_delta = mag - low_estimate;
|
||||
bool meashl = currentHiLow;
|
||||
if (sig_state == STATE_IDLE) {
|
||||
if (mag > (threshold + hysteresis)) { // just become high
|
||||
meashl = true;
|
||||
sig_state = STATE_PULSE;
|
||||
numg = 0;
|
||||
} else {
|
||||
meashl = false; // still low
|
||||
low_estimate += ook_low_delta / OOK_EST_LOW_RATIO;
|
||||
low_estimate += ((ook_low_delta > 0) ? 1 : -1); // Hack to compensate for lack of fixed-point scaling
|
||||
// Calculate default OOK high level estimate
|
||||
high_estimate = 1.35 * low_estimate; // Default is a ratio of low level
|
||||
high_estimate = std::max(high_estimate, min_high_level);
|
||||
high_estimate = std::min(high_estimate, (uint32_t)OOK_MAX_HIGH_LEVEL);
|
||||
}
|
||||
|
||||
} else if (sig_state == STATE_PULSE) {
|
||||
++numg;
|
||||
if (numg > 100) numg = 100;
|
||||
if (mag < (threshold - hysteresis)) {
|
||||
// check if really a bad value
|
||||
if (numg < 3) {
|
||||
// susp
|
||||
sig_state = STATE_GAP;
|
||||
} else {
|
||||
numg = 0;
|
||||
sig_state = STATE_GAP_START;
|
||||
}
|
||||
meashl = false; // low
|
||||
} else {
|
||||
high_estimate += mag / OOK_EST_HIGH_RATIO - high_estimate / OOK_EST_HIGH_RATIO;
|
||||
high_estimate = std::max(high_estimate, min_high_level);
|
||||
high_estimate = std::min(high_estimate, (uint32_t)OOK_MAX_HIGH_LEVEL);
|
||||
meashl = true; // still high
|
||||
}
|
||||
} else if (sig_state == STATE_GAP_START) {
|
||||
++numg;
|
||||
if (mag > (threshold + hysteresis)) { // New pulse?
|
||||
sig_state = STATE_PULSE;
|
||||
meashl = true;
|
||||
} else if (numg >= 3) {
|
||||
sig_state = STATE_GAP;
|
||||
meashl = false; // gap
|
||||
}
|
||||
} else if (sig_state == STATE_GAP) {
|
||||
++numg;
|
||||
if (mag > (threshold + hysteresis)) { // New pulse?
|
||||
numg = 0;
|
||||
sig_state = STATE_PULSE;
|
||||
meashl = true;
|
||||
} else {
|
||||
meashl = false;
|
||||
}
|
||||
}
|
||||
|
||||
bool meashl = (mag > threshold);
|
||||
tm += mag;
|
||||
if (meashl == currentHiLow && currentDuration < 30'000'000) // allow pass 'end' signal
|
||||
{
|
||||
currentDuration += nsPerDecSamp;
|
||||
} else { // called on change, so send the last duration and dir.
|
||||
if (currentDuration >= 30'000'000) sig_state = STATE_IDLE;
|
||||
if (protoList) protoList->feed(currentHiLow, currentDuration / 1000);
|
||||
currentDuration = nsPerDecSamp;
|
||||
currentHiLow = meashl;
|
||||
}
|
||||
}
|
||||
|
||||
cnt += decim_1_out.count; // TODO , check if it is necessary that xdecim factor.
|
||||
if (cnt > 90'000) {
|
||||
threshold = (tm / cnt) / 2;
|
||||
cnt = 0;
|
||||
tm = 0;
|
||||
if (threshold < 50) threshold = 50;
|
||||
if (threshold > 1700) threshold = 1700;
|
||||
}
|
||||
}
|
||||
|
||||
void SubGhzDProcessor::on_message(const Message* const message) {
|
||||
@@ -75,8 +122,6 @@ void SubGhzDProcessor::configure(const SubGhzFPRxConfigureMessage& message) {
|
||||
// constexpr size_t decim_0_output_fs = baseband_fs / decim_0.decimation_factor; //unused
|
||||
// constexpr size_t decim_1_output_fs = decim_0_output_fs / decim_1.decimation_factor; //unused
|
||||
|
||||
modulation = message.modulation; // TODO: add support for FM (currently AM only)
|
||||
|
||||
baseband_fs = message.sampling_rate;
|
||||
baseband_thread.set_sampling_rate(baseband_fs);
|
||||
nsPerDecSamp = 1'000'000'000 / baseband_fs * 8; // Scaled it due to less array buffer sampes due to /8 decimation. 250 nseg (4Mhz) * 8
|
||||
|
||||
@@ -32,7 +32,14 @@
|
||||
#include "message.hpp"
|
||||
#include "dsp_decimate.hpp"
|
||||
|
||||
#pragma GCC push_options
|
||||
#pragma GCC optimize("Os")
|
||||
#include "fprotos/subghzdprotos.hpp"
|
||||
#pragma GCC pop_options
|
||||
|
||||
#define OOK_EST_HIGH_RATIO 3 // Constant for slowness of OOK high level estimator
|
||||
#define OOK_EST_LOW_RATIO 5 // Constant for slowness of OOK low level (noise) estimator (very slow)
|
||||
#define OOK_MAX_HIGH_LEVEL 450000
|
||||
|
||||
class SubGhzDProcessor : public BasebandProcessor {
|
||||
public:
|
||||
@@ -40,9 +47,18 @@ class SubGhzDProcessor : public BasebandProcessor {
|
||||
void on_message(const Message* const message) override;
|
||||
|
||||
private:
|
||||
enum {
|
||||
STATE_IDLE = 0,
|
||||
STATE_PULSE = 1,
|
||||
STATE_GAP_START = 2,
|
||||
STATE_GAP = 3,
|
||||
} sig_state = STATE_IDLE;
|
||||
uint32_t low_estimate = 100;
|
||||
uint32_t high_estimate = 12000;
|
||||
uint32_t min_high_level = 10;
|
||||
uint8_t numg = 0; // count of matched signals to filter spikes
|
||||
size_t baseband_fs = 0; // will be set later by configure message
|
||||
uint32_t nsPerDecSamp = 0;
|
||||
uint8_t modulation = 0;
|
||||
|
||||
/* Array Buffer aux. used in decim0 and decim1 IQ c16 signed data ; (decim0 defines the max length of the array) */
|
||||
std::array<complex16_t, 512> dst{}; // decim0 /4 , 2048/4 = 512 complex I,Q
|
||||
@@ -55,14 +71,10 @@ class SubGhzDProcessor : public BasebandProcessor {
|
||||
dsp::decimate::FIRC16xR16x16Decim2 decim_1{};
|
||||
|
||||
uint32_t currentDuration = 0;
|
||||
uint32_t threshold = 0x0630; // will overwrite after the first iteration
|
||||
uint32_t threshold = 0x0630;
|
||||
bool currentHiLow = false;
|
||||
bool configured{false};
|
||||
|
||||
// for threshold
|
||||
uint32_t cnt = 0;
|
||||
uint32_t tm = 0;
|
||||
|
||||
FProtoListGeneral* protoList = new SubGhzDProtos(); // holds all the protocols we can parse
|
||||
void configure(const SubGhzFPRxConfigureMessage& message);
|
||||
|
||||
|
||||
@@ -39,32 +39,79 @@ void WeatherProcessor::execute(const buffer_c8_t& buffer) {
|
||||
feed_channel_stats(decim_1_out);
|
||||
|
||||
for (size_t i = 0; i < decim_1_out.count; i++) {
|
||||
threshold = (low_estimate + high_estimate) / 2;
|
||||
int32_t const hysteresis = threshold / 8; // +-12%
|
||||
int16_t re = decim_1_out.p[i].real();
|
||||
int16_t im = decim_1_out.p[i].imag();
|
||||
uint32_t mag = ((uint32_t)re * (uint32_t)re) + ((uint32_t)im * (uint32_t)im);
|
||||
|
||||
mag = (mag >> 12); // Decim samples are calculated with saturated gain . (we could also reduce that sat. param at configure time)
|
||||
mag = (mag >> 10);
|
||||
int32_t const ook_low_delta = mag - low_estimate;
|
||||
bool meashl = currentHiLow;
|
||||
if (sig_state == STATE_IDLE) {
|
||||
if (mag > (threshold + hysteresis)) { // just become high
|
||||
meashl = true;
|
||||
sig_state = STATE_PULSE;
|
||||
numg = 0;
|
||||
} else {
|
||||
meashl = false; // still low
|
||||
low_estimate += ook_low_delta / OOK_EST_LOW_RATIO;
|
||||
low_estimate += ((ook_low_delta > 0) ? 1 : -1); // Hack to compensate for lack of fixed-point scaling
|
||||
// Calculate default OOK high level estimate
|
||||
high_estimate = 1.35 * low_estimate; // Default is a ratio of low level
|
||||
high_estimate = std::max(high_estimate, min_high_level);
|
||||
high_estimate = std::min(high_estimate, (uint32_t)OOK_MAX_HIGH_LEVEL);
|
||||
}
|
||||
|
||||
} else if (sig_state == STATE_PULSE) {
|
||||
++numg;
|
||||
if (numg > 100) numg = 100;
|
||||
if (mag < (threshold - hysteresis)) {
|
||||
// check if really a bad value
|
||||
if (numg < 3) {
|
||||
// susp
|
||||
sig_state = STATE_GAP;
|
||||
} else {
|
||||
numg = 0;
|
||||
sig_state = STATE_GAP_START;
|
||||
}
|
||||
meashl = false; // low
|
||||
} else {
|
||||
high_estimate += mag / OOK_EST_HIGH_RATIO - high_estimate / OOK_EST_HIGH_RATIO;
|
||||
high_estimate = std::max(high_estimate, min_high_level);
|
||||
high_estimate = std::min(high_estimate, (uint32_t)OOK_MAX_HIGH_LEVEL);
|
||||
meashl = true; // still high
|
||||
}
|
||||
} else if (sig_state == STATE_GAP_START) {
|
||||
++numg;
|
||||
if (mag > (threshold + hysteresis)) { // New pulse?
|
||||
sig_state = STATE_PULSE;
|
||||
meashl = true;
|
||||
} else if (numg >= 3) {
|
||||
sig_state = STATE_GAP;
|
||||
meashl = false; // gap
|
||||
}
|
||||
} else if (sig_state == STATE_GAP) {
|
||||
++numg;
|
||||
if (mag > (threshold + hysteresis)) { // New pulse?
|
||||
numg = 0;
|
||||
sig_state = STATE_PULSE;
|
||||
meashl = true;
|
||||
} else {
|
||||
meashl = false;
|
||||
}
|
||||
}
|
||||
|
||||
bool meashl = (mag > threshold);
|
||||
tm += mag;
|
||||
if (meashl == currentHiLow && currentDuration < 30'000'000) // allow pass 'end' signal
|
||||
{
|
||||
currentDuration += nsPerDecSamp;
|
||||
} else { // called on change, so send the last duration and dir.
|
||||
if (currentDuration >= 30'000'000) sig_state = STATE_IDLE;
|
||||
if (protoList) protoList->feed(currentHiLow, currentDuration / 1000);
|
||||
currentDuration = nsPerDecSamp;
|
||||
currentHiLow = meashl;
|
||||
}
|
||||
}
|
||||
|
||||
cnt += decim_1_out.count; // TODO , check if it is necessary that xdecim factor.
|
||||
if (cnt > 90'000) {
|
||||
threshold = (tm / cnt) / 2;
|
||||
cnt = 0;
|
||||
tm = 0;
|
||||
if (threshold < 50) threshold = 50;
|
||||
if (threshold > 1700) threshold = 1700;
|
||||
}
|
||||
}
|
||||
|
||||
void WeatherProcessor::on_message(const Message* const message) {
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
#ifndef __PROC_WEATHER_H__
|
||||
#define __PROC_WEATHER_H__
|
||||
|
||||
#include <algorithm>
|
||||
#include "baseband_processor.hpp"
|
||||
#include "baseband_thread.hpp"
|
||||
#include "rssi_thread.hpp"
|
||||
@@ -34,15 +35,28 @@
|
||||
|
||||
#include "fprotos/weatherprotos.hpp"
|
||||
|
||||
#define OOK_EST_HIGH_RATIO 3 // Constant for slowness of OOK high level estimator
|
||||
#define OOK_EST_LOW_RATIO 5 // Constant for slowness of OOK low level (noise) estimator (very slow)
|
||||
#define OOK_MAX_HIGH_LEVEL 450000
|
||||
|
||||
class WeatherProcessor : public BasebandProcessor {
|
||||
public:
|
||||
void execute(const buffer_c8_t& buffer) override;
|
||||
void on_message(const Message* const message) override;
|
||||
|
||||
private:
|
||||
enum {
|
||||
STATE_IDLE = 0,
|
||||
STATE_PULSE = 1,
|
||||
STATE_GAP_START = 2,
|
||||
STATE_GAP = 3,
|
||||
} sig_state = STATE_IDLE;
|
||||
uint32_t low_estimate = 100;
|
||||
uint32_t high_estimate = 12000;
|
||||
uint32_t min_high_level = 10;
|
||||
size_t baseband_fs = 0; // will be set later by configure message.
|
||||
uint32_t nsPerDecSamp = 0;
|
||||
|
||||
uint8_t numg = 0; // count of matched signals to filter spikes
|
||||
/* Array Buffer aux. used in decim0 and decim1 IQ c16 signed data ; (decim0 defines the max length of the array) */
|
||||
std::array<complex16_t, 512> dst{}; // decim0 /4 , 2048/4 = 512 complex I,Q
|
||||
const buffer_c16_t dst_buffer{
|
||||
@@ -58,10 +72,6 @@ class WeatherProcessor : public BasebandProcessor {
|
||||
bool currentHiLow = false;
|
||||
bool configured{false};
|
||||
|
||||
// for threshold
|
||||
uint32_t cnt = 0;
|
||||
uint32_t tm = 0;
|
||||
|
||||
FProtoListGeneral* protoList = new WeatherProtos(); // holds all the protocols we can parse
|
||||
void configure(const SubGhzFPRxConfigureMessage& message);
|
||||
void on_beep_message(const AudioBeepMessage& message);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -21,20 +21,152 @@
|
||||
|
||||
#include "i2cdev_ppmod.hpp"
|
||||
#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 = 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() {
|
||||
// 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 && 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 && 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 && 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() {
|
||||
Command cmd = Command::COMMAND_GETFEAT_DATA_ORIENTATION;
|
||||
orientation_t data;
|
||||
bool success = i2c_read((uint8_t*)&cmd, 2, (uint8_t*)&data, sizeof(orientation_t));
|
||||
if (success == false) {
|
||||
return std::nullopt;
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
std::optional<gpssmall_t> I2cDev_PPmod::get_gps_data() {
|
||||
Command cmd = Command::COMMAND_GETFEAT_DATA_GPS;
|
||||
gpssmall_t data;
|
||||
bool success = i2c_read((uint8_t*)&cmd, 2, (uint8_t*)&data, sizeof(gpssmall_t));
|
||||
if (success == false) {
|
||||
return std::nullopt;
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
std::optional<environment_t> I2cDev_PPmod::get_environment_data() {
|
||||
Command cmd = Command::COMMAND_GETFEAT_DATA_ENVIRONMENT;
|
||||
environment_t data;
|
||||
bool success = i2c_read((uint8_t*)&cmd, 2, (uint8_t*)&data, sizeof(environment_t));
|
||||
if (success == false) {
|
||||
return std::nullopt;
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
std::optional<uint16_t> I2cDev_PPmod::get_light_data() {
|
||||
Command cmd = Command::COMMAND_GETFEAT_DATA_LIGHT;
|
||||
uint16_t data;
|
||||
bool success = i2c_read((uint8_t*)&cmd, 2, (uint8_t*)&data, sizeof(uint16_t));
|
||||
if (success == false) {
|
||||
return std::nullopt;
|
||||
}
|
||||
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;
|
||||
Command cmd = Command::COMMAND_GETFEATURE_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) {
|
||||
return 0;
|
||||
}
|
||||
return mask_;
|
||||
}
|
||||
|
||||
std::optional<I2cDev_PPmod::device_info> I2cDev_PPmod::readDeviceInfo() {
|
||||
@@ -45,7 +177,10 @@ std::optional<I2cDev_PPmod::device_info> I2cDev_PPmod::readDeviceInfo() {
|
||||
if (success == false) {
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
// sanity check
|
||||
if (info.application_count > 1000) {
|
||||
return std::nullopt;
|
||||
}
|
||||
return info;
|
||||
}
|
||||
|
||||
@@ -58,6 +193,10 @@ std::optional<I2cDev_PPmod::standalone_app_info> I2cDev_PPmod::getStandaloneAppI
|
||||
if (success == false) {
|
||||
return std::nullopt;
|
||||
}
|
||||
// sanity check
|
||||
if (info.binary_size == UINT32_MAX) {
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
return info;
|
||||
}
|
||||
|
||||
@@ -30,6 +30,8 @@
|
||||
#include "standalone_app.hpp"
|
||||
#include "i2cdevmanager.hpp"
|
||||
|
||||
#include "i2cdev_ppmod_helper.hpp"
|
||||
|
||||
namespace i2cdev {
|
||||
|
||||
class I2cDev_PPmod : public I2cDev {
|
||||
@@ -38,13 +40,26 @@ class I2cDev_PPmod : public I2cDev {
|
||||
COMMAND_NONE = 0,
|
||||
|
||||
// will respond with device_info
|
||||
COMMAND_INFO = 0x18F0,
|
||||
COMMAND_INFO = 1,
|
||||
|
||||
// will respond with info of application
|
||||
COMMAND_APP_INFO = 0xA90B,
|
||||
COMMAND_APP_INFO,
|
||||
|
||||
// will respond with application data
|
||||
COMMAND_APP_TRANSFER = 0x4183,
|
||||
COMMAND_APP_TRANSFER,
|
||||
|
||||
// Feature specific commands
|
||||
COMMAND_GETFEATURE_MASK,
|
||||
// Feature data getter commands
|
||||
COMMAND_GETFEAT_DATA_GPS,
|
||||
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.
|
||||
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
@@ -66,9 +81,20 @@ class I2cDev_PPmod : public I2cDev {
|
||||
bool init(uint8_t addr_) override;
|
||||
void update() override;
|
||||
|
||||
std::optional<device_info> readDeviceInfo();
|
||||
std::optional<standalone_app_info> getStandaloneAppInfo(uint32_t index);
|
||||
std::vector<uint8_t> downloadStandaloneApp(uint32_t index, size_t offset);
|
||||
uint64_t get_features_mask();
|
||||
std::optional<device_info> readDeviceInfo();
|
||||
std::optional<gpssmall_t> get_gps_data();
|
||||
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 */
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
#ifndef I2CDEV_PPMOD_HELPER_H
|
||||
#define I2CDEV_PPMOD_HELPER_H
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
enum class SupportedFeatures : uint64_t {
|
||||
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
|
||||
{
|
||||
uint8_t hour; /*!< Hour */
|
||||
uint8_t minute; /*!< Minute */
|
||||
uint8_t second; /*!< Second */
|
||||
uint16_t thousand; /*!< Thousand */
|
||||
} gps_time_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
uint8_t day; /*!< Day (start from 1) */
|
||||
uint8_t month; /*!< Month (start from 1) */
|
||||
uint16_t year; /*!< Year (start from 2000) */
|
||||
} gps_date_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
float latitude; /*!< Latitude (degrees) */
|
||||
float longitude; /*!< Longitude (degrees) */
|
||||
float altitude; /*!< Altitude (meters) */
|
||||
uint8_t sats_in_use; /*!< Number of satellites in use */
|
||||
uint8_t sats_in_view; /*!< Number of satellites in view */
|
||||
float speed; /*!< Ground speed, unit: m/s */
|
||||
gps_date_t date; /*!< Fix date */
|
||||
gps_time_t tim; /*!< time in UTC */
|
||||
} gpssmall_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
float angle;
|
||||
float tilt;
|
||||
} orientation_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
float temperature;
|
||||
float humidity;
|
||||
float pressure;
|
||||
} environment_t;
|
||||
|
||||
// light is uint16_t
|
||||
|
||||
#endif
|
||||
@@ -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!
|
||||
@@ -131,8 +132,13 @@ void I2cDev::got_success() {
|
||||
|
||||
bool I2cDev::i2c_read(uint8_t* reg, uint8_t reg_size, uint8_t* data, uint8_t bytes) {
|
||||
if (bytes == 0) return false;
|
||||
if (reg_size > 0 && reg) i2cbus.transmit(addr, reg, reg_size);
|
||||
bool ret = i2cbus.receive(addr, data, bytes);
|
||||
bool ret = true;
|
||||
if (reg_size > 0 && reg) ret = i2cbus.transmit(addr, reg, reg_size, 150);
|
||||
if (!ret) {
|
||||
got_error();
|
||||
return false;
|
||||
}
|
||||
ret = i2cbus.receive(addr, data, bytes, 150);
|
||||
if (!ret)
|
||||
got_error();
|
||||
else
|
||||
@@ -153,7 +159,7 @@ bool I2cDev::i2c_write(uint8_t* reg, uint8_t reg_size, uint8_t* data, uint8_t by
|
||||
// Copy the data into the buffer after the register data
|
||||
memcpy(buffer + reg_size, data, bytes);
|
||||
// Transmit the combined data
|
||||
bool result = i2cbus.transmit(addr, buffer, total_size);
|
||||
bool result = i2cbus.transmit(addr, buffer, total_size, 150);
|
||||
// Clean up the dynamically allocated buffer
|
||||
delete[] buffer;
|
||||
if (!result)
|
||||
@@ -304,7 +310,7 @@ msg_t I2CDevManager::timer_fn(void* arg) {
|
||||
force_scan = false;
|
||||
}
|
||||
for (size_t i = 0; i < devlist.size(); i++) {
|
||||
if (devlist[i].addr != 0 && devlist[i].dev) {
|
||||
if (devlist[i].addr != 0 && devlist[i].dev && devlist[i].dev->query_interval != 0) {
|
||||
if ((curr_timer % devlist[i].dev->query_interval) == 0) { // only if it is device's interval
|
||||
devlist[i].dev->update(); // updates it's data, and broadcasts it. if there is any error it will handle in it, and later we can remove it
|
||||
}
|
||||
@@ -338,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,9 +404,6 @@ class IO {
|
||||
const auto value_low = data_read();
|
||||
uint32_t original_value = (value_high << 8) | value_low;
|
||||
|
||||
if (get_dark_cover()) {
|
||||
original_value = DARKENED_PIXEL(original_value, get_brightness());
|
||||
}
|
||||
return original_value;
|
||||
}
|
||||
|
||||
|
||||
@@ -109,7 +109,7 @@ struct ui_config_t {
|
||||
bool hide_clock : 1;
|
||||
bool clock_show_date : 1;
|
||||
bool clkout_enabled : 1;
|
||||
bool apply_fake_brightness : 1;
|
||||
bool unused_FB : 1; // apply_fake_brightness
|
||||
bool stealth_mode : 1;
|
||||
bool config_login : 1;
|
||||
bool config_splash : 1;
|
||||
@@ -130,7 +130,7 @@ struct ui_config2_t {
|
||||
bool hide_sd_card : 1;
|
||||
|
||||
bool hide_mute : 1;
|
||||
bool hide_fake_brightness : 1;
|
||||
bool UNUSED_3 : 1;
|
||||
bool hide_numeric_battery : 1;
|
||||
bool hide_battery_icon : 1;
|
||||
bool override_batt_calc : 1;
|
||||
@@ -226,9 +226,6 @@ struct data_t {
|
||||
// Rotary encoder dial sensitivity (encoder.cpp/hpp)
|
||||
uint16_t encoder_dial_sensitivity : 4;
|
||||
|
||||
// fake brightness level (not switch, switch is in another place)
|
||||
uint16_t fake_brightness_level : 4;
|
||||
|
||||
// Encoder rotation rate multiplier for larger increments when rotated rapidly
|
||||
uint16_t encoder_rate_multiplier : 4;
|
||||
|
||||
@@ -300,7 +297,6 @@ struct data_t {
|
||||
frequency_tx_correction(0),
|
||||
|
||||
encoder_dial_sensitivity(DIAL_SENSITIVITY_NORMAL),
|
||||
fake_brightness_level(BRIGHTNESS_50),
|
||||
encoder_rate_multiplier(1),
|
||||
UNUSED(0),
|
||||
|
||||
@@ -469,7 +465,6 @@ void init() {
|
||||
set_config_mode_storage_direct(config_mode_backup);
|
||||
|
||||
// Firmware upgrade handling - adjust newly defined fields where 0 is an invalid default
|
||||
if (fake_brightness_level() == 0) set_fake_brightness_level(BRIGHTNESS_50);
|
||||
if (menu_color().v == 0) set_menu_color(Color::grey());
|
||||
}
|
||||
|
||||
@@ -650,10 +645,6 @@ bool stealth_mode() {
|
||||
return data->ui_config.stealth_mode;
|
||||
}
|
||||
|
||||
bool apply_fake_brightness() {
|
||||
return data->ui_config.apply_fake_brightness;
|
||||
}
|
||||
|
||||
bool config_login() {
|
||||
return data->ui_config.config_login;
|
||||
}
|
||||
@@ -757,10 +748,6 @@ void set_config_backlight_timer(const backlight_config_t& new_value) {
|
||||
data->ui_config.enable_backlight_timeout = static_cast<uint8_t>(new_value.timeout_enabled());
|
||||
}
|
||||
|
||||
void set_apply_fake_brightness(const bool v) {
|
||||
data->ui_config.apply_fake_brightness = v;
|
||||
}
|
||||
|
||||
uint32_t pocsag_last_address() {
|
||||
return data->pocsag_last_address;
|
||||
}
|
||||
@@ -947,9 +934,7 @@ bool ui_hide_clock() {
|
||||
bool ui_hide_sd_card() {
|
||||
return data->ui_config2.hide_sd_card;
|
||||
}
|
||||
bool ui_hide_fake_brightness() {
|
||||
return data->ui_config2.hide_fake_brightness;
|
||||
}
|
||||
|
||||
bool ui_hide_numeric_battery() {
|
||||
return data->ui_config2.hide_numeric_battery;
|
||||
}
|
||||
@@ -992,9 +977,6 @@ void set_ui_hide_clock(bool v) {
|
||||
void set_ui_hide_sd_card(bool v) {
|
||||
data->ui_config2.hide_sd_card = v;
|
||||
}
|
||||
void set_ui_hide_fake_brightness(bool v) {
|
||||
data->ui_config2.hide_fake_brightness = v;
|
||||
}
|
||||
void set_ui_hide_numeric_battery(bool v) {
|
||||
data->ui_config2.hide_numeric_battery = v;
|
||||
}
|
||||
@@ -1112,26 +1094,6 @@ void set_config_dst(dst_config_t v) {
|
||||
rtc_time::dst_init();
|
||||
}
|
||||
|
||||
// Fake brightness level (switch is in another place)
|
||||
uint8_t fake_brightness_level() {
|
||||
return data->fake_brightness_level;
|
||||
}
|
||||
void set_fake_brightness_level(uint8_t v) {
|
||||
data->fake_brightness_level = v;
|
||||
}
|
||||
|
||||
// Cycle through 4 brightness options: disabled -> enabled/50% -> enabled/25% -> enabled/12.5% -> disabled
|
||||
void toggle_fake_brightness_level() {
|
||||
bool fbe = apply_fake_brightness();
|
||||
if (config_lcd_inverted_mode()) return; // for now only inverted mode OR fake brightness
|
||||
if ((!fbe) || (data->fake_brightness_level >= BRIGHTNESS_12p5)) {
|
||||
set_apply_fake_brightness(!fbe);
|
||||
data->fake_brightness_level = BRIGHTNESS_50;
|
||||
} else {
|
||||
data->fake_brightness_level++;
|
||||
}
|
||||
}
|
||||
|
||||
// Menu Color Scheme
|
||||
Color menu_color() {
|
||||
return data->menu_color;
|
||||
@@ -1249,7 +1211,6 @@ bool debug_dump() {
|
||||
pmem_dump_file.write_line("headphone_volume_cb: " + to_string_dec_int(data->headphone_volume_cb));
|
||||
pmem_dump_file.write_line("config_mode_storage: 0x" + to_string_hex(data->config_mode_storage, 8));
|
||||
pmem_dump_file.write_line("dst_config: 0x" + to_string_hex((uint32_t)data->dst_config.v, 8));
|
||||
pmem_dump_file.write_line("fake_brightness_level: " + to_string_dec_uint(data->fake_brightness_level));
|
||||
pmem_dump_file.write_line("menu_color: 0x" + to_string_hex(data->menu_color.v, 4));
|
||||
pmem_dump_file.write_line("touchscreen_threshold: " + to_string_dec_uint(data->touchscreen_threshold));
|
||||
|
||||
@@ -1266,7 +1227,6 @@ bool debug_dump() {
|
||||
pmem_dump_file.write_line("ui_config hide_clock: " + to_string_dec_uint(data->ui_config.hide_clock));
|
||||
pmem_dump_file.write_line("ui_config clock_with_date: " + to_string_dec_uint(data->ui_config.clock_show_date));
|
||||
pmem_dump_file.write_line("ui_config clkout_enabled: " + to_string_dec_uint(data->ui_config.clkout_enabled));
|
||||
pmem_dump_file.write_line("ui_config apply_fake_brightness: " + to_string_dec_uint(data->ui_config.apply_fake_brightness));
|
||||
pmem_dump_file.write_line("ui_config stealth_mode: " + to_string_dec_uint(data->ui_config.stealth_mode));
|
||||
pmem_dump_file.write_line("ui_config config_login: " + to_string_dec_uint(data->ui_config.config_login));
|
||||
pmem_dump_file.write_line("ui_config config_splash: " + to_string_dec_uint(data->ui_config.config_splash));
|
||||
@@ -1281,7 +1241,6 @@ bool debug_dump() {
|
||||
pmem_dump_file.write_line("ui_config2 hide_clock: " + to_string_dec_uint(data->ui_config2.hide_clock));
|
||||
pmem_dump_file.write_line("ui_config2 hide_sd_card: " + to_string_dec_uint(data->ui_config2.hide_sd_card));
|
||||
pmem_dump_file.write_line("ui_config2 hide_mute: " + to_string_dec_uint(data->ui_config2.hide_mute));
|
||||
pmem_dump_file.write_line("ui_config2 hide_fake_brightness: " + to_string_dec_uint(data->ui_config2.hide_fake_brightness));
|
||||
pmem_dump_file.write_line("ui_config2 hide_battery_icon: " + to_string_dec_uint(data->ui_config2.hide_battery_icon));
|
||||
pmem_dump_file.write_line("ui_config2 hide_numeric_battery: " + to_string_dec_uint(data->ui_config2.hide_numeric_battery));
|
||||
pmem_dump_file.write_line("ui_config2 theme_id: " + to_string_dec_uint(data->ui_config2.theme_id));
|
||||
|
||||
@@ -135,12 +135,6 @@ typedef union {
|
||||
} dst_config_t;
|
||||
static_assert(sizeof(dst_config_t) == sizeof(uint32_t));
|
||||
|
||||
enum fake_brightness_level_options {
|
||||
BRIGHTNESS_50 = 1,
|
||||
BRIGHTNESS_25 = 2,
|
||||
BRIGHTNESS_12p5 = 3, // 12p5 is 12.5
|
||||
};
|
||||
|
||||
namespace cache {
|
||||
|
||||
/* Set values in cache to sensible defaults. */
|
||||
@@ -273,15 +267,6 @@ uint16_t clkout_freq();
|
||||
dst_config_t config_dst();
|
||||
void set_config_dst(dst_config_t v);
|
||||
|
||||
/* Fake brightness */
|
||||
// switch (if do color change):
|
||||
bool apply_fake_brightness();
|
||||
void set_apply_fake_brightness(const bool v);
|
||||
// level (color change level):
|
||||
uint8_t fake_brightness_level();
|
||||
void set_fake_brightness_level(uint8_t v);
|
||||
void toggle_fake_brightness_level();
|
||||
|
||||
/* Touchscreen threshold */
|
||||
uint16_t touchscreen_threshold();
|
||||
void set_touchscreen_threshold(uint16_t v);
|
||||
@@ -334,7 +319,6 @@ bool ui_hide_camera();
|
||||
bool ui_hide_sleep();
|
||||
bool ui_hide_bias_tee();
|
||||
bool ui_hide_clock();
|
||||
bool ui_hide_fake_brightness();
|
||||
bool ui_hide_numeric_battery();
|
||||
bool ui_hide_battery_icon();
|
||||
bool ui_hide_sd_card();
|
||||
@@ -348,7 +332,6 @@ void set_ui_hide_camera(bool v);
|
||||
void set_ui_hide_sleep(bool v);
|
||||
void set_ui_hide_bias_tee(bool v);
|
||||
void set_ui_hide_clock(bool v);
|
||||
void set_ui_hide_fake_brightness(bool v);
|
||||
void set_ui_hide_numeric_battery(bool v);
|
||||
void set_ui_hide_battery_icon(bool v);
|
||||
void set_ui_hide_sd_card(bool v);
|
||||
|
||||
@@ -1,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"};
|
||||
|
||||
// multi language support will changes (not in use for now)
|
||||
const char** LanguageHelper::currentMessages = englishMessages;
|
||||
|
||||
@@ -58,7 +58,9 @@ enum LangConsts {
|
||||
LANG_RESUME,
|
||||
LANG_FLOOD,
|
||||
LANG_SHOWQR,
|
||||
LANG_SAVE
|
||||
LANG_SAVE,
|
||||
LANG_LOCK,
|
||||
LANG_UNLOCK
|
||||
};
|
||||
|
||||
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;
|
||||
|
||||
@@ -1 +1,25 @@
|
||||
bitmap is for icons, it's colorless and headless; splash and modal isn't using bitmap
|
||||
bitmap is for icons, it's colorless and headless; splash and modal isn't
|
||||
using bitmap
|
||||
|
||||
## Bitmap helper folder
|
||||
The folder `bitmap_tools` contains scripts to convert icons in png format to
|
||||
the PortaPack readable format in `bitmap.hpp`.
|
||||
|
||||
### Convert a folder contains one or more icon.png to one bitmap.hpp
|
||||
The `make_bitmap.py` is the traditional helper, well tested. The folder with
|
||||
the icons is given as argument and generates the `./bitmap.hpp`. This file
|
||||
needs to be copied to `mayhem-firmware/firmware/application/`.
|
||||
The icon size needs to be a multiple of 8. The generated icon is black/white.
|
||||
|
||||
### Convert bitmap array to icon.png
|
||||
The `bitmap_arr_reverse_decode.py` takes an array from the bitmap.hpp and
|
||||
convert it back to a png.
|
||||
|
||||
### Convert both ways
|
||||
The `pp_png2hpp.py` is based on the privious scripts, as all in one solution.
|
||||
With the `--hpp bitmap.hpp` file and the `--graphics /folder_to/png_icons/`
|
||||
arguments, theis script will generate a `bitmap.hpp`.
|
||||
Add the `--reverse` argument to generate png icons from the given `bitmap.hpp`.
|
||||
|
||||
Especially the reverse function got a parser, to automatic get the filename
|
||||
and size of the image.
|
||||
+77
@@ -0,0 +1,77 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
## Note: This helper was just a POC for pp_png3hpp.py to test the regex.
|
||||
|
||||
import argparse
|
||||
import numpy as np
|
||||
import re
|
||||
from PIL import Image
|
||||
|
||||
|
||||
def parse_bitmaphpp(bitmaphpp_file, icon_name):
|
||||
ico_pattern = re.compile(r"static constexpr uint8_t bitmap_(.*)_data\[\] = {\n((?:\s+(?:.*)\n)+)};\nstatic constexpr Bitmap bitmap_.*\{\n\s+\{(.*)\},", re.MULTILINE)
|
||||
ico_data = []
|
||||
|
||||
# read file to buffer, to find multiline regex
|
||||
readfile = open(bitmaphpp_file,'r')
|
||||
buff = readfile.read()
|
||||
readfile.close()
|
||||
|
||||
if icon_name == 'all':
|
||||
for match in ico_pattern.finditer(buff):
|
||||
ico_data.append([match.group(1), match.group(2), match.group(3)])
|
||||
else:
|
||||
for match in ico_pattern.finditer(buff):
|
||||
if match.group(1) in icon_name:
|
||||
ico_data.append([match.group(1), match.group(2), match.group(3)])
|
||||
|
||||
return (ico_data)
|
||||
|
||||
def convert_hpp(icon_name,bitmap_array,iconsize_str):
|
||||
iconsize = iconsize_str.split(", ")
|
||||
bitmap_size = (int(iconsize[0]),int(iconsize[1]))
|
||||
bitmap_data=[]
|
||||
|
||||
image_data = np.zeros((bitmap_size[1], bitmap_size[0]), dtype=np.uint8)
|
||||
|
||||
#print(bitmap_array)
|
||||
for value in bitmap_array.split(",\n"):
|
||||
if (value):
|
||||
#print(int(value, 0))
|
||||
bitmap_data.append(int(value, 0))
|
||||
|
||||
print(f"Count {len(bitmap_data)} Size: {bitmap_size[0]}x{bitmap_size[1]} ({bitmap_size[0]*bitmap_size[1]})")
|
||||
|
||||
for y in range(bitmap_size[1]):
|
||||
for x in range(bitmap_size[0]):
|
||||
byte_index = (y * bitmap_size[0] + x) // 8
|
||||
bit_index = x % 8
|
||||
# bit_index = 7 - (x % 8)
|
||||
pixel_value = (bitmap_data[byte_index] >> bit_index) & 1
|
||||
image_data[y, x] = pixel_value * 255
|
||||
|
||||
image = Image.fromarray(image_data, 'L')
|
||||
imagea = image.copy()
|
||||
imagea.putalpha(image)
|
||||
imagea.save(icon_name+".png")
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument("hpp", help="Path for bitmap.hpp")
|
||||
parser.add_argument("--icon", help="Name of the icon from bitmap.hpp, Use 'All' for all icons in file", default = 'titlebar_image')
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
if args.icon:
|
||||
icon_name = args.icon
|
||||
else:
|
||||
icon_name = 'titlebar_image'
|
||||
|
||||
print("parse", icon_name)
|
||||
icons = parse_bitmaphpp(args.hpp, icon_name)
|
||||
|
||||
for icon in icons:
|
||||
convert_hpp(icon[0],icon[1],icon[2])
|
||||
|
||||
|
||||
Executable
+239
@@ -0,0 +1,239 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
# Convert png icons to bitmap.hpp inspired by
|
||||
# make_bitmap.py - Copyright (C) 2016 Furrtek
|
||||
# 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
|
||||
#
|
||||
# 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 numpy as np
|
||||
import re
|
||||
import sys
|
||||
import os
|
||||
from PIL import Image
|
||||
|
||||
### Convert a directory of icons in png format to one bitmap.hpp file.
|
||||
######################################################################
|
||||
|
||||
def pp_bitmaphpp_header():
|
||||
return ("""/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
// This file was generated by make_bitmap.py
|
||||
|
||||
#ifndef __BITMAP_HPP__
|
||||
#define __BITMAP_HPP__
|
||||
|
||||
#include \"ui.hpp\"
|
||||
|
||||
namespace ui {
|
||||
""")
|
||||
|
||||
|
||||
def convert_png(file):
|
||||
bmp_data = []
|
||||
data = 0
|
||||
|
||||
rgb_im = Image.open(file).convert('RGBA')
|
||||
|
||||
if rgb_im.size[0] % 8 or rgb_im.size[1] % 8:
|
||||
print((file + ": Size is not a multiple of 8. Image is not included in bitmap.hpp."))
|
||||
sys.exit(-1)
|
||||
|
||||
name = os.path.basename(file).split(".")[0].lower()
|
||||
|
||||
bmp_data.append(f"\nstatic constexpr uint8_t bitmap_{name}_data[] = {{\n")
|
||||
|
||||
for i in range(rgb_im.size[1]):
|
||||
for j in range(rgb_im.size[0]):
|
||||
r, g, b, a = rgb_im.getpixel((j, i))
|
||||
|
||||
data >>= 1
|
||||
|
||||
if r > 127 and g > 127 and b > 127 and a > 127:
|
||||
data += 128
|
||||
|
||||
if j % 8 == 7:
|
||||
bmp_data.append(" 0x%0.2X,\n" % data)
|
||||
data = 0
|
||||
|
||||
bmp_data.append(f"""}};
|
||||
static constexpr Bitmap bitmap_{name}{{
|
||||
{{{str(rgb_im.size[0])}, {str(rgb_im.size[1])}}},
|
||||
bitmap_{name}_data}};
|
||||
""")
|
||||
|
||||
out_bmpdata = ''.join(map(str, bmp_data))
|
||||
|
||||
return (out_bmpdata)
|
||||
|
||||
def pp_bitmaphpp_data(pngicons_path):
|
||||
count = 0
|
||||
bitmaphpp_data = []
|
||||
for file in os.listdir(pngicons_path):
|
||||
if os.path.isfile(pngicons_path + file) and file.endswith(".png"):
|
||||
bitmaphpp_data.append(convert_png(pngicons_path + file))
|
||||
count += 1
|
||||
|
||||
return bitmaphpp_data
|
||||
|
||||
|
||||
def pp_bitmaphpp_footer():
|
||||
return("""
|
||||
} /* namespace ui */
|
||||
|
||||
#endif /*__BITMAP_HPP__*/
|
||||
""")
|
||||
|
||||
|
||||
def pp_write_bitmaphpp(pngicons_path, hpp_outpath):
|
||||
bitmaphpp_file = []
|
||||
|
||||
bitmaphpp_file.append(pp_bitmaphpp_header())
|
||||
bitmaphpp_file.append("".join(str(x) for x in pp_bitmaphpp_data(pngicons_path)))
|
||||
bitmaphpp_file.append(pp_bitmaphpp_footer())
|
||||
|
||||
out_file = "".join(str(x) for x in bitmaphpp_file)
|
||||
|
||||
with open(hpp_outpath, "w", encoding="utf-8") as fd:
|
||||
fd.writelines(out_file)
|
||||
|
||||
print("Find your bitmap.hpp at", hpp_outpath)
|
||||
|
||||
|
||||
|
||||
|
||||
### Convert from a bitmap.hpp file one or all icons in png.
|
||||
###########################################################
|
||||
|
||||
def parse_bitmaphpp(bitmaphpp_file,icon_name):
|
||||
ico_pattern = re.compile(r"static constexpr uint8_t bitmap_(.*)_data\[\] = {\n((?:\s+(?:.*)\n)+)};\nstatic constexpr Bitmap bitmap_.*\{\n\s+\{(.*)\},", re.MULTILINE)
|
||||
ico_data = []
|
||||
|
||||
# read file to buffer, to find multiline regex
|
||||
readfile = open(bitmaphpp_file,'r')
|
||||
buff = readfile.read()
|
||||
readfile.close()
|
||||
|
||||
if icon_name == 'all':
|
||||
for match in ico_pattern.finditer(buff):
|
||||
ico_data.append([match.group(1), match.group(2), match.group(3)])
|
||||
else:
|
||||
for match in ico_pattern.finditer(buff):
|
||||
if match.group(1) in icon_name:
|
||||
ico_data.append([match.group(1), match.group(2), match.group(3)])
|
||||
|
||||
return (ico_data)
|
||||
|
||||
|
||||
def convert_hpp(icon_name,bitmap_array,iconsize_str,png_outdir):
|
||||
iconsize = iconsize_str.split(", ")
|
||||
bitmap_size = (int(iconsize[0]),int(iconsize[1]))
|
||||
bitmap_data=[]
|
||||
|
||||
image_data = np.zeros((bitmap_size[1], bitmap_size[0]), dtype=np.uint8)
|
||||
|
||||
for value in bitmap_array.split(",\n"):
|
||||
if (value):
|
||||
bitmap_data.append(int(value, 0))
|
||||
|
||||
for y in range(bitmap_size[1]):
|
||||
for x in range(bitmap_size[0]):
|
||||
byte_index = (y * bitmap_size[0] + x) // 8
|
||||
bit_index = x % 8
|
||||
# bit_index = 7 - (x % 8)
|
||||
pixel_value = (bitmap_data[byte_index] >> bit_index) & 1
|
||||
image_data[y, x] = pixel_value * 255
|
||||
|
||||
image = Image.fromarray(image_data, 'L')
|
||||
icon_out = os.path.join(png_outdir,icon_name+".png")
|
||||
image.save(icon_out)
|
||||
|
||||
|
||||
### Processing
|
||||
##############
|
||||
|
||||
if __name__ == '__main__':
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument("hpp", help="Path of the bitmap.hpp")
|
||||
parser.add_argument("graphics", help="Path of <icon>.png files to convert", default=os.path.join(os.getcwd(),"graphics"))
|
||||
parser.add_argument("--icon","-i", help="Name of the icon to convert in reverse. Use 'all' to convert all. More names can be comma seperated.")
|
||||
parser.add_argument("--reverse","-r", help="Convert icon from bitmap.hpp to <name>.png", action="store_true")
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
if args.reverse:
|
||||
print("Reverse: Converting from hpp to png")
|
||||
|
||||
# filter hpp arg is a file
|
||||
hpp_file_path = args.hpp
|
||||
if not os.path.isfile(hpp_file_path):
|
||||
print(f"Error: {hpp_file_path} is not a valid file.")
|
||||
sys.exit(1)
|
||||
|
||||
# filter graph arg is a path
|
||||
if args.graphics:
|
||||
graphics_path = os.path.join(args.graphics, '')
|
||||
else:
|
||||
graphics_path = os.path.join(os.getcwd(),"graphics", '')
|
||||
if not os.path.exists(graphics_path):
|
||||
os.makedirs(graphics_path) # create if not exist
|
||||
|
||||
# define icons to convert
|
||||
if args.icon:
|
||||
icon_name = args.icon
|
||||
else:
|
||||
icon_name = 'titlebar_image'
|
||||
|
||||
icons = parse_bitmaphpp(hpp_file_path, icon_name)
|
||||
|
||||
for icon in icons:
|
||||
print("Converting icon", icon[0])
|
||||
convert_hpp(icon[0], icon[1], icon[2], graphics_path)
|
||||
sys.exit()
|
||||
else:
|
||||
print("Converting from png to hpp")
|
||||
if args.graphics:
|
||||
graphics_path = os.path.join(args.graphics, '')
|
||||
else:
|
||||
graphics_path = os.path.join(os.getcwd(),"graphics", '')
|
||||
print("From path", graphics_path, "to file", args.hpp)
|
||||
pp_write_bitmaphpp(graphics_path, args.hpp)
|
||||
sys.exit()
|
||||
@@ -0,0 +1,184 @@
|
||||
#!/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"
|
||||
|
||||
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::focus() {
|
||||
menu_view.focus();
|
||||
// put focus on last text line to make it more obvious that list is scrollable
|
||||
menu_view.set_highlighted(10);
|
||||
}
|
||||
|
||||
} /* 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
Binary file not shown.
Binary file not shown.
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user